Millepede-II V04-16-01
pede.f90
Go to the documentation of this file.
1! Code converted using TO_F90 by Alan Miller
2! Date: 2012-03-16 Time: 11:06:00
3
27
252
537
538
792
830
873
875PROGRAM mptwo
876 USE mpmod
877 USE mpdalc
878 USE mptest1, ONLY: nplan,del,dvd
879 USE mptest2, ONLY: nlyr,nmx,nmy,sdevx,sdevy,ntot
880
881 IMPLICIT NONE
882 REAL(mps) :: andf
883 REAL(mps) :: c2ndf
884 REAL(mps) :: deltat
885 REAL(mps) :: diff
886 REAL(mps) :: err
887 REAL(mps) :: gbu
888 REAL(mps) :: gmati
889 REAL(mps) :: rej
890 REAL :: rloop1
891 REAL :: rloop2
892 REAL :: rstext
893 REAL(mps) :: secnd
894 REAL :: rst
895 REAL :: rstp
896 REAL, DIMENSION(2) :: ta
897 INTEGER(mpi) :: i
898 INTEGER(mpi) :: ii
899 INTEGER(mpi) :: iopnmp
900 INTEGER(mpi) :: ix
901 INTEGER(mpi) :: ixv
902 INTEGER(mpi) :: iy
903 INTEGER(mpi) :: k
904 INTEGER(mpi) :: kfl
905 INTEGER(mpi) :: lun
906 INTEGER :: minut
907 INTEGER :: nhour
908 INTEGER(mpi) :: nmxy
909 INTEGER(mpi) :: nrc
910 INTEGER(mpi) :: nsecnd
911 INTEGER(mpi) :: ntsec
912
913 CHARACTER (LEN=24) :: chdate
914 CHARACTER (LEN=24) :: chost
915#ifdef LAPACK64
916 CHARACTER (LEN=6) :: c6
917 INTEGER major, minor, patch
918#endif
919
920 INTEGER(mpl) :: rows
921 INTEGER(mpl) :: cols
922
923 REAL(mpd) :: sums(9)
924 !$ INTEGER(mpi) :: OMP_GET_NUM_PROCS,OMP_GET_MAX_THREADS
925 !$ INTEGER(mpi) :: MXTHRD
926 !$ INTEGER(mpi) :: NPROC
927
928 REAL etime
929
930 SAVE
931 ! ...
932 rstp=etime(ta)
933 CALL fdate(chdate)
934
935 ! millepede monitoring file
936 lunmon=0
937 ! millepede.log file
938 lunlog=8
939 lvllog=1
940 CALL mvopen(lunlog,'millepede.log')
941 CALL getenv('HOSTNAME',chost)
942 IF (chost(1:1) == ' ') CALL getenv('HOST',chost)
943 WRITE(*,*) '($Id: c6be33cb87ef25e4226d5088ec53ebf6d39f4712 $)'
944 iopnmp=0
945 !$ iopnmp=1
946 !$ WRITE(*,*) 'using OpenMP (TM)'
947#ifdef LAPACK64
948 CALL ilaver( major,minor, patch )
949 WRITE(*,110) lapack64, major,minor, patch
950110 FORMAT(' using LAPACK64 with ',(a),', version ',i0,'.',i0,'.',i0)
951#ifdef PARDISO
952 WRITE(*,*) 'using Intel oneMKL PARDISO'
953#endif
954#endif
955#ifdef __GFORTRAN__
956 WRITE(*,111) __gnuc__ , __gnuc_minor__ , __gnuc_patchlevel__
957111 FORMAT(' compiled with gcc ',i0,'.',i0,'.',i0)
958#endif
959#ifdef __PGIC__
960 WRITE(*,111) __pgic__ , __pgic_minor__ , __pgic_patchlevel__
961111 FORMAT(' compiled with pgi ',i0,'.',i0,'.',i0)
962#endif
963 WRITE(*,*) ' '
964 WRITE(*,*) ' < Millepede II-P starting ... ',chdate
965 WRITE(*,*) ' ',chost
966 WRITE(*,*) ' '
967
968 WRITE(8,*) '($Id: c6be33cb87ef25e4226d5088ec53ebf6d39f4712 $)'
969 WRITE(8,*) ' '
970 WRITE(8,*) 'Log-file Millepede II-P ', chdate
971 WRITE(8,*) ' ', chost
972
973 CALL peend(-1,'Still running or crashed')
974 ! read command line and text files
975
976 CALL filetc ! command line and steering file analysis
977 CALL filetx ! read text files
978 ! dummy call for dynamic memory allocation
979 CALL gmpdef(0,nfilb,'dummy call')
980
981 IF (icheck > 0) THEN
982 WRITE(*,*) '!!! Checking input only, no calculation of a solution !!!'
983 WRITE(8,*) '!!! Checking input only, no calculation of a solution !!!'
984 END IF
985 lvllog=mprint ! export print level
986 IF (memdbg > 0) printflagalloc=1 ! debug memory management
987 !$ WRITE(*,*)
988 !$ NPROC=1
989 !$ MXTHRD=1
990 !$ NPROC=OMP_GET_NUM_PROCS() ! number of processors available
991 !$ CALL OMP_SET_NUM_THREADS(MTHRD) ! set max number of threads to MTHRD
992 !$ MXTHRD=OMP_GET_MAX_THREADS() ! get max number of threads back
993 !$ WRITE(*,*) 'Number of processors available: ', NPROC
994 !$ WRITE(*,*) 'Maximum number of OpenMP threads: ', MXTHRD
995 !$ WRITE(*,*) 'Number of threads for processing: ', MTHRD
996 !$ IF (MXREC.GT.0) MTHRDR=1 ! to get allways the same MXREC records
997 !$ IF (ICHECK.GT.1) MTHRDR=1 ! to get allways the same order of records
998 !$ WRITE(*,*) 'Number of threads for reading: ', MTHRDR
999 !$POMP INST INIT ! start profiling with ompP
1000#ifdef LAPACK64
1001 IF(iopnmp > 0) THEN
1002 CALL getenv('OMP_NUM_THREADS',c6)
1003 ELSE
1004 CALL getenv(lapack64//'_NUM_THREADS',c6)
1005 END IF
1006 IF (c6(1:1) == ' ') THEN
1007 IF(iopnmp > 0) THEN
1008 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty OMP_NUM_THREADS)'
1009 ELSE
1010 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty ',lapack64//'_NUM_THREADS)'
1011 END IF
1012 ELSE
1013 WRITE(*,*) 'Number of threads for LAPACK: ', c6
1014 END IF
1015#endif
1016 cols=mthrd
1017 CALL mpalloc(globalchi2sumd,cols,'fractional part of Chi2 sum')
1018 globalchi2sumd=0.0_mpd
1019 CALL mpalloc(globalchi2sumi,cols,'integer part of Chi2 sum')
1020 globalchi2sumi=0_mpl
1021 CALL mpalloc(globalndfsum,cols,'NDF sum')
1022 globalndfsum=0_mpl
1023 CALL mpalloc(globalndfsumw,cols,'weighted NDF sum')
1024 globalndfsumw=0.0_mpd
1025
1026 IF (ncache < 0) THEN
1027 ncache=25000000*mthrd ! default cache size (100 MB per thread)
1028 ENDIF
1029 rows=6; cols=mthrdr
1030 CALL mpalloc(readbufferinfo,rows,cols,'read buffer header')
1031 ! histogram file
1032 lun=7
1033 CALL mvopen(lun,'millepede.his')
1034 CALL hmplun(lun) ! unit for histograms
1035 CALL gmplun(lun) ! unit for xy data
1036
1037 ! debugging
1038 IF(nrecpr /= 0.OR.nrecp2 /= 0) THEN
1039 CALL mvopen(1,'mpdebug.txt')
1040 END IF
1041
1042 rstext=etime(ta)
1043 times(0)=rstext-rstp ! time for text processing
1044
1045 ! preparation of data sub-arrays
1046
1047 CALL loop1
1048 rloop1=etime(ta)
1049 times(1)=rloop1-rstext ! time for LOOP1
1050
1051 CALL loop2
1052 IF(chicut /= 0.0) THEN
1053 WRITE(8,*) 'Chi square cut equiv 3 st.dev applied ...'
1054 WRITE(8,*) ' in first iteration with factor',chicut
1055 WRITE(8,*) ' in second iteration with factor',chirem
1056 WRITE(8,*) ' (reduced by sqrt in next iterations)'
1057 END IF
1058
1059 IF(lhuber /= 0) THEN
1060 WRITE(8,*) 'Down-weighting of outliers in', lhuber,' iterations'
1061 WRITE(8,*) 'Cut on downweight fraction',dwcut
1062 END IF
1063
1064 rloop2=etime(ta)
1065 times(2)=rloop2-rloop1 ! time for LOOP2
1066
1067 IF(icheck > 0) THEN
1068 CALL prtstat
1069 IF (ncgbe < 0) THEN
1070 CALL peend(5,'Ended without solution (empty constraints)')
1071 ELSE
1072 CALL peend(0,'Ended normally')
1073 END IF
1074 GOTO 99 ! only checking input
1075 END IF
1076
1077 ! use different solution methods
1078
1079 CALL mstart('Iteration') ! Solution module starting
1080
1081 CALL xloopn ! all methods
1082
1083 ! ------------------------------------------------------------------
1084
1085 IF(nloopn > 2.AND.nhistp /= 0) THEN ! last iteration
1086 CALL hmprnt(3) ! scaled residual of single measurement (with global deriv.)
1087 CALL hmprnt(12) ! scaled residual of single measurement (no global deriv.)
1088 CALL hmprnt(4) ! chi^2/Ndf
1089 END IF
1090 IF(nloopn > 2) THEN
1091 CALL hmpwrt(3)
1092 CALL hmpwrt(12)
1093 CALL hmpwrt(4)
1094 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
1095 IF (nloopn <= lfitnp) THEN
1096 CALL hmpwrt(13)
1097 CALL hmpwrt(14)
1098 CALL gmpwrt(5)
1099 END IF
1100 END IF
1101 IF(nhistp /= 0) THEN
1102 CALL gmprnt(1)
1103 CALL gmprnt(2)
1104 END IF
1105 CALL gmpwrt(1) ! output of xy data
1106 CALL gmpwrt(2) ! output of xy data
1107 ! 'track quality' per binary file
1108 IF (nfilb > 1) THEN
1109 CALL gmpdef(6,1,'log10(#records) vs file number')
1110 CALL gmpdef(7,1,'final rejection fraction vs file number')
1111 CALL gmpdef(8,1, &
1112 'final <Chi^2/Ndf> from accepted local fits vs file number')
1113 CALL gmpdef(9,1, '<Ndf> from accepted local fits vs file number')
1114
1115 DO i=1,nfilb
1116 kfl=kfd(2,i)
1117 nrc=-kfd(1,i)
1118 IF (nrc > 0) THEN
1119 rej=real(nrc-jfd(kfl),mps)/real(nrc,mps)
1120 CALL gmpxy(6,real(kfl,mps),log10(real(nrc,mps))) ! log10(#records) vs file
1121 CALL gmpxy(7,real(kfl,mps),rej) ! rejection fraction vs file
1122 END IF
1123 IF (jfd(kfl) > 0) THEN
1124 c2ndf=cfd(kfl)/real(jfd(kfl),mps)
1125 CALL gmpxy(8,real(kfl,mps),c2ndf) ! <Chi2/NDF> vs file
1126 andf=real(dfd(kfl),mps)/real(jfd(kfl),mps)
1127 CALL gmpxy(9,real(kfl,mps),andf) ! <NDF> vs file
1128 END IF
1129 END DO
1130 IF(nhistp /= 0) THEN
1131 CALL gmprnt(6)
1132 CALL gmprnt(7)
1133 CALL gmprnt(8)
1134 CALL gmprnt(9)
1135 END IF
1136 CALL gmpwrt(6) ! output of xy data
1137 CALL gmpwrt(7) ! output of xy data
1138 CALL gmpwrt(8) ! output of xy data
1139 CALL gmpwrt(9) ! output of xy data
1140 END IF
1141
1142 IF(ictest == 1) THEN
1143 WRITE(*,*) ' '
1144 WRITE(*,*) 'Misalignment test wire chamber'
1145 WRITE(*,*) ' '
1146
1147 CALL hmpdef( 9,-0.0015,+0.0015,'True - fitted displacement')
1148 CALL hmpdef(10,-0.0015,+0.0015,'True - fitted Vdrift')
1149 DO i=1,4
1150 sums(i)=0.0_mpd
1151 END DO
1152 DO i=1,nplan
1153 diff=real(-del(i)-globalparameter(i),mps)
1154 sums(1)=sums(1)+diff
1155 sums(2)=sums(2)+diff*diff
1156 diff=real(-dvd(i)-globalparameter(100+i),mps)
1157 sums(3)=sums(3)+diff
1158 sums(4)=sums(4)+diff*diff
1159 END DO
1160 sums(1)=0.01_mpd*sums(1)
1161 sums(2)=sqrt(0.01_mpd*sums(2))
1162 sums(3)=0.01_mpd*sums(3)
1163 sums(4)=sqrt(0.01_mpd*sums(4))
1164 WRITE(*,143) 'Parameters 1 - 100: mean =',sums(1), 'rms =',sums(2)
1165 WRITE(*,143) 'Parameters 101 - 200: mean =',sums(3), 'rms =',sums(4)
1166143 FORMAT(6x,a28,f9.6,3x,a5,f9.6)
1167 WRITE(*,*) ' '
1168 WRITE(*,*) ' '
1169 WRITE(*,*) ' I label simulated fitted diff'
1170 WRITE(*,*) ' -------------------------------------------- '
1171 DO i=1,100
1172 WRITE(*,102) i,globalparlabelindex(1,i),-del(i),globalparameter(i),-del(i)-globalparameter(i)
1173 diff=real(-del(i)-globalparameter(i),mps)
1174 CALL hmpent( 9,diff)
1175 END DO
1176 DO i=101,200
1177 WRITE(*,102) i,globalparlabelindex(1,i),-dvd(i-100),globalparameter(i),-dvd(i-100)-globalparameter(i)
1178 diff=real(-dvd(i-100)-globalparameter(i),mps)
1179 CALL hmpent(10,diff)
1180 END DO
1181 IF(nhistp /= 0) THEN
1182 CALL hmprnt( 9)
1183 CALL hmprnt(10)
1184 END IF
1185 CALL hmpwrt( 9)
1186 CALL hmpwrt(10)
1187 END IF
1188 IF(ictest > 1) THEN
1189 WRITE(*,*) ' '
1190 WRITE(*,*) 'Misalignment test Si tracker'
1191 WRITE(*,*) ' '
1192
1193 CALL hmpdef( 9,-0.0025,+0.0025,'True - fitted displacement X')
1194 CALL hmpdef(10,-0.025,+0.025,'True - fitted displacement Y')
1195 DO i=1,9
1196 sums(i)=0.0_mpd
1197 END DO
1198 nmxy=nmx*nmy
1199 ix=0
1200 iy=ntot
1201 DO i=1,nlyr
1202 DO k=1,nmxy
1203 ix=ix+1
1204 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1205 sums(1)=sums(1)+1.0_mpd
1206 sums(2)=sums(2)+diff
1207 sums(3)=sums(3)+diff*diff
1208 ixv=globalparlabelindex(2,ix)
1209 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1210 ii=(ixv*ixv+ixv)/2
1211 gmati=real(globalmatd(ii),mps)
1212 err=sqrt(abs(gmati))
1213 diff=diff/err
1214 sums(7)=sums(7)+1.0_mpd
1215 sums(8)=sums(8)+diff
1216 sums(9)=sums(9)+diff*diff
1217 END IF
1218 END DO
1219 IF (mod(i,3) == 1) THEN
1220 DO k=1,nmxy
1221 iy=iy+1
1222 diff=-real(sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1223 sums(4)=sums(4)+1.0_mpd
1224 sums(5)=sums(5)+diff
1225 sums(6)=sums(6)+diff*diff
1226 ixv=globalparlabelindex(2,iy)
1227 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1228 ii=(ixv*ixv+ixv)/2
1229 gmati=real(globalmatd(ii),mps)
1230 err=sqrt(abs(gmati))
1231 diff=diff/err
1232 sums(7)=sums(7)+1.0_mpd
1233 sums(8)=sums(8)+diff
1234 sums(9)=sums(9)+diff*diff
1235 END IF
1236 END DO
1237 END IF
1238 END DO
1239 sums(2)=sums(2)/sums(1)
1240 sums(3)=sqrt(sums(3)/sums(1))
1241 sums(5)=sums(5)/sums(4)
1242 sums(6)=sqrt(sums(6)/sums(4))
1243 WRITE(*,143) 'Parameters 1 - 500: mean =',sums(2), 'rms =',sums(3)
1244 WRITE(*,143) 'Parameters 501 - 700: mean =',sums(5), 'rms =',sums(6)
1245 IF (sums(7) > 0.5_mpd) THEN
1246 sums(8)=sums(8)/sums(7)
1247 sums(9)=sqrt(sums(9)/sums(7))
1248 WRITE(*,143) 'Parameter pulls, all: mean =',sums(8), 'rms =',sums(9)
1249 END IF
1250 WRITE(*,*) ' '
1251 WRITE(*,*) ' '
1252 WRITE(*,*) ' I label simulated fitted diff'
1253 WRITE(*,*) ' -------------------------------------------- '
1254 ix=0
1255 iy=ntot
1256 DO i=1,nlyr
1257 DO k=1,nmxy
1258 ix=ix+1
1259 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1260 CALL hmpent( 9,diff)
1261 WRITE(*,102) ix,globalparlabelindex(1,ix),-sdevx((i-1)*nmxy+k),globalparameter(ix),-diff
1262 END DO
1263 END DO
1264 DO i=1,nlyr
1265 IF (mod(i,3) == 1) THEN
1266 DO k=1,nmxy
1267 iy=iy+1
1268 diff=real(-sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1269 CALL hmpent(10,diff)
1270 WRITE(*,102) iy,globalparlabelindex(1,iy),-sdevy((i-1)*nmxy+k),globalparameter(iy),-diff
1271 END DO
1272 END IF
1273 END DO
1274 IF(nhistp /= 0) THEN
1275 CALL hmprnt( 9)
1276 CALL hmprnt(10)
1277 END IF
1278 CALL hmpwrt( 9)
1279 CALL hmpwrt(10)
1280 END IF
1281
1282 IF(nrec1+nrec2 > 0) THEN
1283 WRITE(8,*) ' '
1284 IF(nrec1 > 0) THEN
1285 WRITE(8,*) 'Record',nrec1,' has largest residual:',value1
1286 END IF
1287 IF(nrec2 > 0) THEN
1288 WRITE(8,*) 'Record',nrec2,' has largest Chi^2/Ndf:',value2
1289 END IF
1290 END IF
1291 IF(nrec3 < huge(nrec3)) THEN
1292 WRITE(8,*) 'Record',nrec3, ' is first with error (rank deficit/NaN)'
1293 END IF
129499 WRITE(8,*) ' '
1295 IF (iteren > mreqenf) THEN
1296 WRITE(8,*) 'In total 3 +',nloopn,' loops through the data files'
1297 ELSE
1298 WRITE(8,*) 'In total 2 +',nloopn,' loops through the data files'
1299 ENDIF
1300 IF (mnrsit > 0) THEN
1301 WRITE(8,*) ' '
1302 WRITE(8,*) 'In total ',mnrsit,' internal MINRES iterations'
1303 END IF
1304
1305 WRITE(8,103) times(0),times(1),times(2),times(4),times(7), &
1306 times(5),times(8),times(3),times(6)
1307
1308 rst=etime(ta)
1309 deltat=rst-rstp
1310 ntsec=nint(deltat,mpi)
1311 CALL sechms(deltat,nhour,minut,secnd)
1312 nsecnd=nint(secnd,mpi) ! round
1313 WRITE(8,*) 'Total time =',ntsec,' seconds =',nhour,' h',minut, &
1314 ' m',nsecnd,' seconds'
1315 CALL fdate(chdate)
1316 WRITE(8,*) 'end ', chdate
1317 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1318 WRITE(8,*) ' '
1319 WRITE(8,105) gbu
1320
1321 ! Rejects ----------------------------------------------------------
1322
1323 IF(nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) /= 0) THEN
1324 WRITE(8,*) ' '
1325 WRITE(8,*) 'Data rejected in last iteration: '
1326 WRITE(8,*) ' ', &
1327 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', &
1328 nrejec(2), ' (huge) ',nrejec(3),' (large)'
1329 WRITE(8,*) ' '
1330 END IF
1331 IF (icheck <= 0) CALL explfc(8)
1332
1333 WRITE(*,*) ' '
1334 WRITE(*,*) ' < Millepede II-P ending ... ', chdate ! with exit code',ITEXIT,' >'
1335 WRITE(*,*) ' '
1336 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1337 WRITE(*,105) gbu
1338#ifdef LAPACK64
1339#ifdef PARDISO
1340 IF(ipdmem > 0) WRITE(*,106) real(ipdmem,mps)*1.e-6
1341106 FORMAT(' PARDISO dyn. memory allocation: ',f11.6,' GB')
1342#endif
1343#endif
1344 WRITE(*,*) ' '
1345
1346102 FORMAT(2x,i4,i10,2x,3f10.5)
1347103 FORMAT(' Times [in sec] for text processing',f12.3/ &
1348 ' LOOP1',f12.3/ &
1349 ' LOOP2',f12.3/ &
1350 ' func. value ',f12.3,' *',f4.0/ &
1351 ' func. value, global matrix, solution',f12.3,' *',f4.0/ &
1352 ' new solution',f12.3,' *',f4.0/)
1353105 FORMAT(' Peak dynamic memory allocation: ',f11.6,' GB')
1354END PROGRAM mptwo ! Mille
1355
1362
1363SUBROUTINE solglo(ivgbi)
1364 USE mpmod
1365 USE minresmodule, ONLY: minres
1366
1367 IMPLICIT NONE
1368 REAL(mps) :: par
1369 REAL(mps) :: dpa
1370 REAL(mps) :: err
1371 REAL(mps) :: gcor2
1372 INTEGER(mpi) :: iph
1373 INTEGER(mpi) :: istop
1374 INTEGER(mpi) :: itgbi
1375 INTEGER(mpi) :: itgbl
1376 INTEGER(mpi) :: itn
1377 INTEGER(mpi) :: itnlim
1378 INTEGER(mpi) :: nout
1379
1380 INTEGER(mpi), INTENT(IN) :: ivgbi
1381
1382 REAL(mpd) :: shift
1383 REAL(mpd) :: rtol
1384 REAL(mpd) :: anorm
1385 REAL(mpd) :: acond
1386 REAL(mpd) :: arnorm
1387 REAL(mpd) :: rnorm
1388 REAL(mpd) :: ynorm
1389 REAL(mpd) :: gmati
1390 REAL(mpd) :: diag
1391 REAL(mpd) :: matij
1392 LOGICAL :: checka
1393 EXTERNAL avprod, mcsolv, mvsolv
1394 SAVE
1395 DATA iph/0/
1396 ! ...
1397 IF(iph == 0) THEN
1398 iph=1
1399 WRITE(*,101)
1400 END IF
1401 itgbi=globalparvartototal(ivgbi)
1402 itgbl=globalparlabelindex(1,itgbi)
1403
1404 globalvector=0.0_mpd ! reset rhs vector IGVEC
1405 globalvector(ivgbi)=1.0_mpd
1406
1407 ! NOUT =6
1408 nout =0
1409 itnlim=200
1410 shift =0.0_mpd
1411 rtol = mrestl ! from steering
1412 checka=.false.
1413
1414
1415 IF(mbandw == 0) THEN ! default preconditioner
1416 CALL minres(nagb, avprod, mcsolv, globalvector, shift, checka ,.true. , &
1417 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1418
1419 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1420 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.true. , &
1421 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1422 ELSE
1423 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.false. , &
1424 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1425 END IF
1426
1427 par=real(globalparameter(itgbi),mps)
1428 dpa=real(par-globalparstart(itgbi),mps)
1429 gmati=globalcorrections(ivgbi)
1430 err=sqrt(abs(real(gmati,mps)))
1431 IF(gmati < 0.0_mpd) err=-err
1432 diag=matij(ivgbi,ivgbi)
1433 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1434 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1435101 FORMAT(1x,' label parameter presigma differ', &
1436 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1437102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1438END SUBROUTINE solglo
1439
1446
1447SUBROUTINE solgloqlp(ivgbi)
1448 USE mpmod
1449 USE minresqlpmodule, ONLY: minresqlp
1450
1451 IMPLICIT NONE
1452 REAL(mps) :: par
1453 REAL(mps) :: dpa
1454 REAL(mps) :: err
1455 REAL(mps) :: gcor2
1456 INTEGER(mpi) :: iph
1457 INTEGER(mpi) :: istop
1458 INTEGER(mpi) :: itgbi
1459 INTEGER(mpi) :: itgbl
1460 INTEGER(mpi) :: itn
1461 INTEGER(mpi) :: itnlim
1462 INTEGER(mpi) :: nout
1463
1464 INTEGER(mpi), INTENT(IN) :: ivgbi
1465
1466 REAL(mpd) :: shift
1467 REAL(mpd) :: rtol
1468 REAL(mpd) :: mxxnrm
1469 REAL(mpd) :: trcond
1470 REAL(mpd) :: gmati
1471 REAL(mpd) :: diag
1472 REAL(mpd) :: matij
1473
1474 EXTERNAL avprod, mcsolv, mvsolv
1475 SAVE
1476 DATA iph/0/
1477 ! ...
1478 IF(iph == 0) THEN
1479 iph=1
1480 WRITE(*,101)
1481 END IF
1482 itgbi=globalparvartototal(ivgbi)
1483 itgbl=globalparlabelindex(1,itgbi)
1484
1485 globalvector=0.0_mpd ! reset rhs vector IGVEC
1486 globalvector(ivgbi)=1.0_mpd
1487
1488 ! NOUT =6
1489 nout =0
1490 itnlim=200
1491 shift =0.0_mpd
1492 rtol = mrestl ! from steering
1493 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
1494 IF(mrmode == 1) THEN
1495 trcond = 1.0_mpd/epsilon(trcond) ! only QR
1496 ELSE IF(mrmode == 2) THEN
1497 trcond = 1.0_mpd ! only QLP
1498 ELSE
1499 trcond = mrtcnd ! QR followed by QLP
1500 END IF
1501
1502 IF(mbandw == 0) THEN ! default preconditioner
1503 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mcsolv, nout=nout, &
1504 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1505 x=globalcorrections, istop=istop, itn=itn)
1506 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1507 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mvsolv, nout=nout, &
1508 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1509 x=globalcorrections, istop=istop, itn=itn)
1510 ELSE
1511 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, nout=nout, &
1512 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1513 x=globalcorrections, istop=istop, itn=itn)
1514 END IF
1515
1516 par=real(globalparameter(itgbi),mps)
1517 dpa=real(par-globalparstart(itgbi),mps)
1518 gmati=globalcorrections(ivgbi)
1519 err=sqrt(abs(real(gmati,mps)))
1520 IF(gmati < 0.0_mpd) err=-err
1521 diag=matij(ivgbi,ivgbi)
1522 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1523 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1524101 FORMAT(1x,' label parameter presigma differ', &
1525 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1526102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1527END SUBROUTINE solgloqlp
1528
1530SUBROUTINE addcst
1531 USE mpmod
1532
1533 IMPLICIT NONE
1534 REAL(mpd) :: climit
1535 REAL(mpd) :: factr
1536 REAL(mpd) :: sgm
1537
1538 INTEGER(mpi) :: i
1539 INTEGER(mpi) :: icgb
1540 INTEGER(mpi) :: irhs
1541 INTEGER(mpi) :: itgbi
1542 INTEGER(mpi) :: ivgb
1543 INTEGER(mpi) :: j
1544 INTEGER(mpi) :: jcgb
1545 INTEGER(mpi) :: l
1546 INTEGER(mpi) :: label
1547 INTEGER(mpi) :: nop
1548 INTEGER(mpi) :: inone
1549
1550 REAL(mpd) :: rhs
1551 REAL(mpd) :: drhs(4)
1552 INTEGER(mpi) :: idrh (4)
1553 SAVE
1554 ! ...
1555 nop=0
1556 IF(lenconstraints == 0) RETURN ! no constraints
1557 climit=1.0e-5 ! limit for printout
1558 irhs=0 ! number of values in DRHS(.), to be printed
1559
1560 DO jcgb=1,ncgb
1561 icgb=matconssort(3,jcgb) ! unsorted constraint index
1562 i=vecconsstart(icgb)
1563 rhs=listconstraints(i )%value ! right hand side
1564 sgm=listconstraints(i+1)%value ! sigma parameter
1565 DO j=i+2,vecconsstart(icgb+1)-1
1566 label=listconstraints(j)%label
1567 factr=listconstraints(j)%value
1568 itgbi=inone(label) ! -> ITGBI= index of parameter label
1569 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1570
1571 IF(icalcm == 1.AND.nagb > nvgb.AND.ivgb > 0) THEN
1572 CALL mupdat(nvgb+jcgb,ivgb,factr) ! add to matrix
1573 END IF
1574
1575 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
1576 END DO
1577 IF(abs(rhs) > climit) THEN
1578 irhs=irhs+1
1579 idrh(irhs)=jcgb
1580 drhs(irhs)=rhs
1581 nop=1
1582 IF(irhs == 4) THEN
1583 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1584 irhs=0
1585 END IF
1586 END IF
1587 vecconsresiduals(jcgb)=rhs
1588 IF (nagb > nvgb) globalvector(nvgb+jcgb)=rhs
1589 END DO
1590
1591 IF(irhs /= 0) THEN
1592 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1593 END IF
1594 IF(nop == 0) RETURN
1595 WRITE(*,102) ' Constraints: only equation values >', climit,' are printed'
1596101 FORMAT(' ',4(i6,g11.3))
1597102 FORMAT(a,g11.2,a)
1598END SUBROUTINE addcst
1599
1604SUBROUTINE grpcon
1605 USE mpmod
1606 USE mpdalc
1607
1608 IMPLICIT NONE
1609 INTEGER(mpi) :: i
1610 INTEGER(mpi) :: icgb
1611 INTEGER(mpi) :: icgrp
1612 INTEGER(mpi) :: ioff
1613 INTEGER(mpi) :: itgbi
1614 INTEGER(mpi) :: j
1615 INTEGER(mpi) :: jcgb
1616 INTEGER(mpi) :: label
1617 INTEGER(mpi) :: labelf
1618 INTEGER(mpi) :: labell
1619 INTEGER(mpi) :: last
1620 INTEGER(mpi) :: line1
1621 INTEGER(mpi) :: ncon
1622 INTEGER(mpi) :: ndiff
1623 INTEGER(mpi) :: npar
1624 INTEGER(mpi) :: inone
1625 INTEGER(mpi) :: itype
1626 INTEGER(mpi) :: ncgbd
1627 INTEGER(mpi) :: ncgbr
1628 INTEGER(mpi) :: ncgbw
1629 INTEGER(mpi) :: ncgrpd
1630 INTEGER(mpi) :: ncgrpr
1631 INTEGER(mpi) :: next
1632
1633 INTEGER(mpl):: length
1634 INTEGER(mpl) :: rows
1635
1636 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsOffsets
1637 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsList
1638 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParOffsets
1639 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParList
1640 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1641
1642 ncgb=0
1643 ncgbw=0
1644 IF(lenconstraints == 0) RETURN ! no constraints
1645
1646 i=0
1647 last=0
1648 itype=0
1649 ! find next constraint header and count nr of constraints
1650 DO WHILE(i < lenconstraints)
1651 i=i+1
1652 label=listconstraints(i)%label
1653 IF(last < 0.AND.label < 0) THEN
1654 ncgb=ncgb+1
1655 itype=-label
1656 IF(itype == 2) ncgbw=ncgbw+1
1657 END IF
1658 last=label
1659 IF(label > 0) THEN
1660 itgbi=inone(label) ! -> ITGBI= index of parameter label
1661 globalparcons(itgbi)=globalparcons(itgbi)+1
1662 END IF
1663 IF(label > 0.AND.itype == 2) THEN ! weighted constraints
1664 itgbi=inone(label) ! -> ITGBI= index of parameter label
1666 END IF
1667 END DO
1668
1669 WRITE(*,*)
1670 IF (ncgbw == 0) THEN
1671 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files'
1672 ELSE
1673 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files,',ncgbw, 'weighted'
1674 END IF
1675 WRITE(*,*)
1676
1677 ! keys and index for sorting of constraints
1678 length=ncgb+1; rows=3
1679 CALL mpalloc(matconssort,rows,length,'keys and index for sorting (I)')
1680 matconssort(1,ncgb+1)=ntgb+1
1681 ! start of constraint in list
1682 CALL mpalloc(vecconsstart,length,'start of constraint in list (I)')
1684 ! start and parameter range of constraint groups
1685 CALL mpalloc(matconsgroups,rows,length,'start of constraint groups, par. range (I)')
1686 ! parameter ranges (all, variable) of constraints
1687 length=ncgb; rows=4
1688 CALL mpalloc(matconsranges,rows,length,'parameter ranges for constraint (I)')
1689
1690 length=ncgb; rows=3
1691 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1692 matconsgroupindex=0
1693 length=ncgb+1
1694 CALL mpalloc(vecconsparoffsets,length,'offsets for global par list for cons. (I)')
1695 length=ntgb+1
1696 CALL mpalloc(vecparconsoffsets,length,'offsets for cons. list for global par. (I)')
1697 vecparconsoffsets(1)=0
1698 DO i=1,ntgb
1699 vecparconsoffsets(i+1)=vecparconsoffsets(i)+globalparcons(i)
1700 END DO
1702
1703 length=vecparconsoffsets(ntgb+1)
1704 CALL mpalloc(vecconsparlist,length,'global par. list for constraint (I)')
1705 CALL mpalloc(vecparconslist,length,'constraint list for global par. (I)')
1706
1707 ! prepare
1708 i=1
1709 ioff=0
1710 vecconsparoffsets(1)=ioff
1711 DO icgb=1,ncgb
1712 ! new constraint
1713 vecconsstart(icgb)=i
1714 line1=-listconstraints(i)%label
1715 npar=0
1716 i=i+2
1717 DO
1718 label=listconstraints(i)%label
1719 itgbi=inone(label) ! -> ITGBI= index of parameter label
1720 ! list of constraints for 'itgbi'
1721 globalparcons(itgbi)=globalparcons(itgbi)+1
1722 vecparconslist(vecparconsoffsets(itgbi)+globalparcons(itgbi))=icgb
1723 npar=npar+1
1724 vecconsparlist(ioff+npar)=itgbi
1725 i=i+1
1726 IF(i > lenconstraints) EXIT
1727 IF(listconstraints(i)%label < 0) EXIT
1728 END DO
1729 ! sort to find duplicates
1730 CALL sort1k(vecconsparlist(ioff+1),npar)
1731 last=-1
1732 ndiff=0
1733 DO j=1,npar
1734 next=vecconsparlist(ioff+j)
1735 IF (next /= last) THEN
1736 ndiff=ndiff+1
1737 vecconsparlist(ioff+ndiff) = next
1738 END IF
1739 last=next
1740 END DO
1741 matconsranges(1,icgb)=vecconsparlist(ioff+1) ! min parameter
1742 matconsranges(3,icgb)=vecconsparlist(ioff+1) ! min parameter
1743 ioff=ioff+ndiff
1744 matconsranges(2,icgb)=vecconsparlist(ioff) ! max parameter
1745 matconsranges(4,icgb)=vecconsparlist(ioff) ! max parameter
1746 vecconsparoffsets(icgb+1)=ioff
1747 END DO
1749
1750 ! sort (by first, last parameter)
1751 DO icgb=1,ncgb
1752 matconssort(1,icgb)=matconsranges(1,icgb) ! first par.
1753 matconssort(2,icgb)=matconsranges(2,icgb) ! last par.
1754 matconssort(3,icgb)=icgb ! index
1755 END DO
1756 CALL sort2i(matconssort,ncgb)
1757
1758 IF (icheck>1) THEN
1759 print *, ' Constraint #parameters first par. last par. first line'
1760 END IF
1761 ! split into disjoint groups
1762 ncgrp=0
1764 DO jcgb=1,ncgb
1765 icgb=matconssort(3,jcgb)
1766 IF (icheck>0) THEN
1767 npar=vecconsparoffsets(icgb+1)-vecconsparoffsets(icgb)
1768 line1=-listconstraints(vecconsstart(icgb))%label
1769 labelf=globalparlabelindex(1,matconsranges(1,icgb))
1770 labell=globalparlabelindex(1,matconsranges(2,icgb))
1771 print *, jcgb, npar, labelf, labell, line1
1772 END IF
1773 ! already part of group?
1774 icgrp=matconsgroupindex(1,icgb)
1775 IF (icgrp == 0) THEN
1776 ! check all parameters
1777 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1778 itgbi=vecconsparlist(i)
1779 ! check all related constraints
1780 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1781 icgrp=matconsgroupindex(1,vecparconslist(j))
1782 ! already part of group?
1783 IF (icgrp > 0) EXIT
1784 END DO
1785 IF (icgrp > 0) EXIT
1786 END DO
1787 IF (icgrp == 0) THEN
1788 ! new group
1789 ncgrp=ncgrp+1
1790 icgrp=ncgrp
1791 END IF
1792 END IF
1793 ! add to group
1794 matconsgroupindex(2,icgb)=jcgb
1795 matconsgroupindex(3,icgb)=icgb
1796 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1797 itgbi=vecconsparlist(i)
1798 globalparcons(itgbi)=icgrp
1799 ! mark all related constraints
1800 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1801 matconsgroupindex(1,vecparconslist(j))=icgrp
1802 END DO
1803 END DO
1804 END DO
1805 WRITE(*,*) 'GRPCON:',ncgrp,' disjoint constraints groups built'
1806
1807 ! sort by group number
1808 CALL sort2i(matconsgroupindex,ncgb)
1809
1810 matconsgroups(1,1:ncgrp)=0
1811 DO jcgb=1,ncgb
1812 ! set up matConsSort
1813 icgb=matconsgroupindex(3,jcgb)
1814 matconssort(1,jcgb)=matconsranges(1,icgb)
1815 matconssort(2,jcgb)=matconsranges(2,icgb)
1816 matconssort(3,jcgb)=icgb
1817 ! set up matConsGroups
1818 icgrp=matconsgroupindex(1,jcgb)
1819 IF (matconsgroups(1,icgrp) == 0) THEN
1820 matconsgroups(1,icgrp)=jcgb
1821 matconsgroups(2,icgrp)=matconsranges(1,icgb)
1822 matconsgroups(3,icgrp)=matconsranges(2,icgb)
1823 ELSE
1824 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
1825 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
1826 END IF
1827 END DO
1828 matconsgroups(1,ncgrp+1)=ncgb+1
1829 matconsgroups(2,ncgrp+1)=ntgb+1
1830
1831 ! check for redundancy constraint groups
1832 ncgbr=0
1833 ncgrpr=0
1834 ncgbd=0
1835 ncgrpd=0
1836 IF (icheck>0) THEN
1837 print *
1838 print *, ' cons.group first con. first par. last par. #cons #par'
1839 ENDIF
1840 DO icgrp=1,ncgrp
1841 npar=0
1842 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1843 IF (globalparcons(i) == icgrp) npar=npar+1
1844 END DO
1845 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
1846 IF (icheck>0) THEN
1847 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1848 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1849 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ncon, npar
1850 END IF
1851 ! redundancy constraints?
1852 IF (ncon == npar) THEN
1853 IF (irslvrc > 0) THEN
1854 ncgrpr=ncgrpr+1
1855 ncgbr=ncgbr+ncon
1856 IF (icheck > 0) THEN
1857 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1858 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1859 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group resolved'
1860 END IF
1861 ! flag redundant parameters
1862 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1863 IF (globalparcons(i) == icgrp) globalparcons(i)=-icgrp
1864 END DO
1865 ! flag constraint group
1866 matconsgroups(2,icgrp)=ntgb+1
1867 matconsgroups(3,icgrp)=ntgb
1868 ELSE
1869 ncgrpd=ncgrpd+1
1870 ncgbd=ncgbd+ncon
1871 IF (icheck > 0) THEN
1872 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1873 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1874 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group redundant'
1875 END IF
1876 END IF
1877 END IF
1878 END DO
1879 IF (ncgrpr > 0) THEN
1880 WRITE(*,*) 'GRPCON:',ncgbr,' redundancy constraints in ', ncgrpr, ' groups resolved'
1881 ! all constraint groups resolved ?
1882 IF (ncgrpr == ncgrp) ncgrp=0
1883 ENDIF
1884 IF (ncgrpd > 0) THEN
1885 WRITE(*,*) 'GRPCON:',ncgbd,' redundancy constraints in ', ncgrpd, ' groups detected'
1886 ENDIF
1887 WRITE(*,*)
1888
1889 ! clean up
1890 CALL mpdealloc(vecparconslist)
1891 CALL mpdealloc(vecconsparlist)
1892 CALL mpdealloc(vecparconsoffsets)
1893 CALL mpdealloc(vecconsparoffsets)
1894 CALL mpdealloc(matconsgroupindex)
1895
1896END SUBROUTINE grpcon
1897
1901
1902SUBROUTINE prpcon
1903 USE mpmod
1904 USE mpdalc
1905
1906 IMPLICIT NONE
1907 INTEGER(mpi) :: i
1908 INTEGER(mpi) :: icgb
1909 INTEGER(mpi) :: icgrp
1910 INTEGER(mpi) :: ifrst
1911 INTEGER(mpi) :: ilast
1912 INTEGER(mpi) :: isblck
1913 INTEGER(mpi) :: itgbi
1914 INTEGER(mpi) :: ivgb
1915 INTEGER(mpi) :: j
1916 INTEGER(mpi) :: jcgb
1917 INTEGER(mpi) :: jfrst
1918 INTEGER(mpi) :: label
1919 INTEGER(mpi) :: labelf
1920 INTEGER(mpi) :: labell
1921 INTEGER(mpi) :: ncon
1922 INTEGER(mpi) :: ngrp
1923 INTEGER(mpi) :: npar
1924 INTEGER(mpi) :: ncnmxb
1925 INTEGER(mpi) :: ncnmxg
1926 INTEGER(mpi) :: nprmxb
1927 INTEGER(mpi) :: nprmxg
1928 INTEGER(mpi) :: inone
1929 INTEGER(mpi) :: nvar
1930
1931 INTEGER(mpl):: length
1932 INTEGER(mpl) :: rows
1933
1934 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1935
1936 ncgbe=0
1937 !
1938 ! constraint groups already built in GRPCON based on steering,
1939 ! now care about fixed parameters
1940 !
1941 IF(ncgrp == 0) THEN ! no constraints groups
1942 ncgb=0
1943 ncblck=0
1944 RETURN
1945 END IF
1946
1947 length=ncgrp+1; rows=3
1948 ! start and parameter range of constraint blocks
1949 CALL mpalloc(matconsblocks,rows,length,'start of constraint blocks, par. range (I)')
1950
1951 length=ncgb; rows=3
1952 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1953 matconsgroupindex=0
1954
1955 ! check for empty constraints, redefine (accepted/active) constraints and groups
1956 ngrp=0
1957 ncgb=0
1958 DO icgrp=1,ncgrp
1959 ncon=ncgb
1960 ! resolved group ?
1961 IF (matconsgroups(2,icgrp) > matconsgroups(3,icgrp)) cycle
1962 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
1963 icgb=matconssort(3,jcgb)
1964 i=vecconsstart(icgb)+2
1965 npar=0
1966 nvar=0
1967 matconsranges(1,icgb)=ntgb
1968 matconsranges(2,icgb)=1
1969 DO
1970 label=listconstraints(i)%label
1971 itgbi=inone(label) ! -> ITGBI= index of parameter label
1972 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1973 npar=npar+1
1974 IF(ivgb > 0) THEN
1975 nvar=nvar+1
1976 matconsranges(1,icgb)=min(matconsranges(1,icgb),itgbi)
1977 matconsranges(2,icgb)=max(matconsranges(2,icgb),itgbi)
1978 ENDIF
1979 i=i+1
1980 IF(i > lenconstraints) EXIT
1981 IF(listconstraints(i)%label < 0) EXIT
1982 END DO
1983 IF (nvar == 0) THEN
1984 ncgbe=ncgbe+1
1985 ! reset range
1986 matconsranges(1,icgb)=matconsranges(3,icgb)
1987 matconsranges(2,icgb)=matconsranges(4,icgb)
1988 END IF
1989 IF (nvar > 0 .OR. iskpec == 0) THEN
1990 ! constraint accepted (or kept)
1991 ncgb=ncgb+1
1992 matconsgroupindex(1,ncgb)=ngrp+1
1993 matconsgroupindex(2,ncgb)=icgb
1994 matconsgroupindex(3,ncgb)=nvar
1995 END IF
1996 END DO
1997 IF (ncgb > ncon) ngrp=ngrp+1
1998 END DO
1999 ncgrp=ngrp
2000
2001 IF (ncgbe > 0) THEN
2002 IF (iskpec > 0) THEN
2003 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints skipped'
2004 ELSE
2005 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints detected, to be fixed !!!'
2006 WRITE(*,*) ' (use option "skipemptycons" to skip those)'
2007 IF (icheck == 0) THEN
2008 icheck=2 ! switch to '-C'
2009 ncgbe=-ncgbe ! indicate that
2010 WRITE(*,*)
2011 WRITE(*,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2012 WRITE(8,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2013 WRITE(*,*)
2014 END IF
2015 END IF
2016 END IF
2017 WRITE(*,*) 'PRPCON:',ncgb,' constraints accepted'
2018 WRITE(*,*)
2019
2020 IF(ncgb == 0) RETURN ! no constraints left
2021
2022 ! already sorted by group number
2023
2024 matconsgroups(1,1:ncgrp)=0
2025 DO jcgb=1,ncgb
2026 ! set up matConsSort
2027 icgb=matconsgroupindex(2,jcgb)
2028 matconssort(1,jcgb)=matconsranges(1,icgb)
2029 matconssort(2,jcgb)=matconsranges(2,icgb)
2030 matconssort(3,jcgb)=icgb
2031 ! set up matConsGroups
2032 icgrp=matconsgroupindex(1,jcgb)
2033 IF (matconsgroups(1,icgrp) == 0) THEN
2034 matconsgroups(1,icgrp)=jcgb
2035 matconsgroups(2,icgrp)=matconsranges(1,icgb)
2036 matconsgroups(3,icgrp)=matconsranges(2,icgb)
2037 ELSE
2038 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
2039 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
2040 END IF
2041 END DO
2042 matconsgroups(1,ncgrp+1)=ncgb+1
2043 matconsgroups(2,ncgrp+1)=ntgb+1
2044
2045 ! loop over constraints groups, combine into non overlapping blocks
2046 ncblck=0
2047 ncnmxg=0
2048 nprmxg=0
2049 ncnmxb=0
2050 nprmxb=0
2051 mszcon=0
2052 mszprd=0
2053 isblck=1
2054 ilast=0
2055 IF (icheck > 0) THEN
2056 WRITE(*,*)
2057 IF (icheck > 1) &
2058 WRITE(*,*) ' Cons. sorted index #var.par. first line first label last label'
2059 WRITE(*,*) ' Cons. group index first cons. last cons. first label last label'
2060 WRITE(*,*) ' Cons. block index first group last group first label last label'
2061 END IF
2062 DO icgrp=1,ncgrp
2063 IF (icheck > 1) THEN
2064 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2065 icgb=matconssort(3,jcgb)
2066 nvar=matconsgroupindex(3,jcgb)
2067 labelf=globalparlabelindex(1,matconssort(1,jcgb))
2068 labell=globalparlabelindex(1,matconssort(2,jcgb))
2069 IF (nvar > 0) THEN
2070 WRITE(*,*) ' Cons. sorted', jcgb, nvar, &
2071 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2072 ELSE
2073 WRITE(*,*) ' Cons. sorted', jcgb, ' empty (0)', &
2074 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2075 END IF
2076 END DO
2077 END IF
2078 IF (icheck > 0) THEN
2079 !ivgb=globalParLabelIndex(2,matConsGroups(2,icgrp)) ! -> index of variable global parameter
2080 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
2081 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
2082 WRITE(*,*) ' Cons. group ', icgrp, matconsgroups(1,icgrp), &
2083 matconsgroups(1,icgrp+1)-1, labelf, labell
2084 ENDIF
2085 ! combine into non overlapping blocks
2086 ilast=max(ilast, matconsgroups(3,icgrp))
2087 IF (matconsgroups(2,icgrp+1) > ilast) THEN
2088 ncblck=ncblck+1
2089 ifrst=matconsgroups(2,isblck)
2091 matconsblocks(2,ncblck)=ifrst ! save first parameter in block
2092 matconsblocks(3,ncblck)=ilast ! save last parameter in block
2093 ! update matConsSort
2094 jfrst=matconsgroups(2,icgrp)
2095 DO i=icgrp,isblck,-1
2096 DO j=matconsgroups(1,i),matconsgroups(1,i+1)-1
2097 ! non zero range (from group)
2098 matconsranges(1,j)=matconsgroups(2,i)
2100 ! storage range (from max group, ilast)
2101 jfrst=min(jfrst,matconsgroups(2,i))
2102 matconsranges(3,j)=jfrst
2103 matconsranges(4,j)=ilast
2104 END DO
2105 END DO
2106 IF (icheck > 0) THEN
2107 labelf=globalparlabelindex(1,ifrst)
2108 labell=globalparlabelindex(1,ilast)
2109 WRITE(*,*) ' Cons. block ', ncblck, isblck, icgrp, labelf, labell
2110 ENDIF
2111 ! reset for new block
2112 isblck=icgrp+1
2113 END IF
2114 END DO
2116
2117 ! convert from total parameter index to index of variable global parameter
2118 DO i=1,ncblck
2119 ifrst=globalparlabelindex(2,matconsblocks(2,i)) ! -> index of variable global parameter
2120 ilast=globalparlabelindex(2,matconsblocks(3,i)) ! -> index of variable global parameter
2121 IF (ifrst > 0) THEN
2122 matconsblocks(2,i)=ifrst
2123 matconsblocks(3,i)=ilast
2124 ! statistics
2125 ncon=matconsblocks(1,i+1)-matconsblocks(1,i)
2126 npar=ilast+1-ifrst
2127 ncnmxb=max(ncnmxb,ncon)
2128 nprmxb=max(nprmxb,npar)
2129 ! update index ranges
2130 globalindexranges(ifrst)=max(globalindexranges(ifrst),ilast)
2131 ELSE
2132 ! empty
2133 matconsblocks(2,i)=1
2134 matconsblocks(3,i)=0
2135 END IF
2136 END DO
2137 DO icgrp=1,ncgrp
2138 ifrst=globalparlabelindex(2,matconsgroups(2,icgrp)) ! -> index of variable global parameter
2139 ilast=globalparlabelindex(2,matconsgroups(3,icgrp)) ! -> index of variable global parameter
2140 IF (ifrst > 0) THEN
2141 matconsgroups(2,icgrp)=ifrst
2142 matconsgroups(3,icgrp)=ilast
2143 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2144 DO i=1,4
2145 ivgb=globalparlabelindex(2,matconsranges(i,jcgb)) ! -> index of variable global parameter
2146 matconsranges(i,jcgb)=ivgb
2147 END DO
2148 END DO
2149 ! storage sizes, statistics
2150 jcgb=matconsgroups(1,icgrp) ! first cons.
2151 ncon=matconsgroups(1,icgrp+1)-jcgb
2152 npar=matconsranges(4,jcgb)+1-matconsranges(3,jcgb)
2153 ncnmxg=max(ncnmxg,ncon)
2154 nprmxg=max(nprmxg,npar)
2155 mszcon=mszcon+int(ncon,mpl)*int(npar,mpl) ! (sum of) block size for constraint matrix
2156 mszprd=mszprd+int(ncon,mpl)*int(ncon+1,mpl)/2 ! (sum of) block size for product matrix
2157 ELSE
2158 ! empty
2159 matconsgroups(2,icgrp)=1
2160 matconsgroups(3,icgrp)=0
2161 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2162 matconsranges(1,jcgb)=1
2163 matconsranges(2,jcgb)=0
2164 matconsranges(3,jcgb)=1
2165 matconsranges(4,jcgb)=0
2166 END DO
2167 END IF
2168 END DO
2169
2170 ! clean up
2171 CALL mpdealloc(matconsgroupindex)
2172
2173 ! save constraint group for global parameters
2175 DO icgrp=1,ncgrp
2176 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2177 ! index in list
2178 icgb=matconssort(3,jcgb)
2179 DO j=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
2180 label=listconstraints(j)%label
2181 itgbi=inone(label) ! -> ITGBI= index of parameter label
2182 globalparcons(itgbi)=icgrp ! save constraint group
2183 END DO
2184 END DO
2185 END DO
2186
2187 IF (ncgrp+icheck > 1) THEN
2188 WRITE(*,*)
2189 WRITE(*,*) 'PRPCON: constraints split into ', ncgrp, '(disjoint) groups,'
2190 WRITE(*,*) ' groups combined into ', ncblck, '(non overlapping) blocks'
2191 WRITE(*,*) ' max group size (cons., par.) ', ncnmxg, nprmxg
2192 WRITE(*,*) ' max block size (cons., par.) ', ncnmxb, nprmxb
2193 IF (icheck > 0) WRITE(*,*) ' total block matrix sizes ', mszcon, mszprd
2194 END IF
2195
2196END SUBROUTINE prpcon
2197
2201
2202SUBROUTINE feasma
2203 USE mpmod
2204 USE mpdalc
2205
2206 IMPLICIT NONE
2207 REAL(mpd) :: factr
2208 REAL(mpd) :: sgm
2209 INTEGER(mpi) :: i
2210 INTEGER(mpi) :: icgb
2211 INTEGER(mpi) :: icgrp
2212 INTEGER(mpl) :: ij
2213 INTEGER(mpi) :: ifirst
2214 INTEGER(mpi) :: ilast
2215 INTEGER(mpl) :: ioffc
2216 INTEGER(mpl) :: ioffp
2217 INTEGER(mpi) :: irank
2218 INTEGER(mpi) :: ipar0
2219 INTEGER(mpi) :: itgbi
2220 INTEGER(mpi) :: ivgb
2221 INTEGER(mpi) :: j
2222 INTEGER(mpi) :: jcgb
2223 INTEGER(mpl) :: ll
2224 INTEGER(mpi) :: label
2225 INTEGER(mpi) :: ncon
2226 INTEGER(mpi) :: npar
2227 INTEGER(mpi) :: nrank
2228 INTEGER(mpi) :: inone
2229
2230 REAL(mpd):: rhs
2231 REAL(mpd):: evmax
2232 REAL(mpd):: evmin
2233 INTEGER(mpl):: length
2234 REAL(mpd), DIMENSION(:), ALLOCATABLE :: matConstraintsT
2235 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
2236 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
2237 SAVE
2238 ! ...
2239
2240 IF(ncgb == 0) RETURN ! no constraints
2241
2242 ! product matrix A A^T (A is stored as transposed)
2243 length=mszprd
2244 CALL mpalloc(matconsproduct, length, 'product matrix of constraints (blocks)')
2245 matconsproduct=0.0_mpd
2246 length=ncgb
2247 CALL mpalloc(vecconsresiduals, length, 'residuals of constraints')
2248 CALL mpalloc(vecconssolution, length, 'solution for constraints')
2249 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
2250 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
2251 ! constraint matrix A (A is stored as transposed)
2252 length = mszcon
2253 CALL mpalloc(matconstraintst,length,'transposed matrix of constraints (blocks)')
2254 matconstraintst=0.0_mpd
2255
2256 ! loop over sorted constraints, fill matrices, get rank, inverted product matrix (in groups)
2257 ioffc=0 ! group offset in constraint matrix
2258 ioffp=0 ! group offset in product matrix
2259 nrank=0
2260 DO icgrp=1,ncgrp
2261 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2262 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2263 ncon=ilast+1-ifirst
2264 ipar0=matconsranges(3,ifirst)-1 ! parameter offset
2265 npar=matconsranges(4,ifirst)-ipar0 ! number of parameters
2266 IF (npar <= 0) THEN
2267 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, 0, ' (empty)'
2268 cycle ! skip empty groups/cons.
2269 END IF
2270 DO jcgb=ifirst,ilast
2271 ! index in list
2272 icgb=matconssort(3,jcgb)
2273 ! fill constraint matrix
2274 i=vecconsstart(icgb)
2275 rhs=listconstraints(i )%value ! right hand side
2276 sgm=listconstraints(i+1)%value ! sigma parameter
2277 DO j=i+2,vecconsstart(icgb+1)-1
2278 label=listconstraints(j)%label
2279 factr=listconstraints(j)%value
2280 itgbi=inone(label) ! -> ITGBI= index of parameter label
2281 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2282 IF(ivgb > 0) matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)= &
2283 matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)+factr ! matrix element
2284 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2285 END DO
2286 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2287 END DO
2288
2289 ! get rank of groups
2290 DO ll=ioffc+1,ioffc+npar
2291 ij=ioffp
2292 DO i=1,ncon
2293 DO j=1,i
2294 ij=ij+1
2295 matconsproduct(ij)=matconsproduct(ij)+ &
2296 matconstraintst(int(i-1,mpl)*int(npar,mpl)+ll)* &
2297 matconstraintst(int(j-1,mpl)*int(npar,mpl)+ll)
2298 END DO
2299 END DO
2300 END DO
2301 ! inversion of product matrix of constraints
2302 CALL sqminv(matconsproduct(ioffp+1:ij),vecconsresiduals(ifirst:ilast),ncon,irank, auxvectord, auxvectori)
2303 IF (icheck > 1 .OR. irank < ncon) THEN
2304 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, irank
2305 IF (irank < ncon) THEN
2306 WRITE(*,*) ' .. rank deficit !! '
2307 WRITE(*,*) ' E.g. fix all parameters and remove all constraints related to label ', &
2309 END IF
2310 END IF
2311 nrank=nrank+irank
2312 ioffc=ioffc+int(npar,mpl)*int(ncon,mpl)
2313 ioffp=ij
2314 END DO
2315
2316 nmiss1=ncgb-nrank
2317
2318 WRITE(*,*) ' '
2319 WRITE(*,*) 'Rank of product matrix of constraints is',nrank, &
2320 ' for',ncgb,' constraint equations'
2321 WRITE(8,*) 'Rank of product matrix of constraints is',nrank, &
2322 ' for',ncgb,' constraint equations'
2323 IF(nrank < ncgb) THEN
2324 WRITE(*,*) 'Warning: insufficient constraint equations!'
2325 WRITE(8,*) 'Warning: insufficient constraint equations!'
2326 IF (iforce == 0) THEN
2327 isubit=1
2328 WRITE(*,*) ' --> enforcing SUBITO mode'
2329 WRITE(8,*) ' --> enforcing SUBITO mode'
2330 END IF
2331 END IF
2332
2333 ! QL decomposition
2334 IF (nfgb < nvgb) THEN
2335 print *
2336 print *, 'QL decomposition of constraints matrix'
2337 ! monitor progress
2338 IF(monpg1 > 0) THEN
2339 WRITE(lunlog,*) 'QL decomposition of constraints matrix'
2341 END IF
2342 IF(icelim < 2) THEN ! True unless unpacked LAPACK
2343 ! QL decomposition
2345 ! loop over parameter blocks
2347 ! check eignevalues of L
2348 CALL qlgete(evmin,evmax)
2349#ifdef LAPACK64
2350 ELSE
2351 CALL lpqldec(matconstraintst,evmin,evmax)
2352#endif
2353 END IF
2354 IF(monpg1 > 0) CALL monend()
2355 print *, ' largest |eigenvalue| of L: ', evmax
2356 print *, ' smallest |eigenvalue| of L: ', evmin
2357 IF (evmin == 0.0_mpd.AND.icheck == 0) THEN
2358 CALL peend(27,'Aborted, singular QL decomposition of constraints matrix')
2359 stop 'FEASMA: stopping due to singular QL decomposition of constraints matrix'
2360 END IF
2361 END IF
2362
2363 CALL mpdealloc(matconstraintst)
2364 CALL mpdealloc(auxvectord)
2365 CALL mpdealloc(auxvectori)
2366
2367 RETURN
2368END SUBROUTINE feasma ! matrix for feasible solution
2369
2377SUBROUTINE feasib(concut,iact)
2378 USE mpmod
2379 USE mpdalc
2380
2381 IMPLICIT NONE
2382 REAL(mpd) :: factr
2383 REAL(mpd) :: sgm
2384 INTEGER(mpi) :: i
2385 INTEGER(mpi) :: icgb
2386 INTEGER(mpi) :: icgrp
2387 INTEGER(mpi) :: iter
2388 INTEGER(mpi) :: itgbi
2389 INTEGER(mpi) :: ivgb
2390 INTEGER(mpi) :: ieblck
2391 INTEGER(mpi) :: isblck
2392 INTEGER(mpi) :: ifirst
2393 INTEGER(mpi) :: ilast
2394 INTEGER(mpi) :: j
2395 INTEGER(mpi) :: jcgb
2396 INTEGER(mpi) :: label
2397 INTEGER(mpi) :: inone
2398 INTEGER(mpi) :: ncon
2399
2400 REAL(mps), INTENT(IN) :: concut
2401 INTEGER(mpi), INTENT(OUT) :: iact
2402
2403 REAL(mpd) :: rhs
2404 REAL(mpd) ::sum1
2405 REAL(mpd) ::sum2
2406 REAL(mpd) ::sum3
2407
2408 REAL(mpd), DIMENSION(:), ALLOCATABLE :: vecCorrections
2409 SAVE
2410
2411 iact=0
2412 IF(ncgb == 0) RETURN ! no constraints
2413
2414 DO iter=1,2
2415 vecconsresiduals=0.0_mpd
2416
2417 ! calculate right constraint equation discrepancies
2418 DO jcgb=1,ncgb
2419 icgb=matconssort(3,jcgb) ! unsorted constraint index
2420 i=vecconsstart(icgb)
2421 rhs=listconstraints(i )%value ! right hand side
2422 sgm=listconstraints(i+1)%value ! sigma parameter
2423 DO j=i+2,vecconsstart(icgb+1)-1
2424 label=listconstraints(j)%label
2425 factr=listconstraints(j)%value
2426 itgbi=inone(label) ! -> ITGBI= index of parameter label
2427 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2428 ENDDO
2429 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2430 END DO
2431
2432 ! constraint equation discrepancies -------------------------------
2433
2434 sum1=0.0_mpd
2435 sum2=0.0_mpd
2436 sum3=0.0_mpd
2437 DO icgb=1,ncgb
2438 sum1=sum1+vecconsresiduals(icgb)**2
2439 sum2=sum2+abs(vecconsresiduals(icgb))
2440 sum3=max(sum3,abs(vecconsresiduals(icgb)))
2441 END DO
2442 sum1=sqrt(sum1/real(ncgb,mpd))
2443 sum2=sum2/real(ncgb,mpd)
2444
2445 IF(iter == 1.AND.sum1 < concut) RETURN ! do nothing if correction small
2446
2447 IF(iter == 1.AND.ncgb <= 12) THEN
2448 WRITE(*,*) ' '
2449 WRITE(*,*) 'Constraint equation discrepancies:'
2450 WRITE(*,101) (icgb,vecconsresiduals(icgb),icgb=1,ncgb)
2451101 FORMAT(4x,4(i5,g12.4))
2452 WRITE(*,103) concut
2453103 FORMAT(10x,' Cut on rms value is',g8.1)
2454 END IF
2455
2456 IF(iact == 0) THEN
2457 WRITE(*,*) ' '
2458 WRITE(*,*) 'Improve constraints'
2459 END IF
2460 iact=1
2461
2462 WRITE(*,102) iter,sum1,sum2,sum3
2463102 FORMAT(i6,' rms',g12.4,' avrg_abs',g12.4,' max_abs',g12.4)
2464
2465 CALL mpalloc(veccorrections,int(nvgb,mpl),'constraint corrections')
2466 veccorrections=0.0_mpd
2467
2468 ! multiply (group-wise) inverse matrix and constraint vector
2469 isblck=0
2470 DO icgrp=1,ncgrp
2471 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2472 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2473 ncon=ilast+1-ifirst
2474 ieblck=isblck+(ncon*(ncon+1))/2
2475 CALL dbsvx(matconsproduct(isblck+1:ieblck),vecconsresiduals(ifirst:ilast),vecconssolution(ifirst:ilast),ncon)
2476 isblck=ieblck
2477 END DO
2478
2479 DO jcgb=1,ncgb
2480 icgb=matconssort(3,jcgb) ! unsorted constraint index
2481 i=vecconsstart(icgb)
2482 rhs=listconstraints(i )%value ! right hand side
2483 sgm=listconstraints(i+1)%value ! sigma parameter
2484 DO j=i+2,vecconsstart(icgb+1)-1
2485 label=listconstraints(j)%label
2486 factr=listconstraints(j)%value
2487 itgbi=inone(label) ! -> ITGBI= index of parameter label
2488 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2489 IF(ivgb > 0) THEN
2490 veccorrections(ivgb)=veccorrections(ivgb)+vecconssolution(jcgb)*factr
2491 END IF
2492 ENDDO
2493 END DO
2494
2495 DO i=1,nvgb ! add corrections
2496 itgbi=globalparvartototal(i)
2497 globalparameter(itgbi)=globalparameter(itgbi)+veccorrections(i)
2498 END DO
2499
2500 CALL mpdealloc(veccorrections)
2501
2502 END DO ! iteration 1 and 2
2503
2504END SUBROUTINE feasib ! make parameters feasible
2505
2538SUBROUTINE peread(more)
2539 USE mpmod
2540
2541 IMPLICIT NONE
2542 INTEGER(mpi) :: i
2543 INTEGER(mpi) :: iact
2544 INTEGER(mpi) :: ierrc
2545 INTEGER(mpi) :: ierrf
2546 INTEGER(mpi) :: ioffp
2547 INTEGER(mpi) :: ios
2548 INTEGER(mpi) :: ithr
2549 INTEGER(mpi) :: jfile
2550 INTEGER(mpi) :: jrec
2551 INTEGER(mpi) :: k
2552 INTEGER(mpi) :: kfile
2553 INTEGER(mpi) :: l
2554 INTEGER(mpi) :: lun
2555 INTEGER(mpi) :: mpri
2556 INTEGER(mpi) :: n
2557 INTEGER(mpi) :: nact
2558 INTEGER(mpi) :: nbuf
2559 INTEGER(mpi) :: ndata
2560 INTEGER(mpi) :: noff
2561 INTEGER(mpi) :: noffs
2562 INTEGER(mpi) :: npointer
2563 INTEGER(mpi) :: npri
2564 INTEGER(mpi) :: nr
2565 INTEGER(mpi) :: nrc
2566 INTEGER(mpi) :: nrd
2567 INTEGER(mpi) :: nrpr
2568 INTEGER(mpi) :: nthr
2569 INTEGER(mpi) :: ntot
2570 INTEGER(mpi) :: maxRecordSize
2571 INTEGER(mpi) :: maxRecordFile
2572
2573 INTEGER(mpi), INTENT(OUT) :: more
2574
2575 LOGICAL :: lprint
2576 LOGICAL :: floop
2577 LOGICAL :: eof
2578 REAL(mpd) :: ds0
2579 REAL(mpd) :: ds1
2580 REAL(mpd) :: ds2
2581 REAL(mpd) :: dw
2582 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
2583 CHARACTER (LEN=7) :: cfile
2584 SAVE
2585
2586#ifdef READ_C_FILES
2587 INTERFACE
2588 SUBROUTINE readc(bufferD, bufferF, bufferI, bufferLength, lun, err) BIND(c)
2589 USE iso_c_binding
2590 REAL(c_double), DIMENSION(*), INTENT(OUT) :: bufferD
2591 REAL(c_float), DIMENSION(*), INTENT(OUT) :: bufferF
2592 INTEGER(c_int), DIMENSION(*), INTENT(OUT) :: bufferI
2593 INTEGER(c_int), INTENT(INOUT) :: bufferLength
2594 INTEGER(c_int), INTENT(IN), VALUE :: lun
2595 INTEGER(c_int), INTENT(OUT) :: err
2596 END SUBROUTINE readc
2597 END INTERFACE
2598#endif
2599
2600 DATA lprint/.true./
2601 DATA floop/.true./
2602 DATA npri / 0 /, mpri / 1000 /
2603 ! ...
2604 IF(ifile == 0) THEN ! start/restart
2605 nrec=0
2606 nrecd=0
2607 ntot=0
2608 sumrecords=0
2610 numblocks=0
2613 readbufferinfo=0 ! reset management info
2614 nrpr=1
2615 nthr=mthrdr
2616 nact=0 ! active threads (have something still to read)
2617 DO k=1,nthr
2618 IF (ifile < nfilb) THEN
2619 ifile=ifile+1
2621 readbufferinfo(2,k)=nact
2622 nact=nact+1
2623 END IF
2624 END DO
2625 END IF
2626 npointer=size(readbufferpointer)/nact
2627 ndata=size(readbufferdatai)/nact
2628 more=-1
2629 DO k=1,nthr
2630 iact=readbufferinfo(2,k)
2631 readbufferinfo(4,k)=0 ! reset counter
2632 readbufferinfo(5,k)=iact*ndata ! reset offset
2633 END DO
2634 numblocks=numblocks+1 ! new block
2635
2636 !$OMP PARALLEL &
2637 !$OMP DEFAULT(PRIVATE) &
2638 !$OMP SHARED(readBufferInfo,readBufferPointer,readBufferDataI,readBufferDataD, &
2639 !$OMP readBufferDataF,nPointer,nData,skippedRecords,ndimbuf,NTHR,NFILF,FLOOP, &
2640 !$OMP IFD,KFD,IFILE,NFILB,WFD,XFD,icheck,keepOpen,ireeof,nrderr) &
2641 !$OMP NUM_THREADS(NTHR)
2642
2643 ithr=1
2644 !$ ITHR=OMP_GET_THREAD_NUM()+1 ! thread number
2645 jfile=readbufferinfo(1,ithr) ! file index
2646 iact =readbufferinfo(2,ithr) ! active thread number
2647 jrec =readbufferinfo(3,ithr) ! records read
2648 ioffp=iact*npointer
2649 noffs=(ithr-1)*ndimbuf ! offset for intermediate float buffer
2650
2651 files: DO WHILE (jfile > 0)
2652 kfile=kfd(2,jfile)
2653 ! open again
2654 IF (keepopen < 1 .AND. readbufferinfo(3,ithr) == 0) THEN
2655 CALL binopn(kfile,ithr,ios)
2656 END IF
2657 records: DO
2658 nbuf=readbufferinfo(4,ithr)+1
2659 noff=readbufferinfo(5,ithr)+2 ! 2 header words per record
2660 nr=ndimbuf
2661 IF(kfile <= nfilf) THEN ! Fortran file
2662 lun=kfile+10
2663 READ(lun,iostat=ierrf) n,(readbufferdataf(noffs+i),i=1,min(n/2,nr)),&
2664 (readbufferdatai(noff+i),i=1,min(n/2,nr))
2665 nr=n/2
2666 ! convert to double
2667 DO i=1,nr
2668 readbufferdatad(noff+i)=real(readbufferdataf(noffs+i),mpr8)
2669 END DO
2670 ! IF (ierrf < 0) REWIND lun ! end-of-file ! CHK use binrwd()
2671 eof=(ierrf /= 0)
2672 ELSE ! C file
2673 lun=kfile-nfilf
2674 IF (keepopen < 1) lun=ithr
2675#ifdef READ_C_FILES
2676 CALL readc(readbufferdatad(noff+1),readbufferdataf(noffs+1),readbufferdatai(noff+1),nr,lun,ierrc)
2677 n=nr+nr
2678 IF (ierrc > 4) readbufferinfo(6,ithr)=readbufferinfo(6,ithr)+1
2679#else
2680 ierrc=0
2681#endif
2682 eof=(ierrc <= 0.AND.ierrc /= -4) ! allow buffer overruns -> skip record
2683 IF(eof.AND.ierrc < 0) THEN
2684 WRITE(*,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2685 WRITE(8,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2686 IF (icheck <= 0 .AND. ireeof <=0) THEN ! stop unless 'checkinput' mode or 'readerroraseof'
2687 WRITE(cfile,'(I7)') kfile
2688 CALL peend(18,'Aborted, read error(s) for binary file ' // cfile)
2689 stop 'PEREAD: stopping due to read errors'
2690 END IF
2691 IF (kfd(1,jfile) == 1) THEN ! count files with read errors in first loop
2692 !$OMP ATOMIC
2693 nrderr=nrderr+1
2694 END IF
2695 END IF
2696 END IF
2697 IF(eof) EXIT records ! end-of-files or error
2698
2699 jrec=jrec+1
2700 readbufferinfo(3,ithr)=jrec
2701 IF(floop) THEN
2702 xfd(jfile)=max(xfd(jfile),n)
2703 IF(ithr == 1) THEN
2704 CALL hmplnt(1,n)
2705 IF(readbufferdatai(noff+1) /= 0) CALL hmpent(8,real(readbufferdatai(noff+1),mps))
2706 END IF
2707 END IF
2708
2709 IF (nr <= ndimbuf) THEN
2710 readbufferinfo(4,ithr)=nbuf
2711 readbufferinfo(5,ithr)=noff+nr
2712
2713 readbufferpointer(ioffp+nbuf)=noff ! pointer to start of buffer
2714 readbufferdatai(noff )=noff+nr ! pointer to end of buffer
2715 readbufferdatai(noff-1)=jrec ! local record number
2716 readbufferdatad(noff )=real(kfile,mpr8) ! file number
2717 readbufferdatad(noff-1)=real(wfd(kfile),mpr8) ! weight
2718
2719 IF ((noff+nr+2+ndimbuf >= ndata*(iact+1)).OR.(nbuf >= npointer)) EXIT files ! buffer full
2720 ELSE
2721 !$OMP ATOMIC
2723 cycle records
2724 END IF
2725
2726 END DO records
2727
2728 readbufferinfo(1,ithr)=-jfile ! flag eof
2729 IF (keepopen < 1) THEN ! close again
2730 CALL bincls(kfile,ithr)
2731 ELSE ! rewind
2732 CALL binrwd(kfile)
2733 END IF
2734 IF (kfd(1,jfile) == 1) THEN
2735 print *, 'PEREAD: file ', kfile, 'read the first time, found',jrec,' records'
2736 kfd(1,jfile)=-jrec
2737 ELSE
2738 !PRINT *, 'PEREAD: file ', kfile, 'records', jrec, -kfd(1,jfile)
2739 IF (-kfd(1,jfile) /= jrec) THEN
2740 WRITE(cfile,'(I7)') kfile
2741 CALL peend(19,'Aborted, binary file modified (length) ' // cfile)
2742 stop 'PEREAD: file modified (length)'
2743 END IF
2744 END IF
2745 ! take next file
2746 !$OMP CRITICAL
2747 IF (ifile < nfilb) THEN
2748 ifile=ifile+1
2749 jrec=0
2750 readbufferinfo(1,ithr)=ifile
2751 readbufferinfo(3,ithr)=jrec
2752 END IF
2753 !$OMP END CRITICAL
2754 jfile=readbufferinfo(1,ithr)
2755
2756 END DO files
2757 !$OMP END PARALLEL
2758 ! compress pointers
2759 nrd=readbufferinfo(4,1) ! buffers from 1 .thread
2760 DO k=2,nthr
2761 iact =readbufferinfo(2,k)
2762 ioffp=iact*npointer
2763 nbuf=readbufferinfo(4,k)
2764 DO l=1,nbuf
2765 readbufferpointer(nrd+l)=readbufferpointer(ioffp+l)
2766 END DO
2767 nrd=nrd+nbuf
2768 END DO
2769
2770 more=0
2771 DO k=1,nthr
2772 jfile=readbufferinfo(1,k)
2773 IF (jfile > 0) THEN ! no eof yet
2774 readbufferinfo(2,k)=more
2775 more=more+1
2776 ELSE
2777 ! no more files, thread retires
2778 readbufferinfo(1,k)=0
2779 readbufferinfo(2,k)=-1
2780 readbufferinfo(3,k)=0
2782 readbufferinfo(6,k)=0
2783 END IF
2784 END DO
2785 ! record limit ?
2786 IF (mxrec > 0.AND.(ntot+nrd) >= mxrec) THEN
2787 nrd=mxrec-ntot
2788 more=-1
2789 DO k=1,nthr
2790 jfile=readbufferinfo(1,k)
2791 IF (jfile > 0) THEN ! rewind or close files
2792 nrc=readbufferinfo(3,k)
2793 IF (kfd(1,jfile) == 1) kfd(1,jfile)=-nrc
2794 kfile=kfd(2,jfile)
2795 IF (keepopen < 1) THEN ! close again
2796 CALL bincls(kfile,k)
2797 ELSE ! rewind
2798 CALL binrwd(kfile)
2799 END IF
2800 END IF
2801 END DO
2802 END IF
2803
2804 ntot=ntot+nrd
2805 nrec=ntot
2806 numreadbuffer=nrd
2807
2811
2812 DO WHILE (nloopn == 0.AND.ntot >= nrpr)
2813 WRITE(*,*) ' Record ',nrpr
2814 IF (nrpr < 100000) THEN
2815 nrpr=nrpr*10
2816 ELSE
2817 nrpr=nrpr+100000
2818 END IF
2819 END DO
2820
2821 IF (ncache > 0.AND.nloopn <= 1.AND. npri < mpri.AND.mprint > 1) THEN
2822 npri=npri+1
2823 IF (npri == 1) WRITE(*,100)
2824 WRITE(*,101) nrec, nrd, more ,ifile
2825100 FORMAT(/' PeRead records active file' &
2826 /' total block threads number')
2827101 FORMAT(' PeRead',4i10)
2828 END IF
2829
2830 IF (more <= 0) THEN
2831 ifile=0
2832 IF (floop) THEN
2833 ! check for file weights
2834 ds0=0.0_mpd
2835 ds1=0.0_mpd
2836 ds2=0.0_mpd
2837 maxrecordsize=0
2838 maxrecordfile=0
2839 DO k=1,nfilb
2840 IF (xfd(k) > maxrecordsize) THEN
2841 maxrecordsize=xfd(k)
2842 maxrecordfile=k
2843 END IF
2844 dw=real(-kfd(1,k),mpd)
2845 IF (wfd(k) /= 1.0) nfilw=nfilw+1
2846 ds0=ds0+dw
2847 ds1=ds1+dw*real(wfd(k),mpd)
2848 ds2=ds2+dw*real(wfd(k)**2,mpd)
2849 END DO
2850 print *, 'PEREAD: file ', maxrecordfile, 'with max record size ', maxrecordsize
2851 IF (nfilw > 0.AND.ds0 > 0.0_mpd) THEN
2852 ds1=ds1/ds0
2853 ds2=ds2/ds0-ds1*ds1
2854 DO lun=6,lunlog,2
2855 WRITE(lun,177) nfilw,real(ds1,mps),real(ds2,mps)
2856177 FORMAT(/' !!!!!',i4,' weighted binary files', &
2857 /' !!!!! mean, variance of weights =',2g12.4)
2858 END DO
2859 END IF
2860 ! integrate record numbers
2861 DO k=2,nfilb
2862 ifd(k)=ifd(k-1)-kfd(1,k-1)
2863 END DO
2864 ! sort
2865 IF (nthr > 1) CALL sort2k(kfd,nfilb)
2866 IF (skippedrecords > 0) THEN
2867 print *, 'PEREAD skipped records: ', skippedrecords
2868 ndimbuf=maxrecordsize/2 ! adjust buffer size
2869 END IF
2870 END IF
2871 lprint=.false.
2872 floop=.false.
2873 IF (ncache > 0.AND.nloopn <= 1.AND.mprint > 0) &
2875179 FORMAT(/' Read cache usage (#blocks, #records, ', &
2876 'min,max records/block'/17x,i10,i12,2i10)
2877 END IF
2878 RETURN
2879
2880END SUBROUTINE peread
2881
2889SUBROUTINE peprep(mode)
2890 USE mpmod
2891
2892 IMPLICIT NONE
2893
2894 INTEGER(mpi), INTENT(IN) :: mode
2895
2896 INTEGER(mpi) :: ibuf
2897 INTEGER(mpi) :: ichunk
2898 INTEGER(mpi) :: ist
2899 INTEGER(mpi) :: itgbi
2900 INTEGER(mpi) :: j
2901 INTEGER(mpi) :: ja
2902 INTEGER(mpi) :: jb
2903 INTEGER(mpi) :: jsp
2904 INTEGER(mpi) :: nst
2905 INTEGER(mpi), PARAMETER :: maxbad = 100 ! max number of bad records with print out
2906 INTEGER(mpi) :: nbad
2907 INTEGER(mpi) :: nerr
2908 INTEGER(mpi) :: inone
2909
2910 IF (mode > 0) THEN
2911#ifdef __PGIC__
2912 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
2913 ichunk=256
2914#else
2915 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
2916#endif
2917 ! parallelize record loop
2918 !$OMP PARALLEL DO &
2919 !$OMP DEFAULT(PRIVATE) &
2920 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,ICHUNK,iscerr,dscerr) &
2921 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
2922 DO ibuf=1,numreadbuffer ! buffer for current record
2923 ist=readbufferpointer(ibuf)+1
2925 DO ! loop over measurements
2926 CALL isjajb(nst,ist,ja,jb,jsp)
2927 IF(jb == 0) EXIT
2928 DO j=1,ist-jb
2929 readbufferdatai(jb+j)=inone( readbufferdatai(jb+j) ) ! translate to index
2930 END DO
2931 ! scale error ?
2932 IF (iscerr > 0) THEN
2933 IF (jb < ist) THEN
2934 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(1) ! 'global' measurement
2935 ELSE
2936 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(2) ! 'local' measurement
2937 END IF
2938 END IF
2939 END DO
2940 END DO
2941 !$OMP END PARALLEL DO
2942 END IF
2943
2944 !$POMP INST BEGIN(peprep)
2945 IF (mode <= 0) THEN
2946 nbad=0
2947 DO ibuf=1,numreadbuffer ! buffer for current record
2948 CALL pechk(ibuf,nerr)
2949 IF(nerr > 0) THEN
2950 nbad=nbad+1
2951 IF(nbad >= maxbad) EXIT
2952 ELSE
2953 ist=readbufferpointer(ibuf)+1
2955 DO ! loop over measurements
2956 CALL isjajb(nst,ist,ja,jb,jsp)
2957 IF(jb == 0) EXIT
2958 neqn=neqn+1
2959 IF(jb == ist) cycle
2960 negb=negb+1
2961 ndgb=ndgb+(ist-jb)
2962 DO j=1,ist-jb
2963 itgbi=inone( readbufferdatai(jb+j) ) ! generate index
2964 END DO
2965 END DO
2966 END IF
2967 END DO
2968 IF(nbad > 0) THEN
2969 CALL peend(20,'Aborted, bad binary records')
2970 stop 'PEREAD: stopping due to bad records'
2971 END IF
2972 END IF
2973 !$POMP INST END(peprep)
2974
2975END SUBROUTINE peprep
2976
2984SUBROUTINE pechk(ibuf, nerr)
2985 USE mpmod
2986
2987 IMPLICIT NONE
2988 INTEGER(mpi) :: i
2989 INTEGER(mpi) :: is
2990 INTEGER(mpi) :: ist
2991 INTEGER(mpi) :: ioff
2992 INTEGER(mpi) :: ja
2993 INTEGER(mpi) :: jb
2994 INTEGER(mpi) :: jsp
2995 INTEGER(mpi) :: nan
2996 INTEGER(mpi) :: nst
2997
2998 INTEGER(mpi), INTENT(IN) :: ibuf
2999 INTEGER(mpi), INTENT(OUT) :: nerr
3000 SAVE
3001 ! ...
3002
3003 ist=readbufferpointer(ibuf)+1
3005 nerr=0
3006 is=ist
3007 jsp=0
3008 outer: DO WHILE(is < nst)
3009 ja=0
3010 jb=0
3011 inner1: DO
3012 is=is+1
3013 IF(is > nst) EXIT outer
3014 IF(readbufferdatai(is) == 0) EXIT inner1 ! found 1. marker
3015 END DO inner1
3016 ja=is
3017 inner2: DO
3018 is=is+1
3019 IF(is > nst) EXIT outer
3020 IF(readbufferdatai(is) == 0) EXIT inner2 ! found 2. marker
3021 END DO inner2
3022 jb=is
3023 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3024 ! special data
3025 jsp=jb ! pointer to special data
3026 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3027 cycle outer
3028 END IF
3029 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3030 is=is+1
3031 END DO
3032 END DO outer
3033 IF(is > nst) THEN
3034 ioff = readbufferpointer(ibuf)
3035 WRITE(*,100) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi)
3036100 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' is broken !!!')
3037 nerr=nerr+1
3038 ENDIF
3039 nan=0
3040 DO i=ist, nst
3041 IF(.NOT.(readbufferdatad(i) <= 0.0_mpr8).AND..NOT.(readbufferdatad(i) > 0.0_mpr8)) nan=nan+1
3042 END DO
3043 IF(nan > 0) THEN
3044 ioff = readbufferpointer(ibuf)
3045 WRITE(*,101) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi), nan
3046101 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' contains ', i6, ' NaNs !!!')
3047 nerr= nerr+2
3048 ENDIF
3049
3050END SUBROUTINE pechk
3051
3056SUBROUTINE pepgrp
3057 USE mpmod
3058 USE mpdalc
3059
3060 IMPLICIT NONE
3061
3062 INTEGER(mpi) :: ibuf
3063 INTEGER(mpi) :: ichunk
3064 INTEGER(mpi) :: iproc
3065 INTEGER(mpi) :: ioff
3066 INTEGER(mpi) :: ioffbi
3067 INTEGER(mpi) :: ist
3068 INTEGER(mpi) :: itgbi
3069 INTEGER(mpi) :: j
3070 INTEGER(mpi) :: ja
3071 INTEGER(mpi) :: jb
3072 INTEGER(mpi) :: jsp
3073 INTEGER(mpi) :: nalg
3074 INTEGER(mpi) :: nst
3075 INTEGER(mpi) :: inone
3076 INTEGER(mpl) :: length
3077 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
3078
3079 CALL useone ! make (INONE) usable
3080 globalparheader(-2)=-1 ! set flag to inhibit further updates
3081 ! need back index
3082 IF (mcount > 0) THEN
3083 length=globalparheader(-1)*mthrd
3084 CALL mpalloc(backindexusage,length,'global variable-index array')
3086 END IF
3087
3088#ifdef __PGIC__
3089 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
3090 ichunk=256
3091#else
3092 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
3093#endif
3094 ! parallelize record loop
3095 !$OMP PARALLEL DO &
3096 !$OMP DEFAULT(PRIVATE) &
3097 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,backIndexUsage,globalParHeader,ICHUNK,MCOUNT) &
3098 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
3099 DO ibuf=1,numreadbuffer ! buffer for current record
3100 ist=readbufferpointer(ibuf)+1
3102 IF (mcount > 0) THEN
3103 ! count per record
3104 iproc=0
3105 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
3106 ioffbi=globalparheader(-1)*iproc
3107 nalg=0
3108 ioff=readbufferpointer(ibuf)
3109 DO ! loop over measurements
3110 CALL isjajb(nst,ist,ja,jb,jsp)
3111 IF(jb == 0) EXIT
3112 IF (ist > jb) THEN
3113 DO j=1,ist-jb
3114 itgbi=inone( readbufferdatai(jb+j) ) ! translate to index
3115 IF (backindexusage(ioffbi+itgbi) == 0) THEN
3116 nalg=nalg+1
3117 readbufferdatai(ioff+nalg)=itgbi
3118 backindexusage(ioffbi+itgbi)=nalg
3119 END IF
3120 END DO
3121 END IF
3122 END DO
3123 ! reset back index
3124 DO j=1,nalg
3125 itgbi=readbufferdatai(ioff+j)
3126 backindexusage(ioffbi+itgbi)=0
3127 END DO
3128 ! sort (record)
3129 CALL sort1k(readbufferdatai(ioff+1),nalg)
3130 readbufferdatai(ioff)=ioff+nalg
3131 ELSE
3132 ! count per equation
3133 DO ! loop over measurements
3134 CALL isjajb(nst,ist,ja,jb,jsp)
3135 IF(jb == 0) EXIT
3136 IF (ist > jb) THEN
3137 DO j=1,ist-jb
3138 readbufferdatai(jb+j)=inone( readbufferdatai(jb+j) ) ! translate to index
3139 END DO
3140 ! sort (equation)
3141 CALL sort1k(readbufferdatai(jb+1),ist-jb)
3142 END IF
3143 END DO
3144 END IF
3145 END DO
3146 !$OMP END PARALLEL DO
3147
3148 !$POMP INST BEGIN(pepgrp)
3149 DO ibuf=1,numreadbuffer ! buffer for current record
3150 ist=readbufferpointer(ibuf)+1
3152 IF (mcount == 0) THEN
3153 ! equation level
3154 DO ! loop over measurements
3155 CALL isjajb(nst,ist,ja,jb,jsp)
3156 IF(jb == 0) EXIT
3157 CALL pargrp(jb+1,ist)
3158 END DO
3159 ELSE
3160 ! record level, group
3161 CALL pargrp(ist,nst)
3162 ENDIF
3163 END DO
3164 ! free back index
3165 IF (mcount > 0) THEN
3167 END IF
3168 !$POMP INST END(pepgrp)
3169 globalparheader(-2)=0 ! reset flag to reenable further updates
3170
3171END SUBROUTINE pepgrp
3172
3180SUBROUTINE pargrp(inds,inde)
3181 USE mpmod
3182
3183 IMPLICIT NONE
3184
3185 INTEGER(mpi) :: istart
3186 INTEGER(mpi) :: itgbi
3187 INTEGER(mpi) :: j
3188 INTEGER(mpi) :: jstart
3189 INTEGER(mpi) :: jtgbi
3190 INTEGER(mpi) :: lstart
3191 INTEGER(mpi) :: ltgbi
3192
3193 INTEGER(mpi), INTENT(IN) :: inds
3194 INTEGER(mpi), INTENT(IN) :: inde
3195
3196 IF (inds > inde) RETURN
3197
3198 ltgbi=-1
3199 lstart=-1
3200 ! build up groups
3201 DO j=inds,inde
3202 itgbi=readbufferdatai(j)
3203 ! count entries
3205 istart=globalparlabelindex(3,itgbi) ! label of group start
3206 IF (istart == 0) THEN ! not yet in group
3207 IF (itgbi /= ltgbi+1) THEN ! start group
3209 ELSE
3210 IF (lstart == 0) THEN ! extend group
3212 ELSE ! start group
3213 globalparlabelindex(3,itgbi)=globalparlabelindex(1,itgbi)
3214 END IF
3215 END IF
3216 END IF
3217 ltgbi=itgbi
3218 lstart=istart
3219 END DO
3220 ! split groups:
3221 ! - start inside group?
3222 itgbi=readbufferdatai(inds)
3223 istart=globalparlabelindex(3,itgbi) ! label of group start
3224 jstart=globalparlabelindex(1,itgbi) ! label of first parameter
3225 IF (istart /= jstart) THEN ! start new group
3226 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3227 globalparlabelindex(3,itgbi) = jstart
3228 itgbi=itgbi+1
3229 IF (itgbi > globalparheader(-1)) EXIT
3230 END DO
3231 END IF
3232 ! - not neigbours anymore
3233 ltgbi=readbufferdatai(inds)
3234 DO j=inds+1,inde
3235 itgbi=readbufferdatai(j)
3236 IF (itgbi /= ltgbi+1) THEN
3237 ! split after ltgbi
3238 lstart=globalparlabelindex(3,ltgbi) ! label of last group start
3239 jtgbi=ltgbi+1 ! new group after ltgbi
3240 jstart=globalparlabelindex(1,jtgbi)
3241 DO WHILE (globalparlabelindex(3,jtgbi) == lstart)
3242 globalparlabelindex(3,jtgbi) = jstart
3243 jtgbi=jtgbi+1
3244 IF (jtgbi > globalparheader(-1)) EXIT
3245 IF (jtgbi == itgbi) jstart=globalparlabelindex(1,jtgbi)
3246 END DO
3247 ! split at itgbi
3248 jtgbi=itgbi
3249 istart=globalparlabelindex(3,jtgbi) ! label of group start
3250 jstart=globalparlabelindex(1,jtgbi) ! label of first parameter
3251 IF (istart /= jstart) THEN ! start new group
3252 DO WHILE (globalparlabelindex(3,jtgbi) == istart)
3253 globalparlabelindex(3,jtgbi) = jstart
3254 jtgbi=jtgbi+1
3255 IF (jtgbi > globalparheader(-1)) EXIT
3256 END DO
3257 END IF
3258 ENDIF
3259 ltgbi=itgbi
3260 END DO
3261 ! - end inside group?
3262 itgbi=readbufferdatai(inde)
3263 IF (itgbi < globalparheader(-1)) THEN
3264 istart=globalparlabelindex(3,itgbi) ! label of group start
3265 itgbi=itgbi+1
3266 jstart=globalparlabelindex(1,itgbi) ! label of new group start
3267 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3268 globalparlabelindex(3,itgbi) = jstart
3269 itgbi=itgbi+1
3270 IF (itgbi > globalparheader(-1)) EXIT
3271 END DO
3272 END IF
3273
3274END SUBROUTINE pargrp
3275
3298SUBROUTINE isjajb(nst,is,ja,jb,jsp)
3299 USE mpmod
3300
3301 IMPLICIT NONE
3302
3303 INTEGER(mpi), INTENT(IN) :: nst
3304 INTEGER(mpi), INTENT(IN OUT) :: is
3305 INTEGER(mpi), INTENT(OUT) :: ja
3306 INTEGER(mpi), INTENT(OUT) :: jb
3307 INTEGER(mpi), INTENT(OUT) :: jsp
3308 SAVE
3309 ! ...
3310
3311 jsp=0
3312 DO
3313 ja=0
3314 jb=0
3315 IF(is >= nst) RETURN
3316 DO
3317 is=is+1
3318 IF(readbufferdatai(is) == 0) EXIT
3319 END DO
3320 ja=is
3321 DO
3322 is=is+1
3323 IF(readbufferdatai(is) == 0) EXIT
3324 END DO
3325 jb=is
3326 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3327 ! special data
3328 jsp=jb ! pointer to special data
3329 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3330 cycle
3331 END IF
3332 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3333 is=is+1
3334 END DO
3335 EXIT
3336 END DO
3337
3338END SUBROUTINE isjajb
3339
3340
3341!***********************************************************************
3342! LOOPN ...
3348
3349SUBROUTINE loopn
3350 USE mpmod
3351
3352 IMPLICIT NONE
3353 REAL(mpd) :: dsum
3354 REAL(mps) :: elmt
3355 REAL(mpd) :: factrj
3356 REAL(mpd) :: factrk
3357 REAL(mps) :: peakd
3358 REAL(mps) :: peaki
3359 REAL(mps) :: ratae
3360 REAL(mpd) :: rhs
3361 REAL(mps) :: rloop
3362 REAL(mpd) :: sgm
3363 REAL(mps) :: used
3364 REAL(mps) :: usei
3365 REAL(mpd) :: weight
3366 INTEGER(mpi) :: i
3367 INTEGER(mpi) :: ia
3368 INTEGER(mpi) :: ib
3369 INTEGER(mpi) :: ioffb
3370 INTEGER(mpi) :: ipr
3371 INTEGER(mpi) :: itgbi
3372 INTEGER(mpi) :: itgbij
3373 INTEGER(mpi) :: itgbik
3374 INTEGER(mpi) :: ivgb
3375 INTEGER(mpi) :: ivgbij
3376 INTEGER(mpi) :: ivgbik
3377 INTEGER(mpi) :: j
3378 INTEGER(mpi) :: k
3379 INTEGER(mpi) :: lastit
3380 INTEGER(mpi) :: lun
3381 INTEGER(mpi) :: ncrit
3382 INTEGER(mpi) :: ngras
3383 INTEGER(mpi) :: nparl
3384 INTEGER(mpi) :: nr
3385 INTEGER(mpi) :: nrej
3386 INTEGER(mpi) :: inone
3387 INTEGER(mpi) :: ilow
3388 INTEGER(mpi) :: nlow
3389 INTEGER(mpi) :: nzero
3390 LOGICAL :: btest
3391
3392 REAL(mpd):: adder
3393 REAL(mpd)::funref
3394 REAL(mpd)::matij
3395
3396 SAVE
3397 ! ...
3398
3399 ! ----- book and reset ---------------------------------------------
3400 IF(nloopn == 0) THEN ! first call
3401 lastit=-1
3402 iitera=0
3403 END IF
3404
3405 nloopn=nloopn+1 ! increase loop counter
3406 funref=0.0_mpd
3407
3408 IF(nloopn == 1) THEN ! book histograms for 1. iteration
3409 CALL gmpdef(1,4,'Function value in iterations')
3410 IF (metsol == 4 .OR. metsol == 5) THEN ! extend to GMRES, i.e. 6?
3411 CALL gmpdef(2,3,'Number of MINRES steps vs iteration nr')
3412 END IF
3413 CALL hmpdef( 5,0.0,0.0,'Number of degrees of freedom')
3414 CALL hmpdef(11,0.0,0.0,'Number of local parameters')
3415 CALL hmpdef(23,0.0,0.0, 'SQRT of diagonal elements without presigma')
3416 CALL hmpdef(24,0.0,0.0, 'Log10 of off-diagonal elements')
3417 CALL hmpdef(25,0.0,0.0, 'Relative individual pre-sigma')
3418 CALL hmpdef(26,0.0,0.0, 'Relative global pre-sigma')
3419 END IF
3420
3421
3422 CALL hmpdef(3,-prange,prange, & ! book
3423 'Normalized residuals of single (global) measurement')
3424 CALL hmpdef(12,-prange,prange, & ! book
3425 'Normalized residuals of single (local) measurement')
3426 CALL hmpdef(13,-prange,prange, & ! book
3427 'Pulls of single (global) measurement')
3428 CALL hmpdef(14,-prange,prange, & ! book
3429 'Pulls of single (local) measurement')
3430 CALL hmpdef(4,0.0,0.0,'Chi^2/Ndf after local fit')
3431 CALL gmpdef(4,5,'location, dispersion (res.) vs record nr')
3432 CALL gmpdef(5,5,'location, dispersion (pull) vs record nr')
3433
3434 ! WRITE(*,*) 'LOOPN ', NLOOPN, ' executing ICALCM=', ICALCM
3435
3436 ! reset
3437
3438 globalvector=0.0_mpd ! reset rhs vector IGVEC
3440 IF(icalcm == 1) THEN
3441 globalmatd=0.0_mpd
3442 globalmatf=0.
3443 IF (metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) matprecond=0.0_mpd
3444 END IF
3445
3446 IF(nloopn == 2) CALL hmpdef(6,0.0,0.0,'Down-weight fraction')
3447
3448 newite=.false.
3449 IF(iterat /= lastit) THEN ! new iteration
3450 newite=.true.
3451 funref=fvalue
3452 IF(nloopn > 1) THEN
3453 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3)
3454 ! CALL MEND
3455 IF(iterat == 1) THEN
3457 ELSE IF(iterat >= 1) THEN
3458 chicut=sqrt(chicut)
3459 IF(chicut /= 0.0.AND.chicut < 1.5) chicut=1.0
3460 IF(chicut /= 0.0.AND.nrej == 0) chicut=1.0
3461 END IF
3462 END IF
3463 ! WRITE(*,111) ! header line
3464 END IF
3465
3466 DO i=0,3
3467 nrejec(i)=0 ! reset reject counter
3468 END DO
3469 DO k=3,6
3470 writebufferheader(k)=0 ! cache usage
3471 writebufferheader(-k)=0
3472 END DO
3473 ! statistics per binary file
3474 DO i=1,nfilb
3475 jfd(i)=0
3476 cfd(i)=0.0
3477 dfd(i)=0
3478 END DO
3479
3480 IF (imonit /= 0) meashists=0 ! reset monitoring histograms
3481
3482 ! ----- read next data ----------------------------------------------
3483 DO
3484 CALL peread(nr) ! read records
3485 CALL peprep(1) ! prepare records
3487 IF (nr <= 0) EXIT ! next block of events ?
3488 END DO
3489 ! sum up RHS (over threads) once (reduction in LOOPBF: summation for each block)
3490 ioffb=0
3491 DO ipr=2,mthrd
3492 ioffb=ioffb+lenglobalvec
3493 DO k=1,lenglobalvec
3496 END DO
3497 END DO
3498
3499 IF (icalcm == 1) THEN
3500 ! PRINT *, ' cache/w ',(writeBufferHeader(-K),K=3,6),(writeBufferHeader(K),K=3,6)
3501 nparl=writebufferheader(3)
3502 ncrit=writebufferheader(4)
3503 used=real(writebufferheader(-5),mps)/real(writebufferheader(-3),mps)*0.1
3504 usei=real(writebufferheader(5),mps)/real(writebufferheader(3),mps)*0.1
3505 peakd=real(writebufferheader(-6),mps)*0.1
3506 peaki=real(writebufferheader(6),mps)*0.1
3507 WRITE(*,111) nparl,ncrit,usei,used,peaki,peakd
3508111 FORMAT(' Write cache usage (#flush,#overrun,<levels>,', &
3509 'peak(levels))'/2i7,',',4(f6.1,'%'))
3510 ! fill part of MINRES preconditioner matrix from binary files (formerly in mgupdt)
3511 IF (metsol >= 4.AND.metsol < 7) THEN
3512 IF (mbandw == 0) THEN
3513 ! default preconditioner (diagonal)
3514 DO i=1, nvgb
3515 matprecond(i)=matij(i,i)
3516 END DO
3517 ELSE IF (mbandw > 0) THEN
3518 ! band matrix
3519 DO i=1, nvgb
3520 ia=indprecond(i) ! index of diagonal element
3521 DO j=max(1,i-mbandw+1),i
3522 matprecond(ia-i+j)=matij(i,j)
3523 END DO
3524 END DO
3525 END IF
3526 END IF
3527 IF (ichkpg > 0) THEN
3528 ! check parameter groups
3529 CALL ckpgrp
3530 END IF
3531 END IF
3532
3533 ! check entries/counters
3534 nlow=0
3535 ilow=1
3536 nzero=0
3537 DO i=1,nvgb
3538 IF(globalcounter(i) == 0) nzero=nzero+1
3539 IF(globalcounter(i) < mreqena) THEN
3540 nlow=nlow+1
3541 IF(globalcounter(i) < globalcounter(ilow)) ilow=i
3542 END IF
3543 END DO
3544 IF(nlow > 0) THEN
3545 nalow=nalow+nlow
3546 IF(icalcm == 1) nxlow=max(nxlow,nlow) ! for matrix construction ?
3547 itgbi=globalparvartototal(ilow)
3548 print *
3549 print *, " ... warning ..."
3550 print *, " global parameters with too few (< MREQENA) accepted entries: ", nlow
3551 print *, " minimum entries: ", globalcounter(ilow), " for label ", globalparlabelindex(1,itgbi)
3552 print *
3553 END IF
3554 IF(icalcm == 1 .AND. nzero > 0) THEN
3555 ndefec = nzero ! rank defect
3556 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfgb, &
3557 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3558 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfgb, &
3559 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3560 IF (iforce == 0) THEN
3561 isubit=1
3562 WRITE(*,*) ' --> enforcing SUBITO mode'
3563 WRITE(lun,*) ' --> enforcing SUBITO mode'
3564 END IF
3565 END IF
3566
3567 ! ----- after end-of-data add contributions from pre-sigma ---------
3568
3569 IF(nloopn == 1) THEN
3570 ! plot diagonal elements
3571 elmt=0.0
3572 DO i=1,nvgb ! diagonal elements
3573 elmt=real(matij(i,i),mps)
3574 IF(elmt > 0.0) CALL hmpent(23,1.0/sqrt(elmt))
3575 END DO
3576 END IF
3577
3578
3579
3580 ! add pre-sigma contributions to matrix diagonal
3581
3582 ! WRITE(*,*) 'Adding to diagonal ICALCM IND6',ICALCM,IND6
3583
3584 IF(icalcm == 1) THEN
3585 DO ivgb=1,nvgb ! add evtl. pre-sigma
3586 ! WRITE(*,*) 'Index ',IVGB,IVGB,QM(IND6+IVGB)
3587 IF(globalparpreweight(ivgb) /= 0.0) THEN
3588 IF(ivgb > 0) CALL mupdat(ivgb,ivgb,globalparpreweight(ivgb))
3589 END IF
3590 END DO
3591 END IF
3592
3593 CALL hmpwrt(23)
3594 CALL hmpwrt(24)
3595 CALL hmpwrt(25)
3596 CALL hmpwrt(26)
3597
3598
3599 ! add regularization term to F and to rhs --------------------------
3600
3601 ! WRITE(*,*) 'NREGUL ',NREGUL,NLOOPN
3602
3603 IF(nregul /= 0) THEN ! add regularization term to F and to rhs
3604 DO ivgb=1,nvgb
3605 itgbi=globalparvartototal(ivgb) ! global parameter index
3607 adder=globalparpreweight(ivgb)*globalparameter(itgbi)**2
3608 CALL addsums(1, adder, 0, 1.0_mpl)
3609 END DO
3610 END IF
3611
3612
3613 ! ----- add contributions from "measurement" -----------------------
3614
3615
3616 i=1
3617 DO WHILE (i <= lenmeasurements)
3618 rhs=listmeasurements(i )%value ! right hand side
3619 sgm=listmeasurements(i+1)%value ! sigma parameter
3620 i=i+2
3621 weight=0.0
3622 IF(sgm > 0.0) weight=1.0/sgm**2
3623
3624 dsum=-rhs
3625
3626 ! loop over label/factor pairs
3627 ia=i
3628 DO
3629 i=i+1
3630 IF(i > lenmeasurements) EXIT
3631 IF(listmeasurements(i)%label < 0) EXIT
3632 END DO
3633 ib=i-1
3634
3635 DO j=ia,ib
3636 factrj=listmeasurements(j)%value
3637 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3638 IF(itgbij /= 0) THEN
3639 dsum=dsum+factrj*globalparameter(itgbij) ! update residuum
3640 END IF
3641 END DO
3642 DO j=ia,ib
3643 factrj=listmeasurements(j)%value
3644 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3645 ! add to vector
3646 ivgbij=0
3647 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
3648 IF(ivgbij > 0) THEN
3649 globalvector(ivgbij)=globalvector(ivgbij) -weight*dsum*factrj ! vector
3650 globalcounter(ivgbij)=globalcounter(ivgbij)+1
3651 END IF
3652
3653 IF(icalcm == 1.AND.ivgbij > 0) THEN
3654 DO k=ia,j
3655 factrk=listmeasurements(k)%value
3656 itgbik=inone(listmeasurements(k)%label) ! total parameter index
3657 ! add to matrix
3658 ivgbik=0
3659 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
3660 IF(ivgbij > 0.AND.ivgbik > 0) THEN !
3661 CALL mupdat(ivgbij,ivgbik,weight*factrj*factrk)
3662 END IF
3663 END DO
3664 END IF
3665 END DO
3666
3667 adder=weight*dsum**2
3668 CALL addsums(1, adder, 1, 1.0_mpl)
3669
3670 END DO
3671
3672 ! ----- printout ---------------------------------------------------
3673
3674
3675 ! get accurate sum (Chi^2, (w)NDF)
3677
3678 flines=0.5_mpd*fvalue ! Likelihood function value
3679 rloop=iterat+0.01*nloopn
3680 actfun=real(funref-fvalue,mps)
3681 IF(nloopn == 1) actfun=0.0
3682 ngras=nint(angras,mpi)
3683 ratae=0.0 !!!
3684 IF(delfun /= 0.0) THEN
3685 ratae=min(99.9,actfun/delfun) !!!
3686 ratae=max(-99.9,ratae)
3687 END IF
3688
3689 ! rejects ...
3690
3691 nrej =nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3)
3692 IF(nloopn == 1) THEN
3693 IF(nrej /= 0) THEN
3694 WRITE(*,*) ' '
3695 WRITE(*,*) 'Data rejected in initial loop:'
3696 WRITE(*,*) ' ', &
3697 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', &
3698 nrejec(2), ' (huge) ',nrejec(3),' (large)'
3699 END IF
3700 END IF
3701 ! IF(NREJEC(1)+NREJEC(2)+NREJEC(3).NE.0) THEN
3702 ! WRITE(LUNLOG,*) 'Data rejected in initial loop:',NREJEC(1),
3703 ! + ' (Ndf=0) ',NREJEC(2),' (huge) ',NREJEC(3),' (large)'
3704 ! END IF
3705
3706
3707 IF(newite.AND.iterat == 2) THEN
3708 IF(nrecpr /= 0.OR.nrecp2 /= 0) nrecer=nrec3
3709 IF(nrecpr < 0) THEN
3711 END IF
3712 IF(nrecp2 < 0) THEN
3714 END IF
3715 END IF
3716
3717 IF(nloopn <= 2) THEN
3718 IF(nhistp /= 0) THEN
3719 ! CALL HMPRNT(3) ! scaled residual of single measurement
3720 ! CALL HMPRNT(12) ! scaled residual of single measurement
3721 ! CALL HMPRNT(4) ! chi^2/Ndf
3722 END IF
3723 CALL hmpwrt(3)
3724 CALL hmpwrt(12)
3725 CALL hmpwrt(4)
3726 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
3727 IF (nloopn <= lfitnp) THEN
3728 CALL hmpwrt(13)
3729 CALL hmpwrt(14)
3730 CALL gmpwrt(5) ! location, dispersion (pull) as a function of record nr
3731 END IF
3732 END IF
3733 ! IF(NLOOPN.EQ.2.AND.NHISTP.NE.0) CALL HMPRNT(6)
3734 IF(nloopn == 2) CALL hmpwrt(6)
3735 IF(nloopn <= 1) THEN
3736 ! IF(NHISTP.NE.0) CALL HMPRNT(5) ! number of degrees of freedom
3737 ! IF(NHISTP.NE.0) CALL HMPRNT(11) ! Nlocal
3738 CALL hmpwrt(5)
3739 CALL hmpwrt(11)
3740 END IF
3741
3742 ! local fit: band matrix structure !?
3743 IF (nloopn == 1.AND.nbndr(1)+nbndr(2) > 0) THEN
3744 DO lun=6,8,2
3745 WRITE(lun,*) ' '
3746 WRITE(lun,*) ' === local fits have bordered band matrix structure ==='
3747 IF (nbndr(1) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(1),'number of records (upper/left border)'
3748 IF (nbndr(2) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(2),'number of records (lower/right border)'
3749 WRITE(lun,101) ' NBDRX',nbdrx,'max border size'
3750 WRITE(lun,101) ' NBNDX',nbndx,'max band width'
3751 END DO
3752 END IF
3753
3754 lastit=iterat
3755
3756 ! monitoring of residuals
3757 IF (imonit < 0 .OR. (nloopn == 1 .AND. btest(imonit,0))) CALL monres
3758
3759101 FORMAT(1x,a8,' =',i14,' = ',a)
3760! 101 FORMAT(' LOOPN',I6,' Function value',F22.8,10X,I6,' records')
3761! 102 FORMAT(' incl. constraint penalty',F22.8)
3762! 103 FORMAT(I13,3X,A,G12.4)
3763END SUBROUTINE loopn ! loop with fits
3764
3768
3769SUBROUTINE ploopa(lunp)
3770 USE mpmod
3771
3772 IMPLICIT NONE
3773
3774 INTEGER(mpi), INTENT(IN) :: lunp
3775 ! ..
3776 WRITE(lunp,*) ' '
3777 WRITE(lunp,101) ! header line
3778 WRITE(lunp,102) ! header line
3779101 FORMAT(' it fc',' fcn_value dfcn_exp slpr costh iit st', &
3780 ' ls step cutf',1x,'rejects hhmmss FMS')
3781102 FORMAT(' -- --',' ----------- -------- ---- ----- --- --', &
3782 ' -- ----- ----',1x,'------- ------ ---')
3783 RETURN
3784END SUBROUTINE ploopa ! title for iteration
3785
3789
3790SUBROUTINE ploopb(lunp)
3791 USE mpmod
3792
3793 IMPLICIT NONE
3794 INTEGER(mpi) :: ma
3795 INTEGER :: minut
3796 INTEGER(mpi) :: nfa
3797 INTEGER :: nhour
3798 INTEGER(mpi) :: nrej
3799 INTEGER(mpi) :: nsecnd
3800 REAL(mps) :: ratae
3801 REAL :: rstb
3802 REAL(mps) :: secnd
3803 REAL(mps) :: slopes(3)
3804 REAL(mps) :: steps(3)
3805 REAL, DIMENSION(2) :: ta
3806 REAl etime
3807
3808 INTEGER(mpi), INTENT(IN) :: lunp
3809
3810 CHARACTER (LEN=4):: ccalcm(4)
3811 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3812 SAVE
3813
3814 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! rejects
3815 IF(nrej > 9999999) nrej=9999999
3816 rstb=etime(ta)
3817 deltim=rstb-rstart
3818 CALL sechms(deltim,nhour,minut,secnd) ! time
3819 nsecnd=nint(secnd,mpi)
3820 IF(iterat == 0) THEN
3821 WRITE(lunp,103) iterat,nloopn,fvalue, &
3822 chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3823 ELSE
3824 IF (lsinfo == 10) THEN ! line search skipped
3825 WRITE(lunp,105) iterat,nloopn,fvalue,delfun, &
3826 iitera,istopa,chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3827 ELSE
3828 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3829 ratae=max(-99.9,min(99.9,slopes(2)/slopes(1)))
3830 stepl=steps(2)
3831 WRITE(lunp,104) iterat,nloopn,fvalue,delfun,ratae,angras, &
3832 iitera,istopa,lsinfo,stepl, chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3833 ENDIF
3834 END IF
3835103 FORMAT(i3,i3,e12.5,38x,f5.1, 1x,i7, i3,i2.2,i2.2,a4)
3836104 FORMAT(i3,i3,e12.5,1x,e8.2,f6.3,f6.3,i5,2i3,f6.3,f5.1, &
3837 1x,i7, i3,i2.2,i2.2,a4)
3838105 FORMAT(i3,i3,e12.5,1x,e8.2,12x,i5,i3,9x,f5.1, &
3839 1x,i7, i3,i2.2,i2.2,a4)
3840 RETURN
3841END SUBROUTINE ploopb ! iteration line
3842
3846
3847SUBROUTINE ploopc(lunp)
3848 USE mpmod
3849
3850 IMPLICIT NONE
3851 INTEGER(mpi) :: ma
3852 INTEGER(mpi) :: minut
3853 INTEGER(mpi) :: nfa
3854 INTEGER(mpi) :: nhour
3855 INTEGER(mpi) :: nrej
3856 INTEGER(mpi) :: nsecnd
3857 REAL(mps) :: ratae
3858 REAL :: rstb
3859 REAL(mps) :: secnd
3860 REAL(mps) :: slopes(3)
3861 REAL(mps) :: steps(3)
3862 REAL, DIMENSION(2) :: ta
3863 REAL etime
3864
3865 INTEGER(mpi), INTENT(IN) :: lunp
3866 CHARACTER (LEN=4):: ccalcm(4)
3867 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3868 SAVE
3869
3870 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! rejects
3871 IF(nrej > 9999999) nrej=9999999
3872 rstb=etime(ta)
3873 deltim=rstb-rstart
3874 CALL sechms(deltim,nhour,minut,secnd) ! time
3875 nsecnd=nint(secnd,mpi)
3876 IF (lsinfo == 10) THEN ! line search skipped
3877 WRITE(lunp,104) nloopn,fvalue,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3878 ELSE
3879 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3880 ratae=abs(slopes(2)/slopes(1))
3881 stepl=steps(2)
3882 WRITE(lunp,105) nloopn,fvalue, ratae,lsinfo, &
3883 stepl,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3884 END IF
3885104 FORMAT(3x,i3,e12.5,9x, 35x, i7, i3,i2.2,i2.2,a4)
3886105 FORMAT(3x,i3,e12.5,9x, f6.3,14x,i3,f6.3,6x, i7, i3,i2.2,i2.2,a4)
3887 RETURN
3888
3889END SUBROUTINE ploopc ! sub-iteration line
3890
3894
3895SUBROUTINE ploopd(lunp)
3896 USE mpmod
3897 IMPLICIT NONE
3898 INTEGER :: minut
3899 INTEGER :: nhour
3900 INTEGER(mpi) :: nsecnd
3901 REAL :: rstb
3902 REAL(mps) :: secnd
3903 REAL, DIMENSION(2) :: ta
3904 REAL etime
3905
3906 INTEGER(mpi), INTENT(IN) :: lunp
3907 CHARACTER (LEN=4):: ccalcm(4)
3908 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3909 SAVE
3910 rstb=etime(ta)
3911 deltim=rstb-rstart
3912 CALL sechms(deltim,nhour,minut,secnd) ! time
3913 nsecnd=nint(secnd,mpi)
3914
3915 WRITE(lunp,106) nhour,minut,nsecnd,ccalcm(lcalcm)
3916106 FORMAT(69x,i3,i2.2,i2.2,a4)
3917 RETURN
3918END SUBROUTINE ploopd
3919
3921SUBROUTINE explfc(lunit)
3922 USE mpdef
3923 USE mpmod, ONLY: metsol
3924
3925 IMPLICIT NONE
3926 INTEGER(mpi) :: lunit
3927 WRITE(lunit,*) ' '
3928 WRITE(lunit,102) 'Explanation of iteration table'
3929 WRITE(lunit,102) '=============================='
3930 WRITE(lunit,101) 'it', &
3931 'iteration number. Global parameters are improved for it > 0.'
3932 WRITE(lunit,102) 'First function evaluation is called iteraton 0.'
3933 WRITE(lunit,101) 'fc', 'number of function evaluations.'
3934 WRITE(lunit,101) 'fcn_value', 'value of 2 x Likelihood function (LF).'
3935 WRITE(lunit,102) 'The final value is the chi^2 value of the fit and should'
3936 WRITE(lunit,102) 'be about equal to the NDF (see below).'
3937 WRITE(lunit,101) 'dfcn_exp', &
3938 'expected reduction of the value of the Likelihood function (LF)'
3939 WRITE(lunit,101) 'slpr', 'ratio of the actual slope to inital slope.'
3940 WRITE(lunit,101) 'costh', &
3941 'cosine of angle between search direction and -gradient'
3942 IF (metsol == 4) THEN
3943 WRITE(lunit,101) 'iit', &
3944 'number of internal iterations in MINRES algorithm'
3945 WRITE(lunit,101) 'st', 'stop code of MINRES algorithm'
3946 WRITE(lunit,102) '< 0: rhs is very special, with beta2 = 0'
3947 WRITE(lunit,102) '= 0: rhs b = 0, i.e. the exact solution is x = 0'
3948 WRITE(lunit,102) '= 1 requested accuracy achieved, as determined by rtol'
3949 WRITE(lunit,102) '= 2 reasonable accuracy achieved, given eps'
3950 WRITE(lunit,102) '= 3 x has converged to an eigenvector'
3951 WRITE(lunit,102) '= 4 matrix ill-conditioned (Acond has exceeded 0.1/eps)'
3952 WRITE(lunit,102) '= 5 the iteration limit was reached'
3953 WRITE(lunit,102) '= 6 Matrix x vector does not define a symmetric matrix'
3954 WRITE(lunit,102) '= 7 Preconditioner does not define a symmetric matrix'
3955 ELSEIF (metsol == 5) THEN
3956 WRITE(lunit,101) 'iit', &
3957 'number of internal iterations in MINRES-QLP algorithm'
3958 WRITE(lunit,101) 'st', 'stop code of MINRES-QLP algorithm'
3959 WRITE(lunit,102) '= 1: beta_{k+1} < eps, iteration k is the final Lanczos step.'
3960 WRITE(lunit,102) '= 2: beta2 = 0. If M = I, b and x are eigenvectors of A.'
3961 WRITE(lunit,102) '= 3: beta1 = 0. The exact solution is x = 0.'
3962 WRITE(lunit,102) '= 4: A solution to (poss. singular) Ax = b found, given rtol.'
3963 WRITE(lunit,102) '= 5: A solution to (poss. singular) Ax = b found, given eps.'
3964 WRITE(lunit,102) '= 6: Pseudoinverse solution for singular LS problem, given rtol.'
3965 WRITE(lunit,102) '= 7: Pseudoinverse solution for singular LS problem, given eps.'
3966 WRITE(lunit,102) '= 8: The iteration limit was reached.'
3967 WRITE(lunit,102) '= 9: The operator defined by Aprod appears to be unsymmetric.'
3968 WRITE(lunit,102) '=10: The operator defined by Msolve appears to be unsymmetric.'
3969 WRITE(lunit,102) '=11: The operator defined by Msolve appears to be indefinite.'
3970 WRITE(lunit,102) '=12: xnorm has exceeded maxxnorm or will exceed it next iteration.'
3971 WRITE(lunit,102) '=13: Acond has exceeded Acondlim or 0.1/eps.'
3972 WRITE(lunit,102) '=14: Least-squares problem but no converged solution yet.'
3973 WRITE(lunit,102) '=15: A null vector obtained, given rtol.'
3974 ENDIF
3975 WRITE(lunit,101) 'ls', 'line search info'
3976 WRITE(lunit,102) '< 0 recalculate function'
3977 WRITE(lunit,102) '= 0: N or STP lt 0 or step not descending'
3978 WRITE(lunit,102) '= 1: Linesearch convergence conditions reached'
3979 WRITE(lunit,102) '= 2: interval of uncertainty at lower limit'
3980 WRITE(lunit,102) '= 3: max nr of line search calls reached'
3981 WRITE(lunit,102) '= 4: step at the lower bound'
3982 WRITE(lunit,102) '= 5: step at the upper bound'
3983 WRITE(lunit,102) '= 6: rounding error limitation'
3984 WRITE(lunit,101) 'step', &
3985 'the factor for the Newton step during the line search. Usually'
3986 WRITE(lunit,102) &
3987 'a value of 1 gives a sufficient reduction of the LF. Oherwise'
3988 WRITE(lunit,102) 'other step values are tried.'
3989 WRITE(lunit,101) 'cutf', &
3990 'cut factor. Local fits are rejected, if their chi^2 value'
3991 WRITE(lunit,102) &
3992 'is larger than the 3-sigma chi^2 value times the cut factor.'
3993 WRITE(lunit,102) 'A cut factor of 1 is used finally, but initially a larger'
3994 WRITE(lunit,102) 'factor may be used. A value of 0.0 means no cut.'
3995 WRITE(lunit,101) 'rejects', 'total number of rejected local fits.'
3996 WRITE(lunit,101) 'hmmsec', 'the time in hours (h), minutes (mm) and seconds.'
3997 WRITE(lunit,101) 'FMS', 'calculation of Function value, Matrix, Solution.'
3998 WRITE(lunit,*) ' '
3999
4000101 FORMAT(a9,' = ',a)
4001102 FORMAT(13x,a)
4002END SUBROUTINE explfc
4003
4011
4012SUBROUTINE mupdat(i,j,add) !
4013 USE mpmod
4014
4015 IMPLICIT NONE
4016
4017 INTEGER(mpi), INTENT(IN) :: i
4018 INTEGER(mpi), INTENT(IN) :: j
4019 REAL(mpd), INTENT(IN) :: add
4020
4021 INTEGER(mpl):: ijadd
4022 INTEGER(mpl):: ijcsr3
4023 INTEGER(mpl):: ia
4024 INTEGER(mpl):: ja
4025 INTEGER(mpl):: ij
4026 ! ...
4027 IF(i <= 0.OR.j <= 0.OR. add == 0.0_mpd) RETURN
4028 ia=max(i,j) ! larger
4029 ja=min(i,j) ! smaller
4030 ij=0
4031 IF(matsto == 3) THEN
4032 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
4033 ij=ijcsr3(i,j) ! inline code requires same time
4034 IF (ij > 0) globalmatd(ij)=globalmatd(ij)+add
4035 RETURN
4036 ELSE ! sparse symmetric matrix (BSR3)
4037 ! block index
4038 ij=ijcsr3((i-1)/matbsz+1,(j-1)/matbsz+1)
4039 IF (ij > 0) THEN
4040 ! index of first element in block
4041 ij=(ij-1)*matbsz*matbsz+1
4042 ! adjust index for position in block
4043 ij=ij+mod(int(ia-1,mpi),matbsz)*matbsz+mod(int(ja-1,mpi),matbsz)
4044 globalmatd(ij)=globalmatd(ij)+add
4045 ENDIF
4046 RETURN
4047 END IF
4048 ELSE IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4049 ij=ijadd(i,j) ! inline code requires same time
4050 IF (ij == 0) RETURN ! pair is suppressed
4051 IF (ij > 0) THEN
4052 globalmatd(ij)=globalmatd(ij)+add
4053 ELSE
4054 globalmatf(-ij)=globalmatf(-ij)+real(add,mps)
4055 END IF
4056 ELSE ! full or unpacked (block diagonal) symmetric matrix
4057 ! global (ia,ib) to local (row,col) in block
4058 ij=globalrowoffsets(ia)+ja
4059 globalmatd(ij)=globalmatd(ij)+add
4060 END IF
4061 ! MINRES preconditioner
4062 IF(metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) THEN
4063 ij=0 ! no update
4064 IF(ia <= nvgb) THEN ! variable global parameter
4065 IF(mbandw > 0) THEN ! band matrix for Cholesky decomposition
4066 ij=indprecond(ia)-ia+ja
4067 IF(ia > 1.AND.ij <= indprecond(ia-1)) ij=0
4068 ELSE ! default preconditioner (diagonal)
4069 IF(ja == ia) ij=ia
4070 END IF
4071 ELSE ! Lagrange multiplier
4072 ij=offprecond(ia-nvgb)+ja
4073 END IF
4074 ! bad index?
4075 IF(ij < 0.OR.ij > size(matprecond)) THEN
4076 CALL peend(23,'Aborted, bad matrix index')
4077 stop 'mupdat: bad index'
4078 END IF
4079 ! update?
4080 IF(ij /= 0) matprecond(ij)=matprecond(ij)+add
4081 END IF
4082END SUBROUTINE mupdat
4083
4084
4096
4097SUBROUTINE mgupdt(i,j1,j2,il,jl,n,sub)
4098 USE mpmod
4099
4100 IMPLICIT NONE
4101
4102 INTEGER(mpi), INTENT(IN) :: i
4103 INTEGER(mpi), INTENT(IN) :: j1
4104 INTEGER(mpi), INTENT(IN) :: j2
4105 INTEGER(mpi), INTENT(IN) :: il
4106 INTEGER(mpi), INTENT(IN) :: jl
4107 INTEGER(mpi), INTENT(IN) :: n
4108 REAL(mpd), INTENT(IN) :: sub((n*n+n)/2)
4109
4110 INTEGER(mpl):: ij
4111 INTEGER(mpl):: ioff
4112 INTEGER(mpi):: ia
4113 INTEGER(mpi):: ia1
4114 INTEGER(mpi):: ib
4115 INTEGER(mpi):: iblast
4116 INTEGER(mpi):: iblock
4117 INTEGER(mpi):: ijl
4118 INTEGER(mpi):: iprc
4119 INTEGER(mpi):: ir
4120 INTEGER(mpi):: ja
4121 INTEGER(mpi):: jb
4122 INTEGER(mpi):: jblast
4123 INTEGER(mpi):: jblock
4124 INTEGER(mpi):: jc
4125 INTEGER(mpi):: jc1
4126 INTEGER(mpi):: jpg
4127 INTEGER(mpi):: k
4128 INTEGER(mpi):: lr
4129 INTEGER(mpi):: nc
4130
4131 INTEGER(mpl) ijcsr3
4132 ! ...
4133 IF(i <= 0.OR.j1 <= 0.OR.j2 > i) RETURN
4134
4135 IF(matsto == 3) THEN ! sparse symmetric matrix (CSR3, upper triangle)
4136 ja=globalallindexgroups(i) ! first (global) column
4137 jb=globalallindexgroups(i+1)-1 ! last (global) column
4138 ia1=globalallindexgroups(j1) ! first (global) row
4139 ! loop over groups (now in same column)
4140 DO jpg=j1,j2
4141 ia=globalallindexgroups(jpg) ! first (global) row in group
4142 ib=globalallindexgroups(jpg+1)-1 ! last (global) row in group
4143 IF (matbsz < 2) THEN
4144 ! CSR3
4145 ij=ijcsr3(ia,ja)
4146 IF (ij == 0) THEN
4147 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc, matsto
4148 stop
4149 END IF
4150 ioff=ij-ja ! offset
4151 DO ir=ia,ib
4152 jc1=max(ir,ja)
4153 k=il+jc1-ja
4154 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4155 DO jc=jc1,jb
4156 globalmatd(ioff+jc)=globalmatd(ioff+jc)-sub(ijl)
4157 ijl=ijl+k
4158 k=k+1
4159 END DO
4160 ioff=ioff+csr3rowoffsets(ir+1)-csr3rowoffsets(ir)-1
4161 END DO
4162 ELSE
4163 ! BSR3
4164 iblast=-1
4165 jblast=-1
4166 ioff=0
4167 DO ir=ia,ib
4168 iblock=(ir-1)/matbsz+1
4169 jc1=max(ir,ja)
4170 k=il+jc1-ja
4171 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4172 DO jc=jc1,jb
4173 jblock=(jc-1)/matbsz+1
4174 ! index of first element in (new) block
4175 IF (jblock /= jblast.OR.iblock /= iblast) THEN
4176 ioff=(ijcsr3(iblock,jblock)-1)*matbsz*matbsz+1
4177 iblast=iblock
4178 jblast=jblock
4179 END IF
4180 ! adjust index for position in block
4181 ij=ioff+mod(int(ir-1,mpi),matbsz)+mod(int(jc-1,mpi),matbsz)*matbsz
4182 globalmatd(ij)=globalmatd(ij)-sub(ijl)
4183 ijl=ijl+k
4184 k=k+1
4185 END DO
4186 END DO
4187 END IF
4188 END DO
4189 RETURN
4190 END IF
4191
4192 ! lower triangle
4193 ia=globalallindexgroups(i) ! first (global) row
4194 ib=globalallindexgroups(i+1)-1 ! last (global) row
4195 ja=globalallindexgroups(j1) ! first (global) column
4196 jb=globalallindexgroups(j2+1)-1 ! last (global) column
4197
4198 IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4199 CALL ijpgrp(i,j1,ij,lr,iprc) ! index of first element of group 'j1'
4200 IF (ij == 0) THEN
4201 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc,matsto
4202 stop
4203 END IF
4204 k=il
4205 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4206 DO ir=ia,ib
4207 nc=min(ir,jb)-ja ! number of columns -1
4208 IF (jb >= ir) THEN ! diagonal element
4209 globalmatd(ir)=globalmatd(ir)-sub(ijl+jl+nc)
4210 nc=nc-1
4211 END IF
4212 ! off-diagonal elements
4213 IF (iprc == 1) THEN
4214 globalmatd(ij:ij+nc)=globalmatd(ij:ij+nc)-sub(ijl+jl:ijl+jl+nc)
4215 ELSE
4216 globalmatf(ij:ij+nc)=globalmatf(ij:ij+nc)-real(sub(ijl+jl:ijl+jl+nc),mps)
4217 END IF
4218 ij=ij+lr
4219 ijl=ijl+k
4220 k=k+1
4221 END DO
4222 ELSE ! full or unpacked (block diagonal) symmetric matrix
4223 k=il
4224 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4225 DO ir=ia,ib
4226 ! global (ir,0) to local (row,col) in block
4227 ij=globalrowoffsets(ir)
4228 nc=min(ir,jb)-ja ! number of columns -1
4229 globalmatd(ij+ja:ij+ja+nc)=globalmatd(ij+ja:ij+ja+nc)-sub(ijl+jl:ijl+jl+nc)
4230 ijl=ijl+k
4231 k=k+1
4232 END DO
4233 END IF
4234
4235END SUBROUTINE mgupdt
4236
4237
4264
4265SUBROUTINE loopbf(nrej,numfil,naccf,chi2f,ndff)
4266 USE mpmod
4267
4268 IMPLICIT NONE
4269 REAL(mpd) :: cauchy
4270 REAL(mps) :: chichi
4271 REAL(mps) :: chlimt
4272 REAL(mps) :: chndf
4273 REAL(mpd) :: chuber
4274 REAL(mpd) :: down
4275 REAL(mpd) :: pull
4276 REAL(mpd) :: r1
4277 REAL(mpd) :: r2
4278 REAL(mps) :: rec
4279 REAL(mpd) :: rerr
4280 REAL(mpd) :: resid
4281 REAL(mps) :: resing
4282 REAL(mpd) :: resmax
4283 REAL(mpd) :: rmeas
4284 REAL(mpd) :: rmloc
4285 REAL(mpd) :: suwt
4286 REAL(mps) :: used
4287 REAL(mpd) :: wght
4288 REAL(mps) :: chindl
4289 INTEGER(mpi) :: i
4290 INTEGER(mpi) :: ia
4291 INTEGER(mpi) :: ib
4292 INTEGER(mpi) :: ibuf
4293 INTEGER(mpi) :: ichunk
4294 INTEGER(mpl) :: icmn
4295 INTEGER(mpl) :: icost
4296 INTEGER(mpi) :: id
4297 INTEGER(mpi) :: idiag
4298 INTEGER(mpi) :: ieq
4299 INTEGER(mpi) :: iext
4300 INTEGER(mpi) :: ij
4301 INTEGER(mpi) :: ije
4302 INTEGER(mpi) :: ijn
4303 INTEGER(mpi) :: ik
4304 INTEGER(mpi) :: ike
4305 INTEGER(mpi) :: il
4306 INTEGER(mpi) :: im
4307 INTEGER(mpi) :: imeas
4308 INTEGER(mpi) :: in
4309 INTEGER(mpi) :: inv
4310 INTEGER(mpi) :: ioffb
4311 INTEGER(mpi) :: ioffc
4312 INTEGER(mpi) :: ioffd
4313 INTEGER(mpi) :: ioffe
4314 INTEGER(mpi) :: ioffi
4315 INTEGER(mpi) :: ioffq
4316 INTEGER(mpi) :: iprc
4317 INTEGER(mpi) :: iprcnx
4318 INTEGER(mpi) :: iprdbg
4319 INTEGER(mpi) :: iproc
4320 INTEGER(mpi) :: irbin
4321 INTEGER(mpi) :: isize
4322 INTEGER(mpi) :: ist
4323 INTEGER(mpi) :: iter
4324 INTEGER(mpi) :: itgbi
4325 INTEGER(mpi) :: ivgbj
4326 INTEGER(mpi) :: ivgbk
4327 INTEGER(mpi) :: ivpgrp
4328 INTEGER(mpi) :: j
4329 INTEGER(mpi) :: j1
4330 INTEGER(mpi) :: ja
4331 INTEGER(mpi) :: jb
4332 INTEGER(mpi) :: jk
4333 INTEGER(mpi) :: jl
4334 INTEGER(mpi) :: jl1
4335 INTEGER(mpi) :: jn
4336 INTEGER(mpi) :: jnx
4337 INTEGER(mpi) :: joffd
4338 INTEGER(mpi) :: joffi
4339 INTEGER(mpi) :: jproc
4340 INTEGER(mpi) :: jrc
4341 INTEGER(mpi) :: jsp
4342 INTEGER(mpi) :: k
4343 INTEGER(mpi) :: kbdr
4344 INTEGER(mpi) :: kbdrx
4345 INTEGER(mpi) :: kbnd
4346 INTEGER(mpi) :: kfl
4347 INTEGER(mpi) :: kx
4348 INTEGER(mpi) :: lvpgrp
4349 INTEGER(mpi) :: mbdr
4350 INTEGER(mpi) :: mbnd
4351 INTEGER(mpi) :: mside
4352 INTEGER(mpi) :: nalc
4353 INTEGER(mpi) :: nalg
4354 INTEGER(mpi) :: nan
4355 INTEGER(mpi) :: nb
4356 INTEGER(mpi) :: ndf
4357 INTEGER(mpi) :: ndown
4358 INTEGER(mpi) :: neq
4359 INTEGER(mpi) :: nfred
4360 INTEGER(mpi) :: nfrei
4361 INTEGER(mpi) :: ngg
4362 INTEGER(mpi) :: nprdbg
4363 INTEGER(mpi) :: nrank
4364 INTEGER(mpl) :: nrc
4365 INTEGER(mpi) :: nst
4366 INTEGER(mpi) :: nter
4367 INTEGER(mpi) :: nweig
4368 INTEGER(mpi) :: ngrp
4369 INTEGER(mpi) :: npar
4370
4371 INTEGER(mpi), INTENT(IN OUT) :: nrej(0:3)
4372 INTEGER(mpi), INTENT(IN) :: numfil
4373 INTEGER(mpi), INTENT(IN OUT) :: naccf(numfil)
4374 REAL(mps), INTENT(IN OUT) :: chi2f(numfil)
4375 INTEGER(mpi), INTENT(IN OUT) :: ndff(numfil)
4376
4377 REAL(mpd):: dchi2
4378 REAL(mpd)::dvar
4379 REAL(mpd):: dw1
4380 REAL(mpd)::dw2
4381 REAL(mpd)::summ
4382 INTEGER(mpi) :: ijprec
4383
4384 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
4385
4386 LOGICAL:: lprnt
4387 LOGICAL::lhist
4388
4389 CHARACTER (LEN=3):: chast
4390 DATA chuber/1.345_mpd/ ! constant for Huber down-weighting
4391 DATA cauchy/2.3849_mpd/ ! constant for Cauchy down-weighting
4392 SAVE chuber,cauchy
4393 ! ...
4394
4395 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
4396 ! reset header, 3 words per thread:
4397 ! number of entries, offset to data, indices
4400 nprdbg=0
4401 iprdbg=-1
4402
4403 ! parallelize record loop
4404 ! private copy of NREJ,.. for each thread, combined at end, init with 0.
4405 !$OMP PARALLEL DO &
4406 !$OMP DEFAULT(PRIVATE) &
4407 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI, &
4408 !$OMP readBufferDataD,writeBufferHeader,writeBufferInfo, &
4409 !$OMP writeBufferData,writeBufferIndices,writeBufferUpdates,globalVector,globalCounter, &
4410 !$OMP globalParameter,globalParLabelIndex,globalIndexUsage,backIndexUsage, &
4411 !$OMP measBins,numMeas,measIndex,measRes,measHists,globalAllParToGroup,globalAllIndexGroups, &
4412 !$OMP localCorrections,localEquations,ifd, &
4413 !$OMP NAGB,NVGB,NAGBN,ICALCM,ICHUNK,NLOOPN,NRECER,NPRDBG,IPRDBG, &
4414 !$OMP NEWITE,CHICUT,LHUBER,CHUBER,ITERAT,NRECPR,MTHRD,NSPC,NAEQN, &
4415 !$OMP DWCUT,CHHUGE,NRECP2,CAUCHY,LFITNP,LFITBB,IMONIT,IMONMD,MONPG1,LUNLOG) &
4416 !$OMP REDUCTION(+:NREJ,NBNDR,NACCF,CHI2F,NDFF) &
4417 !$OMP REDUCTION(MAX:NBNDX,NBDRX) &
4418 !$OMP REDUCTION(MIN:NREC3) &
4419 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
4420 DO ibuf=1,numreadbuffer ! buffer for current record
4421 jrc=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
4422 kfl=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
4423 nrc=ifd(kfl)+jrc ! global record number
4424 dw1=real(readbufferdatad(readbufferpointer(ibuf)-1),mpd) ! weight
4425 dw2=sqrt(dw1)
4426
4427 iproc=0
4428 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
4429 ioffb=nagb*iproc ! offset 'f'.
4430 ioffc=nagbn*iproc ! offset 'c'.
4431 ioffe=nvgb*iproc ! offset 'e'
4432 ioffd=writebufferheader(-1)*iproc+writebufferinfo(2,iproc+1) ! offset data
4433 ioffi=writebufferheader(1)*iproc+writebufferinfo(3,iproc+1)+3 ! offset indices
4434 ioffq=naeqn*iproc ! offset equations (measurements)
4435 ! ----- reset ------------------------------------------------------
4436 lprnt=.false.
4437 lhist=(iproc == 0)
4438 rec=real(nrc,mps) ! floating point value
4439 IF(nloopn == 1.AND.mod(nrc,100000_mpl) == 0) THEN
4440 WRITE(*,*) 'Record',nrc,' ... still reading'
4441 IF(monpg1>0) WRITE(lunlog,*) 'Record',nrc,' ... still reading'
4442 END IF
4443
4444 ! printout/debug only for one thread at a time
4445
4446
4447 ! flag for record printout -----------------------------------------
4448
4449 lprnt=.false.
4450 IF(newite.AND.(iterat == 1.OR.iterat == 3)) THEN
4451 IF(nrc == nrecpr) lprnt=.true.
4452 IF(nrc == nrecp2) lprnt=.true.
4453 IF(nrc == nrecer) lprnt=.true.
4454 END IF
4455 IF (lprnt)THEN
4456 !$OMP ATOMIC
4457 nprdbg=nprdbg+1 ! number of threads with debug
4458 IF (nprdbg == 1) iprdbg=iproc ! first thread with debug
4459 IF (iproc /= iprdbg) lprnt=.false.
4460 ! print *, ' LPRNT ', NRC, NPRDBG, IPRDBG, IPROC, LPRNT
4461 END IF
4462 IF(lprnt) THEN
4463 WRITE(1,*) ' '
4464 WRITE(1,*) '------------------ Loop',nloopn, &
4465 ': Printout for record',nrc,iproc
4466 WRITE(1,*) ' '
4467 END IF
4468
4469 ! ----- print data -------------------------------------------------
4470
4471 IF(lprnt) THEN
4472 imeas=0 ! local derivatives
4473 ist=readbufferpointer(ibuf)+1
4475 DO ! loop over measurements
4476 CALL isjajb(nst,ist,ja,jb,jsp)
4477 IF(ja == 0) EXIT
4478 IF(imeas == 0) WRITE(1,1121)
4479 imeas=imeas+1
4480 WRITE(1,1122) imeas,readbufferdatad(ja),readbufferdatad(jb), &
4481 (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
4482 END DO
44831121 FORMAT(/'Measured value and local derivatives'/ &
4484 ' i measured std_dev index...derivative ...')
44851122 FORMAT(i3,2g12.4,3(i3,g12.4)/(27x,3(i3,g12.4)))
4486
4487 imeas=0 ! global derivatives
4488 ist=readbufferpointer(ibuf)+1
4490 DO ! loop over measurements
4491 CALL isjajb(nst,ist,ja,jb,jsp)
4492 IF(ja == 0) EXIT
4493 IF(imeas == 0) WRITE(1,1123)
4494 imeas=imeas+1
4495 IF (jb < ist) THEN
4496 IF(ist-jb > 2) THEN
4497 WRITE(1,1124) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4498 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4499 ELSE
4500 WRITE(1,1125) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4501 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4502 END IF
4503 END IF
4504 END DO
45051123 FORMAT(/'Global derivatives'/ &
4506 ' i label gindex vindex derivative ...')
45071124 FORMAT(i3,2(i9,i7,i7,g12.4)/(3x,2(i9,i7,i7,g12.4)))
45081125 FORMAT(i3,2(i9,i7,i7,g12.4))
4509 END IF
4510
4511 ! ----- first loop -------------------------------------------------
4512 ! ------ prepare local fit ------
4513 ! count local and global derivates
4514 ! subtract actual alignment parameters from the measured data
4515
4516 IF(lprnt) THEN
4517 WRITE(1,*) ' '
4518 WRITE(1,*) 'Data corrections using values of global parameters'
4519 WRITE(1,*) '=================================================='
4520 WRITE(1,101)
4521 END IF
4522 nalg=0 ! count number of global derivatives
4523 nalc=0 ! count number of local derivatives
4524 neq=0 ! count number of equations
4525
4526 ist=readbufferpointer(ibuf)+1
4528 DO ! loop over measurements
4529 CALL isjajb(nst,ist,ja,jb,jsp)
4530 IF(ja == 0) EXIT
4531 rmeas=real(readbufferdatad(ja),mpd) ! data
4532 neq=neq+1 ! count equation
4533 localequations(1,ioffq+neq)=ja
4534 localequations(2,ioffq+neq)=jb
4535 localequations(3,ioffq+neq)=ist
4536 ! subtract global ... from measured value
4537 DO j=1,ist-jb ! global parameter loop
4538 itgbi=readbufferdatai(jb+j) ! global parameter label
4539 rmeas=rmeas-real(readbufferdatad(jb+j),mpd)*globalparameter(itgbi) ! subtract !!! reversed
4540 IF (icalcm == 1) THEN
4541 ij=globalparlabelindex(2,itgbi) ! -> index of variable global parameter
4542 IF(ij > 0) THEN
4543 ijn=backindexusage(ioffe+ij) ! get index of index
4544 IF(ijn == 0) THEN ! not yet included
4545 nalg=nalg+1 ! count
4546 globalindexusage(ioffc+nalg)=ij ! store global index
4547 backindexusage(ioffe+ij)=nalg ! store back index
4548 END IF
4549 END IF
4550 END IF
4551 END DO
4552 IF(lprnt) THEN
4553 IF (jb < ist) WRITE(1,102) neq,readbufferdatad(ja),rmeas,readbufferdatad(jb)
4554 END IF
4555 readbufferdatad(ja)=real(rmeas,mpr8) ! global contribution subtracted
4556 DO j=1,jb-ja-1 ! local parameter loop
4557 ij=readbufferdatai(ja+j)
4558 nalc=max(nalc,ij) ! number of local parameters
4559 END DO
4560 END DO
4561101 FORMAT(' index measvalue corrvalue sigma')
4562102 FORMAT(i6,2x,2g12.4,' +-',g12.4)
4563
4564 IF(nalc <= 0) GO TO 90
4565
4566 ngg=(nalg*nalg+nalg)/2
4567 ngrp=0
4568 IF (icalcm == 1) THEN
4569 localglobalmatrix(:nalg*nalc)=0.0_mpd ! reset global-local matrix
4570 localglobalmap(:nalg*nalc)=0 ! reset global-local map
4571 ! store parameter group indices
4572 CALL sort1k(globalindexusage(ioffc+1),nalg) ! sort global par.
4573 lvpgrp=-1
4574 npar=0
4575 DO k=1,nalg
4576 iext=globalindexusage(ioffc+k)
4577 backindexusage(ioffe+iext)=k ! update back index
4578 ivpgrp=globalallpartogroup(iext) ! group
4579 IF (ivpgrp /= lvpgrp) THEN
4580 ngrp=ngrp+1
4581 writebufferindices(ioffi+ngrp)=ivpgrp ! global par group indices
4582 lvpgrp=ivpgrp
4583 npar=npar+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4584 END IF
4585 END DO
4586 ! check NPAR==NALG
4587 IF (npar /= nalg) THEN
4588 print *, ' mismatch of number of global parameters ', nrc, nalg, npar, ngrp
4589 print *, globalindexusage(ioffc+1:ioffc+nalg)
4590 print *, writebufferindices(ioffi+1:ioffi+ngrp)
4591 j=0
4592 DO k=1,ngrp
4593 ivpgrp=writebufferindices(ioffi+k)
4594 j=j+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4595 IF (globalallpartogroup(globalindexusage(ioffc+j)) /= ivpgrp) &
4596 print *, ' bad group ', k, j, ivpgrp, globalindexusage(ioffc+j)
4597 END DO
4598 CALL peend(35,'Aborted, mismatch of number of global parameters')
4599 stop ' mismatch of number of global parameters '
4600 ENDIF
4601 ! index header
4602 writebufferindices(ioffi-2)=jrc ! record number in file
4603 writebufferindices(ioffi-1)=nalg ! number of global parameters
4604 writebufferindices(ioffi )=ngrp ! number of global par groups
4605 DO k=1,ngg
4606 writebufferupdates(ioffd+k)=0.0_mpd ! reset global-global matrix
4607 END DO
4608 END IF
4609 ! ----- iteration start and check ---------------------------------
4610
4611 nter=1 ! first loop without down-weighting
4612 IF(nloopn /= 1.AND.lhuber /= 0) nter=lhuber
4613 localcorrections(ioffq+1:ioffq+neq) = 0._mpd
4614
4615 ! check matrix for bordered band structure (MBDR+MBND+1 <= NALC)
4616 mbnd=-1
4617 mbdr=nalc
4618 mside=-1 ! side (1: upper/left border, 2: lower/right border)
4619 DO i=1, 2*nalc
4620 ibandh(i)=0
4621 END DO
4622 idiag=1
4623
4624 iter=0
4625 resmax=0.0
4626 DO WHILE(iter < nter) ! outlier suppresssion iteration loop
4627 iter=iter+1
4628 resmax=0.0
4629 IF(lprnt) THEN
4630 WRITE(1,*) ' '
4631 WRITE(1,*) 'Outlier-suppression iteration',iter,' of',nter
4632 WRITE(1,*) '=========================================='
4633 WRITE(1,*) ' '
4634 imeas=0
4635 END IF
4636
4637 ! ----- second loop ------------------------------------------------
4638 ! accumulate normal equations for local fit and determine solution
4639 DO i=1,nalc
4640 blvec(i)=0.0_mpd ! reset vector
4641 END DO
4642 DO i=1,(nalc*nalc+nalc)/2 ! GF: FIXME - not really, local parameter number...
4643 clmat(i)=0.0_mpd ! (p)reset matrix
4644 END DO
4645 ndown=0
4646 nweig=0
4647 DO ieq=1,neq! loop over measurements
4648 ja=localequations(1,ioffq+ieq)
4649 jb=localequations(2,ioffq+ieq)
4650 rmeas=real(readbufferdatad(ja),mpd) ! data
4651 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4652 wght =1.0_mpd/rerr**2 ! weight from error
4653 nweig=nweig+1
4654 resid=rmeas-localcorrections(ioffq+ieq) ! subtract previous fit
4655 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4656 IF(iter <= 3) THEN
4657 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4658 wght=wght*chuber*rerr/abs(resid)
4659 ndown=ndown+1
4660 END IF
4661 ELSE ! Cauchy
4662 wght=wght/(1.0+(resid/rerr/cauchy)**2)
4663 END IF
4664 END IF
4665
4666 IF(lprnt.AND.iter /= 1.AND.nter /= 1) THEN
4667 chast=' '
4668 IF(abs(resid) > chuber*rerr) chast='* '
4669 IF(abs(resid) > 3.0*rerr) chast='** '
4670 IF(abs(resid) > 6.0*rerr) chast='***'
4671 IF(imeas == 0) WRITE(1,*) 'Second loop: accumulate'
4672 IF(imeas == 0) WRITE(1,103)
4673 imeas=imeas+1
4674 down=1.0/sqrt(wght)
4675 r1=resid/rerr
4676 r2=resid/down
4677 WRITE(1,104) imeas,rmeas,resid,rerr,r1,chast,r2
4678 END IF
4679103 FORMAT(' index corrvalue residuum sigma', &
4680 ' nresid cnresid')
4681104 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4682
4683 DO j=1,jb-ja-1 ! normal equations, local parameter loop
4684 ij=readbufferdatai(ja+j) ! local parameter index J
4685 blvec(ij)=blvec(ij)+wght*rmeas*real(readbufferdatad(ja+j),mpd)
4686 DO k=1,j
4687 ik=readbufferdatai(ja+k) ! local parameter index K
4688 jk=(ij*ij-ij)/2+ik ! index in symmetric matrix
4689 clmat(jk)=clmat(jk) & ! force double precision
4690 +wght*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)
4691 ! check for band matrix substructure
4692 IF (iter == 1) THEN
4693 id=iabs(ij-ik)+1
4694 im=min(ij,ik) ! upper/left border
4695 ibandh(id)=max(ibandh(id),im)
4696 im=min(nalc+1-ij,nalc+1-ik) ! lower/rght border (mirrored)
4697 ibandh(nalc+id)=max(ibandh(nalc+id),im)
4698 END IF
4699 END DO
4700 END DO
4701 END DO
4702 ! for non trivial fits check for bordered band matrix structure
4703 IF (iter == 1.AND.nalc > 5.AND.lfitbb > 0) THEN
4704 kx=-1
4705 kbdrx=0
4706 icmn=int(nalc,mpl)**3 ! cost (*6) should improve by at least factor 2
4707 ! upper/left border ?
4708 kbdr=0
4709 DO k=nalc,2,-1
4710 kbnd=k-2
4711 kbdr=max(kbdr,ibandh(k))
4712 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4713 IF (icost < icmn) THEN
4714 icmn=icost
4715 kx=k
4716 kbdrx=kbdr
4717 mside=1
4718 END IF
4719 END DO
4720 IF (kx < 0) THEN
4721 ! lower/right border instead?
4722 kbdr=0
4723 DO k=nalc,2,-1
4724 kbnd=k-2
4725 kbdr=max(kbdr,ibandh(k+nalc))
4726 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4727 IF (icost < icmn) THEN
4728 icmn=icost
4729 kx=k
4730 kbdrx=kbdr
4731 mside=2
4732 END IF
4733 END DO
4734 END IF
4735 IF (kx > 0) THEN
4736 mbnd=kx-2
4737 mbdr=kbdrx
4738 END IF
4739 END IF
4740
4741 IF (mbnd >= 0) THEN
4742 ! fast solution for border banded matrix (inverse for ICALCM>0)
4743 IF (nloopn == 1) THEN
4744 nbndr(mside)=nbndr(mside)+1
4745 nbdrx=max(nbdrx,mbdr)
4746 nbndx=max(nbndx,mbnd)
4747 END IF
4748
4749 inv=0
4750 IF (nloopn <= lfitnp.AND.iter == 1) inv=1 ! band part of inverse (for pulls)
4751 IF (icalcm == 1.OR.lprnt) inv=2 ! complete inverse
4752 IF (mside == 1) THEN
4753 CALL sqmibb(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4755 ELSE
4756 CALL sqmibb2(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4758 ENDIF
4759 ELSE
4760 ! full inversion and solution
4761 inv=2
4762 CALL sqminv(clmat,blvec,nalc,nrank,scdiag,scflag)
4763 END IF
4764 ! check for NaNs
4765 nan=0
4766 DO k=1, nalc
4767 IF ((.NOT.(blvec(k) <= 0.0_mpd)).AND. (.NOT.(blvec(k) > 0.0_mpd))) nan=nan+1
4768 END DO
4769
4770 IF(lprnt) THEN
4771 WRITE(1,*) ' '
4772 WRITE(1,*) 'Parameter determination:',nalc,' parameters,', ' rank=',nrank
4773 WRITE(1,*) '-----------------------'
4774 IF(ndown /= 0) WRITE(1,*) ' ',ndown,' data down-weighted'
4775 WRITE(1,*) ' '
4776 END IF
4777
4778 ! ----- third loop -------------------------------------------------
4779 ! calculate single residuals remaining after local fit and chi^2
4780
4781 summ=0.0_mpd
4782 suwt=0.0
4783 imeas=0
4784 DO ieq=1,neq! loop over measurements
4785 ja=localequations(1,ioffq+ieq)
4786 jb=localequations(2,ioffq+ieq)
4787 ist=localequations(3,ioffq+ieq)
4788 rmeas=real(readbufferdatad(ja),mpd) ! data (global contrib. subtracted)
4789 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4790 wght =1.0_mpd/rerr**2 ! weight from error
4791 rmloc=0.0 ! local fit result reset
4792 DO j=1,jb-ja-1 ! local parameter loop
4793 ij=readbufferdatai(ja+j)
4794 rmloc=rmloc+real(readbufferdatad(ja+j),mpd)*blvec(ij) ! local fit result
4795 END DO
4796 localcorrections(ioffq+ieq)=rmloc ! save local fit result
4797 rmeas=rmeas-rmloc ! reduced to residual
4798
4799 ! calculate pulls? (needs covariance matrix)
4800 IF(iter == 1.AND.inv > 0.AND.nloopn <= lfitnp) THEN
4801 dvar=0.0_mpd
4802 DO j=1,jb-ja-1
4803 ij=readbufferdatai(ja+j)
4804 jk=(ij*ij-ij)/2 ! index in symmetric matrix, row offset
4805 ! off diagonal (symmetric)
4806 DO k=1,j-1
4807 ik=readbufferdatai(ja+k)
4808 dvar=dvar+clmat(jk+ik)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)*2.0_mpd
4809 END DO
4810 ! diagonal
4811 dvar=dvar+clmat(jk+ij)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+j),mpd)
4812 END DO
4813 ! some variance left to define a pull?
4814 IF (0.999999_mpd/wght > dvar) THEN
4815 pull=rmeas/sqrt(1.0_mpd/wght-dvar)
4816 IF (lhist) THEN
4817 IF (jb < ist) THEN
4818 CALL hmpent(13,real(pull,mps)) ! histogram pull
4819 CALL gmpms(5,rec,real(pull,mps))
4820 ELSE
4821 CALL hmpent(14,real(pull,mps)) ! histogram pull
4822 END IF
4823 END IF
4824 ! monitoring
4825 IF (imonit /= 0) THEN
4826 IF (jb < ist) THEN
4827 ij=readbufferdatai(jb+1) ! group by first global label
4828 if (imonmd == 0) THEN
4829 irbin=min(measbins,max(1,int(pull*rerr/measres(ij)/measbinsize+0.5*real(measbins,mpd))))
4830 ELSE
4831 irbin=min(measbins,max(1,int(pull/measbinsize+0.5*real(measbins,mpd))))
4832 ENDIF
4833 irbin=irbin+measbins*(measindex(ij)-1+nummeas*iproc)
4834 meashists(irbin)=meashists(irbin)+1
4835 ENDIF
4836 ENDIF
4837 END IF
4838 END IF
4839
4840 IF(iter == 1.AND.jb < ist.AND.lhist) &
4841 CALL gmpms(4,rec,real(rmeas/rerr,mps)) ! residual (with global deriv.)
4842
4843 dchi2=wght*rmeas*rmeas
4844 ! DCHIT=DCHI2
4845 resid=rmeas
4846 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4847 IF(iter <= 3) THEN
4848 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4849 wght=wght*chuber*rerr/abs(resid)
4850 dchi2=2.0*chuber*(abs(resid)/rerr-0.5*chuber)
4851 END IF
4852 ELSE
4853 wght=wght/(1.0_mpd+(resid/rerr/cauchy)**2)
4854 dchi2=log(1.0_mpd+(resid/rerr/cauchy)**2)*cauchy**2
4855 END IF
4856 END IF
4857
4858 down=1.0/sqrt(wght)
4859
4860 ! SUWT=SUWT+DCHI2/DCHIT
4861 suwt=suwt+rerr/down
4862 IF(lprnt) THEN
4863 chast=' '
4864 IF(abs(resid) > chuber*rerr) chast='* '
4865 IF(abs(resid) > 3.0*rerr) chast='** '
4866 IF(abs(resid) > 6.0*rerr) chast='***'
4867 IF(imeas == 0) WRITE(1,*) 'Third loop: single residuals'
4868 IF(imeas == 0) WRITE(1,105)
4869 imeas=imeas+1
4870 r1=resid/rerr
4871 r2=resid/down
4872 IF(resid < 0.0) r1=-r1
4873 IF(resid < 0.0) r2=-r2
4874 WRITE(1,106) imeas,readbufferdatad(ja),rmeas,rerr,r1,chast,r2
4875 END IF
4876105 FORMAT(' index corrvalue residuum sigma', &
4877 ' nresid cnresid')
4878106 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4879
4880 IF(iter == nter) THEN
4881 readbufferdatad(ja)=real(rmeas,mpr8) ! store remaining residual
4882 resmax=max(resmax,abs(rmeas)/rerr)
4883 END IF
4884
4885 IF(iter == 1.AND.lhist) THEN
4886 IF (jb < ist) THEN
4887 CALL hmpent( 3,real(rmeas/rerr,mps)) ! histogram norm residual
4888 ELSE
4889 CALL hmpent(12,real(rmeas/rerr,mps)) ! histogram norm residual
4890 END IF
4891 END IF
4892 summ=summ+dchi2 ! accumulate chi-square sum
4893 END DO
4894
4895 ndf=neq-nrank
4896 resing=(real(nweig,mps)-real(suwt,mps))/real(nweig,mps)
4897 IF (lhist) THEN
4898 IF(iter == 1) CALL hmpent( 5,real(ndf,mps)) ! histogram Ndf
4899 IF(iter == 1) CALL hmpent(11,real(nalc,mps)) ! histogram Nlocal
4900 IF(nloopn == 2.AND.iter == nter) CALL hmpent(6,resing)
4901 END IF
4902 IF(lprnt) THEN
4903 WRITE(1,*) ' '
4904 WRITE(1,*) 'Chi^2=',summ,' at',ndf,' degrees of freedom: ', &
4905 '3-sigma limit is',chindl(3,ndf)*real(ndf,mps)
4906 WRITE(1,*) suwt,' is sum of factors, compared to',nweig, &
4907 ' Downweight fraction:',resing
4908 END IF
4909 IF(nrank /= nalc.OR.nan > 0) THEN
4910 nrej(0)=nrej(0)+1 ! count cases
4911 IF (nrec3 == huge(nrec3)) nrec3=nrc
4912 IF(lprnt) THEN
4913 WRITE(1,*) ' rank deficit/NaN ', nalc, nrank, nan
4914 WRITE(1,*) ' ---> rejected!'
4915 END IF
4916 GO TO 90
4917 END IF
4918 IF(ndf <= 0) THEN
4919 nrej(1)=nrej(1)+1 ! count cases
4920 IF(lprnt) THEN
4921 WRITE(1,*) ' ---> rejected!'
4922 END IF
4923 GO TO 90
4924 END IF
4925
4926 chndf=real(summ/real(ndf,mpd),mps)
4927
4928 IF(iter == 1.AND.lhist) CALL hmpent(4,chndf) ! histogram chi^2/Ndf
4929 END DO ! outlier iteration loop
4930
4931 ! ----- reject eventually ------------------------------------------
4932
4933 IF(newite.AND.iterat == 2) THEN ! find record with largest Chi^2/Ndf
4934 IF(nrecp2 < 0.AND.chndf > writebufferdata(2,iproc+1)) THEN
4935 writebufferdata(2,iproc+1)=chndf
4936 writebufferinfo(8,iproc+1)=jrc
4937 writebufferinfo(9,iproc+1)=kfl
4938 END IF
4939 END IF
4940
4941 chichi=chindl(3,ndf)*real(ndf,mps)
4942 ! GF IF(SUMM.GT.50.0*CHICHI) THEN ! huge
4943 ! CHK CHICUT<0: NO cut (1st iteration)
4944 IF(chicut >= 0.0) THEN
4945 IF(summ > chhuge*chichi) THEN ! huge
4946 nrej(2)=nrej(2)+1 ! count cases with huge chi^2
4947 IF(lprnt) THEN
4948 WRITE(1,*) ' ---> rejected!'
4949 END IF
4950 GO TO 90
4951 END IF
4952
4953 IF(chicut > 0.0) THEN
4954 chlimt=chicut*chichi
4955 ! WRITE(*,*) 'chi^2 ',SUMM,CHLIMT,CHICUT,CHINDL(3,NDF),NDF
4956 IF(summ > chlimt) THEN
4957 IF(lprnt) THEN
4958 WRITE(1,*) ' ---> rejected!'
4959 END IF
4960 ! add to FVALUE
4961 dchi2=chlimt ! total contribution limit
4962 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
4963 nrej(3)=nrej(3)+1 ! count cases with large chi^2
4964 GO TO 90
4965 END IF
4966 END IF
4967 END IF
4968
4969 IF(lhuber > 1.AND.dwcut /= 0.0.AND.resing > dwcut) THEN
4970 ! add to FVALUE
4971 dchi2=summ ! total contribution
4972 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
4973 nrej(3)=nrej(3)+1 ! count cases with large chi^2
4974 ! WRITE(*,*) 'Downweight fraction cut ',RESING,DWCUT,SUMM
4975 IF(lprnt) THEN
4976 WRITE(1,*) ' ---> rejected!'
4977 END IF
4978 GO TO 90
4979 END IF
4980
4981 IF(newite.AND.iterat == 2) THEN ! find record with largest residual
4982 IF(nrecpr < 0.AND.resmax > writebufferdata(1,iproc+1)) THEN
4983 writebufferdata(1,iproc+1)=real(resmax,mps)
4984 writebufferinfo(6,iproc+1)=jrc
4985 writebufferinfo(7,iproc+1)=kfl
4986 END IF
4987 END IF
4988 ! 'track quality' per binary file: accepted records
4989 naccf(kfl)=naccf(kfl)+1
4990 ndff(kfl) =ndff(kfl) +ndf
4991 chi2f(kfl)=chi2f(kfl)+chndf
4992
4993 ! ----- fourth loop ------------------------------------------------
4994 ! update of global matrix and vector according to the "Millepede"
4995 ! principle, from the global/local information
4996
4997 summ=0.0_mpd
4998 DO ieq=1,neq! loop over measurements
4999 ja=localequations(1,ioffq+ieq)
5000 jb=localequations(2,ioffq+ieq)
5001 ist=localequations(3,ioffq+ieq)
5002 rmeas=real(readbufferdatad(ja),mpd) ! data residual
5003 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
5004 wght =1.0_mpd/rerr**2 ! weight from measurement error
5005 dchi2=wght*rmeas*rmeas ! least-square contribution
5006
5007 IF(nloopn /= 1.AND.lhuber /= 0) THEN ! check residual
5008 resid=abs(rmeas)
5009 IF(resid > chuber*rerr) THEN
5010 wght=wght*chuber*rerr/resid ! down-weighting
5011 dchi2=2.0*chuber*(resid/rerr-0.5*chuber) ! modified contribution
5012 END IF
5013 END IF
5014 ! sum up
5015 summ=summ+dchi2
5016
5017 ! global-global matrix contribution: add directly to gg-matrix
5018
5019 DO j=1,ist-jb
5020 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5021 IF(ivgbj > 0) THEN
5022 globalvector(ioffb+ivgbj)=globalvector(ioffb+ivgbj) &
5023 +dw1*wght*rmeas*real(readbufferdatad(jb+j),mpd) ! vector !!! reverse
5024 globalcounter(ioffb+ivgbj)=globalcounter(ioffb+ivgbj)+1
5025 IF(icalcm == 1) THEN
5026 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5027 DO k=1,j
5029 IF(ivgbk > 0) THEN
5030 ike=backindexusage(ioffe+ivgbk) ! get index of index, non-zero
5031 ia=max(ije,ike) ! larger
5032 ib=min(ije,ike) ! smaller
5033 ij=ib+(ia*ia-ia)/2
5034 writebufferupdates(ioffd+ij)=writebufferupdates(ioffd+ij) &
5035 -dw1*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(jb+k),mpd)
5036 END IF
5037 END DO
5038 END IF
5039 END IF
5040 END DO
5041
5042 ! normal equations - rectangular matrix for global/local pars
5043 ! global-local matrix contribution: accumulate rectangular matrix
5044 IF (icalcm /= 1) cycle
5045 DO j=1,ist-jb
5046 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5047 IF(ivgbj > 0) THEN
5048 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5049 DO k=1,jb-ja-1
5050 ik=readbufferdatai(ja+k) ! local index
5051 jk=ik+(ije-1)*nalc ! matrix index
5053 dw2*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(ja+k),mpd)
5055 END DO
5056 END IF
5057 END DO
5058 END DO
5059 ! add to total objective function
5060 CALL addsums(iproc+1, summ, ndf, dw1)
5061
5062 ! ----- final matrix update ----------------------------------------
5063 ! update global matrices and vectors
5064 IF(icalcm /= 1) GO TO 90 ! matrix update
5065 ! (inverse local matrix) * (rectang. matrix) -> CORM
5066 ! T
5067 ! resulting symmetrix matrix = G * Gamma^{-1} * G
5068
5069 ! check sparsity of localGlobalMatrix (with par. groups)
5070 isize=nalc+nalg+1 ! row/clolumn offsets
5071 ! check rows
5072 k=0 ! offset
5073 DO i=1, nalg
5074 localglobalstructure(i)=isize
5075 DO j=1, nalc
5076 IF (localglobalmap(k+j) > 0) THEN
5077 localglobalstructure(isize+1)=j ! column
5078 localglobalstructure(isize+2)=k+j ! index
5079 isize=isize+2
5080 ENDIF
5081 END DO
5082 k=k+nalc
5083 END DO
5084 ! <50% non-zero elements?
5085 IF (isize-localglobalstructure(1) < nalc*nalg) THEN
5086 ! check columns (too)
5087 DO j=1, nalc
5088 localglobalstructure(nalg+j)=isize
5089 k=0 ! offset
5090 DO i=1, nalg
5091 IF (localglobalmap(k+j) > 0) THEN
5092 localglobalstructure(isize+1)=i ! row
5093 localglobalstructure(isize+2)=k+j ! index
5094 isize=isize+2
5095 ENDIF
5096 k=k+nalc
5097 END DO
5098 END DO
5099 localglobalstructure(nalg+nalc+1)=isize
5101 ELSE
5102 CALL dbavat(clmat,localglobalmatrix,writebufferupdates(ioffd+1),nalc,nalg,1)
5103 END IF
5104 ! (rectang. matrix) * (local param vector) -> CORV
5105 ! resulting vector = G * q (q = local parameter)
5106 ! CALL DBGAX(DQ(IGLMA/2+1),BLVEC,DQ(ICORV/2+1),NALG,NALC) ! not done
5107 ! the vector update is not done, because after local fit it is zero!
5108
5109 ! update cache status
5110 writebufferinfo(1,iproc+1)=writebufferinfo(1,iproc+1)+1
5111 writebufferinfo(2,iproc+1)=writebufferinfo(2,iproc+1)+ngg
5112 writebufferinfo(3,iproc+1)=writebufferinfo(3,iproc+1)+ngrp+3
5113 ! check free space
5114 nfred=writebufferheader(-1)-writebufferinfo(2,iproc+1)-writebufferheader(-2)
5116 IF (nfred < 0.OR.nfrei < 0) THEN ! need to flush
5117 nb=writebufferinfo(1,iproc+1)
5118 joffd=writebufferheader(-1)*iproc ! offset data
5119 joffi=writebufferheader(1)*iproc+3 ! offset indices
5120 used=real(writebufferinfo(2,iproc+1),mps)/real(writebufferheader(-1),mps)
5121 writebufferinfo(4,iproc+1)=writebufferinfo(4,iproc+1) +nint(1000.0*used,mpi)
5122 used=real(writebufferinfo(3,iproc+1),mps)/real(writebufferheader(1),mps)
5123 writebufferinfo(5,iproc+1)=writebufferinfo(5,iproc+1) +nint(1000.0*used,mpi)
5124 !$OMP CRITICAL
5127
5128 DO ib=1,nb
5129 nalg=writebufferindices(joffi-1)
5130 il=1 ! row in update matrix
5131 DO in=1,writebufferindices(joffi)
5132 i=writebufferindices(joffi+in)
5133 j=writebufferindices(joffi+1) ! 1. group
5134 iprc=ijprec(i,j) ! group pair precision
5135 jl=1 ! col in update matrix
5136 ! start (rows) for continous groups
5137 j1=j
5138 jl1=jl
5139 ! other groups for row
5140 DO jn=2,in
5142 jnx=writebufferindices(joffi+jn) ! next group
5143 iprcnx=ijprec(i,jnx) ! group pair precision
5144 ! end of continous groups?
5145 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5146 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5147 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5148 ! restart continous groups
5149 j1=jnx ! new 1. column
5150 jl1=jl
5151 iprc=iprcnx
5152 END IF
5153 j=jnx ! last group
5154 END DO
5155 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5156 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5158 END DO
5159 joffd=joffd+(il*il-il)/2
5160 joffi=joffi+writebufferindices(joffi)+3
5161 END DO
5162 !$OMP END CRITICAL
5163 ! reset counter, pointers
5164 DO k=1,3
5165 writebufferinfo(k,iproc+1)=0
5166 END DO
5167 END IF
5168
516990 IF(lprnt) THEN
5170 WRITE(1,*) ' '
5171 WRITE(1,*) '------------------ End of printout for record',nrc
5172 WRITE(1,*) ' '
5173 END IF
5174
5175 DO i=1,nalg ! reset global index array
5176 iext=globalindexusage(ioffc+i)
5177 backindexusage(ioffe+iext)=0
5178 END DO
5179
5180 END DO
5181 !$OMP END PARALLEL DO
5182
5183 IF (icalcm == 1) THEN
5184 ! flush remaining matrices
5185 DO k=1,mthrd ! update statistics
5187 used=real(writebufferinfo(2,k),mps)/real(writebufferheader(-1),mps)
5188 writebufferinfo(4,k)=writebufferinfo(4,k)+nint(1000.0*used,mpi)
5191 writebufferinfo(4,k)=0
5193 used=real(writebufferinfo(3,k),mps)/real(writebufferheader(1),mps)
5194 writebufferinfo(5,k)=writebufferinfo(5,k)+nint(1000.0*used,mpi)
5197 writebufferinfo(5,k)=0
5198 END DO
5199
5200 !$OMP PARALLEL &
5201 !$OMP DEFAULT(PRIVATE) &
5202 !$OMP SHARED(writeBufferHeader,writeBufferInfo,writeBufferIndices,writeBufferUpdates,MTHRD) &
5203 !$OMP SHARED(globalAllParToGroup,globalAllIndexGroups,nspc)
5204 iproc=0
5205 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5206 DO jproc=0,mthrd-1
5207 nb=writebufferinfo(1,jproc+1)
5208 ! print *, ' flush end ', JPROC, NRC, NB
5209 joffd=writebufferheader(-1)*jproc ! offset data
5210 joffi=writebufferheader(1)*jproc+3 ! offset indices
5211 DO ib=1,nb
5212 ! print *, ' buf end ', JPROC,IB,writeBufferIndices(JOFFI-2),writeBufferIndices(JOFFI)
5213 nalg=writebufferindices(joffi-1)
5214 il=1 ! row in update matrix
5215 DO in=1,writebufferindices(joffi)
5216 i=writebufferindices(joffi+in)
5217 !$ IF (MOD(I,MTHRD).EQ.IPROC) THEN
5218 j=writebufferindices(joffi+1) ! 1. group
5219 iprc=ijprec(i,j) ! group pair precision
5220 jl=1 ! col in update matrix
5221 ! start (rows) for continous groups
5222 j1=j
5223 jl1=jl
5224 ! other groups for row
5225 DO jn=2,in
5227 jnx=writebufferindices(joffi+jn) ! next group
5228 iprcnx=ijprec(i,jnx) ! group pair precision
5229 ! end of continous groups?
5230 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5231 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5232 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5233 ! restart continous groups
5234 j1=jnx ! new 1. column
5235 jl1=jl
5236 iprc=iprcnx
5237 END IF
5238 j=jnx ! last group
5239 END DO
5240 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5241 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5242 !$ END IF
5244 END DO
5245 joffd=joffd+(il*il-il)/2
5246 joffi=joffi+writebufferindices(joffi)+3
5247 END DO
5248 END DO
5249 !$OMP END PARALLEL
5250 END IF
5251
5252 IF(newite.AND.iterat == 2) THEN ! get worst records (for printrecord -1 -1)
5253 IF (nrecpr < 0) THEN
5254 DO k=1,mthrd
5255 IF (writebufferdata(1,k) > value1) THEN
5258 END IF
5259 END DO
5260 END IF
5261 IF (nrecp2 < 0) THEN
5262 DO k=1,mthrd
5263 IF (writebufferdata(2,k) > value2) THEN
5266 END IF
5267 END DO
5268 END IF
5269 END IF
5270
5271END SUBROUTINE loopbf
5272
5273
5274
5275
5276!***********************************************************************
5277
5290SUBROUTINE prtglo
5291 USE mpmod
5292
5293 IMPLICIT NONE
5294 REAL(mps):: dpa
5295 REAL(mps):: err
5296 REAL(mps):: gcor
5297 INTEGER(mpi) :: i
5298 INTEGER(mpi) :: icom
5299 INTEGER(mpl) :: icount
5300 INTEGER(mpi) :: ie
5301 INTEGER(mpi) :: iev
5302 INTEGER(mpi) :: ij
5303 INTEGER(mpi) :: imin
5304 INTEGER(mpi) :: iprlim
5305 INTEGER(mpi) :: isub
5306 INTEGER(mpi) :: itgbi
5307 INTEGER(mpi) :: itgbl
5308 INTEGER(mpi) :: ivgbi
5309 INTEGER(mpi) :: j
5310 INTEGER(mpi) :: label
5311 INTEGER(mpi) :: lup
5312 REAL(mps):: par
5313 LOGICAL :: lowstat
5314
5315 REAL(mpd):: diag
5316 REAL(mpd)::gmati
5317 REAL(mpd)::gcor2
5318 INTEGER(mpi) :: labele(3)
5319 REAL(mps):: compnt(3)
5320 SAVE
5321 ! ...
5322
5323 lup=09
5324 CALL mvopen(lup,'millepede.res')
5325
5326 WRITE(*,*) ' '
5327 WRITE(*,*) ' Result of fit for global parameters'
5328 WRITE(*,*) ' ==================================='
5329 WRITE(*,*) ' '
5330
5331 WRITE(*,101)
5332
5333 WRITE(lup,*) 'Parameter ! first 3 elements per line are', &
5334 ' significant (if used as input)'
5335
5336
5337 iprlim=10
5338 DO itgbi=1,ntgb ! all parameter variables
5339 itgbl=globalparlabelindex(1,itgbi)
5340 ivgbi=globalparlabelindex(2,itgbi)
5341 icom=globalparcomments(itgbi) ! comment
5342 IF (icom > 0) WRITE(lup,113) listcomments(icom)%text
5343 par=real(globalparameter(itgbi),mps) ! initial value
5344 icount=0 ! counts
5345 lowstat = .false.
5346 IF(ivgbi > 0) THEN
5347 icount=globalcounter(ivgbi) ! used in last iteration
5348 lowstat = (icount < mreqena) ! too few accepted entries
5349 dpa=real(globalparameter(itgbi)-globalparstart(itgbi),mps) ! difference
5350 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5351 gmati=globalmatd(globalrowoffsets(ivgbi)+ivgbi)
5352 err=sqrt(abs(real(gmati,mps)))
5353 IF(gmati < 0.0_mpd) err=-err
5354 diag=workspacediag(ivgbi)
5355 gcor=-1.0
5356 IF(gmati*diag > 0.0_mpd) THEN ! global correlation
5357 gcor2=1.0_mpd-1.0_mpd/(gmati*diag)
5358 IF(gcor2 >= 0.0_mpd.AND.gcor2 <= 1.0_mpd) gcor=real(sqrt(gcor2),mps)
5359 END IF
5360 END IF
5361 END IF
5362 IF(ipcntr > 1) icount=globalparlabelcounter(itgbi) ! from binary files
5363 IF(lowstat) icount=-(icount+1) ! flag 'lowstat' with icount < 0
5364 IF(itgbi <= iprlim) THEN
5365 IF(ivgbi <= 0) THEN
5366 WRITE(* ,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5367 ELSE
5368 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5369 IF (igcorr == 0) THEN
5370 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5371 ELSE
5372 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5373 END IF
5374 ELSE
5375 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5376 END IF
5377 END IF
5378 ELSE IF(itgbi == iprlim+1) THEN
5379 WRITE(* ,*) '... (further printout suppressed, but see log file)'
5380 END IF
5381
5382 ! file output
5383 IF(ivgbi <= 0) THEN
5384 IF (ipcntr /= 0) THEN
5385 WRITE(lup,110) itgbl,par,real(globalparpresigma(itgbi),mps),icount
5386 ELSE
5387 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5388 END IF
5389 ELSE
5390 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5391 IF (ipcntr /= 0) THEN
5392 WRITE(lup,112) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,icount
5393 ELSE IF (igcorr /= 0) THEN
5394 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5395 ELSE
5396 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5397 END IF
5398 ELSE
5399 IF (ipcntr /= 0) THEN
5400 WRITE(lup,111) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,icount
5401 ELSE
5402 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5403 END IF
5404 END IF
5405 END IF
5406 END DO
5407 rewind lup
5408 CLOSE(unit=lup)
5409
5410 IF(metsol == 2) THEN ! diagonalisation: write eigenvectors
5411 CALL mvopen(lup,'millepede.eve')
5412 imin=1
5413 DO i=nagb,1,-1
5414 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
5415 imin=i ! index of smallest pos. eigenvalue
5416 EXIT
5417 ENDIF
5418 END DO
5419 iev=0
5420
5421 DO isub=0,min(15,imin-1)
5422 IF(isub < 10) THEN
5423 i=imin-isub
5424 ELSE
5425 i=isub-9
5426 END IF
5427
5428 ! DO I=IMIN,MAX(1,IMIN-9),-1 ! backward loop, up to 10 vectors
5429 WRITE(*,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5430 WRITE(lup,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5431 DO j=1,nagb
5432 ij=j+(i-1)*nagb ! index with eigenvector array
5433 IF(j <= nvgb) THEN
5434 itgbi=globalparvartototal(j)
5435 label=globalparlabelindex(1,itgbi)
5436 ELSE
5437 label=nvgb-j ! label negative for constraints
5438 END IF
5439 iev=iev+1
5440 labele(iev)=label
5441 compnt(iev)=real(workspaceeigenvectors(ij),mps) ! component
5442 IF(iev == 3) THEN
5443 WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5444 iev=0
5445 END IF
5446 END DO
5447 IF(iev /= 0) WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5448 iev=0
5449 WRITE(lup,*) ' '
5450 END DO
5451
5452 END IF
5453
5454101 FORMAT(1x,' label parameter presigma differ', &
5455 ' error'/ 1x,'-----------',4x,4('-------------'))
5456102 FORMAT(i10,2x,4g14.5,f8.3)
5457103 FORMAT(3(i11,f11.7,2x))
5458110 FORMAT(i10,2x,2g14.5,28x,i12)
5459111 FORMAT(i10,2x,3g14.5,14x,i12)
5460112 FORMAT(i10,2x,4g14.5,i12)
5461113 FORMAT('!',a)
5462END SUBROUTINE prtglo ! print final log file
5463
5464!***********************************************************************
5465
5475SUBROUTINE prtstat
5476 USE mpmod
5477 USE mpdalc
5478
5479 IMPLICIT NONE
5480 REAL(mps):: par
5481 REAL(mps):: presig
5482 INTEGER(mpi) :: icom
5483 INTEGER(mpl) :: icount
5484 INTEGER(mpi) :: ifrst
5485 INTEGER(mpi) :: ilast
5486 INTEGER(mpi) :: inext
5487 INTEGER(mpi) :: itgbi
5488 INTEGER(mpi) :: itgbl
5489 INTEGER(mpi) :: itpgrp
5490 INTEGER(mpi) :: ivgbi
5491 INTEGER(mpi) :: lup
5492 INTEGER(mpi) :: icgrp
5493 INTEGER(mpi) :: ipgrp
5494 INTEGER(mpi) :: j
5495 INTEGER(mpi) :: jpgrp
5496 INTEGER(mpi) :: k
5497 INTEGER(mpi) :: label1
5498 INTEGER(mpi) :: label2
5499 INTEGER(mpi) :: ncon
5500 INTEGER(mpi) :: npair
5501 INTEGER(mpi) :: nstep
5502 CHARACTER :: c1
5503
5504 INTEGER(mpl):: length
5505
5506 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
5507
5508 INTERFACE ! needed for assumed-shape dummy arguments
5509 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
5510 USE mpdef
5511 INTEGER(mpi), INTENT(IN) :: ipgrp
5512 INTEGER(mpi), INTENT(OUT) :: npair
5513 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
5514 END SUBROUTINE ggbmap
5515 END INTERFACE
5516
5517 SAVE
5518 ! ...
5519
5520 lup=09
5521 CALL mvopen(lup,'millepede.res')
5522 WRITE(lup,*) '*** Results of checking input only, no solution performed ***'
5523 WRITE(lup,*) '! === global parameters ==='
5524 WRITE(lup,*) '! fixed-1: by pre-sigma, -2: by entries cut, -3: by iterated entries cut'
5525 WRITE(lup,*) '! Label Value Pre-sigma Entries Cons. group Status '
5526 !iprlim=10
5527 DO itgbi=1,ntgb ! all parameter variables
5528 itgbl=globalparlabelindex(1,itgbi)
5529 ivgbi=globalparlabelindex(2,itgbi)
5530 icom=globalparcomments(itgbi) ! comment
5531 IF (icom > 0) WRITE(lup,117) listcomments(icom)%text
5532 c1=' '
5533 IF (globalparlabelindex(3,itgbi) == itgbl) c1='>'
5534 par=real(globalparameter(itgbi),mps) ! initial value
5535 presig=real(globalparpresigma(itgbi),mps) ! initial presigma
5536 icount=globalparlabelcounter(itgbi) ! from binary files
5537 icgrp=globalparcons(itgbi) ! constraints group
5538
5539 IF (ivgbi <= 0) THEN
5540 ! not used
5541 IF (ivgbi == -4) THEN
5542 WRITE(lup,116) c1,itgbl,par,presig,icount,icgrp
5543 ELSE
5544 WRITE(lup,110) c1,itgbl,par,presig,icount,icgrp,ivgbi
5545 END IF
5546 ELSE
5547 ! variable
5548 WRITE(lup,111) c1,itgbl,par,presig,icount,icgrp
5549 END IF
5550 END DO
5551 ! appearance statistics
5552 IF (icheck > 1) THEN
5553 WRITE(lup,*) '!.'
5554 WRITE(lup,*) '!.Appearance statistics '
5555 WRITE(lup,*) '!. Label First file and record Last file and record #files #paired-par'
5556 DO itgbi=1,ntgb
5557 itpgrp=globalparlabelindex(4,itgbi)
5558 IF (itpgrp > 0) THEN
5559 WRITE(lup,112) globalparlabelindex(1,itgbi), (appearancecounter(itgbi*5+k), k=-4,0), paircounter(itpgrp)
5560 ELSE ! 'empty' parameter
5561 WRITE(lup,112) globalparlabelindex(1,itgbi)
5562 END IF
5563 END DO
5564 END IF
5565 IF (ncgrp > 0) THEN
5566 WRITE(lup,*) '* === constraint groups ==='
5567 IF (icheck == 1) THEN
5568 WRITE(lup,*) '* Group #Cons. Entries First label Last label'
5569 ELSE
5570 WRITE(lup,*) '* Group #Cons. Entries First label Last label Paired label range'
5571 length=ntpgrp+ncgrp
5572 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
5573 END IF
5574 DO icgrp=1, ncgrp
5575 IF (matconsgroups(2,icgrp) <= matconsgroups(3,icgrp)) THEN
5576 label1=globalparlabelindex(1,globalparvartototal(matconsgroups(2,icgrp))) ! first label
5577 label2=globalparlabelindex(1,globalparvartototal(matconsgroups(3,icgrp))) ! last label
5578 ELSE ! empty group/cons.
5579 label1=0
5580 label2=0
5581 END IF
5582 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
5583 WRITE(lup,113) icgrp, ncon,vecconsgroupcounts(icgrp),label1,label2
5584 IF (icheck > 1 .AND. label1 > 0) THEN
5585 ipgrp=globalparlabelindex(4,globalparvartototal(matconsgroups(2,icgrp))) ! first par. group
5586 ! get paired parameter groups
5587 CALL ggbmap(ntpgrp+icgrp,npair,vecpairedpargroups)
5588 vecpairedpargroups(npair+1)=0
5589 ifrst=0
5590 nstep=1
5591 DO j=1, npair
5592 jpgrp=vecpairedpargroups(j)
5593 inext=globaltotindexgroups(1,jpgrp)
5594 DO k=1,globaltotindexgroups(2,jpgrp)
5595 ! end of continous region ?
5596 IF (ifrst /= 0.AND.inext /= (ilast+nstep)) THEN
5597 label1=globalparlabelindex(1,ifrst)
5598 label2=globalparlabelindex(1,ilast)
5599 WRITE(lup,114) label1, label2
5600 ifrst=0
5601 END IF
5602 ! skip 'self-correlations'
5603 IF (globalparcons(inext) /= icgrp) THEN
5604 IF (ifrst == 0) ifrst=inext
5605 ilast=inext
5606 END IF
5607 inext=inext+1
5608 nstep=1
5609 END DO
5610 ! skip 'empty' parameter
5611 IF (jpgrp == vecpairedpargroups(j+1)-1) THEN
5612 nstep=globaltotindexgroups(1,vecpairedpargroups(j+1)) &
5613 -(globaltotindexgroups(1,jpgrp)+globaltotindexgroups(2,jpgrp)-1)
5614 END IF
5615 END DO
5616 IF (ifrst /= 0) THEN
5617 label1=globalparlabelindex(1,ifrst)
5618 label2=globalparlabelindex(1,ilast)
5619 WRITE(lup,114) label1, label2
5620 END IF
5621 END IF
5622 END DO
5623 IF (icheck > 1) THEN
5624 WRITE(lup,*) '*.'
5625 WRITE(lup,*) '*.Appearance statistics '
5626 WRITE(lup,*) '*. Group First file and record Last file and record #files'
5627 DO icgrp=1, ncgrp
5628 WRITE(lup,115) icgrp, (appearancecounter((ntgb+icgrp)*5+k), k=-4,0)
5629 END DO
5630 END IF
5631 END IF
5632
5633 rewind lup
5634 CLOSE(unit=lup)
5635
5636110 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' fixed',i2)
5637111 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' variable')
5638112 FORMAT(' !.',i10,6i11)
5639113 FORMAT(' * ',i6,i8,3i12)
5640114 FORMAT(' *:',48x,i12,' ..',i12)
5641115 FORMAT(' *.',i10,5i11)
5642116 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' redundant')
5643117 FORMAT(' !!',a)
5644END SUBROUTINE prtstat ! print input statistics
5645
5646
5660
5661SUBROUTINE avprds(n,l,x,is,ie,b)
5662 USE mpmod
5663
5664 IMPLICIT NONE
5665 INTEGER(mpi) :: i
5666 INTEGER(mpi) :: ia
5667 INTEGER(mpi) :: ia2
5668 INTEGER(mpi) :: ib
5669 INTEGER(mpi) :: ib2
5670 INTEGER(mpi) :: in
5671 INTEGER(mpi) :: ipg
5672 INTEGER(mpi) :: iproc
5673 INTEGER(mpi) :: ir
5674 INTEGER(mpi) :: j
5675 INTEGER(mpi) :: ja
5676 INTEGER(mpi) :: ja2
5677 INTEGER(mpi) :: jb
5678 INTEGER(mpi) :: jb2
5679 INTEGER(mpi) :: jn
5680 INTEGER(mpi) :: lj
5681
5682 INTEGER(mpi), INTENT(IN) :: n
5683 INTEGER(mpl), INTENT(IN) :: l
5684 REAL(mpd), INTENT(IN) :: x(n)
5685 INTEGER(mpi), INTENT(IN) :: is
5686 INTEGER(mpi), INTENT(IN) :: ie
5687 REAL(mpd), INTENT(OUT) :: b(n)
5688 INTEGER(mpl) :: k
5689 INTEGER(mpl) :: kk
5690 INTEGER(mpl) :: ku
5691 INTEGER(mpl) :: ll
5692 INTEGER(mpl) :: indij
5693 INTEGER(mpl) :: indid
5694 INTEGER(mpl) :: ij
5695 INTEGER(mpi) :: ichunk
5696 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5697 SAVE
5698 ! ...
5699
5700 ichunk=min((n+mthrd-1)/mthrd/8+1,128)
5701 IF(matsto /= 2) THEN
5702 ! full or unpacked (block diagonal) symmetric matrix
5703 ! parallelize row loop
5704 ! private copy of B(N) for each thread, combined at end, init with 0.
5705 ! slot of 128 'I' for next idle thread
5706 !$OMP PARALLEL DO &
5707 !$OMP PRIVATE(J,IJ) &
5708 !$OMP SCHEDULE(DYNAMIC,ichunk)
5709 DO i=1,n
5710 ij=globalrowoffsets(i+l)+l
5711 DO j=is,min(i,ie)
5712 b(i)=b(i)+globalmatd(ij+j)*x(j)
5713 END DO
5714 END DO
5715 !$OMP END PARALLEL DO
5716
5717 !$OMP PARALLEL DO &
5718 !$OMP PRIVATE(J,IJ) &
5719 !$OMP REDUCTION(+:B) &
5720 !$OMP SCHEDULE(DYNAMIC,ichunk)
5721 DO i=is,ie
5722 ij=globalrowoffsets(i+l)+l
5723 DO j=1,i-1
5724 b(j)=b(j)+globalmatd(ij+j)*x(i)
5725 END DO
5726 END DO
5727 !$OMP END PARALLEL DO
5728 ELSE
5729 ! sparse, compressed matrix
5730 IF(sparsematrixoffsets(2,1) /= n) THEN
5731 CALL peend(24,'Aborted, vector/matrix size mismatch')
5732 stop 'AVPRDS: mismatched vector and matrix'
5733 END IF
5734 ! parallelize row (group) loop
5735 ! slot of 1024 'I' for next idle thread
5736 !$OMP PARALLEL DO &
5737 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
5738 !$OMP PRIVATE(IA,IB,IN,JA,JB,IA2,IB2,JA2,JB2) &
5739 !$OMP REDUCTION(+:B) &
5740 !$OMP SCHEDULE(DYNAMIC,ichunk)
5741 DO ipg=1,napgrp
5742 iproc=0
5743 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5744 ! row group
5745 ia=globalallindexgroups(ipg) ! first (global) row
5746 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
5747 in=ib-ia+1 ! number of rows
5748 ! overlap
5749 ia2=max(ia,is)
5750 ib2=min(ib,ie)
5751 ! diagonal elements
5752 IF (ia2 <= ib2) b(ia2:ib2)=b(ia2:ib2)+globalmatd(ia2:ib2)*x(ia2:ib2)
5753 ! off-diagonals double precision
5754 ir=ipg
5755 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5756 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5757 ku=sparsematrixoffsets(1,ir+1)-kk
5758 indid=kk
5759 indij=ll
5760 IF (ku > 0) THEN
5761 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5762 DO i=ia,ib
5763 IF (i <= ie.AND.i >= is) THEN
5764 DO k=1,ku
5765 j=sparsematrixcolumns(indid+k)
5766 b(j)=b(j)+globalmatd(indij+k)*x(i)
5767 END DO
5768 END IF
5769 DO k=1,ku
5770 j=sparsematrixcolumns(indid+k)
5771 IF (j <= ie.AND.j >= is) THEN
5772 b(i)=b(i)+globalmatd(indij+k)*x(j)
5773 END IF
5774 END DO
5775 indij=indij+ku
5776 END DO
5777 ELSE
5778 ! regions of continous column groups
5779 DO k=2,ku-2,2
5780 j=sparsematrixcolumns(indid+k) ! first group
5781 ja=globalallindexgroups(j) ! first (global) column
5782 lj=sparsematrixcolumns(indid+k-1) ! region offset
5783 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5784 jb=ja+jn-1 ! last (global) column
5785 ja2=max(ja,is)
5786 jb2=min(jb,ie)
5787 IF (ja2 <= jb2) THEN
5788 lj=1 ! index (in group region)
5789 DO i=ia,ib
5790 b(i)=b(i)+dot_product(globalmatd(indij+lj+ja2-ja:indij+lj+jb2-ja),x(ja2:jb2))
5791 lj=lj+jn
5792 END DO
5793 END IF
5794 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5795 lj=1
5796 DO j=ja,jb
5797 b(j)=b(j)+dot_product(globalmatd(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),x(ia2:ib2))
5798 lj=lj+1
5799 END DO
5800 END IF
5801 indij=indij+in*jn
5802 END DO
5803 END IF
5804 END IF
5805 ! mixed precision
5806 IF (nspc > 1) THEN
5807 ir=ipg+napgrp+1 ! off-diagonals single precision
5808 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5809 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5810 ku=sparsematrixoffsets(1,ir+1)-kk
5811 indid=kk
5812 indij=ll
5813 IF (ku == 0) cycle
5814 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5815 DO i=ia,ib
5816 IF (i <= ie.AND.i >= is) THEN
5817 DO k=1,ku
5818 j=sparsematrixcolumns(indid+k)
5819 b(j)=b(j)+globalmatf(indij+k)*x(i)
5820 END DO
5821 END IF
5822 DO k=1,ku
5823 j=sparsematrixcolumns(indid+k)
5824 IF (j <= ie.AND.j >= is) THEN
5825 b(i)=b(i)+globalmatf(indij+k)*x(j)
5826 END IF
5827 END DO
5828 indij=indij+ku
5829 END DO
5830 ELSE
5831 ! regions of continous column groups
5832 DO k=2,ku-2,2
5833 j=sparsematrixcolumns(indid+k) ! first group
5834 ja=globalallindexgroups(j) ! first (global) column
5835 lj=sparsematrixcolumns(indid+k-1) ! region offset
5836 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5837 jb=ja+jn-1 ! last (global) column
5838 ja2=max(ja,is)
5839 jb2=min(jb,ie)
5840 IF (ja2 <= jb2) THEN
5841 lj=1 ! index (in group region)
5842 DO i=ia,ib
5843 b(i)=b(i)+dot_product(real(globalmatf(indij+lj+ja2-ja:indij+lj+jb2-ja),mpd),x(ja2:jb2))
5844 lj=lj+jn
5845 END DO
5846 END IF
5847 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5848 lj=1
5849 DO j=ja,jb
5850 b(j)=b(j)+dot_product(real(globalmatf(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),mpd),x(ia2:ib2))
5851 lj=lj+1
5852 END DO
5853 END IF
5854 indij=indij+in*jn
5855 END DO
5856 END IF
5857 END IF
5858 END DO
5859 ENDIF
5860
5861END SUBROUTINE avprds
5862
5874
5875SUBROUTINE avprd0(n,l,x,b)
5876 USE mpmod
5877
5878 IMPLICIT NONE
5879 INTEGER(mpi) :: i
5880 INTEGER(mpi) :: ia
5881 INTEGER(mpi) :: ib
5882 INTEGER(mpi) :: in
5883 INTEGER(mpi) :: ipg
5884 INTEGER(mpi) :: iproc
5885 INTEGER(mpi) :: ir
5886 INTEGER(mpi) :: j
5887 INTEGER(mpi) :: ja
5888 INTEGER(mpi) :: jb
5889 INTEGER(mpi) :: jn
5890 INTEGER(mpi) :: lj
5891
5892 INTEGER(mpi), INTENT(IN) :: n
5893 INTEGER(mpl), INTENT(IN) :: l
5894 REAL(mpd), INTENT(IN) :: x(n)
5895 REAL(mpd), INTENT(OUT) :: b(n)
5896 INTEGER(mpl) :: k
5897 INTEGER(mpl) :: kk
5898 INTEGER(mpl) :: ku
5899 INTEGER(mpl) :: ll
5900 INTEGER(mpl) :: indij
5901 INTEGER(mpl) :: indid
5902 INTEGER(mpl) :: ij
5903 INTEGER(mpi) :: ichunk
5904 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5905 SAVE
5906 ! ...
5907 !$ DO i=1,n
5908 !$ b(i)=0.0_mpd ! reset 'global' B()
5909 !$ END DO
5910 ichunk=min((n+mthrd-1)/mthrd/8+1,1024)
5911 IF(matsto /= 2) THEN
5912 ! full or unpacked (block diagonal) symmetric matrix
5913 ! parallelize row loop
5914 ! private copy of B(N) for each thread, combined at end, init with 0.
5915 ! slot of 1024 'I' for next idle thread
5916 !$OMP PARALLEL DO &
5917 !$OMP PRIVATE(J,IJ) &
5918 !$OMP REDUCTION(+:B) &
5919 !$OMP SCHEDULE(DYNAMIC,ichunk)
5920 DO i=1,n
5921 ij=globalrowoffsets(i+l)+l
5922 b(i)=globalmatd(ij+i)*x(i)
5923 DO j=1,i-1
5924 b(j)=b(j)+globalmatd(ij+j)*x(i)
5925 b(i)=b(i)+globalmatd(ij+j)*x(j)
5926 END DO
5927 END DO
5928 !$OMP END PARALLEL DO
5929 ELSE
5930 ! sparse, compressed matrix
5931 IF(sparsematrixoffsets(2,1) /= n) THEN
5932 CALL peend(24,'Aborted, vector/matrix size mismatch')
5933 stop 'AVPRD0: mismatched vector and matrix'
5934 END IF
5935 ! parallelize row (group) loop
5936 ! slot of 1024 'I' for next idle thread
5937 !$OMP PARALLEL DO &
5938 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
5939 !$OMP PRIVATE(IA,IB,IN,JA,JB) &
5940 !$OMP REDUCTION(+:B) &
5941 !$OMP SCHEDULE(DYNAMIC,ichunk)
5942 DO ipg=1,napgrp
5943 iproc=0
5944 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5945 ! row group
5946 ia=globalallindexgroups(ipg) ! first (global) row
5947 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
5948 in=ib-ia+1 ! number of rows
5949 !
5950 ! diagonal elements
5951 b(ia:ib)=globalmatd(ia:ib)*x(ia:ib)
5952 ! off-diagonals double precision
5953 ir=ipg
5954 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5955 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5956 ku=sparsematrixoffsets(1,ir+1)-kk
5957 indid=kk
5958 indij=ll
5959 IF (ku > 0) THEN
5960 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5961 DO i=ia,ib
5962 DO k=1,ku
5963 j=sparsematrixcolumns(indid+k)
5964 b(j)=b(j)+globalmatd(indij+k)*x(i)
5965 b(i)=b(i)+globalmatd(indij+k)*x(j)
5966 END DO
5967 indij=indij+ku
5968 END DO
5969 ELSE
5970 ! regions of continous column groups
5971 DO k=2,ku-2,2
5972 j=sparsematrixcolumns(indid+k) ! first group
5973 ja=globalallindexgroups(j) ! first (global) column
5974 lj=sparsematrixcolumns(indid+k-1) ! region offset
5975 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5976 jb=ja+jn-1 ! last (global) column
5977 lj=1 ! index (in group region)
5978 DO i=ia,ib
5979 b(i)=b(i)+dot_product(globalmatd(indij+lj:indij+lj+jn-1),x(ja:jb))
5980 lj=lj+jn
5981 END DO
5982 IF (mextnd == 0) THEN
5983 lj=1
5984 DO j=ja,jb
5985 b(j)=b(j)+dot_product(globalmatd(indij+lj:indij+jn*in:jn),x(ia:ib))
5986 lj=lj+1
5987 END DO
5988 END IF
5989 indij=indij+in*jn
5990 END DO
5991 END IF
5992 END IF
5993 ! mixed precision
5994 IF (nspc > 1) THEN
5995 ir=ipg+napgrp+1 ! off-diagonals single precision
5996 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5997 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5998 ku=sparsematrixoffsets(1,ir+1)-kk
5999 indid=kk
6000 indij=ll
6001 IF (ku == 0) cycle
6002 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6003 DO i=ia,ib
6004 DO k=1,ku
6005 j=sparsematrixcolumns(indid+k)
6006 b(j)=b(j)+real(globalmatf(indij+k),mpd)*x(i)
6007 b(i)=b(i)+real(globalmatf(indij+k),mpd)*x(j)
6008 END DO
6009 indij=indij+ku
6010 END DO
6011 ELSE
6012 ! regions of continous column groups
6013 DO k=2,ku-2,2
6014 j=sparsematrixcolumns(indid+k) ! first group
6015 ja=globalallindexgroups(j) ! first (global) column
6016 lj=sparsematrixcolumns(indid+k-1) ! region offset
6017 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6018 jb=ja+jn-1 ! last (global) column
6019 lj=1 ! index (in group region)
6020 DO i=ia,ib
6021 b(i)=b(i)+dot_product(real(globalmatf(indij+lj:indij+lj+jn-1),mpd),x(ja:jb))
6022 lj=lj+jn
6023 END DO
6024 IF (mextnd == 0) THEN
6025 lj=1
6026 DO j=ja,jb
6027 b(j)=b(j)+dot_product(real(globalmatf(indij+lj:indij+jn*in:jn),mpd),x(ia:ib))
6028 lj=lj+1
6029 END DO
6030 END IF
6031 indij=indij+in*jn
6032 END DO
6033 END IF
6034 END IF
6035 END DO
6036 ENDIF
6037
6038END SUBROUTINE avprd0
6039
6040
6043SUBROUTINE anasps
6044 USE mpmod
6045
6046 IMPLICIT NONE
6047 INTEGER(mpi) :: ia
6048 INTEGER(mpi) :: ib
6049 INTEGER(mpi) :: ipg
6050 INTEGER(mpi) :: ir
6051 INTEGER(mpi) :: ispc
6052 INTEGER(mpi) :: lj
6053 REAL(mps) :: avg
6054
6055
6056 INTEGER(mpl) :: in
6057 INTEGER(mpl) :: jn
6058 INTEGER(mpl) :: k
6059 INTEGER(mpl) :: kk
6060 INTEGER(mpl) :: ku
6061 INTEGER(mpl) :: ll
6062 INTEGER(mpl) :: indid
6063 INTEGER(mpl), DIMENSION(12) :: icount
6064 SAVE
6065
6066 ! require sparse storage
6067 IF(matsto /= 2) RETURN
6068 ! reset
6069 icount=0
6070 icount(4)=huge(icount(4))
6071 icount(7)=huge(icount(7))
6072 icount(10)=huge(icount(10))
6073 ! loop over precisions
6074 DO ispc=1,nspc
6075 ! loop over row groups
6076 DO ipg=1,napgrp
6077 ! row group
6078 ia=globalallindexgroups(ipg) ! first (global) row
6079 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6080 in=ib-ia+1 ! number of rows
6081
6082 ir=ipg+(ispc-1)*(napgrp+1)
6083 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6084 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6085 ku=sparsematrixoffsets(1,ir+1)-kk
6086 indid=kk
6087 IF (ku == 0) cycle
6088 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6089 icount(1)=icount(1)+in
6090 icount(2)=icount(2)+in*ku
6091 ELSE
6092 ! regions of continous column groups
6093 DO k=2,ku-2,2
6094 lj=sparsematrixcolumns(indid+k-1) ! region offset
6095 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6096 icount(3)=icount(3)+1 ! block (region) counter
6097 icount(4)=min(icount(4),jn) ! min number of columns per block (region)
6098 icount(5)=icount(5)+jn ! sum number of columns per block (region)
6099 icount(6)=max(icount(6),jn) ! max number of columns per block (region)
6100 icount(7)=min(icount(7),in) ! min number of rows per block (region)
6101 icount(8)=icount(8)+in ! sum number of rows per block (region)
6102 icount(9)=max(icount(9),in) ! max number of rows per block (region)
6103 icount(10)=min(icount(10),in*jn) ! min number of elements per block (region)
6104 icount(11)=icount(11)+in*jn ! sum number of elements per block (region)
6105 icount(12)=max(icount(12),in*jn) ! max number of elements per block (region)
6106 END DO
6107 END IF
6108 END DO
6109 END DO
6110
6111 WRITE(*,*) "analysis of sparsity structure"
6112 IF (icount(1) > 0) THEN
6113 WRITE(*,101) "rows without compression/blocks ", icount(1)
6114 WRITE(*,101) " contained elements ", icount(2)
6115 ENDIF
6116 WRITE(*,101) "number of block matrices ", icount(3)
6117 avg=real(icount(5),mps)/real(icount(3),mps)
6118 WRITE(*,101) "number of columns (min,mean,max) ", icount(4), avg, icount(6)
6119 avg=real(icount(8),mps)/real(icount(3),mps)
6120 WRITE(*,101) "number of rows (min,mean,max) ", icount(7), avg, icount(9)
6121 avg=real(icount(11),mps)/real(icount(3),mps)
6122 WRITE(*,101) "number of elements (min,mean,max) ", icount(10), avg, icount(12)
6123101 FORMAT(2x,a34,i10,f10.3,i10)
6124
6125END SUBROUTINE anasps
6126
6136
6137SUBROUTINE avprod(n,x,b)
6138 USE mpmod
6139
6140 IMPLICIT NONE
6141
6142 INTEGER(mpi), INTENT(IN) :: n
6143 REAL(mpd), INTENT(IN) :: x(n)
6144 REAL(mpd), INTENT(OUT) :: b(n)
6145
6146 SAVE
6147 ! ...
6148 IF(n > nagb) THEN
6149 CALL peend(24,'Aborted, vector/matrix size mismatch')
6150 stop 'AVPROD: mismatched vector and matrix'
6151 END IF
6152 ! input to AVPRD0
6153 vecxav(1:n)=x
6154 vecxav(n+1:nagb)=0.0_mpd
6155 !use elimination for constraints ?
6156 IF(n < nagb) CALL qlmlq(vecxav,1,.false.) ! Q*x
6157 ! calclulate vecBav=globalMat*vecXav
6158 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
6159 !use elimination for constraints ?
6160 IF(n < nagb) CALL qlmlq(vecbav,1,.true.) ! Q^t*x
6161 ! output from AVPRD0
6162 b=vecbav(1:n)
6163
6164END SUBROUTINE avprod
6165
6166
6176
6177SUBROUTINE ijpgrp(itema,itemb,ij,lr,iprc)
6178 USE mpmod
6179
6180 IMPLICIT NONE
6181 INTEGER(mpi) :: ispc
6182 INTEGER(mpi) :: item1
6183 INTEGER(mpi) :: item2
6184 INTEGER(mpi) :: itemc
6185 INTEGER(mpi) :: jtem
6186 INTEGER(mpi) :: jtemn
6187 INTEGER(mpi) :: np
6188
6189 INTEGER(mpi), INTENT(IN) :: itema
6190 INTEGER(mpi), INTENT(IN) :: itemb
6191 INTEGER(mpl), INTENT(OUT) :: ij
6192 INTEGER(mpi), INTENT(OUT) :: lr
6193 INTEGER(mpi), INTENT(OUT) :: iprc
6194
6195 INTEGER(mpl) :: k
6196 INTEGER(mpl) :: kk
6197 INTEGER(mpl) :: kl
6198 INTEGER(mpl) :: ku
6199 INTEGER(mpl) :: ll
6200 ! ...
6201 ij=0
6202 lr=0
6203 iprc=0
6204 item1=max(itema,itemb) ! larger index
6205 item2=min(itema,itemb) ! smaller index
6206 IF(item2 <= 0.OR.item1 > napgrp) RETURN
6207 np=globalallindexgroups(item1+1)-globalallindexgroups(item1) ! size of group item1
6208 ! loop over precisions
6209 outer: DO ispc=1,nspc
6210 kk=sparsematrixoffsets(1,item1) ! offset (column lists)
6211 ll=sparsematrixoffsets(2,item1) ! offset (matrix)
6212 kl=1
6213 ku=sparsematrixoffsets(1,item1+1)-kk
6214 item1=item1+napgrp+1
6215 iprc=ispc
6216 IF (sparsematrixcolumns(kk+1) == 0) THEN ! compression ?
6217 ! compressed (list of continous regions of parameter groups (pairs of offset and 1. group index)
6218 kl=2
6219 ku=ku-2
6220 IF(ku < kl) cycle outer ! not found
6221 DO
6222 k=2*((kl+ku)/4) ! binary search
6223 jtem=sparsematrixcolumns(kk+k) ! first column (group) of region
6224 jtemn=sparsematrixcolumns(kk+k+2) ! first column (group) after region
6225 IF(item2 >= jtem.AND.item2 < jtemn) THEN
6226 ! length of region
6227 lr=sparsematrixcolumns(kk+k+1)-sparsematrixcolumns(kk+k-1)
6228 IF (globalallindexgroups(item2)-globalallindexgroups(jtem) >= lr) cycle outer ! outside region
6229 EXIT ! found
6230 END IF
6231 IF(item2 < jtem) THEN
6232 ku=k-2
6233 ELSE IF(item2 >= jtemn) THEN
6234 kl=k+2
6235 END IF
6236 IF(kl <= ku) cycle
6237 cycle outer ! not found
6238 END DO
6239 ! group offset in row
6240 ij=sparsematrixcolumns(kk+k-1)
6241 ! absolute offset
6242 ij=ll+ij*np+globalallindexgroups(item2)-globalallindexgroups(jtem)+1
6243
6244 ELSE
6245 ! simple column list
6246 itemc=globalallindexgroups(item2) ! first (col) index of group
6247 lr=int(ku,mpi) ! number of columns
6248 IF(ku < kl) cycle outer ! not found
6249 DO
6250 k=(kl+ku)/2 ! binary search
6251 jtem=sparsematrixcolumns(kk+k)
6252 IF(itemc == jtem) EXIT ! found
6253 IF(itemc < jtem) THEN
6254 ku=k-1
6255 ELSE IF(itemc > jtem) THEN
6256 kl=k+1
6257 END IF
6258 IF(kl <= ku) cycle
6259 cycle outer ! not found
6260 END DO
6261 ij=ll+k
6262
6263 END IF
6264 RETURN
6265 END DO outer
6266
6267END SUBROUTINE ijpgrp
6268
6274
6275FUNCTION ijprec(itema,itemb)
6276 USE mpmod
6277
6278 IMPLICIT NONE
6279
6280 INTEGER(mpi) :: lr
6281 INTEGER(mpl) :: ij
6282
6283 INTEGER(mpi), INTENT(IN) :: itema
6284 INTEGER(mpi), INTENT(IN) :: itemb
6285 INTEGER(mpi) :: ijprec
6286
6287 ! ...
6288 ijprec=1
6289 IF (matsto == 2.AND.nspc > 1) THEN ! sparse storage with mixed precision
6290 ! check groups
6291 CALL ijpgrp(itema,itemb,ij,lr,ijprec)
6292 END IF
6293
6294END FUNCTION ijprec
6295
6303
6304FUNCTION ijadd(itema,itemb) ! index using "d" and "z"
6305 USE mpmod
6306
6307 IMPLICIT NONE
6308
6309 INTEGER(mpi) :: item1
6310 INTEGER(mpi) :: item2
6311 INTEGER(mpi) :: ipg1
6312 INTEGER(mpi) :: ipg2
6313 INTEGER(mpi) :: lr
6314 INTEGER(mpi) :: iprc
6315
6316 INTEGER(mpi), INTENT(IN) :: itema
6317 INTEGER(mpi), INTENT(IN) :: itemb
6318
6319 INTEGER(mpl) :: ijadd
6320 INTEGER(mpl) :: ij
6321 ! ...
6322 ijadd=0
6323 item1=max(itema,itemb) ! larger index
6324 item2=min(itema,itemb) ! smaller index
6325 !print *, ' ijadd ', item1, item2
6326 IF(item2 <= 0.OR.item1 > nagb) RETURN
6327 IF(item1 == item2) THEN ! diagonal element
6328 ijadd=item1
6329 RETURN
6330 END IF
6331 ! ! off-diagonal element
6332 ! get parameter groups
6333 ipg1=globalallpartogroup(item1)
6334 ipg2=globalallpartogroup(item2)
6335 ! get offset for groups
6336 CALL ijpgrp(ipg1,ipg2,ij,lr,iprc)
6337 IF (ij == 0) RETURN
6338 ! add offset inside groups
6339 ijadd=ij+(item2-globalallindexgroups(ipg2))+(item1-globalallindexgroups(ipg1))*lr
6340 ! reduced precision?
6341 IF (iprc > 1) ijadd=-ijadd
6342
6343END FUNCTION ijadd
6344
6352
6353FUNCTION ijcsr3(itema,itemb) ! index using "d" and "z"
6354 USE mpmod
6355
6356 IMPLICIT NONE
6357
6358 INTEGER(mpi) :: item1
6359 INTEGER(mpi) :: item2
6360 INTEGER(mpi) :: jtem
6361
6362 INTEGER(mpi), INTENT(IN) :: itema
6363 INTEGER(mpi), INTENT(IN) :: itemb
6364
6365 INTEGER(mpl) :: ijcsr3
6366 INTEGER(mpl) :: kk
6367 INTEGER(mpl) :: ks
6368 INTEGER(mpl) :: ke
6369
6370 ! ...
6371 ijcsr3=0
6372 item1=max(itema,itemb) ! larger index
6373 item2=min(itema,itemb) ! smaller index
6374 !print *, ' ijadd ', item1, item2
6375 IF(item2 <= 0.OR.item1 > nagb) RETURN
6376 ! start of column list for row
6377 ks=csr3rowoffsets(item2)
6378 ! end of column list for row
6379 ke=csr3rowoffsets(item2+1)-1
6380 ! binary search
6381 IF(ke < ks) THEN
6382 ! empty list
6383 print *, ' IJCSR3 empty list ', item1, item2, ks, ke
6384 CALL peend(23,'Aborted, bad matrix index')
6385 stop 'ijcsr3: empty list'
6386 ENDIF
6387 DO
6388 kk=(ks+ke)/2 ! center of rgion
6389 jtem=int(csr3columnlist(kk),mpi)
6390 IF(item1 == jtem) EXIT ! found
6391 IF(item1 < jtem) THEN
6392 ke=kk-1
6393 ELSE
6394 ks=kk+1
6395 END IF
6396 IF(ks <= ke) cycle
6397 ! not found
6398 print *, ' IJCSR3 not found ', item1, item2, ks, ke
6399 CALL peend(23,'Aborted, bad matrix index')
6400 stop 'ijcsr3: not found'
6401 END DO
6402 ijcsr3=kk
6403END FUNCTION ijcsr3
6404
6410
6411FUNCTION matij(itema,itemb)
6412 USE mpmod
6413
6414 IMPLICIT NONE
6415
6416 INTEGER(mpi) :: item1
6417 INTEGER(mpi) :: item2
6418 INTEGER(mpl) :: i
6419 INTEGER(mpl) :: j
6420 INTEGER(mpl) :: ij
6421 INTEGER(mpl) :: ijadd
6422 INTEGER(mpl) :: ijcsr3
6423
6424 INTEGER(mpi), INTENT(IN) :: itema
6425 INTEGER(mpi), INTENT(IN) :: itemb
6426
6427 REAL(mpd) :: matij
6428 ! ...
6429 matij=0.0_mpd
6430 item1=max(itema,itemb) ! larger index
6431 item2=min(itema,itemb) ! smaller index
6432 IF(item2 <= 0.OR.item1 > nagb) RETURN
6433
6434 i=item1
6435 j=item2
6436
6437 IF(matsto < 2) THEN ! full or unpacked (block diagonal) symmetric matrix
6438 ij=globalrowoffsets(i)+j
6439 matij=globalmatd(ij)
6440 ELSE IF(matsto ==2) THEN ! sparse symmetric matrix (custom)
6441 ij=ijadd(item1,item2) ! inline code requires same time
6442 IF(ij > 0) THEN
6443 matij=globalmatd(ij)
6444 ELSE IF (ij < 0) THEN
6445 matij=real(globalmatf(-ij),mpd)
6446 END IF
6447 ELSE ! sparse symmetric matrix (CSR3)
6448 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
6449 ij=ijcsr3(item1,item2) ! inline code requires same time
6450 IF(ij > 0) matij=globalmatd(ij)
6451 ELSE ! sparse symmetric matrix (BSR3)
6452 ! block index
6453 ij=ijcsr3((item1-1)/matbsz+1,(item2-1)/matbsz+1)
6454 IF (ij > 0) THEN
6455 ! index of first element in block
6456 ij=(ij-1)*matbsz*matbsz+1
6457 ! adjust index for position in block
6458 ij=ij+mod(item1-1,matbsz)*matbsz+mod(item2-1,matbsz)
6459 matij=globalmatd(ij)
6460 ENDIF
6461 END IF
6462 END IF
6463
6464END FUNCTION matij
6465
6468
6469SUBROUTINE mhalf2
6470 USE mpmod
6471
6472 IMPLICIT NONE
6473 INTEGER(mpi) :: i
6474 INTEGER(mpi) :: ia
6475 INTEGER(mpi) :: ib
6476 INTEGER(mpi) :: ichunk
6477 INTEGER(mpi) :: in
6478 INTEGER(mpi) :: ipg
6479 INTEGER(mpi) :: ir
6480 INTEGER(mpi) :: ispc
6481 INTEGER(mpi) :: j
6482 INTEGER(mpi) :: ja
6483 INTEGER(mpi) :: jb
6484 INTEGER(mpi) :: jn
6485 INTEGER(mpi) :: lj
6486
6487 INTEGER(mpl) :: ij
6488 INTEGER(mpl) :: ijadd
6489 INTEGER(mpl) :: k
6490 INTEGER(mpl) :: kk
6491 INTEGER(mpl) :: ku
6492 INTEGER(mpl) :: ll
6493 ! ...
6494
6495 ichunk=min((napgrp+mthrd-1)/mthrd/8+1,1024)
6496
6497 DO ispc=1,nspc
6498 ! parallelize row loop
6499 ! slot of 1024 'I' for next idle thread
6500 !$OMP PARALLEL DO &
6501 !$OMP PRIVATE(I,IR,K,KK,LL,KU,IJ,J,LJ) &
6502 !$OMP PRIVATE(IA,IB,IN,JA,JB,JN) &
6503 !$OMP SCHEDULE(DYNAMIC,ichunk)
6504 DO ipg=1,napgrp
6505 ! row group
6506 ia=globalallindexgroups(ipg) ! first (global) row
6507 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6508 in=ib-ia+1 ! number of rows
6509 !
6510 ir=ipg+(ispc-1)*(napgrp+1)
6511 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6512 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6513 ku=sparsematrixoffsets(1,ir+1)-kk
6514 ! regions of continous column groups
6515 DO k=2,ku-2,2
6516 j=sparsematrixcolumns(kk+k) ! first group
6517 ja=globalallindexgroups(j) ! first (global) column
6518 lj=sparsematrixcolumns(kk+k-1) ! region offset
6519 jn=sparsematrixcolumns(kk+k+1)-lj ! number of columns
6520 jb=ja+jn-1 ! last (global) column
6521 ! skip first half
6522 IF (sparsematrixcolumns(kk+k+2) <= ipg) THEN
6523 ll=ll+in*jn
6524 cycle
6525 END IF
6526 ! at diagonal or in second half
6527 DO i=ia,ib ! loop over rows
6528 DO j=ja,jb ! loop over columns
6529 ll=ll+1
6530 IF (j > i) THEN
6531 ij=ijadd(i,j)
6532 IF (ispc==1) THEN
6533 globalmatd(ll)=globalmatd(ij)
6534 ELSE
6535 globalmatf(ll)=globalmatf(-ij)
6536 END IF
6537 END IF
6538 END DO
6539 END DO
6540 END DO
6541 END DO
6542 !$OMP END PARALLEL DO
6543 END DO
6544
6545END SUBROUTINE mhalf2
6546
6555
6556SUBROUTINE sechms(deltat,nhour,minut,secnd)
6557 USE mpdef
6558
6559 IMPLICIT NONE
6560 REAL(mps), INTENT(IN) :: deltat
6561 INTEGER(mpi), INTENT(OUT) :: minut
6562 INTEGER(mpi), INTENT(OUT):: nhour
6563 REAL(mps), INTENT(OUT):: secnd
6564 INTEGER(mpi) :: nsecd
6565 ! DELTAT = time in sec -> NHOUR,MINUT,SECND
6566 ! ...
6567 nsecd=nint(deltat,mpi) ! -> integer
6568 nhour=nsecd/3600
6569 minut=nsecd/60-60*nhour
6570 secnd=deltat-60*(minut+60*nhour)
6571END SUBROUTINE sechms
6572
6600
6601INTEGER(mpi) FUNCTION inone(item) ! translate 1-D identifier to nrs
6602 USE mpmod
6603 USE mpdalc
6604
6605 IMPLICIT NONE
6606 INTEGER(mpi), INTENT(IN) :: item
6607 INTEGER(mpi) :: j
6608 INTEGER(mpi) :: k
6609 INTEGER(mpi) :: iprime
6610 INTEGER(mpl) :: length
6611 INTEGER(mpl), PARAMETER :: four = 4
6612
6613 inone=0
6614 !print *, ' INONE ', item
6615 IF(item <= 0) RETURN
6616 IF(globalparheader(-1) == 0) THEN
6617 length=128 ! initial number
6618 CALL mpalloc(globalparlabelindex,four,length,'INONE: label & index')
6619 CALL mpalloc(globalparlabelcounter,length,'INONE: counter') ! updated in pargrp
6620 CALL mpalloc(globalparhashtable,2*length,'INONE: hash pointer')
6622 globalparheader(-0)=int(length,mpi) ! length of labels/indices
6623 globalparheader(-1)=0 ! number of stored items
6624 globalparheader(-2)=0 ! =0 during build-up
6625 globalparheader(-3)=int(length,mpi) ! next number
6626 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number
6627 globalparheader(-5)=0 ! number of overflows
6628 globalparheader(-6)=0 ! nr of variable parameters
6629 globalparheader(-8)=0 ! number of sorted items
6630 END IF
6631 outer: DO
6632 j=1+mod(item,globalparheader(-4))+globalparheader(-0)
6633 inner: DO ! normal case: find item
6634 k=j
6636 IF(j == 0) EXIT inner ! unused hash code
6637 IF(item == globalparlabelindex(1,j)) EXIT outer ! found
6638 END DO inner
6639 ! not found
6640 IF(globalparheader(-1) == globalparheader(-0).OR.globalparheader(-2) /= 0) THEN
6641 globalparheader(-5)=globalparheader(-5)+1 ! overflow
6642 j=0
6643 RETURN
6644 END IF
6645 globalparheader(-1)=globalparheader(-1)+1 ! increase number of elements
6647 j=globalparheader(-1)
6648 globalparhashtable(k)=j ! hash index
6649 globalparlabelindex(1,j)=item ! add new item
6650 globalparlabelindex(2,j)=0 ! reset index (for variable par.)
6651 globalparlabelindex(3,j)=0 ! reset group info (first label)
6652 globalparlabelindex(4,j)=0 ! reset group info (group index)
6653 globalparlabelcounter(j)=0 ! reset (long) counter
6654 IF(globalparheader(-1) /= globalparheader(-0)) EXIT outer
6655 ! update with larger dimension and redefine index
6657 CALL upone
6658 IF (lvllog > 1) WRITE(lunlog,*) 'INONE: array increased to', &
6659 globalparheader(-3),' words'
6660 END DO outer
6661
6662 ! counting now in pargrp
6663 !IF(globalParHeader(-2) == 0) THEN
6664 ! globalParLabelIndex(2,j)=globalParLabelIndex(2,j)+1 ! increase counter
6665 ! globalParHeader(-7)=globalParHeader(-7)+1
6666 !END IF
6667 inone=j
6668END FUNCTION inone
6669
6671SUBROUTINE upone
6672 USE mpmod
6673 USE mpdalc
6674
6675 IMPLICIT NONE
6676 INTEGER(mpi) :: i
6677 INTEGER(mpi) :: j
6678 INTEGER(mpi) :: k
6679 INTEGER(mpi) :: iprime
6680 INTEGER(mpi) :: nused
6681 LOGICAL :: finalUpdate
6682 INTEGER(mpl) :: oldLength
6683 INTEGER(mpl) :: newLength
6684 INTEGER(mpl), PARAMETER :: four = 4
6685 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArr
6686 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: tempVec
6687 SAVE
6688 ! ...
6689 finalupdate=(globalparheader(-3) == globalparheader(-1))
6690 IF(finalupdate) THEN ! final (cleanup) call
6691 IF (globalparheader(-1) > globalparheader(-8)) THEN
6694 END IF
6695 END IF
6696 ! save old LabelIndex
6697 nused = globalparheader(-1)
6698 oldlength = globalparheader(-0)
6699 CALL mpalloc(temparr,four,oldlength,'INONE: temp array')
6700 temparr(:,1:nused)=globalparlabelindex(:,1:nused)
6701 CALL mpalloc(tempvec,oldlength,'INONE: temp vector')
6702 tempvec(1:nused)=globalparlabelcounter(1:nused)
6706 ! create new LabelIndex
6707 newlength = globalparheader(-3)
6708 CALL mpalloc(globalparlabelindex,four,newlength,'INONE: label & index')
6709 CALL mpalloc(globalparlabelcounter,newlength,'INONE: counter')
6710 CALL mpalloc(globalparhashtable,2*newlength,'INONE: hash pointer')
6712 globalparlabelindex(:,1:nused) = temparr(:,1:nused) ! copy back saved content
6713 globalparlabelcounter(1:nused) = tempvec(1:nused) ! copy back saved content
6714 CALL mpdealloc(tempvec)
6715 CALL mpdealloc(temparr)
6716 globalparheader(-0)=int(newlength,mpi) ! length of labels/indices
6718 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number < LNDA
6719 ! redefine hash
6720 outer: DO i=1,globalparheader(-1)
6722 inner: DO
6723 k=j
6725 IF(j == 0) EXIT inner ! unused hash code
6726 IF(j == i) cycle outer ! found
6727 ENDDO inner
6729 END DO outer
6730 IF(.NOT.finalupdate) RETURN
6731
6732 globalparheader(-2)=1 ! set flag to inhibit further updates
6733 IF (lvllog > 1) THEN
6734 WRITE(lunlog,*) ' '
6735 WRITE(lunlog,*) 'INONE: array reduced to',newlength,' words'
6736 WRITE(lunlog,*) 'INONE:',globalparheader(-1),' items stored.'
6737 END IF
6738END SUBROUTINE upone ! update, redefine
6739
6741SUBROUTINE useone
6742 USE mpmod
6743
6744 IMPLICIT NONE
6745 INTEGER(mpi) :: i
6746 INTEGER(mpi) :: j
6747 INTEGER(mpi) :: k
6748 SAVE
6749 ! ...
6750 IF (globalparheader(-1) > globalparheader(-8)) THEN
6752 ! redefine hash
6754 outer: DO i=1,globalparheader(-1)
6756 inner: DO
6757 k=j
6759 IF(j == 0) EXIT inner ! unused hash code
6760 IF(j == i) cycle outer ! found
6761 ENDDO inner
6763 END DO outer
6765 END IF
6766END SUBROUTINE useone ! make usable
6767
6772
6773INTEGER(mpi) FUNCTION iprime(n)
6774 USE mpdef
6775
6776 IMPLICIT NONE
6777 INTEGER(mpi), INTENT(IN) :: n
6778 INTEGER(mpi) :: nprime
6779 INTEGER(mpi) :: nsqrt
6780 INTEGER(mpi) :: i
6781 ! ...
6782 SAVE
6783 nprime=n ! max number
6784 IF(mod(nprime,2) == 0) nprime=nprime+1 ! ... odd number
6785 outer: DO
6786 nprime=nprime-2 ! next lower odd number
6787 nsqrt=int(sqrt(real(nprime,mps)),mpi)
6788 DO i=3,nsqrt,2 !
6789 IF(i*(nprime/i) == nprime) cycle outer ! test prime number
6790 END DO
6791 EXIT outer ! found
6792 END DO outer
6793 iprime=nprime
6794END FUNCTION iprime
6795
6805SUBROUTINE loop1
6806 USE mpmod
6807 USE mpdalc
6808
6809 IMPLICIT NONE
6810 INTEGER(mpi) :: i
6811 INTEGER(mpi) :: idum
6812 INTEGER(mpi) :: in
6813 INTEGER(mpi) :: indab
6814 INTEGER(mpi) :: itgbi
6815 INTEGER(mpi) :: itgbl
6816 INTEGER(mpi) :: ivgbi
6817 INTEGER(mpi) :: j
6818 INTEGER(mpi) :: jgrp
6819 INTEGER(mpi) :: lgrp
6820 INTEGER(mpi) :: mqi
6821 INTEGER(mpi) :: nc31
6822 INTEGER(mpi) :: nr
6823 INTEGER(mpi) :: nwrd
6824 INTEGER(mpi) :: inone
6825 REAL(mpd) :: param
6826 REAL(mpd) :: presg
6827 REAL(mpd) :: prewt
6828
6829 INTEGER(mpl) :: length
6830 INTEGER(mpl) :: rows
6831 SAVE
6832 ! ...
6833 WRITE(lunlog,*) ' '
6834 WRITE(lunlog,*) 'LOOP1: starting'
6835 CALL mstart('LOOP1')
6836
6837 ! add labels from parameter, constraints, measurements, comments -------------
6838 DO i=1, lenparameters
6839 idum=inone(listparameters(i)%label)
6840 END DO
6841 DO i=1, lenpresigmas
6842 idum=inone(listpresigmas(i)%label)
6843 END DO
6844 DO i=1, lenconstraints
6845 idum=inone(listconstraints(i)%label)
6846 END DO
6847 DO i=1, lenmeasurements
6848 idum=inone(listmeasurements(i)%label)
6849 END DO
6850 DO i=1, lencomments
6851 idum=inone(listcomments(i)%label)
6852 END DO
6853
6854 IF(globalparheader(-1) /= 0) THEN
6855 WRITE(lunlog,*) 'LOOP1:',globalparheader(-1), ' labels from txt data stored'
6856 END IF
6857 WRITE(lunlog,*) 'LOOP1: reading data files'
6858
6859 neqn=0 ! number of equations
6860 negb=0 ! number of equations with global parameters
6861 ndgb=0 ! number of global derivatives
6862 DO
6863 DO j=1,globalparheader(-1)
6864 globalparlabelindex(2,j)=0 ! reset count
6865 END DO
6866
6867 ! read all data files and add all labels to global labels table ----
6868
6869 IF(mprint /= 0) THEN
6870 WRITE(*,*) 'Read all binary data files:'
6871 END IF
6872 CALL hmpldf(1,'Number of words/record in binary file')
6873 CALL hmpdef(8,0.0,60.0,'not_stored data per record')
6874 ! define read buffer
6875 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
6876 nwrd=nc31+1
6877 length=nwrd*mthrdr
6878 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
6879 nwrd=nc31*10+2+ndimbuf
6880 length=nwrd*mthrdr
6881 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
6882 CALL mpalloc(readbufferdatad,length,'read buffer, double')
6883 ! to read (old) float binary files
6884 length=(ndimbuf+2)*mthrdr
6885 CALL mpalloc(readbufferdataf,length,'read buffer, float')
6886
6887 DO
6888 CALL peread(nr) ! read records
6889 IF (skippedrecords == 0) THEN
6890 CALL peprep(0) ! prepare records
6891 CALL pepgrp ! update parameter group info
6892 END IF
6893 IF(nr <= 0) EXIT ! end of data?
6894 END DO
6895 ! release read buffer
6900 IF (skippedrecords == 0) THEN
6901 EXIT
6902 ELSE
6903 WRITE(lunlog,*) 'LOOP1: reading data files again'
6904 END IF
6905 END DO
6906
6907 IF(nhistp /= 0) THEN
6908 CALL hmprnt(1)
6909 CALL hmprnt(8)
6910 END IF
6911 CALL hmpwrt(1)
6912 CALL hmpwrt(8)
6913 ntgb = globalparheader(-1) ! total number of labels/parameters
6914 IF (ntgb == 0) THEN
6915 CALL peend(21,'Aborted, no labels/parameters defined')
6916 stop 'LOOP1: no labels/parameters defined'
6917 END IF
6918 CALL upone ! finalize the global label table
6919
6920 WRITE(lunlog,*) 'LOOP1:',ntgb, &
6921 ' is total number NTGB of labels/parameters'
6922 ! histogram number of entries per label ----------------------------
6923 CALL hmpldf(2,'Number of entries per label')
6924 DO j=1,ntgb
6925 CALL hmplnt(2,globalparlabelindex(2,j))
6926 END DO
6927 IF(nhistp /= 0) CALL hmprnt(2) ! print histogram
6928 CALL hmpwrt(2) ! write to his file
6929
6930 ! three subarrays for all global parameters ------------------------
6931 length=ntgb
6932 CALL mpalloc(globalparameter,length,'global parameters')
6933 globalparameter=0.0_mpd
6934 CALL mpalloc(globalparpresigma,length,'pre-sigmas') ! presigmas
6936 CALL mpalloc(globalparstart,length,'global parameters at start')
6938 CALL mpalloc(globalparcopy,length,'copy of global parameters')
6939 CALL mpalloc(globalparcons,length,'global parameter constraints')
6941 CALL mpalloc(globalparcomments,length,'global parameter comments')
6943
6944 DO i=1,lenparameters ! parameter start values
6945 param=listparameters(i)%value
6946 in=inone(listparameters(i)%label)
6947 IF(in /= 0) THEN
6948 globalparameter(in)=param
6949 globalparstart(in)=param
6950 ENDIF
6951 END DO
6952
6953 DO i=1, lencomments
6954 in=inone(listcomments(i)%label)
6955 IF(in /= 0) globalparcomments(in)=i
6956 END DO
6957
6958 npresg=0
6959 DO i=1,lenpresigmas ! pre-sigma values
6960 presg=listpresigmas(i)%value
6961 in=inone(listpresigmas(i)%label)
6962 IF(in /= 0) THEN
6963 IF(presg > 0.0) npresg=npresg+1 ! FIXME: check if enough 'entries'?
6964 globalparpresigma(in)=presg ! insert pre-sigma 0 or > 0
6965 END IF
6966 END DO
6967 WRITE(lunlog,*) 'LOOP1:',npresg,' is number of pre-sigmas'
6968 WRITE(*,*) 'LOOP1:',npresg,' is number of pre-sigmas'
6969 IF(npresg == 0) WRITE(*,*) 'Warning: no pre-sigmas defined'
6970
6971 ! build constraint groups, check for redundancy constrints
6972 CALL grpcon
6973
6974 ! determine flag variable (active) or fixed (inactive) -------------
6975
6976 indab=0
6977 DO i=1,ntgb
6978 IF (globalparpresigma(i) < 0.0) THEN
6979 globalparlabelindex(2,i)=-1 ! fixed (pre-sigma), not used in matrix (not active)
6980 ELSE IF(globalparlabelcounter(i) < mreqenf) THEN
6981 globalparlabelindex(2,i)=-2 ! fixed (entries cut), not used in matrix (not active)
6982 ELSE IF (globalparcons(i) < 0) THEN
6983 globalparlabelindex(2,i)=-4 ! fixed (redundant), not used in matrix (not active)
6984 ELSE
6985 indab=indab+1
6986 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
6987 END IF
6988 END DO
6989 globalparheader(-6)=indab ! counted variable
6990 nvgb=indab ! nr of variable parameters
6991 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
6992 IF(iteren > mreqenf) THEN
6993 IF (mcount == 0) THEN
6994 CALL loop1i ! iterate entries cut
6995 ELSE
6996 WRITE(lunlog,*) 'LOOP1: counting records, NO iteration of entries cut !'
6997 iteren=0
6998 END IF
6999 END IF
7000
7001 ! --- check for parameter groups
7002 CALL hmpdef(15,0.0,120.0,'Number of parameters per group')
7003 ntpgrp=0
7004 DO j=1,ntgb
7005 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7006 ! new group?
7008 globalparlabelindex(4,j)=ntpgrp ! relation total index -> group
7009 END DO
7010 ! check variable parameters
7011 nvpgrp=0
7012 lgrp=-1
7013 DO j=1,ntgb
7014 IF (globalparlabelindex(2,j) <= 0) cycle ! skip fixed parameter
7015 ! new group ?
7016 IF (globalparlabelindex(4,j) /= lgrp) nvpgrp=nvpgrp+1
7017 lgrp=globalparlabelindex(4,j)
7018 END DO
7019 length=ntpgrp; rows=2
7020 CALL mpalloc(globaltotindexgroups,rows,length,'parameter groups, 1. index and size')
7022 ! fill
7023 lgrp=-1
7024 DO j=1,ntgb
7025 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7026 jgrp=globalparlabelindex(4,j)
7027 IF (jgrp /= lgrp) globaltotindexgroups(1,jgrp)=j ! first (total) index
7028 globaltotindexgroups(2,jgrp)=globaltotindexgroups(2,jgrp)+1 ! (total) size
7029 lgrp=jgrp
7030 END DO
7031 DO j=1,ntpgrp
7032 CALL hmpent(15,real(globaltotindexgroups(2,j),mps))
7033 END DO
7034 IF(nhistp /= 0) CALL hmprnt(15) ! print histogram
7035 CALL hmpwrt(15) ! write to his file
7036 WRITE(lunlog,*) 'LOOP1:',ntpgrp, &
7037 ' is total number NTPGRP of label/parameter groups'
7038 !print *, ' globalTotIndexGroups ', globalTotIndexGroups
7039
7040 ! translation table of length NVGB of total global indices ---------
7041 length=nvgb
7042 CALL mpalloc(globalparvartototal,length,'translation table var -> total')
7043 indab=0
7044 DO i=1,ntgb
7045 IF(globalparlabelindex(2,i) > 0) THEN
7046 indab=indab+1
7047 globalparvartototal(indab)=i
7048 END IF
7049 END DO
7050
7051 ! regularization ---------------------------------------------------
7052 CALL mpalloc(globalparpreweight,length,'pre-sigmas weights') ! presigma weights
7053 WRITE(*,112) ' Default pre-sigma =',regpre, &
7054 ' (if no individual pre-sigma defined)'
7055 WRITE(*,*) 'Pre-sigma factor is',regula
7056
7057 IF(nregul == 0) THEN
7058 WRITE(*,*) 'No regularization will be done'
7059 ELSE
7060 WRITE(*,*) 'Regularization will be done, using factor',regula
7061 END IF
7062112 FORMAT(a,e9.2,a)
7063 IF (nvgb <= 0) THEN
7064 CALL peend(22,'Aborted, no variable global parameters')
7065 stop '... no variable global parameters'
7066 ENDIF
7067
7068 DO ivgbi=1,nvgb ! IVGBI = index of variable global parameter
7069 itgbi=globalparvartototal(ivgbi) ! ITGBI = global parameter index
7070 presg=globalparpresigma(itgbi) ! get pre-sigma
7071 prewt=0.0 ! pre-weight
7072 IF(presg > 0.0) THEN
7073 prewt=1.0/presg**2 ! 1/presigma^2
7074 ELSE IF(presg == 0.0.AND.regpre > 0.0) THEN
7075 prewt=1.0/real(regpre**2,mpd) ! default 1/presigma^2
7076 END IF
7077 globalparpreweight(ivgbi)=regula*prewt ! weight = factor / presigma^2
7078 END DO
7079
7080 ! WRITE(*,*) 'GlPa_index GlPa_label array1 array6'
7081 DO i=1,ntgb
7082 itgbl=globalparlabelindex(1,i)
7083 ivgbi=globalparlabelindex(2,i)
7084 IF(ivgbi > 0) THEN
7085 ! WRITE(*,111) I,ITGBL,QM(IND1+I),QM(IND6+IVGBI)
7086 ELSE
7087 ! WRITE(*,111) I,ITGBL,QM(IND1+I)
7088 END IF
7089 END DO
7090 ! 111 FORMAT(I5,I10,F10.5,E12.4)
7091 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7092 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7093 ! To avoid INT(mpi) overflows in diagonalization
7094 IF (metsol == 2.AND.nvgb >= 46340) THEN
7095 metsol=1
7096 WRITE(*,101) 'Too many variable parameters for diagonalization, fallback is inversion'
7097 END IF
7098
7099 ! print overview over important numbers ----------------------------
7100
7101 nrecal=nrec
7102 IF(mprint /= 0) THEN
7103 WRITE(*,*) ' '
7104 WRITE(*,101) ' NREC',nrec,'number of records'
7105 IF (nrecd > 0) WRITE(*,101) ' NRECD',nrec,'number of records containing doubles'
7106 WRITE(*,101) ' NEQN',neqn,'number of equations (measurements)'
7107 WRITE(*,101) ' NEGB',negb,'number of equations with global parameters'
7108 WRITE(*,101) ' NDGB',ndgb,'number of global derivatives'
7109 IF (mcount == 0) THEN
7110 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7111 ELSE
7112 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7113 ENDIF
7114 IF(iteren > mreqenf) &
7115 WRITE(*,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7116 WRITE(*,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7117 IF (mreqpe > 1) WRITE(*,101) &
7118 'MREQPE',mreqpe,'required number of pair entries'
7119 IF (msngpe >= 1) WRITE(*,101) &
7120 'MSNGPE',msngpe,'max pair entries single prec. storage'
7121 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7122 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7123 IF(mprint > 1) THEN
7124 WRITE(*,*) ' '
7125 WRITE(*,*) 'Global parameter labels:'
7126 mqi=ntgb
7127 IF(mqi <= 100) THEN
7128 WRITE(*,*) (globalparlabelindex(2,i),i=1,mqi)
7129 ELSE
7130 WRITE(*,*) (globalparlabelindex(2,i),i=1,30)
7131 WRITE(*,*) ' ...'
7132 mqi=((mqi-20)/20)*20+1
7133 WRITE(*,*) (globalparlabelindex(2,i),i=mqi,ntgb)
7134 END IF
7135 END IF
7136 WRITE(*,*) ' '
7137 WRITE(*,*) ' '
7138 END IF
7139 WRITE(8,*) ' '
7140 WRITE(8,101) ' NREC',nrec,'number of records'
7141 IF (nrecd > 0) WRITE(8,101) ' NRECD',nrec,'number of records containing doubles'
7142 WRITE(8,101) ' NEQN',neqn,'number of equations (measurements)'
7143 WRITE(8,101) ' NEGB',negb,'number of equations with global parameters'
7144 WRITE(8,101) ' NDGB',ndgb,'number of global derivatives'
7145 IF (mcount == 0) THEN
7146 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7147 ELSE
7148 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7149 ENDIF
7150 IF(iteren > mreqenf) &
7151 WRITE(8,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7152 WRITE(8,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7153
7154 WRITE(lunlog,*) 'LOOP1: ending'
7155 WRITE(lunlog,*) ' '
7156 CALL mend
7157
7158101 FORMAT(1x,a8,' =',i14,' = ',a)
7159END SUBROUTINE loop1
7160
7168SUBROUTINE loop1i
7169 USE mpmod
7170 USE mpdalc
7171
7172 IMPLICIT NONE
7173 INTEGER(mpi) :: i
7174 INTEGER(mpi) :: ibuf
7175 INTEGER(mpi) :: ij
7176 INTEGER(mpi) :: indab
7177 INTEGER(mpi) :: ist
7178 INTEGER(mpi) :: j
7179 INTEGER(mpi) :: ja
7180 INTEGER(mpi) :: jb
7181 INTEGER(mpi) :: jsp
7182 INTEGER(mpi) :: nc31
7183 INTEGER(mpi) :: nr
7184 INTEGER(mpi) :: nlow
7185 INTEGER(mpi) :: nst
7186 INTEGER(mpi) :: nwrd
7187
7188 INTEGER(mpl) :: length
7189 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: newCounter
7190 SAVE
7191
7192 ! ...
7193 WRITE(lunlog,*) ' '
7194 WRITE(lunlog,*) 'LOOP1: iterating'
7195 WRITE(*,*) ' '
7196 WRITE(*,*) 'LOOP1: iterating'
7197
7198 length=ntgb
7199 CALL mpalloc(newcounter,length,'new entries counter')
7200 newcounter=0
7201
7202 ! define read buffer
7203 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7204 nwrd=nc31+1
7205 length=nwrd*mthrdr
7206 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7207 nwrd=nc31*10+2+ndimbuf
7208 length=nwrd*mthrdr
7209 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7210 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7211 ! to read (old) float binary files
7212 length=(ndimbuf+2)*mthrdr
7213 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7214
7215 DO
7216 CALL peread(nr) ! read records
7217 CALL peprep(1) ! prepare records
7218 DO ibuf=1,numreadbuffer ! buffer for current record
7219 ist=readbufferpointer(ibuf)+1
7221 nwrd=nst-ist+1
7222 DO ! loop over measurements
7223 CALL isjajb(nst,ist,ja,jb,jsp)
7224 IF(ja == 0.AND.jb == 0) EXIT
7225 IF(ja /= 0) THEN
7226 nlow=0
7227 DO j=1,ist-jb
7228 ij=readbufferdatai(jb+j) ! index of global parameter
7229 ij=globalparlabelindex(2,ij) ! change to variable parameter
7230 IF(ij == -2) nlow=nlow+1 ! fixed by entries cut
7231 END DO
7232 IF(nlow == 0) THEN
7233 DO j=1,ist-jb
7234 ij=readbufferdatai(jb+j) ! index of global parameter
7235 newcounter(ij)=newcounter(ij)+1 ! count again
7236 END DO
7237 ENDIF
7238 END IF
7239 END DO
7240 ! end-of-event
7241 END DO
7242 IF(nr <= 0) EXIT ! end of data?
7243 END DO
7244
7245 ! release read buffer
7250
7251 indab=0
7252 DO i=1,ntgb
7253 IF(globalparlabelindex(2,i) > 0) THEN
7254 IF(newcounter(i) >= mreqenf .OR. globalparlabelcounter(i) >= iteren) THEN
7255 indab=indab+1
7256 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7257 ELSE
7258 globalparlabelindex(2,i)=-3 ! fixed (iterated entries cut), not used in matrix (not active)
7259 END IF
7260 END IF
7261 END DO
7262 globalparheader(-6)=indab ! counted variable
7263 nvgb=indab ! nr of variable parameters
7264 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7265 CALL mpdealloc(newcounter)
7266
7267END SUBROUTINE loop1i
7268
7279
7280SUBROUTINE loop2
7281 USE mpmod
7282 USE mpdalc
7283
7284 IMPLICIT NONE
7285 REAL(mps) :: chin2
7286 REAL(mps) :: chin3
7287 REAL(mps) :: cpr
7288 REAL(mps) :: fsum
7289 REAL(mps) :: gbc
7290 REAL(mps) :: gbu
7291 INTEGER(mpi) :: i
7292 INTEGER(mpi) :: ia
7293 INTEGER(mpi) :: ib
7294 INTEGER(mpi) :: ibuf
7295 INTEGER(mpi) :: icblst
7296 INTEGER(mpi) :: icboff
7297 INTEGER(mpi) :: icgb
7298 INTEGER(mpi) :: icgrp
7299 INTEGER(mpi) :: icount
7300 INTEGER(mpi) :: iext
7301 INTEGER(mpi) :: ihis
7302 INTEGER(mpi) :: ij
7303 INTEGER(mpi) :: ij1
7304 INTEGER(mpi) :: ijn
7305 INTEGER(mpi) :: ioff
7306 INTEGER(mpi) :: ipoff
7307 INTEGER(mpi) :: iproc
7308 INTEGER(mpi) :: irecmm
7309 INTEGER(mpi) :: ist
7310 INTEGER(mpi) :: itgbi
7311 INTEGER(mpi) :: itgbij
7312 INTEGER(mpi) :: itgbik
7313 INTEGER(mpi) :: ivgbij
7314 INTEGER(mpi) :: ivgbik
7315 INTEGER(mpi) :: ivpgrp
7316 INTEGER(mpi) :: j
7317 INTEGER(mpi) :: ja
7318 INTEGER(mpi) :: jb
7319 INTEGER(mpi) :: jcgrp
7320 INTEGER(mpi) :: jext
7321 INTEGER(mpi) :: jcgb
7322 INTEGER(mpi) :: jrec
7323 INTEGER(mpi) :: jsp
7324 INTEGER(mpi) :: joff
7325 INTEGER(mpi) :: k
7326 INTEGER(mpi) :: kcgrp
7327 INTEGER(mpi) :: kfile
7328 INTEGER(mpi) :: l
7329 INTEGER(mpi) :: label
7330 INTEGER(mpi) :: labelf
7331 INTEGER(mpi) :: labell
7332 INTEGER(mpi) :: lvpgrp
7333 INTEGER(mpi) :: lu
7334 INTEGER(mpi) :: lun
7335 INTEGER(mpi) :: maeqnf
7336 INTEGER(mpi) :: nall
7337 INTEGER(mpi) :: naeqna
7338 INTEGER(mpi) :: naeqnf
7339 INTEGER(mpi) :: naeqng
7340 INTEGER(mpi) :: npdblk
7341 INTEGER(mpi) :: nc31
7342 INTEGER(mpi) :: ncachd
7343 INTEGER(mpi) :: ncachi
7344 INTEGER(mpi) :: ncachr
7345 INTEGER(mpi) :: ncon
7346 INTEGER(mpi) :: nda
7347 INTEGER(mpi) :: ndf
7348 INTEGER(mpi) :: ndfmax
7349 INTEGER(mpi) :: nfixed
7350 INTEGER(mpi) :: nggd
7351 INTEGER(mpi) :: nggi
7352 INTEGER(mpi) :: nmatmo
7353 INTEGER(mpi) :: noff
7354 INTEGER(mpi) :: npair
7355 INTEGER(mpi) :: npar
7356 INTEGER(mpi) :: nparmx
7357 INTEGER(mpi) :: nr
7358 INTEGER(mpi) :: nrece
7359 INTEGER(mpi) :: nrecf
7360 INTEGER(mpi) :: nrecmm
7361 INTEGER(mpi) :: nst
7362 INTEGER(mpi) :: nwrd
7363 INTEGER(mpi) :: inone
7364 INTEGER(mpi) :: inc
7365 REAL(mps) :: wgh
7366 REAL(mps) :: wolfc3
7367 REAL(mps) :: wrec
7368 REAL(mps) :: chindl
7369
7370 REAL(mpd)::dstat(3)
7371 REAL(mpd)::rerr
7372 INTEGER(mpl):: nblock
7373 INTEGER(mpl):: nbwrds
7374 INTEGER(mpl):: noff8
7375 INTEGER(mpl):: ndimbi
7376 INTEGER(mpl):: ndimsa(4)
7377 INTEGER(mpl):: ndgn
7378 INTEGER(mpl):: nnzero
7379 INTEGER(mpl):: matsiz(2)
7380 INTEGER(mpl):: matwords
7381 INTEGER(mpl):: mbwrds
7382 INTEGER(mpl):: length
7383 INTEGER(mpl):: rows
7384 INTEGER(mpl):: cols
7385 INTEGER(mpl), PARAMETER :: two=2
7386 INTEGER(mpi) :: maxGlobalPar = 0
7387 INTEGER(mpi) :: maxLocalPar = 0
7388 INTEGER(mpi) :: maxEquations = 0
7389
7390 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupList
7391 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupIndex
7392 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
7393 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecBlockCounts
7394
7395 INTERFACE ! needed for assumed-shape dummy arguments
7396 SUBROUTINE ndbits(npgrp,ndims,nsparr,ihst)
7397 USE mpdef
7398 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7399 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7400 INTEGER(mpl), DIMENSION(:,:), INTENT(OUT) :: nsparr
7401 INTEGER(mpi), INTENT(IN) :: ihst
7402 END SUBROUTINE ndbits
7403 SUBROUTINE ckbits(npgrp,ndims)
7404 USE mpdef
7405 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7406 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7407 END SUBROUTINE ckbits
7408 SUBROUTINE spbits(npgrp,nsparr,nsparc)
7409 USE mpdef
7410 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7411 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
7412 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: nsparc
7413 END SUBROUTINE spbits
7414 SUBROUTINE gpbmap(ngroup,npgrp,npair)
7415 USE mpdef
7416 INTEGER(mpi), INTENT(IN) :: ngroup
7417 INTEGER(mpi), DIMENSION(:,:), INTENT(IN) :: npgrp
7418 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npair
7419 END SUBROUTINE gpbmap
7420 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
7421 USE mpdef
7422 INTEGER(mpi), INTENT(IN) :: ipgrp
7423 INTEGER(mpi), INTENT(OUT) :: npair
7424 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
7425 END SUBROUTINE ggbmap
7426 SUBROUTINE pbsbits(npgrp,ibsize,nnzero,nblock,nbkrow)
7427 USE mpdef
7428 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7429 INTEGER(mpi), INTENT(IN) :: ibsize
7430 INTEGER(mpl), INTENT(OUT) :: nnzero
7431 INTEGER(mpl), INTENT(OUT) :: nblock
7432 INTEGER(mpi), DIMENSION(:),INTENT(OUT) :: nbkrow
7433 END SUBROUTINE pbsbits
7434 SUBROUTINE pblbits(npgrp,ibsize,nsparr,nsparc)
7435 USE mpdef
7436 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7437 INTEGER(mpi), INTENT(IN) :: ibsize
7438 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7439 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7440 END SUBROUTINE pblbits
7441 SUBROUTINE prbits(npgrp,nsparr)
7442 USE mpdef
7443 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7444 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparr
7445 END SUBROUTINE prbits
7446 SUBROUTINE pcbits(npgrp,nsparr,nsparc)
7447 USE mpdef
7448 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7449 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7450 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7451 END SUBROUTINE pcbits
7452 END INTERFACE
7453
7454 SAVE
7455
7456 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
7457
7458 ! ...
7459 WRITE(lunlog,*) ' '
7460 WRITE(lunlog,*) 'LOOP2: starting'
7461 CALL mstart('LOOP2')
7462
7463 ! two subarrays to get the global parameter indices, used in an event
7464 length=nvgb
7465 CALL mpalloc(globalindexusage,length,'global index')
7466 CALL mpalloc(backindexusage,length,'back index')
7468 CALL mpalloc(globalindexranges,length,'global index ranges')
7470
7471 ! prepare constraints - determine number of constraints NCGB
7472 ! - sort and split into blocks
7473 ! - update globalIndexRanges
7474 CALL prpcon
7475
7476 IF (metsol == 3.AND.icelim <= 0) THEN
7477 ! decomposition: enforce elimination
7478 icelim=1
7479 WRITE(lunlog,*) ' Elimination for constraints enforced for solution by decomposition!'
7480 END IF
7481 IF (metsol == 9.AND.icelim > 0) THEN
7482 ! sparsePARDISO: enforce multipliers
7483 icelim=0
7484 WRITE(lunlog,*) ' Lagrange multipliers enforced for solution by sparsePARDISO!'
7485 END IF
7486 IF (matsto > 0.AND.icelim > 1) THEN
7487 ! decomposition: enforce elimination
7488 icelim=1
7489 WRITE(lunlog,*) ' Elimination for constraints with mpqldec enforced (LAPACK only for unpacked storage)!'
7490 END IF
7491 IF (icelim > 0) THEN ! elimination
7492 nagb=nvgb ! total number of parameters
7493 napgrp=nvpgrp ! total number of parameter groups
7494 nfgb=nvgb-ncgb ! number of fit parameters
7495 nprecond(1)=0 ! number of constraints for preconditioner
7496 nprecond(2)=nfgb ! matrix size for preconditioner
7497 nprecond(3)=0 ! number of constraint blocks for preconditioner
7498 ELSE ! Lagrange multipliers
7499 nagb=nvgb+ncgb ! total number of parameters
7500 napgrp=nvpgrp+ncgb ! total number of parameter groups
7501 nfgb=nagb ! number of fit parameters
7502 nprecond(1)=ncgb ! number of constraints for preconditioner
7503 nprecond(2)=nvgb ! matrix size for preconditioner
7504 nprecond(3)=ncblck ! number of constraint blocks for preconditioner
7505 ENDIF
7506 noff8=int(nagb,mpl)*int(nagb-1,mpl)/2
7507
7508 ! all (variable) parameter groups
7509 length=napgrp+1
7510 CALL mpalloc(globalallindexgroups,length,'all parameter groups, 1. index')
7512 ivpgrp=0
7513 lvpgrp=-1
7514 DO i=1,ntgb
7515 ij=globalparlabelindex(2,i)
7516 IF (ij <= 0) cycle ! variable ?
7517 IF (globalparlabelindex(4,i) /= lvpgrp) THEN
7518 ivpgrp=ivpgrp+1
7519 globalallindexgroups(ivpgrp)=ij ! first index
7520 lvpgrp=globalparlabelindex(4,i)
7521 END IF
7522 END DO
7523 ! Lagrange multipliers
7524 IF (napgrp > nvpgrp) THEN
7525 DO jcgb=1, ncgb
7526 ivpgrp=ivpgrp+1
7527 globalallindexgroups(ivpgrp)=nvgb+jcgb
7528 END DO
7529 END IF
7531 ! from all (variable) parameters to group
7532 length=nagb
7533 CALL mpalloc(globalallpartogroup,length,'translation table all (var) par -> group')
7535 DO i=1,napgrp
7538 END DO
7539 END DO
7540 IF (icheck > 2) THEN
7541 print *
7542 print *, ' Variable parameter groups ', nvpgrp
7543 DO i=1,nvpgrp
7545 k=globalparlabelindex(4,itgbi) ! (total) group index
7547 globalparlabelindex(1,itgbi)
7548 END DO
7549 print *
7550 END IF
7551
7552 ! read all data files and add all variable index pairs -------------
7553
7554 IF (icheck > 1) CALL clbmap(ntpgrp+ncgrp)
7555
7556 IF(matsto == 2) THEN
7557 ! MINRES, sparse storage
7558 CALL clbits(napgrp,mreqpe,mhispe,msngpe,mextnd,ndimbi,nspc) ! get dimension for bit storage, encoding, precision info
7559 END IF
7560 IF(matsto == 3) THEN
7561 ! PARDISO, upper triangle (parameter groups) incl. rectangular part (constraints)
7562 CALL plbits(nvpgrp,nvgb,ncgb,ndimbi) ! get dimension for bit storage, global parameters and constraints
7563 END IF
7564
7565 IF (imonit /= 0) THEN
7566 length=ntgb
7567 CALL mpalloc(measindex,length,'measurement counter/index')
7568 measindex=0
7569 CALL mpalloc(measres,length,'measurement resolution')
7570 measres=0.0_mps
7571 lunmon=9
7572 CALL mvopen(lunmon,'millepede.mon')
7573 ENDIF
7574
7575 ! for checking appearance
7576 IF (icheck > 1) THEN
7577 length=5*(ntgb+ncgrp)
7578 CALL mpalloc(appearancecounter,length,'appearance statistics')
7580 length=ntgb
7581 CALL mpalloc(paircounter,length,'pair statistics')
7582 paircounter=0
7583 END IF
7584
7585 ! checking constraint goups
7586 IF (icheck > 0.AND. ncgrp > 0) THEN
7587 length=ncgrp
7588 CALL mpalloc(vecconsgroupcounts,length,'counter for constraint groups')
7590 CALL mpalloc(vecconsgrouplist,length,'constraint group list')
7591 CALL mpalloc(vecconsgroupindex,length,'constraint group index')
7592 vecconsgroupindex=0
7593 END IF
7594
7595 ! reading events===reading events===reading events===reading events=
7596 nrece =0 ! 'empty' records (no variable global parameters)
7597 nrecf =0 ! records with fixed global parameters
7598 naeqng=0 ! count number of equations (with global der.)
7599 naeqnf=0 ! count number of equations ( " , fixed)
7600 naeqna=0 ! all
7601 WRITE(lunlog,*) 'LOOP2: start event reading'
7602 ! monitoring for sparse matrix?
7603 irecmm=0
7604 IF (matsto == 2.AND.matmon /= 0) THEN
7605 nmatmo=0
7606 IF (matmon > 0) THEN
7607 nrecmm=matmon
7608 ELSE
7609 nrecmm=1
7610 END IF
7611 END IF
7612 DO k=1,3
7613 dstat(k)=0.0_mpd
7614 END DO
7615 ! define read buffer
7616 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7617 nwrd=nc31+1
7618 length=nwrd*mthrdr
7619 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7620 nwrd=nc31*10+2+ndimbuf
7621 length=nwrd*mthrdr
7622 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7623 CALL mpalloc(readbufferdatad,length,'read buffer, real')
7624 ! to read (old) float binary files
7625 length=(ndimbuf+2)*mthrdr
7626 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7627
7628 DO
7629 CALL peread(nr) ! read records
7630 CALL peprep(1) ! prepare records
7631 ioff=0
7632 DO ibuf=1,numreadbuffer ! buffer for current record
7633 jrec=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
7634 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7635 nrec=ifd(kfile)+jrec ! global record number
7636 ! Printout for DEBUG
7637 IF(nrec <= mdebug) THEN
7638 nda=0
7639 wrec =real(readbufferdatad(readbufferpointer(ibuf)-1),mps) ! weight
7640 WRITE(*,*) ' '
7641 WRITE(*,*) 'Record number ',nrec,' from file ',kfile
7642 IF (wgh /= 1.0) WRITE(*,*) ' weight ',wrec
7643 ist=readbufferpointer(ibuf)+1
7645 DO ! loop over measurements
7646 CALL isjajb(nst,ist,ja,jb,jsp)
7647 IF(ja == 0) EXIT
7648 nda=nda+1
7649 IF(nda > mdebg2) THEN
7650 IF(nda == mdebg2+1) WRITE(*,*) '... and more data'
7651 cycle
7652 END IF
7653 WRITE(*,*) ' '
7654 WRITE(*,*) nda, ' Measured value =',readbufferdatad(ja),' +- ',readbufferdatad(jb)
7655 WRITE(*,*) 'Local derivatives:'
7656 WRITE(*,107) (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
7657107 FORMAT(6(i3,g12.4))
7658 IF (jb < ist) THEN
7659 WRITE(*,*) 'Global derivatives:'
7660 WRITE(*,108) (globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
7661 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
7662108 FORMAT(3i11,g12.4)
7663 END IF
7664 IF(nda == 1) THEN
7665 WRITE(*,*) 'total_par_label __label__ var_par_index derivative'
7666 END IF
7667 END DO
7668 WRITE(*,*) ' '
7669 END IF
7670
7671 nagbn =0 ! count number of global derivatives
7672 nalcn =0 ! count number of local derivatives
7673 naeqn =0 ! count number of equations
7674 icgrp =0 ! count constraint groups
7675 maeqnf=naeqnf
7676 ist=readbufferpointer(ibuf)+1
7678 nwrd=nst-ist+1
7679 DO ! loop over measurements
7680 CALL isjajb(nst,ist,ja,jb,jsp)
7681 IF(ja == 0.AND.jb == 0) EXIT
7682 naeqn=naeqn+1
7683 naeqna=naeqna+1
7684 IF(ja /= 0) THEN
7685 IF (ist > jb) THEN
7686 naeqng=naeqng+1
7687 ! monitoring, group measurements, sum up entries and errors
7688 IF (imonit /= 0) THEN
7689 rerr =real(readbufferdatad(jb),mpd) ! the error
7690 ij=readbufferdatai(jb+1) ! index of first global parameter, used to group measurements
7691 measindex(ij)=measindex(ij)+1
7692 measres(ij)=measres(ij)+rerr
7693 END IF
7694 END IF
7695 nfixed=0
7696 DO j=1,ist-jb
7697 ij=readbufferdatai(jb+j) ! index of global parameter
7698 ! check appearance
7699 IF (icheck > 1) THEN
7700 joff = 5*(ij-1)
7701 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7702 IF (appearancecounter(joff+1) == 0) THEN
7703 appearancecounter(joff+1) = kfile
7704 appearancecounter(joff+2) = jrec ! (local) record number
7705 END IF
7706 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=appearancecounter(joff+5)+1
7707 appearancecounter(joff+3) = kfile
7708 appearancecounter(joff+4) = jrec ! (local) record number
7709 ! count pairs
7710 DO k=1,j
7712 END DO
7713 jcgrp=globalparcons(ij)
7714 ! correlate constraint groups with 'other' parameter groups
7715 DO k=1,j
7716 kcgrp=globalparcons(readbufferdatai(jb+k))
7717 IF (kcgrp == jcgrp) cycle
7718 IF (jcgrp > 0) CALL inbmap(ntpgrp+jcgrp,globalparlabelindex(4,readbufferdatai(jb+k)))
7719 IF (kcgrp > 0) CALL inbmap(ntpgrp+kcgrp,globalparlabelindex(4,ij))
7720 END DO
7721 END IF
7722 ! check constraint groups
7723 IF (icheck > 0.AND.ncgrp > 0) THEN
7724 k=globalparcons(ij) ! constraint group
7725 IF (k > 0) THEN
7726 icount=naeqn
7727 IF (mcount > 0) icount=1 ! count records
7728 IF (vecconsgroupindex(k) == 0) THEN
7729 ! add to list
7730 icgrp=icgrp+1
7731 vecconsgrouplist(icgrp)=k
7732 ! check appearance
7733 IF (icheck > 1) THEN
7734 joff = 5*(ntgb+k-1)
7735 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7736 IF (appearancecounter(joff+1) == 0) THEN
7737 appearancecounter(joff+1) = kfile
7738 appearancecounter(joff+2) = jrec ! (local) record number
7739 END IF
7740 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=&
7741 appearancecounter(joff+5)+1
7742 appearancecounter(joff+3) = kfile
7743 appearancecounter(joff+4) = jrec ! (local) record number
7744 END IF
7745 END IF
7746 IF (vecconsgroupindex(k) < icount) THEN
7747 ! count
7748 vecconsgroupindex(k)=icount
7750 END IF
7751 END IF
7752 END IF
7753
7754 ij=globalparlabelindex(2,ij) ! change to variable parameter
7755 IF(ij > 0) THEN
7756 ijn=backindexusage(ij) ! get index of index
7757 IF(ijn == 0) THEN ! not yet included
7758 nagbn=nagbn+1 ! count
7759 globalindexusage(nagbn)=ij ! store variable index
7760 backindexusage(ij)=nagbn ! store back index
7761 END IF
7762 ELSE
7763 nfixed=nfixed+1
7764 END IF
7765 END DO
7766 IF (nfixed > 0) naeqnf=naeqnf+1
7767 END IF
7768
7769 IF(ja /= 0.AND.jb /= 0) THEN
7770 DO j=1,jb-ja-1 ! local parameters
7771 ij=readbufferdatai(ja+j)
7772 nalcn=max(nalcn,ij)
7773 END DO
7774 END IF
7775 END DO
7776
7777 ! end-of-event
7778 IF (naeqnf > maeqnf) nrecf=nrecf+1
7779 irecmm=irecmm+1
7780 ! end-of-event-end-of-event-end-of-event-end-of-event-end-of-event-e
7781
7782 maxglobalpar=max(nagbn,maxglobalpar) ! maximum number of global parameters
7783 maxlocalpar=max(nalcn,maxlocalpar) ! maximum number of local parameters
7784 maxequations=max(naeqn,maxequations) ! maximum number of equations
7785
7786 ! sample statistics for caching
7787 dstat(1)=dstat(1)+real((nwrd+2)*2,mpd) ! record size
7788 dstat(2)=dstat(2)+real(nagbn+2,mpd) ! indices,
7789 dstat(3)=dstat(3)+real(nagbn*nagbn+nagbn,mpd) ! data for MUPDAT
7790
7791 ! clear constraint groups index
7792 DO k=1, icgrp
7793 vecconsgroupindex(vecconsgrouplist(k))=0
7794 END DO
7795
7796 CALL sort1k(globalindexusage,nagbn) ! sort global par.
7797
7798 IF (nagbn == 0) THEN
7799 nrece=nrece+1
7800 ELSE
7801 ! update parameter range
7804 ENDIF
7805
7806 ! overwrite read buffer with lists of global labels
7807 ioff=ioff+1
7808 readbufferpointer(ibuf)=ioff
7809 readbufferdatai(ioff)=ioff+nagbn
7810 joff=ioff
7811 lvpgrp=-1
7812 DO i=1,nagbn ! reset global index array, store parameter groups
7813 iext=globalindexusage(i)
7814 backindexusage(iext)=0
7815 ivpgrp=globalallpartogroup(iext)
7816 !ivpgrp=iext
7817 IF (ivpgrp /= lvpgrp) THEN
7818 joff=joff+1
7819 readbufferdatai(joff)=ivpgrp
7820 lvpgrp=ivpgrp
7821 END IF
7822 END DO
7823 readbufferdatai(ioff)=joff
7824 ioff=joff
7825
7826 END DO
7827 ioff=0
7828
7829 IF (matsto == 3) THEN
7830 !$OMP PARALLEL &
7831 !$OMP DEFAULT(PRIVATE) &
7832 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7833 iproc=0
7834 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7835 DO ibuf=1,numreadbuffer
7836 ist=readbufferpointer(ibuf)+1
7838 DO i=ist,nst ! store all combinations
7839 iext=readbufferdatai(i) ! variable global index
7840 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct column per thread
7841 DO l=i,nst
7842 jext=readbufferdatai(l)
7843 CALL inbits(iext,jext,1) ! save space
7844 END DO
7845 !$ ENDIF
7846 END DO
7847 END DO
7848 !$OMP END PARALLEL
7849 END IF
7850 IF (matsto == 2) THEN
7851 !$OMP PARALLEL &
7852 !$OMP DEFAULT(PRIVATE) &
7853 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7854 iproc=0
7855 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7856 DO ibuf=1,numreadbuffer
7857 ist=readbufferpointer(ibuf)+1
7859 DO i=ist,nst ! store all combinations
7860 iext=readbufferdatai(i) ! variable global index
7861 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct rows per thread
7862 DO l=ist,i
7863 jext=readbufferdatai(l)
7864 CALL inbits(iext,jext,1) ! save space
7865 END DO
7866 !$ ENDIF
7867 END DO
7868 END DO
7869 !$OMP END PARALLEL
7870 ! monitoring
7871 IF (matmon /= 0.AND. &
7872 (irecmm >= nrecmm.OR.irecmm == mxrec)) THEN
7873 IF (nmatmo == 0) THEN
7874 WRITE(*,*)
7875 WRITE(*,*) 'Monitoring of sparse matrix construction'
7876 WRITE(*,*) ' records ........ off-diagonal elements ', &
7877 '....... compression memory'
7878 WRITE(*,*) ' non-zero used(double) used', &
7879 '(float) [%] [GB]'
7880 END IF
7881 nmatmo=nmatmo+1
7882 CALL ckbits(globalallindexgroups,ndimsa)
7883 gbc=1.0e-9*real((mpi*ndimsa(2)+mpd*ndimsa(3)+mps*ndimsa(4))/mpi*(bit_size(1_mpi)/8),mps) ! GB compressed
7884 gbu=1.0e-9*real(((mpi+mpd)*(ndimsa(3)+ndimsa(4)))/mpi*(bit_size(1_mpi)/8),mps) ! GB uncompressed
7885 cpr=100.0*gbc/gbu
7886 WRITE(*,1177) irecmm,ndimsa(1),ndimsa(3),ndimsa(4),cpr,gbc
78871177 FORMAT(i9,3i13,f10.2,f11.6)
7888 DO WHILE(irecmm >= nrecmm)
7889 IF (matmon > 0) THEN
7890 nrecmm=nrecmm+matmon
7891 ELSE
7892 nrecmm=nrecmm*2
7893 END IF
7894 END DO
7895 END IF
7896
7897 END IF
7898
7899 IF (nr <= 0) EXIT ! next block of events ?
7900 END DO
7901 ! release read buffer
7906
7907 WRITE(lunlog,*) 'LOOP2: event reading ended - end of data'
7908 DO k=1,3
7909 dstat(k)=dstat(k)/real(nrec,mpd)
7910 END DO
7911 ! end=of=data=end=of=data=end=of=data=end=of=data=end=of=data=end=of
7912
7913 IF (icheck > 0.AND. ncgrp > 0) THEN
7914 CALL mpdealloc(vecconsgroupindex)
7915 CALL mpdealloc(vecconsgrouplist)
7916 END IF
7917
7918 IF (icheck > 1) THEN
7920 END IF
7921 IF (icheck > 3) THEN
7922 length=ntpgrp+ncgrp
7923 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
7924 print *
7925 print *, ' Total parameter groups pairs', ntpgrp
7926 DO i=1,ntpgrp
7927 itgbi=globaltotindexgroups(1,i)
7928 CALL ggbmap(i,npair,vecpairedpargroups)
7929 k=globalparlabelindex(4,itgbi) ! (total) group index
7930 print *, i, itgbi, globalparlabelindex(1,itgbi), npair, ':', vecpairedpargroups(:npair)
7931 END DO
7932 print *
7933 END IF
7934
7935 ! check constraints
7936 IF(matsto == 2) THEN
7937
7938 ! constraints and index pairs with Lagrange multiplier
7939 inc=max(mreqpe, msngpe+1) ! keep constraints in double precision
7940
7941 ! loop over (sorted) constraints
7942 DO jcgb=1,ncgb
7943 icgb=matconssort(3,jcgb) ! unsorted constraint index
7944 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
7945 label=listconstraints(i)%label
7946 itgbi=inone(label)
7947 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
7948 IF(ij > 0 .AND. nagb > nvgb) THEN
7950 END IF
7951 END DO
7952 END DO
7953 END IF
7954 IF(matsto == 3) THEN
7955 ! loop over (sorted) constraints
7956 DO jcgb=1,ncgb
7957 icgb=matconssort(3,jcgb) ! unsorted constraint index
7958 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
7959 label=listconstraints(i)%label
7960 itgbi=inone(label)
7961 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
7962 IF(ij > 0.AND.listconstraints(i)%value /= 0.0_mpd) THEN
7963 ! non-zero coefficient
7964 CALL irbits(ij,jcgb)
7965 END IF
7966 END DO
7967 END DO
7968 END IF
7969
7970 ! check measurements
7971 IF(matsto == 2 .OR. matsto == 3) THEN
7972 ! measurements - determine index-pairs
7973
7974 i=1
7975 DO WHILE (i <= lenmeasurements)
7976 i=i+2
7977 ! loop over label/factor pairs
7978 ia=i
7979 DO
7980 i=i+1
7981 IF(i > lenmeasurements) EXIT
7982 IF(listmeasurements(i)%label < 0) EXIT
7983 END DO
7984 ib=i-1
7985
7986 DO j=ia,ib
7987 itgbij=inone(listmeasurements(j)%label) ! total parameter index
7988 ! first index
7989 ivgbij=0
7990 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
7991 DO k=ia,j
7992 itgbik=inone(listmeasurements(k)%label) ! total parameter index
7993 ! second index
7994 ivgbik=0
7995 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
7996 IF(ivgbij > 0.AND.ivgbik > 0) THEN
7998 IF (mprint > 1) WRITE(*,*) 'add index pair ',ivgbij,ivgbik
7999 END IF
8000 END DO
8001 END DO
8002
8003 END DO
8004 ELSE
8005 ! more checks for block diagonal structure
8006 ! loop over measurements
8007 i=1
8008 DO WHILE (i <= lenmeasurements)
8009 i=i+2
8010 ! loop over label/factor pairs
8011 ia=i
8012 DO
8013 i=i+1
8014 IF(i > lenmeasurements) EXIT
8015 IF(listmeasurements(i)%label < 0) EXIT
8016 END DO
8017 ib=i-1
8018 ij1=nvgb
8019 ijn=1
8020 DO j=ia,ib
8021 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8022 ! first index
8023 ij=0
8024 IF(itgbij /= 0) ij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8025 IF (ij > 0) THEN
8026 ij1=min(ij1,ij)
8027 ijn=max(ijn,ij)
8028 END IF
8029 END DO
8030 globalindexranges(ij1)=max(globalindexranges(ij1),ijn)
8031 END DO
8032
8033 END IF
8034
8035 nummeas=0 ! number of measurement groups
8036 IF (imonit /= 0) THEN
8037 DO i=1,ntgb
8038 IF (measindex(i) > 0) THEN
8040 measres(i) = measres(i)/real(measindex(i),mpd)
8041 measindex(i) = nummeas
8042 END IF
8043 END DO
8044 length=nummeas*mthrd*measbins
8045 CALL mpalloc(meashists,length,'measurement counter')
8046 END IF
8047
8048 ! check for block diagonal structure, count blocks
8049 npblck=0
8050 l=0
8051 DO i=1,nvgb
8052 IF (i > l) npblck=npblck+1
8053 l=max(l,globalindexranges(i))
8054 globalindexranges(i)=npblck ! block number
8055 END DO
8056
8057 length=npblck+1; rows=2
8058 ! parameter blocks
8059 CALL mpalloc(matparblockoffsets,rows,length,'global parameter blocks (I)')
8061 CALL mpalloc(vecparblockconoffsets,length,'global parameter blocks (I)')
8063 ! fill matParBlocks
8064 l=0
8065 DO i=1,nvgb
8066 IF (globalindexranges(i) > l) THEN
8067 l=globalindexranges(i) ! block number
8068 matparblockoffsets(1,l)=i-1 ! block offset
8069 END IF
8070 END DO
8072 nparmx=0
8073 DO i=1,npblck
8074 rows=matparblockoffsets(1,i+1)-matparblockoffsets(1,i)
8075 nparmx=max(nparmx,int(rows,mpi))
8076 END DO
8077
8078 ! connect constraint blocks
8079 DO i=1,ncblck
8080 ia=matconsblocks(2,i) ! first parameter in constraint block
8081 IF (ia > matconsblocks(3,i)) cycle
8082 ib=globalindexranges(ia) ! parameter block number
8083 matparblockoffsets(2,ib+1)=i
8084 END DO
8085
8086 ! use diagonal block matrix storage?
8087 IF (npblck > 1) THEN
8088 IF (icheck > 0) THEN
8089 WRITE(*,*)
8090 DO i=1,npblck
8091 ia=matparblockoffsets(1,i)
8092 ib=matparblockoffsets(1,i+1)
8093 ja=matparblockoffsets(2,i)
8094 jb=matparblockoffsets(2,i+1)
8097 WRITE(*,*) ' Parameter block', i, ib-ia, jb-ja, labelf, labell
8098 ENDDO
8099 ENDIF
8100 WRITE(lunlog,*)
8101 WRITE(lunlog,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8102 WRITE(*,*)
8103 WRITE(*,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8104 IF ((metsol == 1.OR.metsol == 3.OR.metsol>=7).AND.nagb == nvgb) THEN
8105 WRITE(*,*) 'Using block diagonal storage mode'
8106 ELSE
8107 ! keep single block = full matrix
8108 DO i=1,2
8110 END DO
8111 npblck=1
8112 DO i=1,nvgb
8114 END DO
8115 END IF
8116 END IF
8117
8118 ! print numbers ----------------------------------------------------
8119
8120 IF (nagb >= 65536) THEN
8121 noff=int(noff8/1000,mpi)
8122 ELSE
8123 noff=int(noff8,mpi)
8124 END IF
8125 ndgn=0
8126 matwords=0
8127 IF(matsto == 2) THEN
8128 ihis=0
8129 IF (mhispe > 0) THEN
8130 ihis=15
8131 CALL hmpdef(ihis,0.0,real(mhispe,mps), 'NDBITS: #off-diagonal elements')
8132 END IF
8133 length=(napgrp+1)*nspc
8134 CALL mpalloc(sparsematrixoffsets,two,length, 'sparse matrix row offsets')
8136 ndgn=ndimsa(3)+ndimsa(4) ! actual number of off-diagonal elements
8137 matwords=ndimsa(2)+length*4 ! size of sparsity structure
8138
8139 IF (mhispe > 0) THEN
8140 IF (nhistp /= 0) CALL hmprnt(ihis)
8141 CALL hmpwrt(ihis)
8142 END IF
8143 END IF
8144 IF (matsto == 3) THEN
8145 length=nagb+1
8146 CALL mpalloc(csr3rowoffsets,length, 'sparse matrix row offsets (CSR3)')
8147 IF (mpdbsz > 1) THEN
8148 ! BSR3, check (for optimal) block size
8149 mbwrds=0
8150 DO i=1,mpdbsz
8151 npdblk=(nagb-1)/ipdbsz(i)+1
8152 length=int(npdblk,mpl)
8153 CALL mpalloc(vecblockcounts,length, 'sparse matrix row offsets (CSR3)')
8154 CALL pbsbits(globalallindexgroups,ipdbsz(i),nnzero,nblock,vecblockcounts)
8155 nbwrds=2*int(nblock,mpl)*int(ipdbsz(i)*ipdbsz(i)+1,mpl) ! number of words needed
8156 IF ((i == 1).OR.(nbwrds < mbwrds)) THEN
8157 matbsz=ipdbsz(i)
8158 mbwrds=nbwrds
8159 csr3rowoffsets(1)=1
8160 DO k=1,npdblk
8161 csr3rowoffsets(k+1)=csr3rowoffsets(k)+vecblockcounts(k)
8162 END DO
8163 END IF
8164 CALL mpdealloc(vecblockcounts)
8165 END DO
8166 ELSE
8167 ! CSR3
8169 !csr3RowOffsets(nvgb+2:)=csr3RowOffsets(nvgb+1) ! Lagrange multipliers (empty)
8170 END IF
8171 END IF
8172
8173 nagbn=maxglobalpar ! max number of global parameters in one event
8174 nalcn=maxlocalpar ! max number of local parameters in one event
8175 naeqn=maxequations ! max number of equations in one event
8178 ! matrices for event matrices
8179 ! split up cache
8180 IF (fcache(2) == 0.0) THEN ! from data (DSTAT)
8181 fcache(1)=real(dstat(1),mps)*fcache(1) ! leave some part free for fluctuations
8182 fcache(2)=real(dstat(2),mps)
8183 fcache(3)=real(dstat(3),mps)
8184 END IF
8185 fsum=fcache(1)+fcache(2)+fcache(3)
8186 DO k=1,3
8187 fcache(k)=fcache(k)/fsum
8188 END DO
8189 ncachr=nint(real(ncache,mps)*fcache(1),mpi) ! read cache
8190 ! define read buffer
8191 nc31=ncachr/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
8192 nwrd=nc31+1
8193 length=nwrd*mthrdr
8194 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
8195 nwrd=nc31*10+2+ndimbuf
8196 length=nwrd*mthrdr
8197 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
8198 CALL mpalloc(readbufferdatad,length,'read buffer, real')
8199 ! to read (old) float binary files
8200 length=(ndimbuf+2)*mthrdr
8201 CALL mpalloc(readbufferdataf,length,'read buffer, float')
8202
8203 ncachi=nint(real(ncache,mps)*fcache(2),mpi) ! index cache
8204 ncachd=ncache-ncachr-ncachi ! data cache
8205 nggd=(nagbn*nagbn+nagbn)/2+ncachd/(2*mthrd) ! number of double
8206 nggi=2+nagbn+ncachi/mthrd ! number of ints
8207 length=nagbn*mthrd
8208 CALL mpalloc(globalindexusage,length, 'global parameters (dim =max/event)')
8209 length=nvgb*mthrd
8210 CALL mpalloc(backindexusage,length,'global variable-index array')
8212 length=nagbn*nalcn
8213 CALL mpalloc(localglobalmatrix,length,'local/global matrix, content')
8214 CALL mpalloc(localglobalmap,length,'local/global matrix, map (counts)')
8215 length=2*nagbn*nalcn+nagbn+nalcn+1
8216 CALL mpalloc(localglobalstructure,length,'local/global matrix, (sparsity) structure')
8217 length=nggd*mthrd
8218 CALL mpalloc(writebufferupdates,length,'symmetric update matrices')
8219 writebufferheader(-1)=nggd ! number of words per thread
8220 writebufferheader(-2)=(nagbn*nagbn+nagbn)/2 ! min free (double) words
8221 length=nggi*mthrd
8222 CALL mpalloc(writebufferindices,length,'symmetric update matrix indices')
8223 rows=9; cols=mthrd
8224 CALL mpalloc(writebufferinfo,rows,cols,'write buffer status (I)')
8225 rows=2; cols=mthrd
8226 CALL mpalloc(writebufferdata,rows,cols,'write buffer status (F)')
8227 writebufferheader(1)=nggi ! number of words per thread
8228 writebufferheader(2)=nagbn+3 ! min free words
8229
8230 ! print all relevant dimension parameters
8231
8232 DO lu=6,8,2 ! unit 6 and 8
8233
8234 WRITE(lu,*) ' '
8235 WRITE(lu,101) 'NTGB',ntgb,'total number of parameters'
8236 WRITE(lu,102) '(all parameters, appearing in binary files)'
8237 WRITE(lu,101) 'NVGB',nvgb,'number of variable parameters'
8238 WRITE(lu,102) '(appearing in fit matrix/vectors)'
8239 WRITE(lu,101) 'NAGB',nagb,'number of all parameters'
8240 WRITE(lu,102) '(including Lagrange multiplier or reduced)'
8241 WRITE(lu,101) 'NTPGRP',ntpgrp,'total number of parameter groups'
8242 WRITE(lu,101) 'NVPGRP',nvpgrp,'number of variable parameter groups'
8243 WRITE(lu,101) 'NFGB',nfgb,'number of fit parameters'
8244 IF(metsol >= 4.AND. metsol <7) THEN ! band matrix as MINRES preconditioner
8245 WRITE(lu,101) 'MBANDW',mbandw,'band width of preconditioner matrix'
8246 WRITE(lu,102) '(if <0, no preconditioner matrix)'
8247 END IF
8248 IF (nagb >= 65536) THEN
8249 WRITE(lu,101) 'NOFF/K',noff,'max number of off-diagonal elements'
8250 ELSE
8251 WRITE(lu,101) 'NOFF',noff,'max number of off-diagonal elements'
8252 END IF
8253 IF(ndgn /= 0) THEN
8254 IF (nagb >= 65536) THEN
8255 WRITE(lu,101) 'NDGN/K',ndgn/1000,'actual number of off-diagonal elements'
8256 ELSE
8257 WRITE(lu,101) 'NDGN',ndgn,'actual number of off-diagonal elements'
8258 ENDIF
8259 ENDIF
8260 WRITE(lu,101) 'NCGB',ncgb,'number of constraints'
8261 WRITE(lu,101) 'NAGBN',nagbn,'max number of global parameters in an event'
8262 WRITE(lu,101) 'NALCN',nalcn,'max number of local parameters in an event'
8263 WRITE(lu,101) 'NAEQN',naeqn,'max number of equations in an event'
8264 IF (mprint > 1) THEN
8265 WRITE(lu,101) 'NAEQNA',naeqna,'number of equations'
8266 WRITE(lu,101) 'NAEQNG',naeqng, &
8267 'number of equations with global parameters'
8268 WRITE(lu,101) 'NAEQNF',naeqnf, &
8269 'number of equations with fixed global parameters'
8270 WRITE(lu,101) 'NRECF',nrecf, &
8271 'number of records with fixed global parameters'
8272 END IF
8273 IF (nrece > 0) THEN
8274 WRITE(lu,101) 'NRECE',nrece, &
8275 'number of records without variable parameters'
8276 END IF
8277 IF (ncache > 0) THEN
8278 WRITE(lu,101) 'NCACHE',ncache,'number of words for caching'
8279 WRITE(lu,111) (fcache(k)*100.0,k=1,3)
8280111 FORMAT(22x,'cache splitting ',3(f6.1,' %'))
8281 END IF
8282 WRITE(lu,*) ' '
8283
8284 WRITE(lu,*) ' '
8285 WRITE(lu,*) 'Solution method and matrix-storage mode:'
8286 IF(metsol == 1) THEN
8287 WRITE(lu,*) ' METSOL = 1: matrix inversion'
8288 ELSE IF(metsol == 2) THEN
8289 WRITE(lu,*) ' METSOL = 2: diagonalization'
8290 ELSE IF(metsol == 3) THEN
8291 WRITE(lu,*) ' METSOL = 3: decomposition'
8292 ELSE IF(metsol == 4) THEN
8293 WRITE(lu,*) ' METSOL = 4: MINRES (rtol', mrestl,')'
8294 ELSE IF(metsol == 5) THEN
8295 WRITE(lu,*) ' METSOL = 5: MINRES-QLP (rtol', mrestl,')'
8296 ELSE IF(metsol == 6) THEN
8297 WRITE(lu,*) ' METSOL = 6: GMRES'
8298#ifdef LAPACK64
8299 ELSE IF(metsol == 7) THEN
8300 WRITE(lu,*) ' METSOL = 7: LAPACK factorization'
8301 ELSE IF(metsol == 8) THEN
8302 WRITE(lu,*) ' METSOL = 8: LAPACK factorization'
8303#ifdef PARDISO
8304 ELSE IF(metsol == 9) THEN
8305 WRITE(lu,*) ' METSOL = 9: Intel oneMKL PARDISO'
8306#endif
8307#endif
8308 END IF
8309 WRITE(lu,*) ' with',mitera,' iterations'
8310 IF(matsto == 0) THEN
8311 WRITE(lu,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
8312 ELSE IF(matsto == 1) THEN
8313 WRITE(lu,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
8314 ELSE IF(matsto == 2) THEN
8315 WRITE(lu,*) ' MATSTO = 2: sparse matrix (custom)'
8316 ELSE IF(matsto == 3) THEN
8317 IF (matbsz < 2) THEN
8318 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
8319 ELSE
8320 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
8321 WRITE(lu,*) ' block size', matbsz
8322 END IF
8323 END IF
8324 IF(npblck > 1) THEN
8325 WRITE(lu,*) ' block diagonal with', npblck, ' blocks'
8326 END IF
8327 IF(mextnd>0) WRITE(lu,*) ' with extended storage'
8328 IF(dflim /= 0.0) THEN
8329 WRITE(lu,103) 'Convergence assumed, if expected dF <',dflim
8330 END IF
8331 IF(ncgb > 0) THEN
8332 IF(nfgb < nvgb) THEN
8333 IF (icelim > 1) THEN
8334 WRITE(lu,*) 'Constraints handled by elimination with LAPACK'
8335 ELSE
8336 WRITE(lu,*) 'Constraints handled by elimination'
8337 END IF
8338 ELSE
8339 WRITE(lu,*) 'Constraints handled by Lagrange multipliers'
8340 ENDIF
8341 END IF
8342
8343 END DO ! print loop
8344
8345 IF(nalcn == 0) THEN
8346 CALL peend(28,'Aborted, no local parameters')
8347 stop 'LOOP2: stopping due to missing local parameters'
8348 END IF
8349
8350 ! Wolfe conditions
8351
8352 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8353 IF(wolfc1 == 0.0) wolfc1=1.0e-4
8354 IF(wolfc2 == 0.0) wolfc2=0.9
8355 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8356 IF(wolfc1 <= 0.0) wolfc1=1.0e-4
8357 IF(wolfc2 >= 1.0) wolfc2=0.9
8358 IF(wolfc1 > wolfc2) THEN ! exchange
8359 wolfc3=wolfc1
8361 wolfc2=wolfc3
8362 ELSE
8363 wolfc1=1.0e-4
8364 wolfc2=0.9
8365 END IF
8366 WRITE(*,105) wolfc1,wolfc2
8367 WRITE(lun,105) wolfc1,wolfc2
8368105 FORMAT(' Constants C1, C2 for Wolfe conditions:',g12.4,', ',g12.4)
8369
8370 ! prepare matrix and gradient storage ------------------------------
837132 matsiz=0 ! number of words for double, single precision storage
8372 IF (matsto == 3) THEN ! sparse matrix (CSR3, BSR3)
8373 npdblk=(nagb-1)/matbsz+1 ! number of row blocks
8374 length=csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
8375 matsiz(1)=length*int(matbsz*matbsz,mpl)
8376 matwords=(length+nagb+1)*2 ! size of sparsity structure
8377 CALL mpalloc(csr3columnlist,length,'sparse matrix column list (CSR3)')
8378 IF (matbsz > 1) THEN
8380 ELSE
8382 END IF
8383 ELSE IF (matsto == 2) THEN ! sparse matrix (custom)
8384 matsiz(1)=ndimsa(3)+nagb
8385 matsiz(2)=ndimsa(4)
8386 CALL mpalloc(sparsematrixcolumns,ndimsa(2),'sparse matrix column list')
8388 CALL anasps ! analyze sparsity structure
8389 ELSE ! full or unpacked matrix, optional block diagonal
8390 length=nagb
8391 CALL mpalloc(globalrowoffsets,length,'global row offsets (full or unpacked (block) storage)')
8392 ! loop over blocks (multiple blocks only with elimination !)
8394 DO i=1,npblck
8395 ipoff=matparblockoffsets(1,i)
8396 icboff=matparblockoffsets(2,i) ! constraint block offset
8397 icblst=matparblockoffsets(2,i+1) ! constraint block offset
8398 npar=matparblockoffsets(1,i+1)-ipoff ! size of block (number of parameters)
8399 IF (icblst > icboff) THEN
8400 ncon=matconsblocks(1,icblst+1)-matconsblocks(1,icboff+1) ! number of constraints in (parameter) block
8401 ELSE
8402 ncon=0
8403 ENDIF
8405 nall = npar; IF (icelim <= 0) nall=npar+ncon ! add Lagrange multipliers
8406 DO k=1,nall
8407 globalrowoffsets(ipoff+k)=matsiz(1)-ipoff
8408 IF (matsto == 1) THEN
8409 matsiz(1)=matsiz(1)+k ! full ('triangular')
8410 ELSE
8411 matsiz(1)=matsiz(1)+nall ! unpacked ('quadratic')
8412 END IF
8413 END DO
8414 END DO
8415 END IF
8416 matwords=matwords+matsiz(1)*2+matsiz(2) ! #words for matrix storage
8417
8418 CALL feasma ! prepare constraint matrices
8419
8420 IF (icheck <= 0) CALL vmprep(matsiz) ! prepare matrix and gradient storage
8421 WRITE(*,*) ' '
8422 IF (matwords < 250000) THEN
8423 WRITE(*,*) 'Size of global matrix: < 1 MB'
8424 ELSE
8425 WRITE(*,*) 'Size of global matrix:',int(real(matwords,mps)*4.0e-6,mpi),' MB'
8426 ENDIF
8427 ! print chi^2 cut tables
8428
8429 ndfmax=naeqn-1
8430 WRITE(lunlog,*) ' '
8431 WRITE(lunlog,*) ' Cut values of Chi^2/Ndf and Chi2,'
8432 WRITE(lunlog,*) ' corresponding to 2 and 3 standard deviations'
8433 WRITE(lunlog,*) ' Ndf Chi^2/Ndf(2) Chi^2(2) ', &
8434 ' Chi^2/Ndf(3) Chi^2(3)'
8435 ndf=0
8436 DO
8437 IF(ndf > naeqn) EXIT
8438 IF(ndf < 10) THEN
8439 ndf=ndf+1
8440 ELSE IF(ndf < 20) THEN
8441 ndf=ndf+2
8442 ELSE IF(ndf < 100) THEN
8443 ndf=ndf+5
8444 ELSE IF(ndf < 200) THEN
8445 ndf=ndf+10
8446 ELSE
8447 EXIT
8448 END IF
8449 chin2=chindl(2,ndf)
8450 chin3=chindl(3,ndf)
8451 WRITE(lunlog,106) ndf,chin2,chin2*real(ndf,mps),chin3, chin3*real(ndf,mps)
8452 END DO
8453
8454 WRITE(lunlog,*) 'LOOP2: ending'
8455 WRITE(lunlog,*) ' '
8456 ! warnings from check input mode
8457 IF (icheck > 0) THEN
8458 IF (ncgbe /= 0) THEN
8459 WRITE(*,199) ' '
8460 WRITE(*,199) ' '
8461 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8462 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8463 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8464 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8465 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8466 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8467 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8468 WRITE(*,199) ' '
8469 WRITE(*,*) ' Number of empty constraints =',abs(ncgbe), ', should be 0'
8470 WRITE(*,*) ' => please check constraint definition, mille data'
8471 WRITE(*,199) ' '
8472 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8473 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8474 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8475 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8476 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8477 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8478 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8479 WRITE(*,199) ' '
8480 END IF
8481 END IF
8482 CALL mend
8483101 FORMAT(1x,a8,' =',i14,' = ',a)
8484102 FORMAT(22x,a)
8485103 FORMAT(1x,a,g12.4)
8486106 FORMAT(i6,2(3x,f9.3,f12.1,3x))
8487199 FORMAT(7x,a)
8488END SUBROUTINE loop2
8489
8494SUBROUTINE monres
8495 USE mpmod
8496 USE mpdalc
8497
8498 IMPLICIT NONE
8499 INTEGER(mpi) :: i
8500 INTEGER(mpi) :: ij
8501 INTEGER(mpi) :: imed
8502 INTEGER(mpi) :: j
8503 INTEGER(mpi) :: k
8504 INTEGER(mpi) :: nent
8505 INTEGER(mpi), DIMENSION(measBins) :: isuml ! location
8506 INTEGER(mpi), DIMENSION(measBins) :: isums ! scale
8507 REAL(mps) :: amed
8508 REAL(mps) :: amad
8509
8510 INTEGER(mpl) :: ioff
8511 LOGICAL :: lfirst
8512 SAVE
8513 DATA lfirst /.true./
8514
8515 ! combine data from threads
8516 ioff=0
8517 DO i=2,mthrd
8518 ioff=ioff+measbins*nummeas
8519 DO j=1,measbins*nummeas
8520 meashists(j)=meashists(j)+meashists(ioff+j)
8521 END DO
8522 END DO
8523
8524 IF (lfirst) THEN
8525 IF (imonmd == 0) THEN
8526 WRITE(lunmon,'(A)') '*** Normalized residuals grouped by first global label (per local fit cycle) ***'
8527 ELSE
8528 WRITE(lunmon,'(A)') '*** Pulls grouped by first global label (per local fit cycle) ***'
8529 ENDIF
8530 WRITE(lunmon,'(A)') '! LFC Label Entries Median RMS(MAD) <error>'
8531 lfirst=.false.
8532 END IF
8533
8534 !$POMP INST BEGIN(monres)
8535 ! analyze histograms
8536 ioff=0
8537 DO i=1,ntgb
8538 IF (measindex(i) > 0) THEN
8539 isuml=0
8540 ! sum up content
8541 isuml(1)=meashists(ioff+1)
8542 DO j=2,measbins
8543 isuml(j)=isuml(j-1)+meashists(ioff+j)
8544 END DO
8545 nent=isuml(measbins)
8546 IF (nent > 0) THEN
8547 ! get median (for location)
8548 DO j=2,measbins
8549 IF (2*isuml(j) > nent) EXIT
8550 END DO
8551 imed=j
8552 amed=real(j,mps)
8553 IF (isuml(j) > isuml(j-1)) amed=amed+real(nent-2*isuml(j-1),mps)/real(2*isuml(j)-2*isuml(j-1),mps)
8554 amed=real(measbinsize,mps)*(amed-real(measbins/2,mps))
8555 ! sum up differences
8556 isums = 0
8557 DO j=imed,measbins
8558 k=j-imed+1
8559 isums(k)=isums(k)+meashists(ioff+j)
8560 END DO
8561 DO j=imed-1,1,-1
8562 k=imed-j
8563 isums(k)=isums(k)+meashists(ioff+j)
8564 END DO
8565 DO j=2, measbins
8566 isums(j)=isums(j)+isums(j-1)
8567 END DO
8568 ! get median (for scale)
8569 DO j=2,measbins
8570 IF (2*isums(j) > nent) EXIT
8571 END DO
8572 amad=real(j-1,mps)
8573 IF (isums(j) > isums(j-1)) amad=amad+real(nent-2*isums(j-1),mps)/real(2*isums(j)-2*isums(j-1),mps)
8574 amad=real(measbinsize,mps)*amad
8575 ELSE
8576 amed=0.0
8577 amad=0.0
8578 END IF
8579 ij=globalparlabelindex(1,i)
8580 WRITE(lunmon,110) nloopn, ij, nent, amed, amad*1.4826, real(measres(i),mps)
8581 !
8582 ioff=ioff+measbins
8583 END IF
8584 END DO
8585 !$POMP INST END(monres)
8586
8587110 FORMAT(i5,2i10,3g14.5)
8588END SUBROUTINE monres
8589
8590
8594
8595SUBROUTINE vmprep(msize)
8596 USE mpmod
8597 USE mpdalc
8598
8599 IMPLICIT NONE
8600 INTEGER(mpi) :: i
8601 INTEGER(mpi) :: ib
8602 INTEGER(mpi) :: ioff
8603 INTEGER(mpi) :: ipar0
8604 INTEGER(mpi) :: ncon
8605 INTEGER(mpi) :: npar
8606 INTEGER(mpi) :: nextra
8607#ifdef LAPACK64
8608 INTEGER :: nbopt, nboptx, ILAENV
8609#endif
8610 !
8611 INTEGER(mpl), INTENT(IN) :: msize(2)
8612
8613 INTEGER(mpl) :: length
8614 INTEGER(mpl) :: nwrdpc
8615 INTEGER(mpl), PARAMETER :: three = 3
8616
8617 SAVE
8618 ! ...
8619 ! Vector/matrix storage
8620 length=nagb*mthrd
8621 CALL mpalloc(globalvector,length,'rhs vector') ! double precision vector
8622 CALL mpalloc(globalcounter,length,'rhs counter') ! integer vector
8624 length=naeqn*mthrd
8625 CALL mpalloc(localcorrections,length,'residual vector of one record')
8626 CALL mpalloc(localequations,three,length,'mesurements indices (ISJAJB) of one record')
8627 length=nalcn*nalcn
8628 CALL mpalloc(aux,length,' local fit scratch array: aux')
8629 CALL mpalloc(vbnd,length,' local fit scratch array: vbnd')
8630 CALL mpalloc(vbdr,length,' local fit scratch array: vbdr')
8631 length=((nalcn+1)*nalcn)/2
8632 CALL mpalloc(clmat,length,' local fit matrix: clmat')
8633 CALL mpalloc(vbk,length,' local fit scratch array: vbk')
8634 length=nalcn
8635 CALL mpalloc(blvec,length,' local fit vector: blvec')
8636 CALL mpalloc(vzru,length,' local fit scratch array: vzru')
8637 CALL mpalloc(scdiag,length,' local fit scratch array: scdiag')
8638 CALL mpalloc(scflag,length,' local fit scratch array: scflag')
8639 CALL mpalloc(ibandh,2*length,' local fit band width hist.: ibandh')
8640
8641 CALL mpalloc(globalmatd,msize(1),'global matrix (D)' )
8642 CALL mpalloc(globalmatf,msize(2),'global matrix (F)')
8643
8644 mszpcc=0
8645 IF(metsol >= 4.AND.metsol < 7.AND. mbandw >= 0) THEN ! GMRES/MINRES algorithms
8646 ! array space is:
8647 ! variable-width band matrix or diagonal matrix for parameters
8648 ! followed by symmetric matrix for constraints
8649 ! followed by rectangular matrix for constraints
8650 nwrdpc=0
8651 ncon=nagb-nvgb ! number of Lagrange multipliers
8652 ! constraint block info
8653 length=4*ncblck; IF(ncon == 0) length=0
8654 CALL mpalloc(blockprecond,length,'preconditioner: constraint blocks')
8655 length=ncon
8656 CALL mpalloc(offprecond,length,'preconditioner: constraint offsets')
8657 !END IF
8658 ! variable-width band matrix ?
8659 IF(mbandw > 0) THEN
8660 length=nagb
8661 CALL mpalloc(indprecond,length,'pointer-array variable-band matrix')
8662 nwrdpc=nwrdpc+length
8663 DO i=1,min(mbandw,nvgb)
8664 indprecond(i)=(i*i+i)/2 ! increasing number
8665 END DO
8666 DO i=min(mbandw,nvgb)+1,nvgb
8667 indprecond(i)=indprecond(i-1)+mbandw ! fixed band width
8668 END DO
8669 DO i=nvgb+1,nagb ! reset
8670 indprecond(i)=0
8671 END DO
8672 END IF
8673 ! symmetric part
8674 length=(ncon*ncon+ncon)/2
8675 ! add 'band' part
8676 IF(mbandw > 0) THEN ! variable-width band matrix
8677 length=length+indprecond(nvgb)
8678 ELSE ! default preconditioner (diagonal)
8679 length=length+nvgb
8680 END IF
8681 ! add rectangular part (compressed, constraint blocks)
8682 IF(ncon > 0) THEN
8683 ioff=0
8684 ! extra space (for forward solution in EQUDEC)
8685 nextra=max(0,mbandw-1)
8686 DO ib=1,ncblck
8687 ! first constraint in block
8688 blockprecond(ioff+1)=matconsblocks(1,ib)
8689 ! last constraint in block
8690 blockprecond(ioff+2)=matconsblocks(1,ib+1)-1
8691 ! parameter offset
8692 ipar0=matconsblocks(2,ib)-1
8693 blockprecond(ioff+3)=ipar0
8694 ! number of parameters (-> columns)
8695 npar=matconsblocks(3,ib)-ipar0
8696 blockprecond(ioff+4)=npar+nextra
8697 DO i=blockprecond(ioff+1),blockprecond(ioff+2)
8698 offprecond(i)=length-ipar0
8699 length=length+npar+nextra
8700 mszpcc=mszpcc+npar+nextra
8701 END DO
8702 ioff=ioff+4
8703 END DO
8704 ELSE
8705 IF(mbandw == 0) length=length+1 ! for valid precons argument matPreCond((ncon*ncon+ncon)/2+nvgb+1)
8706 END IF
8707 ! allocate
8708 IF(mbandw > 0) THEN
8709 CALL mpalloc(matprecond,length,'variable-band preconditioner matrix')
8710 ELSE
8711 CALL mpalloc(matprecond,length,'default preconditioner matrix')
8712 END IF
8713 nwrdpc=nwrdpc+2*length
8714 IF (nwrdpc > 250000) THEN
8715 WRITE(*,*)
8716 WRITE(*,*) 'Size of preconditioner matrix:',int(real(nwrdpc,mps)*4.0e-6,mpi),' MB'
8717 END IF
8718
8719 END IF
8720
8721
8722 length=nagb
8723 CALL mpalloc(globalcorrections,length,'corrections') ! double prec corrections
8724
8725 length=nagb
8726 CALL mpalloc(workspaced,length,'auxiliary array (D1)') ! double aux 1
8727 CALL mpalloc(workspacelinesearch,length,'auxiliary array (D2)') ! double aux 2
8728 CALL mpalloc(workspacei, length,'auxiliary array (I)') ! int aux 1
8729
8730 IF(metsol == 1) THEN
8731 CALL mpalloc(workspacediag,length,'diagonal of global matrix)') ! double aux 1
8732 CALL mpalloc(workspacerow,length,'(pivot) row of global matrix)')
8733 ! CALL MEGARR('t D',2*NAGB,'auxiliary array') ! double aux 8
8734 END IF
8735
8736 IF(metsol == 2) THEN
8737 IF(nagb>46300) THEN
8738 CALL peend(23,'Aborted, bad matrix index (will exceed 32bit)')
8739 stop 'vmprep: bad index (matrix to large for diagonalization)'
8740 END IF
8741 CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8742 CALL mpalloc(workspacediagonalization,length,'auxiliary array (D3)') ! double aux 3
8743 CALL mpalloc(workspaceeigenvalues,length,'auxiliary array (D6)') ! double aux 6
8744 length=nagb*nagb
8745 CALL mpalloc(workspaceeigenvectors,length,'(rotation) matrix U') ! rotation matrix
8746 END IF
8747
8748 IF(metsol >= 4.AND.metsol < 7) THEN
8749 CALL mpalloc(vecxav,length,'vector X (AVPROD)') ! double aux 1
8750 CALL mpalloc(vecbav,length,'vector B (AVPROD)') ! double aux 1
8751 END IF
8752
8753#ifdef LAPACK64
8754 IF(metsol == 7) THEN
8755 IF(nagb > nvgb) CALL mpalloc(lapackipiv, length,'IPIV for DSPTRG (L)') ! pivot indices for DSPTRF
8756 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8757 END IF
8758 IF(metsol == 8) THEN
8759 IF(nagb > nvgb) THEN
8760 CALL mpalloc(lapackipiv, length,'LAPACK IPIV (L)')
8761 nbopt = ilaenv( 1_mpl, 'DSYTRF', 'U', int(nagb,mpl), int(nagb,mpl), -1_mpl, -1_mpl ) ! optimal block size
8762 print *
8763 print *, 'LAPACK optimal block size for DSYTRF:', nbopt
8764 lplwrk=length*int(nbopt,mpl)
8765 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8766 ELSE IF(nfgb < nvgb.AND.icelim > 1) THEN
8767 ! elimination of constraints with LAPACK
8768 lplwrk=1
8769 DO i=1,npblck
8770 npar=matparblockoffsets(1,i+1)-matparblockoffsets(1,i) ! number of parameters in block
8771 ncon=vecparblockconoffsets(i+1)-vecparblockconoffsets(i) ! number of constraints in block
8772 nbopt = ilaenv( 1_mpl, 'DORMQL', 'RN', int(npar,mpl), int(npar,mpl), int(ncon,mpl), int(npar,mpl) ) ! optimal buffer size
8773 IF (int(npar,mpl)*int(nbopt,mpl) > lplwrk) THEN
8774 lplwrk=int(npar,mpl)*int(nbopt,mpl)
8775 nboptx=nbopt
8776 END IF
8777 END DO
8778 print *
8779 print *, 'LAPACK optimal block size for DORMQL:', nboptx
8780 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8781 END IF
8782 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8783 END IF
8784#endif
8785
8786END SUBROUTINE vmprep
8787
8791
8792SUBROUTINE minver
8793 USE mpmod
8794
8795 IMPLICIT NONE
8796 INTEGER(mpi) :: i
8797 INTEGER(mpi) :: ib
8798 INTEGER(mpi) :: icoff
8799 INTEGER(mpi) :: ipoff
8800 INTEGER(mpi) :: j
8801 INTEGER(mpi) :: lun
8802 INTEGER(mpi) :: ncon
8803 INTEGER(mpi) :: nfit
8804 INTEGER(mpi) :: npar
8805 INTEGER(mpi) :: nrank
8806 INTEGER(mpl) :: imoff
8807 INTEGER(mpl) :: ioff1
8808 REAL(mpd) :: matij
8809
8810 EXTERNAL avprds
8811
8812 SAVE
8813 ! ...
8814 lun=lunlog ! log file
8815
8816 IF(icalcm == 1) THEN
8817 ! save diagonal (for global correlation)
8818 DO i=1,nagb
8819 workspacediag(i)=matij(i,i)
8820 END DO
8821 ! use elimination for constraints ?
8822 IF(nfgb < nvgb) THEN
8823 ! monitor progress
8824 IF(monpg1 > 0) THEN
8825 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
8827 END IF
8828 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
8829 IF(monpg1 > 0) CALL monend()
8830 END IF
8831 END IF
8832
8833 ! loop over blocks (multiple blocks only with elimination !)
8834 DO ib=1,npblck
8835 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
8836 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
8837 icoff=vecparblockconoffsets(ib) ! constraint offset for block
8838 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
8839 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
8840 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
8841 ! use elimination for constraints ?
8842 IF(nfit < npar) THEN
8843 CALL qlsetb(ib)
8844 ! solve L^t*y=d by backward substitution
8846 ! transform, reduce rhs
8847 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
8848 ! correction from eliminated part
8849 DO i=1,nfit
8850 DO j=1,ncon
8851 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
8853 END DO
8854 END DO
8855 END IF
8856
8857 IF(icalcm == 1) THEN
8858 ! monitor progress
8859 IF(monpg1 > 0) THEN
8860 WRITE(lunlog,*) 'Inversion of global matrix (A->A^-1)'
8862 END IF
8863 ! invert and solve
8864 CALL sqminl(globalmatd(imoff+1:), globalcorrections(ipoff+1:),nfit,nrank, &
8866 IF(monpg1 > 0) CALL monend()
8867 IF(nfit /= nrank) THEN
8868 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
8869 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8870 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
8871 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8872 IF (iforce == 0 .AND. isubit == 0) THEN
8873 isubit=1
8874 WRITE(*,*) ' --> enforcing SUBITO mode'
8875 WRITE(lun,*) ' --> enforcing SUBITO mode'
8876 END IF
8877 ELSE IF(ndefec == 0) THEN
8878 IF(npblck == 1) THEN
8879 WRITE(lun,*) 'No rank defect of the symmetric matrix'
8880 ELSE
8881 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
8882 END IF
8883 END IF
8884 ndefec=ndefec+nfit-nrank ! rank defect
8885
8886 ELSE ! multiply gradient by inverse matrix
8887 workspaced(:nfit)=globalcorrections(ipoff+1:ipoff+nfit)
8888 CALL dbsvxl(globalmatd(imoff+1:),workspaced,globalcorrections(ipoff+1:),nfit)
8889 END IF
8890
8891 !use elimination for constraints ?
8892 IF(nfit < npar) THEN
8893 ! extend, transform back solution
8894 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
8895 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
8896 END IF
8897 END DO
8898
8899END SUBROUTINE minver
8900
8904
8905SUBROUTINE mchdec
8906 USE mpmod
8907
8908 IMPLICIT NONE
8909 INTEGER(mpi) :: i
8910 INTEGER(mpi) :: ib
8911 INTEGER(mpi) :: icoff
8912 INTEGER(mpi) :: ipoff
8913 INTEGER(mpi) :: j
8914 INTEGER(mpi) :: lun
8915 INTEGER(mpi) :: ncon
8916 INTEGER(mpi) :: nfit
8917 INTEGER(mpi) :: npar
8918 INTEGER(mpi) :: nrank
8919 INTEGER(mpl) :: imoff
8920 INTEGER(mpl) :: ioff1
8921
8922 REAL(mpd) :: evmax
8923 REAL(mpd) :: evmin
8924
8925 EXTERNAL avprds
8926
8927 SAVE
8928 ! ...
8929 lun=lunlog ! log file
8930
8931 IF(icalcm == 1) THEN
8932 ! use elimination for constraints ?
8933 ! monitor progress
8934 IF(monpg1 > 0) THEN
8935 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
8937 END IF
8938 IF(nfgb < nvgb) CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
8939 IF(monpg1 > 0) CALL monend()
8940 END IF
8941
8942 ! loop over blocks (multiple blocks only with elimination !)
8943 DO ib=1,npblck
8944 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
8945 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
8946 icoff=vecparblockconoffsets(ib) ! constraint offset for block
8947 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
8948 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
8949 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
8950 ! use elimination for constraints ?
8951 IF(nfit < npar) THEN
8952 CALL qlsetb(ib)
8953 ! solve L^t*y=d by backward substitution
8955 ! transform, reduce rhs
8956 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
8957 ! correction from eliminated part
8958 DO i=1,nfit
8959 DO j=1,ncon
8960 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
8962 END DO
8963 END DO
8964 END IF
8965
8966 IF(icalcm == 1) THEN
8967 ! monitor progress
8968 IF(monpg1 > 0) THEN
8969 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
8971 END IF
8972 ! decompose and solve
8973 CALL chdec2(globalmatd(imoff+1:),nfit,nrank,evmax,evmin,monpg1)
8974 IF(monpg1 > 0) CALL monend()
8975 IF(nfit /= nrank) THEN
8976 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
8977 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8978 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
8979 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8980 IF (iforce == 0 .AND. isubit == 0) THEN
8981 isubit=1
8982 WRITE(*,*) ' --> enforcing SUBITO mode'
8983 WRITE(lun,*) ' --> enforcing SUBITO mode'
8984 END IF
8985 ELSE IF(ndefec == 0) THEN
8986 IF(npblck == 1) THEN
8987 WRITE(lun,*) 'No rank defect of the symmetric matrix'
8988 ELSE
8989 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
8990 END IF
8991 WRITE(lun,*) ' largest diagonal element (LDLt)', evmax
8992 WRITE(lun,*) ' smallest diagonal element (LDLt)', evmin
8993 END IF
8994 ndefec=ndefec+nfit-nrank ! rank defect
8995
8996 END IF
8997 ! backward/forward substitution
8998 CALL chslv2(globalmatd(imoff+1:),globalcorrections(ipoff+1:),nfit)
8999
9000 !use elimination for constraints ?
9001 IF(nfit < npar) THEN
9002 ! extend, transform back solution
9003 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9004 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9005 END IF
9006 END DO
9007
9008END SUBROUTINE mchdec
9009
9010#ifdef LAPACK64
9011
9016
9017SUBROUTINE mdptrf
9018 USE mpmod
9019
9020 IMPLICIT NONE
9021 INTEGER(mpi) :: i
9022 INTEGER(mpi) :: ib
9023 INTEGER(mpi) :: icoff
9024 INTEGER(mpi) :: ipoff
9025 INTEGER(mpi) :: j
9026 INTEGER(mpi) :: lun
9027 INTEGER(mpi) :: ncon
9028 INTEGER(mpi) :: nfit
9029 INTEGER(mpi) :: npar
9030 INTEGER(mpl) :: imoff
9031 INTEGER(mpl) :: ioff1
9032 INTEGER(mpi) :: infolp
9033 REAL(mpd) :: matij
9034
9035 EXTERNAL avprds
9036
9037 SAVE
9038 ! ...
9039 lun=lunlog ! log file
9040
9041 IF(icalcm == 1) THEN
9042 IF(ilperr == 1) THEN
9043 ! save diagonal (for global correlation)
9044 DO i=1,nagb
9045 workspacediag(i)=matij(i,i)
9046 END DO
9047 END IF
9048 ! use elimination for constraints ?
9049 IF(nfgb < nvgb) THEN
9050 ! monitor progress
9051 IF(monpg1 > 0) THEN
9052 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9054 END IF
9055 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9056 IF(monpg1 > 0) CALL monend()
9057 END IF
9058 END IF
9059
9060 ! loop over blocks (multiple blocks only with elimination !)
9061 DO ib=1,npblck
9062 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9063 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9064 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9065 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9066 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9067 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9068 ! use elimination for constraints ?
9069 IF(nfit < npar) THEN
9070 CALL qlsetb(ib)
9071 ! solve L^t*y=d by backward substitution
9073 ! transform, reduce rhs
9074 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9075 ! correction from eliminated part
9076 DO i=1,nfit
9077 DO j=1,ncon
9078 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9080 END DO
9081 END DO
9082 END IF
9083
9084 IF(icalcm == 1) THEN
9085 ! multipliers?
9086 IF (nfit > npar) THEN
9087 ! monitor progress
9088 IF(monpg1 > 0) THEN
9089 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9091 END IF
9092 !$POMP INST BEGIN(dsptrf)
9093 CALL dsptrf('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),infolp)
9094 !$POMP INST END(dsptrf)
9095 IF(monpg1 > 0) CALL monend()
9096 ELSE
9097 ! monitor progress
9098 IF(monpg1 > 0) THEN
9099 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9101 END IF
9102 !$POMP INST BEGIN(dpptrf)
9103 CALL dpptrf('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
9104 !$POMP INST END(dpptrf)
9105 IF(monpg1 > 0) CALL monend()
9106 ENDIF
9107 ! check result
9108 IF(infolp==0) THEN
9109 IF(npblck == 1) THEN
9110 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9111 ELSE
9112 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9113 END IF
9114 ELSE
9115 ndefec=ndefec+1 ! (lower limit of) rank defect
9116 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9117 '-by-',nfit,' failed at index ', infolp
9118 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9119 '-by-',nfit,' failed at index ', infolp
9120 CALL peend(29,'Aborted, factorization of global matrix failed')
9121 stop 'mdptrf: bad matrix'
9122 END IF
9123 END IF
9124 ! backward/forward substitution
9125 ! multipliers?
9126 IF (nfit > npar) THEN
9127 CALL dsptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),lapackipiv(ipoff+1:),&
9128 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9129 IF(infolp /= 0) print *, ' DSPTRS failed: ', infolp
9130 ELSE
9131 CALL dpptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),&
9132 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9133 IF(infolp /= 0) print *, ' DPPTRS failed: ', infolp
9134 ENDIF
9135
9136 !use elimination for constraints ?
9137 IF(nfit < npar) THEN
9138 ! extend, transform back solution
9139 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9140 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9141 END IF
9142 END DO
9143
9144END SUBROUTINE mdptrf
9145
9151
9152SUBROUTINE mdutrf
9153 USE mpmod
9154
9155 IMPLICIT NONE
9156 INTEGER(mpi) :: i
9157 INTEGER(mpi) :: ib
9158 INTEGER(mpi) :: icoff
9159 INTEGER(mpi) :: ipoff
9160 INTEGER(mpi) :: j
9161 INTEGER(mpi) :: lun
9162 INTEGER(mpi) :: ncon
9163 INTEGER(mpi) :: nfit
9164 INTEGER(mpi) :: npar
9165 INTEGER(mpl) :: imoff
9166 INTEGER(mpl) :: ioff1
9167 INTEGER(mpl) :: iloff
9168 INTEGER(mpi) :: infolp
9169
9170 REAL(mpd) :: matij
9171
9172 EXTERNAL avprds
9173
9174 SAVE
9175 ! ...
9176 lun=lunlog ! log file
9177
9178 IF(icalcm == 1) THEN
9179 IF(ilperr == 1) THEN
9180 ! save diagonal (for global correlation)
9181 DO i=1,nagb
9182 workspacediag(i)=matij(i,i)
9183 END DO
9184 END IF
9185 ! use elimination for constraints ?
9186 IF(nfgb < nvgb) THEN
9187 ! monitor progress
9188 IF(monpg1 > 0) THEN
9189 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9191 END IF
9192 IF (icelim > 1) THEN
9193 CALL lpavat(.true.)
9194 ELSE
9195 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9196 END IF
9197 IF(monpg1 > 0) CALL monend()
9198 END IF
9199 END IF
9200
9201 ! loop over blocks (multiple blocks only with elimination !)
9202 iloff=0 ! offset of L in lapackQL
9203 DO ib=1,npblck
9204 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9205 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9206 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9207 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9208 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9209 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9210 ! use elimination for constraints ?
9211 IF(nfit < npar) THEN
9212 IF (icelim > 1) THEN
9213 ! solve L^t*y=d by backward substitution
9214 vecconssolution(1:ncon)=vecconsresiduals(icoff+1:icoff+ncon)
9215 CALL dtrtrs('L','T','N',int(ncon,mpl),1_mpl,lapackql(iloff+npar-ncon+1:),int(npar,mpl),&
9216 vecconssolution,int(ncon,mpl),infolp)
9217 IF(infolp /= 0) print *, ' DTRTRS failed: ', infolp
9218 ! transform, reduce rhs, Q^t*b
9219 CALL dormql('L','T',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9220 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9221 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9222 ELSE
9223 CALL qlsetb(ib)
9224 ! solve L^t*y=d by backward substitution
9226 ! transform, reduce rhs
9227 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9228 END IF
9229 ! correction from eliminated part
9230 DO i=1,nfit
9231 DO j=1,ncon
9232 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9234 END DO
9235 END DO
9236 END IF
9237
9238 IF(icalcm == 1) THEN
9239 ! multipliers?
9240 IF (nfit > npar) THEN
9241 ! monitor progress
9242 IF(monpg1 > 0) THEN
9243 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9245 END IF
9246 !$POMP INST BEGIN(dsytrf)
9247 CALL dsytrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
9248 lapackipiv(ipoff+1:),lapackwork,lplwrk,infolp)
9249 !$POMP INST END(dsytrf)
9250 IF(monpg1 > 0) CALL monend()
9251 ELSE
9252 ! monitor progress
9253 IF(monpg1 > 0) THEN
9254 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9256 END IF
9257 !$POMP INST BEGIN(dpotrf)
9258 CALL dpotrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
9259 !$POMP INST END(dpotrf)
9260 IF(monpg1 > 0) CALL monend()
9261 ENDIF
9262 ! check result
9263 IF(infolp==0) THEN
9264 IF(npblck == 1) THEN
9265 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9266 ELSE
9267 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9268 END IF
9269 ELSE
9270 ndefec=ndefec+1 ! (lower limit of) rank defect
9271 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9272 '-by-',nfit,' failed at index ', infolp
9273 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9274 '-by-',nfit,' failed at index ', infolp
9275 CALL peend(29,'Aborted, factorization of global matrix failed')
9276 stop 'mdutrf: bad matrix'
9277 END IF
9278 END IF
9279 ! backward/forward substitution
9280 ! multipliers?
9281 IF (nfit > npar) THEN
9282 CALL dsytrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(nfit,mpl),&
9283 lapackipiv(ipoff+1:),globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9284 IF(infolp /= 0) print *, ' DSYTRS failed: ', infolp
9285 ELSE
9286 CALL dpotrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(npar,mpl),&
9287 globalcorrections(ipoff+1:),int(npar,mpl),infolp)
9288 IF(infolp /= 0) print *, ' DPOTRS failed: ', infolp
9289 ENDIF
9290
9291 !use elimination for constraints ?
9292 IF(nfit < npar) THEN
9293 IF (icelim > 1) THEN
9294 ! correction from eliminated part
9295 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9296 ! extend, transform back solution, Q*x
9297 CALL dormql('L','N',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9298 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9299 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9300 ELSE
9301 ! extend, transform back solution
9302 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9303 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9304 END IF
9305 END IF
9306 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9307 END DO
9308
9309END SUBROUTINE mdutrf
9310
9321SUBROUTINE lpqldec(a,emin,emax)
9322 USE mpmod
9323 USE mpdalc
9324
9325 IMPLICIT NONE
9326 INTEGER(mpi) :: ib
9327 INTEGER(mpi) :: icb
9328 INTEGER(mpi) :: icboff
9329 INTEGER(mpi) :: icblst
9330 INTEGER(mpi) :: icoff
9331 INTEGER(mpi) :: icfrst
9332 INTEGER(mpi) :: iclast
9333 INTEGER(mpi) :: ipfrst
9334 INTEGER(mpi) :: iplast
9335 INTEGER(mpi) :: ipoff
9336 INTEGER(mpi) :: i
9337 INTEGER(mpi) :: j
9338 INTEGER(mpi) :: ncon
9339 INTEGER(mpi) :: npar
9340 INTEGER(mpi) :: npb
9341 INTEGER(mpl) :: imoff
9342 INTEGER(mpl) :: iloff
9343 INTEGER(mpi) :: infolp
9344 INTEGER :: nbopt, ILAENV
9345
9346 REAL(mpd), INTENT(IN) :: a(mszcon)
9347 REAL(mpd), INTENT(OUT) :: emin
9348 REAL(mpd), INTENT(OUT) :: emax
9349 SAVE
9350
9351 print *
9352 ! loop over blocks (multiple blocks only with elimination !)
9353 iloff=0 ! size of unpacked constraint matrix
9354 DO ib=1,npblck
9355 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9356 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9357 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9358 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9359 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9360 END DO
9361 ! allocate
9362 CALL mpalloc(lapackql, iloff, 'LAPACK QL (QL decomp.) ')
9363 lapackql=0.
9364 iloff=ncgb
9365 CALL mpalloc(lapacktau, iloff, 'LAPACK TAU (QL decomp.) ')
9366 ! fill
9367 iloff=0 ! offset of unpacked constraint matrix block
9368 imoff=0 ! offset of packed constraint matrix block
9369 DO ib=1,npblck
9370 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9371 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9372 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9373 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9374 IF(ncon <= 0) cycle
9375 ! block with constraints
9376 icboff=matparblockoffsets(2,ib) ! constraint block offset
9377 icblst=matparblockoffsets(2,ib+1) ! constraint block offset
9378 DO icb=icboff+1,icboff+icblst
9379 icfrst=matconsblocks(1,icb) ! first constraint in block
9380 iclast=matconsblocks(1,icb+1)-1 ! last constraint in block
9381 DO j=icfrst,iclast
9382 ipfrst=matconsranges(3,j)-ipoff ! first (rel.) parameter
9383 iplast=matconsranges(4,j)-ipoff ! last (rel.) parameters
9384 npb=iplast-ipfrst+1
9385 lapackql(iloff+ipfrst:iloff+iplast)=a(imoff+1:imoff+npb)
9386 imoff=imoff+npb
9387 iloff=iloff+npar
9388 END DO
9389 END DO
9390 END DO
9391 ! decompose
9392 iloff=0 ! offset of unpacked constraint matrix block
9393 emax=-1.
9394 emin=1.
9395 DO ib=1,npblck
9396 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9397 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9398 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9399 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9400 IF(ncon <= 0) cycle
9401 ! block with constraints
9402 nbopt = ilaenv( 1_mpl, 'DGEQLF', '', int(npar,mpl), int(ncon,mpl), int(npar,mpl), -1_mpl ) ! optimal block size
9403 print *, 'LAPACK optimal block size for DGEQLF:', nbopt
9404 lplwrk=int(ncon,mpl)*int(nbopt,mpl)
9405 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (d)')
9406 !$POMP INST BEGIN(dgeqlf)
9407 CALL dgeqlf(int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9408 lapacktau(icoff+1:),lapackwork,lplwrk,infolp)
9409 IF(infolp /= 0) print *, ' DGEQLF failed: ', infolp
9410 !$POMP INST END(dgeqlf)
9411 CALL mpdealloc(lapackwork)
9412 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9413 ! get min/max diaginal element of L
9414 imoff=iloff
9415 IF(emax < emin) THEN
9416 emax=lapackql(imoff)
9417 emin=emax
9418 END IF
9419 DO i=1,ncon
9420 IF (abs(emax) < abs(lapackql(imoff))) emax=lapackql(imoff)
9421 IF (abs(emin) > abs(lapackql(imoff))) emin=lapackql(imoff)
9422 imoff=imoff-npar-1
9423 END DO
9424 END DO
9425 print *
9426END SUBROUTINE lpqldec
9427
9437SUBROUTINE lpavat(t)
9438 USE mpmod
9439
9440 IMPLICIT NONE
9441 INTEGER(mpi) :: i
9442 INTEGER(mpi) :: ib
9443 INTEGER(mpi) :: icoff
9444 INTEGER(mpi) :: ipoff
9445 INTEGER(mpi) :: j
9446 INTEGER(mpi) :: ncon
9447 INTEGER(mpi) :: npar
9448 INTEGER(mpl) :: imoff
9449 INTEGER(mpl) :: iloff
9450 INTEGER(mpi) :: infolp
9451 CHARACTER (LEN=1) :: transr, transl
9452
9453 LOGICAL, INTENT(IN) :: t
9454 SAVE
9455
9456 IF (t) THEN ! Q^t*A*Q
9457 transr='N'
9458 transl='T'
9459 ELSE ! Q*A*Q^t
9460 transr='T'
9461 transl='N'
9462 ENDIF
9463
9464 ! loop over blocks (multiple blocks only with elimination !)
9465 iloff=0 ! offset of L in lapackQL
9466 DO ib=1,npblck
9467 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9468 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9469 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9470 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9471 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9472 IF(ncon <= 0 ) cycle
9473
9474 !$POMP INST BEGIN(dormql)
9475 ! expand matrix (copy lower to upper triangle)
9476 ! parallelize row loop
9477 ! slot of 32 'I' for next idle thread
9478 !$OMP PARALLEL DO &
9479 !$OMP PRIVATE(J) &
9480 !$OMP SCHEDULE(DYNAMIC,32)
9481 DO i=ipoff+1,ipoff+npar
9482 DO j=ipoff+1,i-1
9484 ENDDO
9485 ENDDO
9486 ! A*Q
9487 CALL dormql('R',transr,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9488 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9489 lapackwork,lplwrk,infolp)
9490 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9491 ! Q^t*(A*Q)
9492 CALL dormql('L',transl,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9493 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9494 lapackwork,lplwrk,infolp)
9495 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9496 !$POMP INST END(dormql)
9497
9498 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9499 END DO
9500
9501END SUBROUTINE lpavat
9502
9503#ifdef PARDISO
9504include 'mkl_pardiso.f90'
9505!===============================================================================
9506! Copyright 2004-2022 Intel Corporation.
9507!
9508! This software and the related documents are Intel copyrighted materials, and
9509! your use of them is governed by the express license under which they were
9510! provided to you (License). Unless the License provides otherwise, you may not
9511! use, modify, copy, publish, distribute, disclose or transmit this software or
9512! the related documents without Intel's prior written permission.
9513!
9514! This software and the related documents are provided as is, with no express
9515! or implied warranties, other than those that are expressly stated in the
9516! License.
9517!===============================================================================
9518!
9519! Content : Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO Fortran-90
9520! use case
9521!
9522!*******************************************************************************
9523
9528SUBROUTINE mspardiso
9529 USE mkl_pardiso
9530 USE mpmod
9531 USE mpdalc
9532 IMPLICIT NONE
9533
9534 !.. Internal solver memory pointer
9535 TYPE(mkl_pardiso_handle) :: pt(64) ! Handle to internal data structure
9536 !.. All other variables
9537 INTEGER(mpl), PARAMETER :: maxfct =1 ! Max. number of factors with identical sparsity structure kept in memory
9538 INTEGER(mpl), PARAMETER :: mnum = 1 ! Actual factor to use
9539 INTEGER(mpl), PARAMETER :: nrhs = 1 ! Number of right hand sides
9540
9541 INTEGER(mpl) :: mtype ! Matrix type (symmetric, pos. def.: 2, indef.: -2)
9542 INTEGER(mpl) :: phase ! Solver phase(s) to be executed
9543 INTEGER(mpl) :: error ! Error code
9544 INTEGER(mpl) :: msglvl ! Message level
9545
9546 INTEGER(mpi) :: i
9547 INTEGER(mpl) :: ij
9548 INTEGER(mpl) :: idum(1)
9549 INTEGER(mpi) :: lun
9550 INTEGER(mpl) :: length
9551 INTEGER(mpi) :: nfill
9552 INTEGER(mpi) :: npdblk
9553 REAL(mpd) :: adum(1)
9554 REAL(mpd) :: ddum(1)
9555
9556 INTEGER(mpl) :: iparm(64)
9557 REAL(mpd), ALLOCATABLE :: b( : ) ! Right hand side (of equations system)
9558 REAL(mpd), ALLOCATABLE :: x( : ) ! Solution (of equations system)
9559 SAVE
9560
9561 lun=lunlog ! log file
9562
9563 error = 0 ! initialize error flag
9564 msglvl = ipddbg ! print statistical information
9565 npdblk=(nfgb-1)/matbsz+1 ! number of row blocks
9566
9567 IF(icalcm == 1) THEN
9568 mtype = 2 ! positive definite symmetric matrix
9569 IF (nfgb > nvgb) mtype = -2 ! indefinte symmetric matrix (Lagrange multipliers)
9570
9571 !$POMP INST BEGIN(mspd00)
9572 WRITE(*,*)
9573 WRITE(*,*) 'MSPARDISO: number of non-zero elements = ', csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
9574 ! fill up last block?
9575 nfill = npdblk*matbsz-nfgb
9576 IF (nfill > 0) THEN
9577 WRITE(*,*) 'MSPARDISO: number of rows to fill up = ', nfill
9578 ! end of last block
9579 ij = (csr3rowoffsets(npdblk+1)-csr3rowoffsets(1))*int(matbsz,mpl)*int(matbsz,mpl)
9580 DO i=1,nfill
9581 globalmatd(ij) = 1.0_mpd
9582 ij = ij-matbsz-1 ! back one row and one column in last block
9583 END DO
9584 END IF
9585
9586 ! close previous PARADISO run
9587 IF (ipdmem > 0) THEN
9588 !.. Termination and release of memory
9589 phase = -1 ! release internal memory
9590 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), adum, idum, idum, &
9591 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9592 IF (error /= 0) THEN
9593 WRITE(lun,*) 'The following ERROR was detected: ', error
9594 WRITE(*,'(A,2I10)') ' PARDISO release failed (phase, error): ', phase, error
9595 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9596 CALL peend(40,'Aborted, other error: PARDISO release')
9597 stop 'MSPARDISO: stopping due to error in PARDISO release'
9598 END IF
9599 ipdmem=0
9600 END IF
9601
9602 !..
9603 !.. Set up PARDISO control parameter
9604 !..
9605 iparm=0 ! using defaults
9606 iparm(2) = 2 ! fill-in reordering from METIS
9607 iparm(10) = 8 ! perturb the pivot elements with 1E-8
9608 iparm(18) = -1 ! Output: number of nonzeros in the factor LU
9609 iparm(19) = -1 ! Output: Mflops for LU factorization
9610 iparm(21) = 1 ! pivoting for symmetric indefinite matrices
9611 DO i=1, lenpardiso
9612 iparm(listpardiso(i)%label)=listpardiso(i)%ivalue
9613 END DO
9614 IF (iparm(1) == 0) WRITE(lun,*) 'PARDISO using defaults '
9615 IF (iparm(43) /= 0) THEN
9616 WRITE(lun,*) 'PARDISO: computation of the diagonal of inverse matrix not implemented !'
9617 iparm(43) = 0 ! no computation of the diagonal of inverse matrix
9618 END IF
9619
9620 ! necessary for the FIRST call of the PARDISO solver.
9621 DO i = 1, 64
9622 pt(i)%DUMMY = 0
9623 END DO
9624 !$POMP INST END(mspd00)
9625 END IF
9626
9627 IF(icalcm == 1) THEN
9628 ! monitor progress
9629 IF(monpg1 > 0) THEN
9630 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9632 END IF
9633 ! decompose and solve
9634 !.. Reordering and Symbolic Factorization, This step also allocates
9635 ! all memory that is necessary for the factorization
9636 !$POMP INST BEGIN(mspd11)
9637 phase = 11 ! only reordering and symbolic factorization
9638 IF (matbsz > 1) THEN
9639 iparm(1) = 1 ! non default setting
9640 iparm(37) = matbsz ! using BSR3 instead of CSR3
9641 END IF
9642 IF (ipddbg > 0) THEN
9643 DO i=1,64
9644 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9645 END DO
9646 END IF
9647 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9648 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9649 !$POMP INST END(mspd11)
9650 WRITE(lun,*) 'PARDISO reordering completed ... '
9651 WRITE(lun,*) 'PARDISO peak memory required (KB)', iparm(15)
9652 IF (ipddbg > 0) THEN
9653 DO i=1,64
9654 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9655 END DO
9656 END IF
9657 IF (error /= 0) THEN
9658 WRITE(lun,*) 'The following ERROR was detected: ', error
9659 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9660 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9661 CALL peend(40,'Aborted, other error: PARDISO reordering')
9662 stop 'MSPARDISO: stopping due to error in PARDISO reordering'
9663 END IF
9664 IF (iparm(60) == 0) THEN
9665 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(17) ! in core
9666 ELSE
9667 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(63) ! out of core
9668 END IF
9669 WRITE(lun,*) 'Size (KB) of allocated memory = ',ipdmem
9670 WRITE(lun,*) 'Number of nonzeros in factors = ',iparm(18)
9671 WRITE(lun,*) 'Number of factorization MFLOPS = ',iparm(19)
9672
9673 !.. Factorization.
9674 !$POMP INST BEGIN(mspd22)
9675 phase = 22 ! only factorization
9676 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9677 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9678 !$POMP INST END(mspd22)
9679 WRITE(lun,*) 'PARDISO factorization completed ... '
9680 IF (ipddbg > 0) THEN
9681 DO i=1,64
9682 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9683 END DO
9684 END IF
9685 IF (error /= 0) THEN
9686 WRITE(lun,*) 'The following ERROR was detected: ', error
9687 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9688 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9689 CALL peend(40,'Aborted, other error: PARDISO factorization')
9690 stop 'MSPARDISO: stopping due to error in PARDISO factorization'
9691 ENDIF
9692 IF (mtype < 0) THEN
9693 IF (iparm(14) > 0) &
9694 WRITE(lun,*) 'Number of perturbed pivots = ',iparm(14)
9695 WRITE(lun,*) 'Number of positive eigenvalues = ',iparm(22)-nfill
9696 WRITE(lun,*) 'Number of negative eigenvalues = ',iparm(23)
9697 ELSE IF (iparm(30) > 0) THEN
9698 WRITE(lun,*) 'Equation with bad pivot (<=0.) = ',iparm(30)
9699 END IF
9700
9701 IF (monpg1 > 0) CALL monend()
9702 END IF
9703
9704 ! backward/forward substitution
9705 !.. Back substitution and iterative refinement
9706 length=nfgb+nfill
9707 CALL mpalloc(b,length,' PARDISO r.h.s')
9708 CALL mpalloc(x,length,' PARDISO solution')
9710 !$POMP INST BEGIN(mspd33)
9711 iparm(6) = 0 ! don't update r.h.s. with solution
9712 phase = 33 ! only solving
9713 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9714 idum, nrhs, iparm, msglvl, b, x, error)
9715 !$POMP INST END(mspd33)
9717 CALL mpdealloc(x)
9718 CALL mpdealloc(b)
9719 WRITE(lun,*) 'PARDISO solve completed ... '
9720 IF (error /= 0) THEN
9721 WRITE(lun,*) 'The following ERROR was detected: ', error
9722 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9723 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9724 CALL peend(40,'Aborted, other error: PARDISO solve')
9725 stop 'MSPARDISO: stopping due to error in PARDISO solve'
9726 ENDIF
9727
9728END SUBROUTINE mspardiso
9729#endif
9730#endif
9731
9733SUBROUTINE mdiags
9734 USE mpmod
9735
9736 IMPLICIT NONE
9737 REAL(mps) :: evalue
9738 INTEGER(mpi) :: i
9739 INTEGER(mpi) :: iast
9740 INTEGER(mpi) :: idia
9741 INTEGER(mpi) :: imin
9742 INTEGER(mpl) :: ioff1
9743 INTEGER(mpi) :: j
9744 INTEGER(mpi) :: last
9745 INTEGER(mpi) :: lun
9746 INTEGER(mpi) :: nmax
9747 INTEGER(mpi) :: nmin
9748 INTEGER(mpi) :: ntop
9749 REAL(mpd) :: matij
9750 !
9751 EXTERNAL avprds
9752
9753 SAVE
9754 ! ...
9755
9756 lun=lunlog ! log file
9757
9758 ! save diagonal (for global correlation)
9759 IF(icalcm == 1) THEN
9760 DO i=1,nagb
9761 workspacediag(i)=matij(i,i)
9762 END DO
9763 ENDIF
9764
9765 !use elimination for constraints ?
9766 IF(nfgb < nvgb) THEN
9767 IF(icalcm == 1) THEN
9768 ! monitor progress
9769 IF(monpg1 > 0) THEN
9770 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9772 END IF
9773 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9774 IF(monpg1 > 0) CALL monend()
9775 ENDIF
9776 ! solve L^t*y=d by backward substitution
9778 ! transform, reduce rhs
9779 CALL qlmlq(globalcorrections,1,.true.) ! Q^t*b
9780 ! correction from eliminated part
9781 DO i=1,nfgb
9782 DO j=1,ncgb
9783 ioff1=globalrowoffsets(nfgb+j)+i ! global (nfit+j,i)
9785 END DO
9786 END DO
9787 END IF
9788
9789 IF(icalcm == 1) THEN
9790 ! eigenvalues eigenvectors symm_input
9791 workspaceeigenvalues=0.0_mpd
9794
9795 ! histogram of positive eigenvalues
9796
9797 nmax=int(1.0+log10(real(workspaceeigenvalues(1),mps)),mpi) ! > log of largest eigenvalue
9798 imin=1
9799 DO i=nfgb,1,-1
9800 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
9801 imin=i ! index of smallest pos. eigenvalue
9802 EXIT
9803 END IF
9804 END DO
9805 nmin=int(log10(real(workspaceeigenvalues(imin),mps)),mpi) ! log of smallest pos. eigenvalue
9806 ntop=nmin+6
9807 DO WHILE(ntop < nmax)
9808 ntop=ntop+3
9809 END DO
9810
9811 CALL hmpdef(7,real(nmin,mps),real(ntop,mps), 'log10 of positive eigenvalues')
9812 DO idia=1,nfgb
9813 IF(workspaceeigenvalues(idia) > 0.0_mpd) THEN ! positive
9814 evalue=log10(real(workspaceeigenvalues(idia),mps))
9815 CALL hmpent(7,evalue)
9816 END IF
9817 END DO
9818 IF(nhistp /= 0) CALL hmprnt(7)
9819 CALL hmpwrt(7)
9820
9821 iast=max(1,imin-60)
9822 CALL gmpdef(3,2,'low-value end of eigenvalues')
9823 DO i=iast,nfgb
9824 evalue=real(workspaceeigenvalues(i),mps)
9825 CALL gmpxy(3,real(i,mps),evalue)
9826 END DO
9827 IF(nhistp /= 0) CALL gmprnt(3)
9828 CALL gmpwrt(3)
9829
9830 DO i=1,nfgb
9831 workspacediagonalization(i)=0.0_mpd
9832 IF(workspaceeigenvalues(i) /= 0.0_mpd) THEN
9833 workspacediagonalization(i)=max(0.0_mpd,log10(abs(workspaceeigenvalues(i)))+3.0_mpd)
9835 END IF
9836 END DO
9837 last=min(nfgb,nvgb)
9838 WRITE(lun,*) ' '
9839 WRITE(lun,*) 'The first (largest) eigenvalues ...'
9840 WRITE(lun,102) (workspaceeigenvalues(i),i=1,min(20,nagb))
9841 WRITE(lun,*) ' '
9842 WRITE(lun,*) 'The last eigenvalues ... up to',last
9843 WRITE(lun,102) (workspaceeigenvalues(i),i=max(1,last-19),last)
9844 WRITE(lun,*) ' '
9845 IF(nagb > nvgb) THEN
9846 WRITE(lun,*) 'The eigenvalues from',nvgb+1,' to',nagb
9847 WRITE(lun,102) (workspaceeigenvalues(i),i=nvgb+1,nagb)
9848 WRITE(lun,*) ' '
9849 ENDIF
9850 WRITE(lun,*) 'Log10 + 3 of ',nfgb,' eigenvalues in decreasing', ' order'
9851 WRITE(lun,*) '(for Eigenvalue < 0.001 the value 0.0 is shown)'
9852 WRITE(lun,101) (workspacediagonalization(i),i=1,nfgb)
9853 IF(workspacediagonalization(nfgb) < 0) WRITE(lun,*) 'Negative values are ', &
9854 'printed for negative eigenvalues'
9856 WRITE(lun,*) ' '
9857 WRITE(lun,*) last,' significances: insignificant if ', &
9858 'compatible with N(0,1)'
9859 WRITE(lun,101) (workspacediagonalization(i),i=1,last)
9860
9861
9862101 FORMAT(10f7.1)
9863102 FORMAT(5e14.6)
9864
9865 END IF
9866
9867 ! solution ---------------------------------------------------------
9869 ! eigenvalues eigenvectors
9871
9872 !use elimination for constraints ?
9873 IF(nfgb < nvgb) THEN
9874 ! extend, transform back solution
9876 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
9877 END IF
9878
9879END SUBROUTINE mdiags
9880
9882SUBROUTINE zdiags
9883 USE mpmod
9884
9885 IMPLICIT NONE
9886 INTEGER(mpi) :: i
9887 INTEGER(mpl) :: ioff1
9888 INTEGER(mpl) :: ioff2
9889 INTEGER(mpi) :: j
9890
9891 ! eigenvalue eigenvectors cov.matrix
9893
9894 !use elimination for constraints ?
9895 IF(nfgb < nvgb) THEN
9896 ! extend, transform eigenvectors
9897 ioff1=nfgb*nfgb
9898 ioff2=nfgb*nvgb
9899 workspaceeigenvectors(ioff2+1:)=0.0_mpd
9900 DO i=nfgb,1,-1
9901 ioff1=ioff1-nfgb
9902 ioff2=ioff2-nvgb
9903 DO j=nfgb,1,-1
9905 END DO
9906 workspaceeigenvectors(ioff2+nfgb+1:ioff2+nvgb)=0.0_mpd
9907 END DO
9908 CALL qlmlq(workspaceeigenvectors,nvgb,.false.) ! Q*U
9909 END IF
9910
9911END SUBROUTINE zdiags
9912
9918
9919SUBROUTINE mminrs
9920 USE mpmod
9921 USE minresmodule, ONLY: minres
9922
9923 IMPLICIT NONE
9924 INTEGER(mpi) :: istop
9925 INTEGER(mpi) :: itn
9926 INTEGER(mpi) :: itnlim
9927 INTEGER(mpi) :: lun
9928 INTEGER(mpi) :: nout
9929 INTEGER(mpi) :: nrkd
9930 INTEGER(mpi) :: nrkd2
9931
9932 REAL(mpd) :: shift
9933 REAL(mpd) :: rtol
9934 REAL(mpd) :: anorm
9935 REAL(mpd) :: acond
9936 REAL(mpd) :: arnorm
9937 REAL(mpd) :: rnorm
9938 REAL(mpd) :: ynorm
9939 LOGICAL :: checka
9940 EXTERNAL avprds, avprod, mvsolv, mcsolv
9941 SAVE
9942 ! ...
9943 lun=lunlog ! log file
9944
9945 nout=lun
9946 itnlim=2000 ! iteration limit
9947 shift =0.0_mpd ! not used
9948 rtol = mrestl ! from steering
9949 checka=.false.
9950
9952 !use elimination for constraints ?
9953 IF(nfgb < nvgb) THEN
9954 ! solve L^t*y=d by backward substitution
9956 ! input to AVPRD0
9957 vecxav(1:nfgb)=0.0_mpd
9959 CALL qlmlq(vecxav,1,.false.) ! Q*x
9960 ! calclulate vecBav=globalMat*vecXav
9961 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
9962 ! correction from eliminated part
9964 ! transform, reduce rhs
9965 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
9966 END IF
9967
9968 IF(mbandw == 0) THEN ! default preconditioner
9969 IF(icalcm == 1) THEN
9970 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
9971 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
9972 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
9974 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
9975 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
9976 IF(monpg1 > 0) CALL monend()
9977 END IF
9978 CALL minres(nfgb, avprod, mcsolv, workspaced, shift, checka ,.true. , &
9979 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
9980 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
9981 IF(icalcm == 1) THEN
9982 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
9983 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
9984 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
9986 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
9987 IF(monpg1 > 0) CALL monend()
9988 END IF
9989 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.true. , &
9990 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
9991 ELSE
9992 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.false. , &
9993 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
9994 END IF
9995
9996 !use elimination for constraints ?
9997 IF(nfgb < nvgb) THEN
9998 ! extend, transform back solution
10000 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10001 END IF
10002
10003 iitera=itn
10004 istopa=istop
10005 mnrsit=mnrsit+itn
10006
10007 IF (istopa == 0) print *, 'MINRES: istop=0, exact solution x=0.'
10008
10009END SUBROUTINE mminrs
10010
10016
10017SUBROUTINE mminrsqlp
10018 USE mpmod
10019 USE minresqlpmodule, ONLY: minresqlp
10020
10021 IMPLICIT NONE
10022 INTEGER(mpi) :: istop
10023 INTEGER(mpi) :: itn
10024 INTEGER(mpi) :: itnlim
10025 INTEGER(mpi) :: lun
10026 INTEGER(mpi) :: nout
10027 INTEGER(mpi) :: nrkd
10028 INTEGER(mpi) :: nrkd2
10029
10030 REAL(mpd) :: rtol
10031 REAL(mpd) :: mxxnrm
10032 REAL(mpd) :: trcond
10033
10034 EXTERNAL avprds, avprod, mvsolv, mcsolv
10035 SAVE
10036 ! ...
10037 lun=lunlog ! log file
10038
10039 nout=lun
10040 itnlim=2000 ! iteration limit
10041 rtol = mrestl ! from steering
10042 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
10043 IF(mrmode == 1) THEN
10044 trcond = 1.0_mpd/epsilon(trcond) ! only QR
10045 ELSE IF(mrmode == 2) THEN
10046 trcond = 1.0_mpd ! only QLP
10047 ELSE
10048 trcond = mrtcnd ! QR followed by QLP
10049 END IF
10050
10052 !use elimination for constraints ?
10053 IF(nfgb < nvgb) THEN
10054 ! solve L^t*y=d by backward substitution
10056 ! input to AVPRD0
10057 vecxav(1:nfgb)=0.0_mpd
10059 CALL qlmlq(vecxav,1,.false.) ! Q*x
10060 ! calclulate vecBav=globalMat*vecXav
10061 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10062 ! correction from eliminated part
10064 ! transform, reduce rhs
10065 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10066 END IF
10067
10068 IF(mbandw == 0) THEN ! default preconditioner
10069 IF(icalcm == 1) THEN
10070 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10071 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10072 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10074 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10075 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10076 IF(monpg1 > 0) CALL monend()
10077 END IF
10078 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mcsolv, nout=nout, &
10079 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10080 x=globalcorrections, istop=istop, itn=itn)
10081 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10082 IF(icalcm == 1) THEN
10083 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10084 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10085 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10087 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10088 IF(monpg1 > 0) CALL monend()
10089 END IF
10090
10091 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mvsolv, nout=nout, &
10092 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10093 x=globalcorrections, istop=istop, itn=itn)
10094 ELSE
10095 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, nout=nout, &
10096 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10097 x=globalcorrections, istop=istop, itn=itn)
10098 END IF
10099
10100 !use elimination for constraints ?
10101 IF(nfgb < nvgb) THEN
10102 ! extend, transform back solution
10104 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10105 END IF
10106
10107 iitera=itn
10108 istopa=istop
10109 mnrsit=mnrsit+itn
10110
10111 IF (istopa == 3) print *, 'MINRES: istop=0, exact solution x=0.'
10112
10113END SUBROUTINE mminrsqlp
10114
10122
10123SUBROUTINE mcsolv(n,x,y) ! solve M*y = x
10124 USE mpmod
10125
10126 IMPLICIT NONE
10127 INTEGER(mpi),INTENT(IN) :: n
10128 REAL(mpd), INTENT(IN) :: x(n)
10129 REAL(mpd), INTENT(OUT) :: y(n)
10130 SAVE
10131 ! ...
10133 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),y,x)
10134END SUBROUTINE mcsolv
10135
10143
10144SUBROUTINE mvsolv(n,x,y) ! solve M*y = x
10145 USE mpmod
10146
10147 IMPLICIT NONE
10148
10149 INTEGER(mpi), INTENT(IN) :: n
10150 REAL(mpd), INTENT(IN) :: x(n)
10151 REAL(mpd), INTENT(OUT) :: y(n)
10152
10153 SAVE
10154 ! ...
10155 y=x ! copy to output vector
10156
10158END SUBROUTINE mvsolv
10159
10160
10161
10162!***********************************************************************
10163
10176
10177SUBROUTINE xloopn !
10178 USE mpmod
10179
10180 IMPLICIT NONE
10181 REAL(mps) :: catio
10182 REAL(mps) :: concu2
10183 REAL(mps) :: concut
10184 REAL, DIMENSION(2) :: ta
10185 REAL etime
10186 INTEGER(mpi) :: i
10187 INTEGER(mpi) :: iact
10188 INTEGER(mpi) :: iagain
10189 INTEGER(mpi) :: idx
10190 INTEGER(mpi) :: info
10191 INTEGER(mpi) :: ib
10192 INTEGER(mpi) :: ipoff
10193 INTEGER(mpi) :: icoff
10194 INTEGER(mpl) :: ioff
10195 INTEGER(mpi) :: itgbi
10196 INTEGER(mpi) :: ivgbi
10197 INTEGER(mpi) :: jcalcm
10198 INTEGER(mpi) :: k
10199 INTEGER(mpi) :: labelg
10200 INTEGER(mpi) :: litera
10201 INTEGER(mpi) :: lrej
10202 INTEGER(mpi) :: lun
10203 INTEGER(mpi) :: lunp
10204 INTEGER(mpi) :: minf
10205 INTEGER(mpi) :: mrati
10206 INTEGER(mpi) :: nan
10207 INTEGER(mpi) :: ncon
10208 INTEGER(mpi) :: nfaci
10209 INTEGER(mpi) :: nloopsol
10210 INTEGER(mpi) :: npar
10211 INTEGER(mpi) :: nrati
10212 INTEGER(mpi) :: nrej
10213 INTEGER(mpi) :: nsol
10214 INTEGER(mpi) :: inone
10215#ifdef LAPACK64
10216 INTEGER(mpi) :: infolp
10217 INTEGER(mpi) :: nfit
10218 INTEGER(mpl) :: imoff
10219#endif
10220
10221 REAL(mpd) :: stp
10222 REAL(mpd) :: dratio
10223 REAL(mpd) :: dwmean
10224 REAL(mpd) :: db
10225 REAL(mpd) :: db1
10226 REAL(mpd) :: db2
10227 REAL(mpd) :: dbdot
10228 REAL(mpd) :: dbsig
10229 LOGICAL :: btest
10230 LOGICAL :: warner
10231 LOGICAL :: warners
10232 LOGICAL :: warnerss
10233 LOGICAL :: warners3
10234 LOGICAL :: lsflag
10235 CHARACTER (LEN=7) :: cratio
10236 CHARACTER (LEN=7) :: cfacin
10237 CHARACTER (LEN=7) :: crjrat
10238 EXTERNAL avprds
10239 SAVE
10240 ! ...
10241
10242 ! Printout of algorithm for solution and important parameters ------
10243
10244 lun=lunlog ! log file
10245
10246 DO lunp=6,lunlog,lunlog-6
10247 WRITE(lunp,*) ' '
10248 WRITE(lunp,*) 'Solution algorithm: '
10249 WRITE(lunp,121) '=================================================== '
10250
10251 IF(metsol == 1) THEN
10252 WRITE(lunp,121) 'solution method:','matrix inversion'
10253 ELSE IF(metsol == 2) THEN
10254 WRITE(lunp,121) 'solution method:','diagonalization'
10255 ELSE IF(metsol == 3) THEN
10256 WRITE(lunp,121) 'solution method:','decomposition'
10257 ELSE IF(metsol == 4) THEN
10258 WRITE(lunp,121) 'solution method:', 'minres (Paige/Saunders)'
10259 ELSE IF(metsol == 5) THEN
10260 WRITE(lunp,121) 'solution method:', 'minres-qlp (Choi/Paige/Saunders)'
10261 IF(mrmode == 1) THEN
10262 WRITE(lunp,121) ' ', ' using QR factorization' ! only QR
10263 ELSE IF(mrmode == 2) THEN
10264 WRITE(lunp,121) ' ', ' using QLP factorization' ! only QLP
10265 ELSE
10266 WRITE(lunp,121) ' ', ' using QR and QLP factorization' ! QR followed by QLP
10267 WRITE(lunp,123) 'transition condition', mrtcnd
10268 END IF
10269 ELSE IF(metsol == 6) THEN
10270 WRITE(lunp,121) 'solution method:', &
10271 'gmres (generalized minimzation of residuals)'
10272#ifdef LAPACK64
10273 ELSE IF(metsol == 7) THEN
10274 IF (nagb > nvgb) THEN
10275 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSPTRF)'
10276 ELSE
10277 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPPTRF)'
10278 ENDIF
10279 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10280 ELSE IF(metsol == 8) THEN
10281 IF (nagb > nvgb) THEN
10282 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSYTRF)'
10283 ELSE
10284 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPOTRF)'
10285 ENDIF
10286 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10287#ifdef PARDISO
10288 ELSE IF(metsol == 9) THEN
10289 IF (matbsz < 2) THEN
10290 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (CSR3))'
10291 ELSE
10292 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (BSR3))'
10293 ENDIF
10294#endif
10295#endif
10296 END IF
10297 WRITE(lunp,123) 'convergence limit at Delta F=',dflim
10298 WRITE(lunp,122) 'maximum number of iterations=',mitera
10299 matrit=min(matrit,mitera)
10300 IF(matrit > 1) THEN
10301 WRITE(lunp,122) 'matrix recalculation up to ',matrit, '. iteration'
10302 END IF
10303 IF(metsol >= 4.AND.metsol < 7) THEN
10304 IF(matsto == 1) THEN
10305 WRITE(lunp,121) 'matrix storage:','full'
10306 ELSE IF(matsto == 2) THEN
10307 WRITE(lunp,121) 'matrix storage:','sparse'
10308 END IF
10309 WRITE(lunp,122) 'pre-con band-width parameter=',mbandw
10310 IF(mbandw == 0) THEN
10311 WRITE(lunp,121) 'pre-conditioning:','default'
10312 ELSE IF(mbandw < 0) THEN
10313 WRITE(lunp,121) 'pre-conditioning:','none!'
10314 ELSE IF(mbandw > 0) THEN
10315 IF(lprecm > 0) THEN
10316 WRITE(lunp,121) 'pre-conditioning=','skyline-matrix (rank preserving)'
10317 ELSE
10318 WRITE(lunp,121) 'pre-conditioning=','band-matrix'
10319 ENDIF
10320 END IF
10321 END IF
10322 IF(regpre == 0.0_mpd.AND.npresg == 0) THEN
10323 WRITE(lunp,121) 'using pre-sigmas:','no'
10324 ELSE
10325 ! FIXME: NPRESG contains parameters that failed the 'entries' cut...
10326 WRITE(lunp,124) 'pre-sigmas defined for', &
10327 REAL(100*npresg,mps)/REAL(nvgb,mps),' % of variable parameters'
10328 WRITE(lunp,123) 'default pre-sigma=',regpre
10329 END IF
10330 IF(nregul == 0) THEN
10331 WRITE(lunp,121) 'regularization:','no'
10332 ELSE
10333 WRITE(lunp,121) 'regularization:','yes'
10334 WRITE(lunp,123) 'regularization factor=',regula
10335 END IF
10336
10337 IF(chicut /= 0.0) THEN
10338 WRITE(lunp,121) 'Chi square cut equiv 3 st.dev applied'
10339 WRITE(lunp,123) '... in first iteration with factor',chicut
10340 WRITE(lunp,123) '... in second iteration with factor',chirem
10341 WRITE(lunp,121) ' (reduced by sqrt in next iterations)'
10342 END IF
10343 IF(iscerr > 0) THEN
10344 WRITE(lunp,121) 'Scaling of measurement errors applied'
10345 WRITE(lunp,123) '... factor for "global" measuements',dscerr(1)
10346 WRITE(lunp,123) '... factor for "local" measuements',dscerr(2)
10347 END IF
10348 IF(lhuber /= 0) THEN
10349 WRITE(lunp,122) 'Down-weighting of outliers in', lhuber,' iterations'
10350 WRITE(lunp,123) 'Cut on downweight fraction',dwcut
10351 END IF
10352
10353
10354121 FORMAT(1x,a40,3x,a)
10355122 FORMAT(1x,a40,3x,i0,a)
10356123 FORMAT(1x,a40,2x,e9.2)
10357124 FORMAT(1x,a40,3x,f5.1,a)
10358 END DO
10359
10360 ! initialization of iterations -------------------------------------
10361
10362 iitera=0
10363 nsol =0 ! counter for solutions
10364 info =0
10365 lsinfo=0
10366 stp =0.0_mpd
10367 stepl =real(stp,mps)
10368 concut=1.0e-12 ! initial constraint accuracy
10369 concu2=1.0e-06 ! constraint accuracy
10370 icalcm=1 ! require matrix calculation
10371 iterat=0 ! iteration counter
10372 iterat=-1
10373 litera=-2
10374 nloopsol=0 ! (new) solution from this nloopn
10375 nrej=0 ! reset number of rejects
10376 IF(metsol == 1) THEN
10377 wolfc2=0.5 ! not accurate
10378 minf=1
10379 ELSE IF(metsol == 2) THEN
10380 wolfc2=0.5 ! not acurate
10381 minf=2
10382 ELSE IF(metsol == 3) THEN
10383 wolfc2=0.5 ! not acurate
10384 minf=1
10385 ELSE IF(metsol == 4) THEN
10386 wolfc2=0.1 ! accurate
10387 minf=3
10388 ELSE IF(metsol == 5) THEN
10389 wolfc2=0.1 ! accurate
10390 minf=3
10391 ELSE IF(metsol == 6) THEN
10392 wolfc2=0.1 ! accurate
10393 minf=3
10394 ELSE
10395 wolfc2=0.5 ! not accurate
10396 minf=1
10397 END IF
10398
10399 ! check initial feasibility of constraint equations ----------------
10400
10401 WRITE(*,*) ' '
10402 IF(nofeas == 0) THEN ! make parameter feasible
10403 WRITE(lunlog,*) 'Checking feasibility of parameters:'
10404 WRITE(*,*) 'Checking feasibility of parameters:'
10405 CALL feasib(concut,iact) ! check feasibility
10406 IF(iact /= 0) THEN ! done ...
10407 WRITE(*,102) concut
10408 WRITE(*,*) ' parameters are made feasible'
10409 WRITE(lunlog,102) concut
10410 WRITE(lunlog,*) ' parameters are made feasible'
10411 ELSE ! ... was OK
10412 WRITE(*,*) ' parameters are feasible (i.e. satisfy constraints)'
10413 WRITE(lunlog,*) ' parameters are feasible (i.e. satisfy constraints)'
10414 END IF
10415 concut=concu2 ! cut for constraint check
10416 END IF
10417 iact=1 ! set flag for new data loop
10418 nofeas=0 ! set check-feasibility flag
10419
10420 WRITE(*,*) ' '
10421 WRITE(*,*)'Reading files and accumulating vectors/matrices ...'
10422 WRITE(*,*) ' '
10423 IF(monpg1>0) THEN
10424 WRITE(lunlog,*)
10425 WRITE(lunlog,*)'Reading files and accumulating vectors/matrices ...'
10426 WRITE(lunlog,*)
10427 END IF
10428
10429 rstart=etime(ta)
10430 iterat=-1
10431 litera= 0
10432 jcalcm=-1
10433 iagain= 0
10434
10435 icalcm=1
10436
10437 ! Block 1: data loop with vector (and matrix) calculation ----------
10438
10439 DO
10440 IF(iterat >= 0) THEN
10441 lcalcm=jcalcm+3 ! mode (1..4) of last loop
10442 IF(jcalcm+1 /= 0) THEN
10443 IF(iterat == 0) THEN
10444 CALL ploopa(6) ! header
10445 CALL ploopb(6)
10446 CALL ploopa(lunlog) ! iteration line
10447 CALL ploopb(lunlog)
10448 iterat=1
10449 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10450 ELSE
10451 IF(iterat /= litera) THEN
10452 CALL ploopb(6)
10453 ! CALL PLOOPA(LUNLOG)
10454 CALL ploopb(lunlog)
10455 litera=iterat
10456 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,delfun) ! fcn-value (with expected)
10457 IF(metsol == 4 .OR. metsol == 5) THEN ! extend to 6, i.e. GMRES?
10458 CALL gmpxy(2,real(iterat,mps),real(iitera,mps)) ! MINRES iterations
10459 END IF
10460 ELSE
10461 CALL ploopc(6) ! sub-iteration line
10462 CALL ploopc(lunlog)
10463 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10464 END IF
10465 END IF
10466 ELSE
10467 CALL ploopd(6) ! solution line
10468 CALL ploopd(lunlog)
10469 END IF
10470 rstart=etime(ta)
10471 ! CHK
10472 IF (iabs(jcalcm) <= 1) THEN
10473 idx=jcalcm+4
10474 times(idx )=(times(idx )*times(idx+3)+deltim) /(times(idx+3)+1.0)
10475 times(idx+3)= times(idx+3)+1.0
10476 END IF
10477 END IF
10478 jcalcm=icalcm
10479
10480 IF(icalcm >= 0) THEN ! ICALCM = +1 & 0
10481 CALL loopn ! data loop
10482 CALL addcst ! constraints
10483 lrej=nrej
10484 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! total number of rejects
10485 IF(3*nrej > nrecal) THEN
10486 WRITE(*,*) ' '
10487 WRITE(*,*) 'Data rejected in previous loop: '
10488 WRITE(*,*) ' ', &
10489 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', &
10490 nrejec(2), ' (huge) ',nrejec(3),' (large)'
10491 WRITE(*,*) 'Too many rejects (>33.3%) - stop'
10492 CALL peend(26,'Aborted, too many rejects')
10493 stop
10494 END IF
10495 ! fill second half (j>i) of global matrix for extended storage, experimental
10496 IF (icalcm == 1.AND.mextnd > 0) CALL mhalf2()
10497 END IF
10498 ! Block 2: new iteration with calculation of solution --------------
10499 IF(abs(icalcm) == 1) THEN ! ICALCM = +1 & -1
10500 DO i=1,nagb
10501 globalcorrections(i)=globalvector(i) ! copy rhs
10502 END DO
10503 DO i=1,nvgb
10504 itgbi=globalparvartototal(i)
10505 workspacelinesearch(i)=globalparameter(itgbi) ! copy X for line search
10506 END DO
10507
10508 iterat=iterat+1 ! increase iteration count
10509 IF(metsol == 1) THEN
10510 CALL minver ! inversion
10511 ELSE IF(metsol == 2) THEN
10512 CALL mdiags ! diagonalization
10513 ELSE IF(metsol == 3) THEN
10514 CALL mchdec ! decomposition
10515 ELSE IF(metsol == 4) THEN
10516 CALL mminrs ! MINRES
10517 ELSE IF(metsol == 5) THEN
10518 CALL mminrsqlp ! MINRES-QLP
10519 ELSE IF(metsol == 6) THEN
10520 WRITE(*,*) '... reserved for GMRES (not yet!)'
10521 CALL mminrs ! GMRES not yet
10522#ifdef LAPACK64
10523 ELSE IF(metsol == 7) THEN
10524 CALL mdptrf ! LAPACK (packed storage)
10525 ELSE IF(metsol == 8) THEN
10526 CALL mdutrf ! LAPACK (unpacked storage)
10527#ifdef PARDISO
10528 ELSE IF(metsol == 9) THEN
10529 CALL mspardiso ! Intel oneMKL PARDISO (sparse matrix (CSR3, upper triangle))
10530#endif
10531#endif
10532 END IF
10533 nloopsol=nloopn ! (new) solution for this nloopn
10534
10535 ! check feasibility and evtl. make step vector feasible
10536
10537 DO i=1,nvgb
10538 itgbi=globalparvartototal(i)
10539 globalparcopy(itgbi)=globalparameter(itgbi) ! save
10540 globalparameter(itgbi)=globalparameter(itgbi)+globalcorrections(i) ! update
10541 END DO
10542 CALL feasib(concut,iact) ! improve constraints
10543 concut=concu2 ! new cut for constraint check
10544 DO i=1,nvgb
10545 itgbi=globalparvartototal(i)
10546 globalcorrections(i)=globalparameter(itgbi)-globalparcopy(itgbi) ! feasible stp
10547 globalparameter(itgbi)=globalparcopy(itgbi) ! restore
10548 END DO
10549
10552 db2=dbdot(nvgb,globalvector,globalvector)
10553 delfun=real(db,mps)
10554 angras=real(db/sqrt(db1*db2),mps)
10555 dbsig=16.0_mpd*sqrt(max(db1,db2))*epsilon(db) ! significant change
10556
10557 ! do line search for this iteration/solution ?
10558 ! lsearch >2: all, =2: all with (next) chicut =1., =1: last, <1: none
10559 lsflag=(lsearch > 2 .OR. (lsearch == 2 .AND. chicut < 2.25) .OR. &
10560 (lsearch == 1 .AND. chicut < 2.25 .AND. (delfun <= dflim .OR. iterat >= mitera)))
10561 lsflag=lsflag .AND. (db > dbsig) ! require significant change
10562 IF (lsflag) THEN
10563 ! initialize line search based on slopes and prepare next
10564 CALL ptldef(wolfc2, 10.0, minf,10)
10565 IF(metsol == 1) THEN
10566 wolfc2=0.5 ! not accurate
10567 minf=3
10568 ELSE IF(metsol == 2) THEN
10569 wolfc2=0.5 ! not acurate
10570 minf=3
10571 ELSE IF(metsol == 3) THEN
10572 wolfc2=0.5 ! not acurate
10573 minf=3
10574 ELSE IF(metsol == 4) THEN
10575 wolfc2=0.1 ! accurate
10576 minf=4
10577 ELSE IF(metsol == 5) THEN
10578 wolfc2=0.1 ! accurate
10579 minf=4
10580 ELSE IF(metsol == 6) THEN
10581 wolfc2=0.1 ! accurate
10582 minf=4
10583 ELSE
10584 wolfc2=0.5 ! not accurate
10585 minf=3
10586 END IF
10587 ENDIF
10588
10589 ! change significantly negative ?
10590 IF(db <= -dbsig) THEN
10591 WRITE(*,*) 'Function not decreasing:',db
10592 IF(db > -1.0e-3_mpd) THEN ! 100311, VB/CK: allow some margin for numerics
10593 iagain=iagain+1
10594 IF (iagain <= 1) THEN
10595 WRITE(*,*) '... again matrix calculation'
10596 icalcm=1
10597 cycle
10598 ELSE
10599 WRITE(*,*) '... aborting iterations'
10600 GO TO 90
10601 END IF
10602 ELSE
10603 WRITE(*,*) '... stopping iterations'
10604 iagain=-1
10605 GO TO 90
10606 END IF
10607 ELSE
10608 iagain=0
10609 END IF
10610 icalcm=0 ! switch
10611 ENDIF
10612 ! Block 3: line searching ------------------------------------------
10613
10614 IF(icalcm+2 == 0) EXIT
10615 IF (lsflag) THEN
10616 CALL ptline(nvgb,workspacelinesearch, & ! current parameter values
10617 flines, & ! chi^2 function value
10618 globalvector, & ! gradient
10619 globalcorrections, & ! step vector stp
10620 stp, & ! returned step factor
10621 info) ! returned information
10622 ! WRITE(*,*) 'PTLINE returns INFO, STP=',INFO, STP
10623 ELSE ! skip line search
10624 info=10
10625 stepl=1.0
10626 IF (nloopn == nloopsol) THEN ! new solution: update corrections
10628 ENDIF
10629 ENDIF
10630 lsinfo=info
10631
10632 stepl=real(stp,mps)
10633 nan=0
10634 DO i=1,nvgb
10635 itgbi=globalparvartototal(i)
10636 IF ((.NOT.(workspacelinesearch(i) <= 0.0_mpd)).AND. &
10637 (.NOT.(workspacelinesearch(i) > 0.0_mpd))) nan=nan+1
10638 globalparameter(itgbi)=workspacelinesearch(i) ! current parameter values
10639 END DO
10640
10641 IF (nan > 0) THEN
10642 WRITE(*,*) 'Result vector containes ', nan,' NaNs - stop'
10643 CALL peend(25,'Aborted, result vector contains NaNs')
10644 stop
10645 END IF
10646
10647 ! subito exit, if required -----------------------------------------
10648
10649 IF(isubit /= 0) THEN ! subito
10650 WRITE(*,*) 'Subito! Exit after first step.'
10651 GO TO 90
10652 END IF
10653
10654 IF(info == 0) THEN
10655 WRITE(*,*) 'INFO=0 should not happen (line search input err)'
10656 IF (iagain <= 0) THEN
10657 icalcm=1
10658 cycle
10659 ENDIF
10660 END IF
10661 IF(info < 0 .OR. nloopn == nloopsol) cycle
10662 ! Block 4: line search convergence ---------------------------------
10663
10664 CALL ptlprt(lunlog)
10665 CALL feasib(concut,iact) ! check constraints
10666 IF(iact /= 0.OR.chicut > 1.0) THEN
10667 icalcm=-1
10668 IF(iterat < matrit) icalcm=+1
10669 cycle ! iterate
10670 END IF
10671 IF(delfun <= dflim) GO TO 90 ! convergence
10672 IF(iterat >= mitera) GO TO 90 ! ending
10673 icalcm=-1
10674 IF(iterat < matrit) icalcm=+1
10675 cycle ! next iteration
10676
10677 ! Block 5: iteration ending ----------------------------------------
10678
1067990 icalcm=-2
10680 END DO
10681 IF(nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) /= 0) THEN
10682 WRITE(*,*) ' '
10683 WRITE(*,*) 'Data rejected in last loop: '
10684 WRITE(*,*) ' ', &
10685 nrejec(0), ' (rank deficit/NaN) ',nrejec(1),' (Ndf=0) ', &
10686 nrejec(2), ' (huge) ',nrejec(3),' (large)'
10687 END IF
10688
10689 ! monitoring of residuals
10690 IF (imonit > 0 .AND. btest(imonit,1)) CALL monres
10691 IF (lunmon > 0) CLOSE(unit=lunmon)
10692
10693 ! construct inverse from diagonalization
10694 IF(metsol == 2) CALL zdiags
10695
10696 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
10697#ifdef LAPACK64
10698 IF (metsol == 7.OR.metsol == 8) THEN
10699 ! inverse from factorization
10700 ! loop over blocks (multiple blocks only with elimination !)
10701 DO ib=1,npblck
10702 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10703 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10704 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10705 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10706 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
10707 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
10708 IF (nfit > npar) THEN
10709 ! monitor progress
10710 IF(monpg1 > 0) THEN
10711 WRITE(lunlog,*) 'Inverse of global matrix from LDLt factorization'
10713 END IF
10714 IF (matsto == 1) THEN
10715 !$POMP INST BEGIN(dsptri)
10716 CALL dsptri('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),workspaced,infolp)
10717 IF(infolp /= 0) print *, ' DSPTRI failed: ', infolp
10718 !$POMP INST END(dsptri)
10719 IF(monpg1 > 0) CALL monend()
10720 ELSE
10721 !$POMP INST BEGIN(dsytri)
10722 CALL dsytri('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
10723 lapackipiv(ipoff+1:),workspaced,infolp)
10724 IF(infolp /= 0) print *, ' DSYTRI failed: ', infolp
10725 !$POMP INST END(dsytri)
10726 IF(monpg1 > 0) CALL monend()
10727 END IF
10728 ELSE
10729 IF(monpg1 > 0) THEN
10730 WRITE(lunlog,*) 'Inverse of global matrix from LLt factorization'
10732 END IF
10733 IF (matsto == 1) THEN
10734 !$POMP INST BEGIN(dpptri)
10735 CALL dpptri('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
10736 IF(infolp /= 0) print *, ' DPPTRI failed: ', infolp
10737 !$POMP INST END(dpptri)
10738 ELSE
10739 !$POMP INST BEGIN(dpotri)
10740 CALL dpotri('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
10741 IF(infolp /= 0) print *, ' DPOTRI failed: ', infolp
10742 !$POMP INST END(dpotri)
10743 END IF
10744 IF(monpg1 > 0) CALL monend()
10745 END IF
10746 END DO
10747 END IF
10748#endif
10749 !use elimination for constraints ?
10750 IF(nfgb < nvgb) THEN
10751 ! extend, transform matrix
10752 ! loop over blocks
10753 DO ib=1,npblck
10754 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10755 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10756 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10757 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10758 DO i=npar-ncon+1,npar
10759 ioff=globalrowoffsets(i+ipoff)+ipoff
10760 globalmatd(ioff+1:ioff+i)=0.0_mpd
10761 END DO
10762 END DO
10763 ! monitor progress
10764 IF(monpg1 > 0) THEN
10765 WRITE(lunlog,*) 'Expansion of global matrix (A->Q*A*Q^t)'
10767 END IF
10768 IF(icelim < 2) THEN
10769 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.false.) ! Q*A*Q^t
10770#ifdef LAPACK64
10771 ELSE ! unpack storage, use LAPACK
10772 CALL lpavat(.false.)
10773#endif
10774 END IF
10775 IF(monpg1 > 0) CALL monend()
10776 END IF
10777 END IF
10778
10779 dwmean=sumndf/real(ndfsum,mpd)
10780 dratio=fvalue/dwmean/real(ndfsum-nfgb,mpd)
10781 catio=real(dratio,mps)
10782 IF(nloopn /= 1.AND.lhuber /= 0) THEN
10783 catio=catio/0.9326 ! correction Huber downweighting (in global chi2)
10784 END IF
10785 mrati=nint(100.0*catio,mpi)
10786
10787 DO lunp=6,lunlog,lunlog-6
10788 WRITE(lunp,*) ' '
10789 IF (nfilw <= 0) THEN
10790 WRITE(lunp,*) 'Sum(Chi^2)/Sum(Ndf) =',fvalue
10791 WRITE(lunp,*) ' / (',ndfsum,'-',nfgb,')'
10792 WRITE(lunp,*) ' =',dratio
10793 ELSE
10794 WRITE(lunp,*) 'Sum(W*Chi^2)/Sum(Ndf)/<W> =',fvalue
10795 WRITE(lunp,*) ' / (',ndfsum,'-', nfgb,')'
10796 WRITE(lunp,*) ' /',dwmean
10797 WRITE(lunp,*) ' =',dratio
10798 END IF
10799 WRITE(lunp,*) ' '
10800 IF(nloopn /= 1.AND.lhuber /= 0) WRITE(lunp,*) &
10801 ' with correction for down-weighting ',catio
10802 END DO
10803 nrej=nrejec(0)+nrejec(1)+nrejec(2)+nrejec(3) ! total number of rejects
10804
10805 ! ... the end with exit code ???????????????????????????????????????
10806
10807 ! WRITE(*,199) ! write exit code
10808 ! + '-----------------------------------------------------------'
10809 ! IF(ITEXIT.EQ.0) WRITE(*,199)
10810 ! + 'Exit code = 0: Convergence reached'
10811 ! IF(ITEXIT.EQ.1) WRITE(*,199)
10812 ! + 'Exit code = 1: No improvement in last iteration'
10813 ! IF(ITEXIT.EQ.2) WRITE(*,199)
10814 ! + 'Exit code = 2: Maximum number of iterations reached'
10815 ! IF(ITEXIT.EQ.3) WRITE(*,199)
10816 ! + 'Exit code = 3: Failure'
10817 ! WRITE(*,199)
10818 ! + '-----------------------------------------------------------'
10819 ! WRITE(*,199) ' '
10820
10821
10822 nrati=nint(10000.0*real(nrej,mps)/real(nrecal,mps),mpi)
10823 WRITE(crjrat,197) 0.01_mpd*real(nrati,mpd)
10824 nfaci=nint(100.0*sqrt(catio),mpi)
10825
10826 WRITE(cratio,197) 0.01_mpd*real(mrati,mpd)
10827 WRITE(cfacin,197) 0.01_mpd*real(nfaci,mpd)
10828
10829 warner=.false. ! warnings
10830 IF(mrati < 90.OR.mrati > 110) warner=.true.
10831 IF(nrati > 100) warner=.true.
10832 IF(ncgbe /= 0) warner=.true.
10833 warners = .false. ! severe warnings
10834 IF(nalow /= 0) warners=.true.
10835 warnerss = .false. ! more severe warnings
10836 IF(nmiss1 /= 0) warnerss=.true.
10837 IF(iagain /= 0) warnerss=.true.
10838 IF(ndefec /= 0) warnerss=.true.
10839 IF(ndefpg /= 0) warnerss=.true.
10840 warners3 = .false. ! more severe warnings
10841 IF(nrderr /= 0) warners3=.true.
10842
10843 IF(warner.OR.warners.OR.warnerss.Or.warners3) THEN
10844 WRITE(*,199) ' '
10845 WRITE(*,199) ' '
10846 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
10847 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
10848 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
10849 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
10850 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
10851 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
10852 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
10853
10854 IF(mrati < 90.OR.mrati > 110) THEN
10855 WRITE(*,199) ' '
10856 WRITE(*,*) ' Chi^2/Ndf = ',cratio, ' (should be close to 1)'
10857 WRITE(*,*) ' => multiply all input standard ', &
10858 'deviations by factor',cfacin
10859 END IF
10860
10861 IF(nrati > 100) THEN
10862 WRITE(*,199) ' '
10863 WRITE(*,*) ' Fraction of rejects =',crjrat,' %', &
10864 ' (should be far below 1 %)'
10865 WRITE(*,*) ' => please provide correct mille data'
10866 CALL chkrej ! check (and print) rejection details
10867 END IF
10868
10869 IF(iagain /= 0) THEN
10870 WRITE(*,199) ' '
10871 WRITE(*,*) ' Matrix not positiv definite '// &
10872 '(function not decreasing)'
10873 WRITE(*,*) ' => please provide correct mille data'
10874 END IF
10875
10876 IF(ndefec /= 0) THEN
10877 WRITE(*,199) ' '
10878 WRITE(*,*) ' Rank defect =',ndefec, &
10879 ' for global matrix, should be 0'
10880 WRITE(*,*) ' => please provide correct mille data'
10881 END IF
10882
10883 IF(ndefpg /= 0) THEN
10884 WRITE(*,199) ' '
10885 WRITE(*,*) ' Rank defect for',ndefpg, &
10886 ' parameter groups, should be 0'
10887 WRITE(*,*) ' => please provide correct mille data'
10888 END IF
10889
10890 IF(nmiss1 /= 0) THEN
10891 WRITE(*,199) ' '
10892 WRITE(*,*) ' Rank defect =',nmiss1, &
10893 ' for constraint equations, should be 0'
10894 WRITE(*,*) ' => please correct constraint definition'
10895 END IF
10896
10897 IF(ncgbe /= 0) THEN
10898 WRITE(*,199) ' '
10899 WRITE(*,*) ' Number of empty constraints =',ncgbe, ', should be 0'
10900 WRITE(*,*) ' => please check constraint definition, mille data'
10901 END IF
10902
10903 IF(nxlow /= 0) THEN
10904 WRITE(*,199) ' '
10905 WRITE(*,*) ' Possible rank defects =',nxlow, ' for global matrix'
10906 WRITE(*,*) ' (too few accepted entries)'
10907 WRITE(*,*) ' => please check mille data and ENTRIES cut'
10908 END IF
10909
10910 IF(nalow /= 0) THEN
10911 WRITE(*,199) ' '
10912 WRITE(*,*) ' Possible bad elements =',nalow, ' in global vector'
10913 WRITE(*,*) ' (toos few accepted entries)'
10914 IF(ipcntr > 0) WRITE(*,*) ' (indicated in millepede.res by counts<0)'
10915 WRITE(*,*) ' => please check mille data and ENTRIES cut'
10916 END IF
10917
10918 IF(nrderr /= 0) THEN
10919 WRITE(*,199) ' '
10920 WRITE(*,*) ' Binary file(s) with read errors =',nrderr, ' (treated as EOF)'
10921 WRITE(*,*) ' => please check mille data'
10922 END IF
10923
10924 WRITE(*,199) ' '
10925 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
10926 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
10927 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
10928 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
10929 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
10930 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
10931 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
10932 WRITE(*,199) ' '
10933
10934 ENDIF
10935
10936 CALL mend ! modul ending
10937
10938 ! ------------------------------------------------------------------
10939
10940 IF(metsol == 1) THEN
10941
10942 ELSE IF(metsol == 2) THEN
10943 ! CALL zdiags moved up (before qlssq)
10944 ELSE IF(metsol == 3) THEN
10945 ! decomposition - nothing foreseen yet
10946 ELSE IF(metsol == 4 .OR. metsol == 5) THEN
10947 ! errors and correlations from MINRES
10948 DO k=1,mnrsel
10949 labelg=lbmnrs(k)
10950 IF(labelg == 0) cycle
10951 itgbi=inone(labelg)
10952 ivgbi=0
10953 IF(itgbi /= 0) ivgbi=globalparlabelindex(2,itgbi)
10954 IF(ivgbi < 0) ivgbi=0
10955 IF(ivgbi == 0) cycle
10956 ! determine error and global correlation for parameter IVGBI
10957 IF (metsol == 4) THEN
10958 CALL solglo(ivgbi)
10959 ELSE
10960 CALL solgloqlp(ivgbi)
10961 ENDIF
10962 END DO
10963
10964 ELSE IF(metsol == 6) THEN
10965
10966#ifdef LAPACK64
10967 ELSE IF(metsol == 7) THEN
10968 ! LAPACK - nothing foreseen yet
10969#endif
10970 END IF
10971
10972 CALL prtglo ! print result
10973
10974 IF (warners3) THEN
10975 CALL peend(4,'Ended with severe warnings (bad binary file(s))')
10976 ELSE IF (warnerss) THEN
10977 CALL peend(3,'Ended with severe warnings (bad global matrix)')
10978 ELSE IF (warners) THEN
10979 CALL peend(2,'Ended with severe warnings (insufficient measurements)')
10980 ELSE IF (warner) THEN
10981 CALL peend(1,'Ended with warnings (bad measurements)')
10982 ELSE
10983 CALL peend(0,'Ended normally')
10984 END IF
10985
10986102 FORMAT(' Call FEASIB with cut=',g10.3)
10987 ! 103 FORMAT(1X,A,G12.4)
10988197 FORMAT(f7.2)
10989199 FORMAT(7x,a)
10990END SUBROUTINE xloopn ! standard solution
10991
10992
10997
10998SUBROUTINE chkrej
10999 USE mpmod
11000 USE mpdalc
11001
11002 IMPLICIT NONE
11003 INTEGER(mpi) :: i
11004 INTEGER(mpi) :: kfl
11005 INTEGER(mpi) :: kmin
11006 INTEGER(mpi) :: kmax
11007 INTEGER(mpi) :: nrc
11008 INTEGER(mpi) :: nrej
11009
11010 REAL(mps) :: fmax
11011 REAL(mps) :: fmin
11012 REAL(mps) :: frac
11013
11014 REAL(mpd) :: sumallw
11015 REAL(mpd) :: sumrejw
11016
11017 sumallw=0.; sumrejw=0.;
11018 kmin=0; kmax=0;
11019 fmax=-1.; fmin=2;
11020
11021 DO i=1,nfilb
11022 kfl=kfd(2,i)
11023 nrc=-kfd(1,i)
11024 IF (nrc > 0) THEN
11025 nrej=nrc-jfd(kfl)
11026 sumallw=sumallw+real(nrc,mpd)*wfd(kfl)
11027 sumrejw=sumrejw+real(nrej,mpd)*wfd(kfl)
11028 frac=real(nrej,mps)/real(nrc,mps)
11029 IF (frac > fmax) THEN
11030 kmax=kfl
11031 fmax=frac
11032 END IF
11033 IF (frac < fmin) THEN
11034 kmin=kfl
11035 fmin=frac
11036 END IF
11037 END IF
11038 END DO
11039 IF (nfilw > 0) &
11040 WRITE(*,"(' Weighted fraction =',F8.2,' %')") 100.*sumrejw/sumallw
11041 IF (nfilb > 1) THEN
11042 WRITE(*,"(' File with max. fraction ',I6,' :',F8.2,' %')") kmax, 100.*fmax
11043 WRITE(*,"(' File with min. fraction ',I6,' :',F8.2,' %')") kmin, 100.*fmin
11044 END IF
11045
11046END SUBROUTINE chkrej
11047
11061
11062SUBROUTINE filetc
11063 USE mpmod
11064 USE mpdalc
11065
11066 IMPLICIT NONE
11067 INTEGER(mpi) :: i
11068 INTEGER(mpi) :: ia
11069 INTEGER(mpi) :: iargc
11070 INTEGER(mpi) :: ib
11071 INTEGER(mpi) :: ie
11072 INTEGER(mpi) :: ierrf
11073 INTEGER(mpi) :: ieq
11074 INTEGER(mpi) :: ifilb
11075 INTEGER(mpi) :: ioff
11076 INTEGER(mpi) :: iopt
11077 INTEGER(mpi) :: ios
11078 INTEGER(mpi) :: iosum
11079 INTEGER(mpi) :: it
11080 INTEGER(mpi) :: k
11081 INTEGER(mpi) :: mat
11082 INTEGER(mpi) :: nab
11083 INTEGER(mpi) :: nline
11084 INTEGER(mpi) :: npat
11085 INTEGER(mpi) :: ntext
11086 INTEGER(mpi) :: nu
11087 INTEGER(mpi) :: nuf
11088 INTEGER(mpi) :: nums
11089 INTEGER(mpi) :: nufile
11090 INTEGER(mpi) :: lenfileInfo
11091 INTEGER(mpi) :: lenFileNames
11092 INTEGER(mpi) :: matint
11093 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: vecfileInfo
11094 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArray
11095 INTEGER(mpl) :: rows
11096 INTEGER(mpl) :: cols
11097 INTEGER(mpl) :: newcols
11098 INTEGER(mpl) :: length
11099
11100 CHARACTER (LEN=1024) :: text
11101 CHARACTER (LEN=1024) :: fname
11102 CHARACTER (LEN=14) :: bite(3)
11103 CHARACTER (LEN=32) :: keystx
11104 INTEGER(mpi), PARAMETER :: mnum=100
11105 REAL(mpd) :: dnum(mnum)
11106
11107#ifdef READ_C_FILES
11108 INTERFACE
11109 SUBROUTINE initc(nfiles) BIND(c)
11110 USE iso_c_binding
11111 INTEGER(c_int), INTENT(IN), VALUE :: nfiles
11112 END SUBROUTINE initc
11113 END INTERFACE
11114#endif
11115
11116 SAVE
11117 DATA bite/'C_binary','text ','Fortran_binary'/
11118 ! ...
11119 CALL mstart('FILETC/X')
11120
11121 nuf=1 ! C binary is default
11122 DO i=1,8
11123 times(i)=0.0
11124 END DO
11125
11126 ! read command line options ----------------------------------------
11127
11128 filnam=' ' ! print command line options and find steering file
11129 DO i=1,iargc()
11130 IF(i == 1) THEN
11131 WRITE(*,*) ' '
11132 WRITE(*,*) 'Command line options: '
11133 WRITE(*,*) '--------------------- '
11134 END IF
11135 CALL getarg(i,text) ! get I.th text from command line
11136 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11137 WRITE(*,101) i,text(1:nab) ! echo print
11138 IF(text(ia:ia) /= '-') THEN
11139 nu=nufile(text(ia:ib)) ! inquire on file existence
11140 IF(nu == 2) THEN ! existing text file
11141 IF(filnam /= ' ') THEN
11142 WRITE(*,*) 'Second text file in command line - stop'
11143 CALL peend(12,'Aborted, second text file in command line')
11144 stop
11145 ELSE
11146 filnam=text
11147 END IF
11148 ELSE
11149 WRITE(*,*) 'Open error for file:',text(ia:ib),' - stop'
11150 CALL peend(16,'Aborted, open error for file')
11151 IF(text(ia:ia) /= '/') THEN
11152 CALL getenv('PWD',text)
11153 CALL rltext(text,ia,ib,nab)
11154 WRITE(*,*) 'PWD:',text(ia:ib)
11155 END IF
11156 stop
11157 END IF
11158 ELSE
11159 IF(index(text(ia:ib),'b') /= 0) THEN
11160 mdebug=3 ! debug flag
11161 WRITE(*,*) 'Debugging requested'
11162 END IF
11163 it=index(text(ia:ib),'t')
11164 IF(it /= 0) THEN
11165 ictest=1 ! internal test files
11166 ieq=index(text(ia+it:ib),'=')+it
11167 IF (it /= ieq) THEN
11168 IF (index(text(ia+ieq:ib),'SL0' ) /= 0) ictest=2
11169 IF (index(text(ia+ieq:ib),'SLE' ) /= 0) ictest=3
11170 IF (index(text(ia+ieq:ib),'BP' ) /= 0) ictest=4
11171 IF (index(text(ia+ieq:ib),'BRLF') /= 0) ictest=5
11172 IF (index(text(ia+ieq:ib),'BRLC') /= 0) ictest=6
11173 END IF
11174 END IF
11175 IF(index(text(ia:ib),'s') /= 0) isubit=1 ! like "subito"
11176 IF(index(text(ia:ib),'f') /= 0) iforce=1 ! like "force"
11177 IF(index(text(ia:ib),'c') /= 0) icheck=1 ! like "checkinput"
11178 IF(index(text(ia:ib),'C') /= 0) icheck=2 ! like "checkinput 2"
11179 END IF
11180 IF(i == iargc()) WRITE(*,*) '--------------------- '
11181 END DO
11182
11183
11184 ! create test files for option -t ----------------------------------
11185
11186 IF(ictest >= 1) THEN
11187 WRITE(*,*) ' '
11188 IF (ictest == 1) THEN
11189 CALL mptest ! 'wire chamber'
11190 ELSE
11191 CALL mptst2(ictest-2) ! 'silicon tracker'
11192 END IF
11193 IF(filnam == ' ') filnam='mp2str.txt'
11194 WRITE(*,*) ' '
11195 END IF
11196
11197 ! check default steering file with file-name "steerfile" -----------
11198
11199 IF(filnam == ' ') THEN ! check default steering file
11200 text='steerfile'
11201 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11202 nu=nufile(text(ia:ib)) ! inquire on file existence and type
11203 IF(nu > 0) THEN
11204 filnam=text
11205 ELSE
11206 CALL peend(10,'Aborted, no steering file')
11207 stop 'in FILETC: no steering file. .'
11208 END IF
11209 END IF
11210
11211
11212 ! open, read steering file:
11213 ! end
11214 ! fortranfiles
11215 ! cfiles
11216
11217
11218 CALL rltext(filnam,ia,ib,nfnam) ! return indices for non-blank area
11219 WRITE(*,*) ' '
11220 WRITE(*,*) 'Listing of steering file: ',filnam(1:nfnam)
11221 WRITE(*,*) '-------------------------'
11222 OPEN(10,file=filnam(1:nfnam),iostat=ios)
11223 IF(ios /= 0) THEN
11224 WRITE(*,*) 'Open error for steering file - stop'
11225 CALL peend(11,'Aborted, open error for steering file')
11226 IF(filnam(1:1) /= '/') THEN
11227 CALL getenv('PWD',text)
11228 CALL rltext(text,ia,ib,nab)
11229 WRITE(*,*) 'PWD:',text(ia:ib)
11230 END IF
11231 stop
11232 END IF
11233 ifile =0
11234 nfiles=0
11235
11236 lenfileinfo=2
11237 lenfilenames=0
11238 rows=6; cols=lenfileinfo
11239 CALL mpalloc(vecfileinfo,rows,cols,'file info from steering')
11240 nline=0
11241 DO
11242 READ(10,102,iostat=ierrf) text ! read steering file
11243 IF (ierrf < 0) EXIT ! eof
11244 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11245 nline=nline+1
11246 IF(nline <= 50) THEN ! print up to 50 lines
11247 WRITE(*,101) nline,text(1:nab)
11248 IF(nline == 50) WRITE(*,*) ' ...'
11249 END IF
11250 IF(ia == 0) cycle ! skip empty lines
11251
11252 CALL rltext(text,ia,ib,nab) ! test content 'end'
11253 IF(ib == ia+2) THEN
11254 mat=matint(text(ia:ib),'end',npat,ntext)
11255 IF(mat == max(npat,ntext)) THEN ! exact matching
11256 text=' '
11257 CALL intext(text,nline)
11258 WRITE(*,*) ' end-statement after',nline,' text lines'
11259 EXIT
11260 END IF
11261 END IF
11262
11263 keystx='fortranfiles'
11264 mat=matint(text(ia:ib),keystx,npat,ntext)
11265 IF(mat == max(npat,ntext)) THEN ! exact matching
11266 nuf=3
11267 ! WRITE(*,*) 'Fortran files'
11268 cycle
11269 END IF
11270
11271 keystx='Cfiles'
11272 mat=matint(text(ia:ib),keystx,npat,ntext)
11273 IF(mat == max(npat,ntext)) THEN ! exact matching
11274 nuf=1
11275 ! WRITE(*,*) 'Cfiles'
11276 cycle
11277 END IF
11278
11279 keystx='closeandreopen' ! don't keep binary files open
11280 mat=matint(text(ia:ib),keystx,npat,ntext)
11281 IF(mat == max(npat,ntext)) THEN ! exact matching
11282 keepopen=0
11283 cycle
11284 END IF
11285
11286 ! file names
11287 ! check for file options (' -- ')
11288 ie=ib
11289 iopt=index(text(ia:ib),' -- ')
11290 IF (iopt > 0) ie=iopt-1
11291
11292 IF(nab == 0) cycle
11293 nu=nufile(text(ia:ie)) ! inquire on file existence
11294 IF(nu > 0) THEN ! existing file
11295 IF (nfiles == lenfileinfo) THEN ! increase length
11296 CALL mpalloc(temparray,rows,cols,'temp file info from steering')
11297 temparray=vecfileinfo
11298 CALL mpdealloc(vecfileinfo)
11299 lenfileinfo=lenfileinfo*2
11300 newcols=lenfileinfo
11301 CALL mpalloc(vecfileinfo,rows,newcols,'file info from steering')
11302 vecfileinfo(:,1:cols)=temparray(:,1:cols)
11303 CALL mpdealloc(temparray)
11304 cols=newcols
11305 ENDIF
11306 nfiles=nfiles+1 ! count number of files
11307 IF(nu == 1) nu=nuf !
11308 lenfilenames=lenfilenames+ie-ia+1 ! total length of file names
11309 vecfileinfo(1,nfiles)=nline ! line number
11310 vecfileinfo(2,nfiles)=nu ! cbinary =1, text =2, fbinary=3
11311 vecfileinfo(3,nfiles)=ia ! file name start
11312 vecfileinfo(4,nfiles)=ie ! file name end
11313 vecfileinfo(5,nfiles)=iopt ! option start
11314 vecfileinfo(6,nfiles)=ib ! option end
11315 ELSE
11316 ! WRITE(*,*) 'Open error for file ',TEXT(IA:IB)
11317 ! STOP
11318 END IF
11319 END DO
11320 rewind 10
11321 ! read again to fill dynamic arrays with file info
11322 length=nfiles
11323 CALL mpalloc(mfd,length,'file type')
11324 CALL mpalloc(nfd,length,'file line (in steering)')
11325 CALL mpalloc(lfd,length,'file name length')
11326 CALL mpalloc(ofd,length,'file option')
11327 length=lenfilenames
11328 CALL mpalloc(tfd,length,'file name')
11329 nline=0
11330 i=1
11331 ioff=0
11332 DO
11333 READ(10,102,iostat=ierrf) text ! read steering file
11334 IF (ierrf < 0) EXIT ! eof
11335 nline=nline+1
11336 IF (nline == vecfileinfo(1,i)) THEN
11337 nfd(i)=vecfileinfo(1,i)
11338 mfd(i)=vecfileinfo(2,i)
11339 ia=vecfileinfo(3,i)-1
11340 lfd(i)=vecfileinfo(4,i)-ia ! length file name
11341 DO k=1,lfd(i)
11342 tfd(ioff+k)=text(ia+k:ia+k)
11343 END DO
11344 ! tfd(i)=text(vecFileInfo(3,i):vecFileInfo(4,i)) ! file name
11345 ioff=ioff+lfd(i)
11346 ofd(i)=1.0 ! option for file
11347 IF (vecfileinfo(5,i) > 0) THEN
11348 CALL ratext(text(vecfileinfo(5,i)+4:vecfileinfo(6,i)),nums,dnum,mnum) ! translate text to DP numbers
11349 IF (nums > 0) ofd(i)=real(dnum(1),mps)
11350 END IF
11351 i=i+1
11352 IF (i > nfiles) EXIT
11353 ENDIF
11354 ENDDO
11355 CALL mpdealloc(vecfileinfo)
11356 rewind 10
11357 ! additional info for binary files
11358 length=nfiles; rows=2
11359 CALL mpalloc(ifd,length,'integrated record numbers (=offset)')
11360 CALL mpalloc(jfd,length,'number of accepted records')
11361 CALL mpalloc(kfd,rows,length,'number of records in file, file order')
11362 CALL mpalloc(dfd,length,'ndf sum')
11363 CALL mpalloc(xfd,length,'max. record size')
11364 CALL mpalloc(wfd,length,'file weight')
11365 CALL mpalloc(cfd,length,'chi2 sum')
11366 CALL mpalloc(sfd,rows,length,'start, end of file name in TFD')
11367 CALL mpalloc(yfd,length,'modification date')
11368 yfd=0
11369 !
11370 WRITE(*,*) '-------------------------'
11371 WRITE(*,*) ' '
11372
11373 ! print table of files ---------------------------------------------
11374
11375 IF (mprint > 1) THEN
11376 WRITE(*,*) 'Table of files:'
11377 WRITE(*,*) '---------------'
11378 END IF
11379 WRITE(8,*) ' '
11380 WRITE(8,*) 'Text and data files:'
11381 ioff=0
11382 DO i=1,nfiles
11383 DO k=1,lfd(i)
11384 fname(k:k)=tfd(ioff+k)
11385 END DO
11386 ! fname=tfd(i)(1:lfd(i))
11387 IF (mprint > 1) WRITE(*,103) i,bite(mfd(i)),fname(1:lfd(i))
11388 WRITE(8,103) i,bite(mfd(i)),fname(1:lfd(i))
11389 ioff=ioff+lfd(i)
11390 END DO
11391 IF (mprint > 1) THEN
11392 WRITE(*,*) '---------------'
11393 WRITE(*,*) ' '
11394 END IF
11395
11396 ! open the binary Fortran (data) files on unit 11, 12, ...
11397
11398 iosum=0
11399 nfilf=0
11400 nfilb=0
11401 nfilw=0
11402 ioff=0
11403 ifilb=0
11404 IF (keepopen < 1) ifilb=1
11405 DO i=1,nfiles
11406 IF(mfd(i) == 3) THEN
11407 nfilf=nfilf+1
11408 nfilb=nfilb+1
11409 ! next file name
11410 sfd(1,nfilb)=ioff
11411 sfd(2,nfilb)=lfd(i)
11412 CALL binopn(nfilb,ifilb,ios)
11413 IF(ios == 0) THEN
11414 wfd(nfilb)=ofd(i)
11415 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11416 ELSE ! failure
11417 iosum=iosum+1
11418 nfilf=nfilf-1
11419 nfilb=nfilb-1
11420 END IF
11421 END IF
11422 ioff=ioff+lfd(i)
11423 END DO
11424
11425 ! open the binary C files
11426
11427 nfilc=-1
11428 ioff=0
11429 DO i=1,nfiles ! Cfiles
11430 IF(mfd(i) == 1) THEN
11431#ifdef READ_C_FILES
11432 IF(nfilc < 0) THEN ! initialize
11433 CALL initc(max(nfiles,mthrdr)) ! uncommented by GF
11434 nfilc=0
11435 END IF
11436 nfilc=nfilc+1
11437 nfilb=nfilb+1
11438 ! next file name
11439 sfd(1,nfilb)=ioff
11440 sfd(2,nfilb)=lfd(i)
11441 CALL binopn(nfilb,ifilb,ios)
11442 IF(ios == 0) THEN
11443 wfd(nfilb)=ofd(i)
11444 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11445 ELSE ! failure
11446 iosum=iosum+1
11447 nfilc=nfilc-1
11448 nfilb=nfilb-1
11449 END IF
11450#else
11451 WRITE(*,*) 'Opening of C-files not supported.'
11452 ! GF add
11453 iosum=iosum+1
11454 ! GF add end
11455#endif
11456 END IF
11457 ioff=ioff+lfd(i)
11458 END DO
11459
11460 DO k=1,nfilb
11461 kfd(1,k)=1 ! reset (negated) record counters
11462 kfd(2,k)=k ! set file number
11463 ifd(k)=0 ! reset integrated record numbers
11464 xfd(k)=0 ! reset max record size
11465 END DO
11466
11467 IF(iosum /= 0) THEN
11468 CALL peend(15,'Aborted, open error(s) for binary files')
11469 stop 'FILETC: open error '
11470 END IF
11471 IF(nfilb == 0) THEN
11472 CALL peend(14,'Aborted, no binary files')
11473 stop 'FILETC: no binary files '
11474 END IF
11475 IF (keepopen > 0) THEN
11476 WRITE(*,*) nfilb,' binary files opened' ! corrected by GF
11477 ELSE
11478 WRITE(*,*) nfilb,' binary files opened and closed' ! corrected by GF
11479 END IF
11480101 FORMAT(i3,2x,a)
11481102 FORMAT(a)
11482103 FORMAT(i3,2x,a14,3x,a)
11483 ! CALL mend
11484 RETURN
11485END SUBROUTINE filetc
11486
11537
11538SUBROUTINE filetx ! ---------------------------------------------------
11539 USE mpmod
11540
11541 IMPLICIT NONE
11542 INTEGER(mpi) :: i
11543 INTEGER(mpi) :: ia
11544 INTEGER(mpi) :: ib
11545 INTEGER(mpi) :: ierrf
11546 INTEGER(mpi) :: ioff
11547 INTEGER(mpi) :: ios
11548 INTEGER(mpi) :: iosum
11549 INTEGER(mpi) :: k
11550 INTEGER(mpi) :: mat
11551 INTEGER(mpi) :: nab
11552 INTEGER(mpi) :: nfiln
11553 INTEGER(mpi) :: nline
11554 INTEGER(mpi) :: nlinmx
11555 INTEGER(mpi) :: npat
11556 INTEGER(mpi) :: ntext
11557 INTEGER(mpi) :: matint
11558
11559 ! CALL MSTART('FILETX')
11560
11561 CHARACTER (LEN=1024) :: text
11562 CHARACTER (LEN=1024) :: fname
11563
11564 WRITE(*,*) ' '
11565 WRITE(*,*) 'Processing text files ...'
11566 WRITE(*,*) ' '
11567
11568 iosum=0
11569 ioff=0
11570 DO i=0,nfiles
11571 IF(i == 0) THEN
11572 WRITE(*,*) 'File ',filnam(1:nfnam)
11573 nlinmx=100
11574 ELSE
11575 nlinmx=10
11576 ia=ioff
11577 ioff=ioff+lfd(i)
11578 IF(mfd(i) /= 2) cycle ! exclude binary files
11579 DO k=1,lfd(i)
11580 fname(k:k)=tfd(ia+k)
11581 END DO
11582 WRITE(*,*) 'File ',fname(1:lfd(i))
11583 IF (mprint > 1) WRITE(*,*) ' '
11584 OPEN(10,file=fname(1:lfd(i)),iostat=ios,form='FORMATTED')
11585 IF(ios /= 0) THEN
11586 WRITE(*,*) 'Open error for file ',fname(1:lfd(i))
11587 iosum=iosum+1
11588 cycle
11589 END IF
11590 END IF
11591
11592 nline=0
11593 nfiln=1
11594 ! read text file
11595 DO
11596 READ(10,102,iostat=ierrf) text
11597 IF (ierrf < 0) THEN
11598 text=' '
11599 CALL intext(text,nline)
11600 WRITE(*,*) ' end-of-file after',nline,' text lines'
11601 EXIT ! eof
11602 ENDIF
11603 nline=nline+1
11604 IF(nline <= nlinmx.AND.mprint > 1) THEN ! print first 10 lines of every text fiLE
11605 CALL rltext(text,ia,ib,nab)
11606 nab=max(1,nab)
11607 WRITE(*,101) nline,text(1:nab)
11608 IF(nline == nlinmx) WRITE(*,*) ' ...'
11609 END IF
11610
11611 CALL rltext(text,ia,ib,nab) ! test content 'end'
11612 IF(ib == ia+2) THEN
11613 mat=matint(text(ia:ib),'end',npat,ntext)
11614 IF(mat == max(npat,ntext)) THEN ! exact matching
11615 text=' '
11616 CALL intext(text,nline)
11617 WRITE(*,*) ' end-statement after',nline,' text lines'
11618 EXIT
11619 END IF
11620 END IF
11621
11622 IF(i == 0) THEN ! first text file - exclude lines with file names
11623 IF(nfiln <= nfiles) THEN
11624 IF(nline == nfd(nfiln)) THEN
11625 nfiln=nfiln+1
11626 text=' '
11627 ! WRITE(*,*) 'line is excluded ',TEXT(1:10)
11628 END IF
11629 END IF
11630 END IF
11631 ! WRITE(*,*) TEXT(1:40),' < interprete text'
11632 CALL intext(text,nline) ! interprete text
11633 END DO
11634 WRITE(*,*) ' '
11635 rewind 10
11636 CLOSE(unit=10)
11637 END DO
11638
11639 IF(iosum /= 0) THEN
11640 CALL peend(16,'Aborted, open error(s) for text files')
11641 stop 'FILETX: open error(s) in text files '
11642 END IF
11643
11644 WRITE(*,*) '... end of text file processing.'
11645 WRITE(*,*) ' '
11646
11647 IF(lunkno /= 0) THEN
11648 WRITE(*,*) ' '
11649 WRITE(*,*) lunkno,' unknown keywords in steering files, ', &
11650 'or file non-existing,'
11651 WRITE(*,*) ' see above!'
11652 WRITE(*,*) '------------> stop'
11653 WRITE(*,*) ' '
11654 CALL peend(13,'Aborted, unknown keywords in steering file')
11655 stop
11656 END IF
11657
11658 ! check methods
11659
11660 IF(metsol == 0) THEN ! if undefined
11661 IF(matsto == 0) THEN ! if unpacked symmetric
11662 metsol=8 ! LAPACK
11663 ELSE IF(matsto == 1) THEN ! if full symmetric
11664 metsol=4 ! MINRES
11665 ELSE IF(matsto == 2) THEN ! if sparse
11666 metsol=4 ! MINRES
11667 END IF
11668 ELSE IF(metsol == 1) THEN ! if inversion
11669 matsto=1
11670 ELSE IF(metsol == 2) THEN ! if diagonalization
11671 matsto=1
11672 ELSE IF(metsol == 3) THEN ! if decomposition
11673 matsto=1
11674 ELSE IF(metsol == 4) THEN ! if MINRES
11675 ! MATSTO=2 or 1
11676 ELSE IF(metsol == 5) THEN ! if MINRES-QLP
11677 ! MATSTO=2 or 1
11678 ELSE IF(metsol == 6) THEN ! if GMRES
11679 ! MATSTO=2 or 1
11680#ifdef LAPACK64
11681 ELSE IF(metsol == 7) THEN ! if LAPACK
11682 matsto=1
11683 ELSE IF(metsol == 8) THEN ! if LAPACK
11684 matsto=0
11685#ifdef PARDISO
11686 ELSE IF(metsol == 9) THEN ! if Intel oneMKL PARDISO
11687 matsto=3
11688#endif
11689#endif
11690 ELSE
11691 WRITE(*,*) 'MINRES forced with sparse matrix!'
11692 WRITE(*,*) ' '
11693 WRITE(*,*) 'MINRES forced with sparse matrix!'
11694 WRITE(*,*) ' '
11695 WRITE(*,*) 'MINRES forced with sparse matrix!'
11696 metsol=4 ! forced
11697 matsto=2 ! forced
11698 END IF
11699 IF(matsto > 4) THEN
11700 WRITE(*,*) 'MINRES forced with sparse matrix!'
11701 WRITE(*,*) ' '
11702 WRITE(*,*) 'MINRES forced with sparse matrix!'
11703 WRITE(*,*) ' '
11704 WRITE(*,*) 'MINRES forced with sparse matrix!'
11705 metsol=4 ! forced
11706 matsto=2 ! forced
11707 END IF
11708
11709 ! print information about methods and matrix storage modes
11710
11711 WRITE(*,*) ' '
11712 WRITE(*,*) 'Solution method and matrix-storage mode:'
11713 IF(metsol == 1) THEN
11714 WRITE(*,*) ' METSOL = 1: matrix inversion'
11715 ELSE IF(metsol == 2) THEN
11716 WRITE(*,*) ' METSOL = 2: diagonalization'
11717 ELSE IF(metsol == 3) THEN
11718 WRITE(*,*) ' METSOL = 3: decomposition'
11719 ELSE IF(metsol == 4) THEN
11720 WRITE(*,*) ' METSOL = 4: MINRES'
11721 ELSE IF(metsol == 5) THEN
11722 WRITE(*,*) ' METSOL = 5: MINRES-QLP'
11723 ELSE IF(metsol == 6) THEN
11724 WRITE(*,*) ' METSOL = 6: GMRES (-> MINRES)'
11725#ifdef LAPACK64
11726 ELSE IF(metsol == 7) THEN
11727 WRITE(*,*) ' METSOL = 7: LAPACK factorization'
11728 ELSE IF(metsol == 8) THEN
11729 WRITE(*,*) ' METSOL = 8: LAPACK factorization'
11730#ifdef PARDISO
11731 ELSE IF(metsol == 9) THEN
11732 WRITE(*,*) ' METSOL = 9: Intel oneMKL PARDISO'
11733#endif
11734#endif
11735 END IF
11736
11737 WRITE(*,*) ' with',mitera,' iterations'
11738
11739 IF(matsto == 0) THEN
11740 WRITE(*,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
11741 ELSEIF(matsto == 1) THEN
11742 WRITE(*,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
11743 ELSE IF(matsto == 2) THEN
11744 WRITE(*,*) ' MATSTO = 2: sparse matrix (custom)'
11745 ELSE IF(matsto == 3) THEN
11746 IF (mpdbsz == 0) THEN
11747 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
11748 ELSE
11749 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
11750 END IF
11751 END IF
11752 IF(mbandw /= 0.AND.(metsol >= 4.AND. metsol <7)) THEN ! band matrix as MINRES preconditioner
11753 WRITE(*,*) ' and band matrix, width',mbandw
11754 END IF
11755
11756 IF(chicut /= 0.0) THEN
11757 WRITE(*,*) 'Chi square cut equiv 3 st.dev applied ...'
11758 WRITE(*,*) ' in first iteration with factor',chicut
11759 WRITE(*,*) ' in second iteration with factor',chirem
11760 WRITE(*,*) ' (reduced by sqrt in next iterations)'
11761 END IF
11762
11763 IF(lhuber /= 0) THEN
11764 WRITE(*,*) ' Down-weighting of outliers in', lhuber,' iterations'
11765 WRITE(*,*) ' Cut on downweight fraction',dwcut
11766 END IF
11767
11768 WRITE(*,*) 'Iterations (solutions) with line search:'
11769 IF(lsearch > 2) THEN
11770 WRITE(*,*) ' All'
11771 ELSEIF (lsearch == 1) THEN
11772 WRITE(*,*) ' Last'
11773 ELSEIF (lsearch < 1) THEN
11774 WRITE(*,*) ' None'
11775 ELSE
11776 IF (chicut /= 0.0) THEN
11777 WRITE(*,*) ' All with Chi square cut scaling factor <= 1.'
11778 ELSE
11779 WRITE(*,*) ' All'
11780 ENDIF
11781 ENDIF
11782
11783 IF(nummeasurements>0) THEN
11784 WRITE(*,*)
11785 WRITE(*,*) ' Number of external measurements ', nummeasurements
11786 ENDIF
11787
11788 CALL mend
11789
11790101 FORMAT(i3,2x,a)
11791102 FORMAT(a)
11792END SUBROUTINE filetx
11793
11803
11804INTEGER(mpi) FUNCTION nufile(fname)
11805 USE mpdef
11806
11807 IMPLICIT NONE
11808 INTEGER(mpi) :: ios
11809 INTEGER(mpi) :: l1
11810 INTEGER(mpi) :: ll
11811 INTEGER(mpi) :: nm
11812 INTEGER(mpi) :: npat
11813 INTEGER(mpi) :: ntext
11814 INTEGER(mpi) :: nuprae
11815 INTEGER(mpi) :: matint
11816
11817 CHARACTER (LEN=*), INTENT(INOUT) :: fname
11818 LOGICAL :: ex
11819 SAVE
11820 ! ...
11821 nufile=0
11822 nuprae=0
11823 IF(len(fname) > 5) THEN
11824 IF(fname(1:5) == 'rfio:') nuprae=1
11825 IF(fname(1:5) == 'dcap:') nuprae=2
11826 IF(fname(1:5) == 'root:') nuprae=3
11827 END IF
11828 IF(nuprae == 0) THEN
11829 INQUIRE(file=fname,iostat=ios,exist=ex)
11830 IF(ios /= 0) nufile=-abs(ios)
11831 IF(ios /= 0) RETURN
11832 ELSE IF(nuprae == 1) THEN ! rfio:
11833 ll=len(fname)
11834 fname=fname(6:ll)
11835 ex=.true.
11836 nufile=1
11837 RETURN
11838 ELSE
11839 ex=.true. ! assume file existence
11840 END IF
11841 IF(ex) THEN
11842 nufile=1 ! binary
11843 ll=len(fname)
11844 l1=max(1,ll-3)
11845 nm=matint('xt',fname(l1:ll),npat,ntext)
11846 IF(nm == 2) nufile=2 ! text
11847 IF(nm < 2) THEN
11848 nm=matint('tx',fname(l1:ll),npat,ntext)
11849 IF(nm == 2) nufile=2 ! text
11850 END IF
11851 END IF
11852END FUNCTION nufile
11853
11861SUBROUTINE intext(text,nline)
11862 USE mpmod
11863 USE mptext
11864
11865 IMPLICIT NONE
11866 INTEGER(mpi) :: i
11867 INTEGER(mpi) :: ia
11868 INTEGER(mpi) :: ib
11869 INTEGER(mpi) :: ier
11870 INTEGER(mpi) :: iomp
11871 INTEGER(mpi) :: j
11872 INTEGER(mpi) :: k
11873 INTEGER(mpi) :: kkey
11874 INTEGER(mpi) :: label
11875 INTEGER(mpi) :: lkey
11876 INTEGER(mpi) :: mat
11877 INTEGER(mpi) :: miter
11878 INTEGER(mpi) :: nab
11879 INTEGER(mpi) :: nkey
11880 INTEGER(mpi) :: nkeys
11881 INTEGER(mpi) :: nl
11882 INTEGER(mpi) :: nmeth
11883 INTEGER(mpi) :: npat
11884 INTEGER(mpi) :: ntext
11885 INTEGER(mpi) :: nums
11886 INTEGER(mpi) :: matint
11887
11888 CHARACTER (LEN=*), INTENT(IN) :: text
11889 INTEGER(mpi), INTENT(IN) :: nline
11890
11891#ifdef LAPACK64
11892#ifdef PARDISO
11893 parameter(nkeys=7,nmeth=10)
11894#else
11895 parameter(nkeys=6,nmeth=9)
11896#endif
11897#else
11898 parameter(nkeys=6,nmeth=7)
11899#endif
11900 CHARACTER (LEN=16) :: methxt(nmeth)
11901 CHARACTER (LEN=16) :: keylst(nkeys)
11902 CHARACTER (LEN=32) :: keywrd
11903 CHARACTER (LEN=32) :: keystx
11904 CHARACTER (LEN=itemCLen) :: ctext
11905 INTEGER(mpi), PARAMETER :: mnum=100
11906 REAL(mpd) :: dnum(mnum)
11907#ifdef LAPACK64
11908#ifdef PARDISO
11909 INTEGER(mpi) :: ipvs ! ... integer value
11910#endif
11911#endif
11912 INTEGER(mpi) :: lpvs ! ... integer label
11913 REAL(mpd) :: plvs ! ... float value
11914
11915 INTERFACE
11916 SUBROUTINE additem(length,list,label,value)
11917 USE mpmod
11918 INTEGER(mpi), INTENT(IN OUT) :: length
11919 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
11920 INTEGER(mpi), INTENT(IN) :: label
11921 REAL(mpd), INTENT(IN) :: value
11922 END SUBROUTINE additem
11923 SUBROUTINE additemc(length,list,label,text)
11924 USE mpmod
11925 INTEGER(mpi), INTENT(IN OUT) :: length
11926 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
11927 INTEGER(mpi), INTENT(IN) :: label
11928 CHARACTER(LEN = itemCLen), INTENT(IN) :: text
11929 END SUBROUTINE additemc
11930 SUBROUTINE additemi(length,list,label,ivalue)
11931 USE mpmod
11932 INTEGER(mpi), INTENT(IN OUT) :: length
11933 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
11934 INTEGER(mpi), INTENT(IN) :: label
11935 INTEGER(mpi), INTENT(IN) :: ivalue
11936 END SUBROUTINE additemi
11937 END INTERFACE
11938
11939 SAVE
11940#ifdef LAPACK64
11941#ifdef PARDISO
11942 DATA keylst/'unknown','parameter','constraint','measurement','method','comment','pardiso'/
11943 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
11944 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK', &
11945 'sparsePARDISO'/
11946#else
11947 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
11948 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
11949 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK'/
11950#endif
11951#else
11952 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
11953 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
11954 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition'/
11955#endif
11956 DATA lkey/-1/ ! last keyword
11957
11958 ! ...
11959 nkey=-1 ! new keyword
11960 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11961 IF(nab == 0) GOTO 10
11962 CALL ratext(text(1:nab),nums,dnum,mnum) ! translate text to DP numbers
11963
11964 IF(nums /= 0) nkey=0
11965 IF(keyb /= 0) THEN
11966 keywrd=text(keya:keyb) ! text is TEXT(KEYA)...TEXT(KEYB)
11967 ! WRITE(*,*) 'Keyword is ',KEYWRD
11968
11969 ! compare keywords
11970
11971 DO nkey=2,nkeys ! loop over all pede keywords
11972 keystx=keylst(nkey) ! copy NKEY.th pede keyword
11973 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
11974 IF(100*mat >= 80*max(npat,ntext)) GO TO 10 ! 80% (symmetric) matching
11975 END DO
11976
11977 ! more comparisons
11978
11979 keystx='print'
11980 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
11981 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
11982 mprint=1
11983 IF(nums > 0) mprint=nint(dnum(1),mpi)
11984 RETURN
11985 END IF
11986
11987 keystx='debug'
11988 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
11989 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
11990 mdebug=3
11991 ! GF IF(NUMS.GT.0) MPRINT=DNUM(1)
11992 IF(nums > 0) mdebug=nint(dnum(1),mpi)
11993 IF(nums > 1) mdebg2=nint(dnum(2),mpi)
11994 RETURN
11995 END IF
11996
11997 keystx='entries'
11998 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
11999 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12000 IF(nums > 0 .AND. dnum(1) > 0.5) mreqenf=nint(dnum(1),mpi)
12001 IF(nums > 1 .AND. dnum(2) > 0.5) mreqena=nint(dnum(2),mpi)
12002 IF(nums > 2 .AND. dnum(3) > 0.5) iteren=nint(dnum(1)*dnum(3),mpi)
12003 RETURN
12004 END IF
12005
12006 keystx='printrecord'
12007 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12008 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12009 IF(nums > 0) nrecpr=nint(dnum(1),mpi)
12010 IF(nums > 1) nrecp2=nint(dnum(2),mpi)
12011 RETURN
12012 END IF
12013
12014 keystx='maxrecord'
12015 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12016 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12017 IF (nums > 0.AND.dnum(1) > 0.) mxrec=nint(dnum(1),mpi)
12018 RETURN
12019 END IF
12020
12021 keystx='cache'
12022 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12023 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12024 IF (nums > 0.AND.dnum(1) >= 0.) ncache=nint(dnum(1),mpi) ! cache size, <0 keeps default
12025 IF (nums == 2.AND.dnum(2) > 0..AND.dnum(2) <= 1.0) & ! read cache fill level
12026 fcache(1)=real(dnum(2),mps)
12027 IF (nums >= 4) THEN ! explicit cache splitting
12028 DO k=1,3
12029 fcache(k)=real(dnum(k+1),mps)
12030 END DO
12031 END IF
12032 RETURN
12033 END IF
12034
12035 keystx='chisqcut'
12036 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12037 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12038 IF(nums == 0) THEN ! always 3-sigma cut
12039 chicut=1.0
12040 chirem=1.0
12041 ELSE
12042 chicut=real(dnum(1),mps)
12043 IF(chicut < 1.0) chicut=-1.0
12044 IF(nums == 1) THEN
12045 chirem=1.0 ! 3-sigma cut, if not specified
12046 ELSE
12047 chirem=real(dnum(2),mps)
12048 IF(chirem < 1.0) chirem=1.0
12049 IF(chicut >= 1.0) chirem=min(chirem,chicut)
12050 END IF
12051 END IF
12052 RETURN
12053 END IF
12054
12055 ! GF added:
12056 keystx='hugecut'
12057 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12058 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12059 IF(nums > 0) chhuge=real(dnum(1),mps)
12060 IF(chhuge < 1.0) chhuge=1.0 ! at least (!!) 3-sigma
12061 RETURN
12062 END IF
12063 ! GF added end
12064
12065 keystx='linesearch'
12066 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12067 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12068 IF(nums > 0) lsearch=nint(dnum(1),mpi)
12069 RETURN
12070 END IF
12071
12072 keystx='localfit'
12073 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12074 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12075 IF(nums > 0) lfitnp=nint(dnum(1),mpi)
12076 IF(nums > 1) lfitbb=nint(dnum(2),mpi)
12077 RETURN
12078 END IF
12079
12080 keystx='regularization'
12081 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12082 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12083 nregul=1
12084 regula=real(dnum(1),mps)
12085 IF(nums >= 2) regpre=real(dnum(2),mps)
12086 RETURN
12087 END IF
12088
12089 keystx='regularisation'
12090 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12091 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12092 nregul=1
12093 regula=real(dnum(1),mps)
12094 IF(nums >= 2) regpre=real(dnum(2),mps)
12095 RETURN
12096 END IF
12097
12098 keystx='presigma'
12099 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12100 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12101 regpre=real(dnum(1),mps)
12102 RETURN
12103 END IF
12104
12105 keystx='matiter'
12106 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12107 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12108 matrit=nint(dnum(1),mpi)
12109 RETURN
12110 END IF
12111
12112 keystx='matmoni'
12113 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12114 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12115 matmon=-1
12116 IF (nums > 0.AND.dnum(1) > 0.) matmon=nint(dnum(1),mpi)
12117 RETURN
12118 END IF
12119
12120 keystx='bandwidth'
12121 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12122 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12123 IF(nums > 0) mbandw=nint(dnum(1),mpi)
12124 IF(mbandw < 0) mbandw=-1
12125 IF(nums > 1) lprecm=nint(dnum(2),mpi)
12126 RETURN
12127 END IF
12128
12129 ! KEYSTX='outlierrejection'
12130 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12131 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12132 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12133 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12134 ! CHDFRJ=DNUM(1)
12135 ! IF(CHDFRJ.LT.3.0) CHDFRJ=100.0
12136 ! RETURN
12137 ! END IF
12138
12139 ! KEYSTX='outliersuppression'
12140 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12141 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12142 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12143 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12144 ! LHUBER=DNUM(1)
12145 ! IF(LHUBER.LE.2) LHUBER=2 ! at least 2 Huber iterations
12146 ! RETURN
12147 ! END IF
12148
12149 keystx='outlierdownweighting'
12150 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12151 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12152 lhuber=nint(dnum(1),mpi)
12153 IF(lhuber > 0.AND.lhuber <= 2) lhuber=2 ! at least 2 Huber iterations (if any)
12154 RETURN
12155 END IF
12156
12157 keystx='dwfractioncut'
12158 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12159 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12160 dwcut=real(dnum(1),mps)
12161 IF(dwcut > 0.5) dwcut=0.5
12162 RETURN
12163 END IF
12164
12165 keystx='pullrange'
12166 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12167 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12168 prange=abs(real(dnum(1),mps))
12169 RETURN
12170 END IF
12171
12172 keystx='subito'
12173 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12174 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12175 isubit=1
12176 RETURN
12177 END IF
12178
12179 keystx='force'
12180 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12181 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12182 iforce=1
12183 RETURN
12184 END IF
12185
12186 keystx='memorydebug'
12187 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12188 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12189 memdbg=1
12190 IF (nums > 0.AND.dnum(1) > 0.0) memdbg=nint(dnum(1),mpi)
12191 RETURN
12192 END IF
12193
12194 keystx='globalcorr'
12195 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12196 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12197 igcorr=1
12198 RETURN
12199 END IF
12200
12201 keystx='printcounts'
12202 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12203 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12204 ipcntr=1
12205 IF (nums > 0.AND.dnum(1) > 0.0) ipcntr=nint(dnum(1),mpi)
12206 RETURN
12207 END IF
12208
12209 keystx='weightedcons'
12210 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12211 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12212 iwcons=1
12213 IF (nums > 0) iwcons=nint(dnum(1),mpi)
12214 RETURN
12215 END IF
12216
12217 keystx='skipemptycons'
12218 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12219 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12220 iskpec=1
12221 RETURN
12222 END IF
12223
12224 keystx='resolveredundancycons'
12225 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12226 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12227 irslvrc=1
12228 RETURN
12229 END IF
12230
12231 keystx='withelimination'
12232 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12233 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12234 icelim=1
12235 RETURN
12236 END IF
12237
12238#ifdef LAPACK64
12239 keystx='withLAPACKelimination'
12240 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12241 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12242 icelim=2
12243 RETURN
12244 END IF
12245#endif
12246
12247 keystx='withmultipliers'
12248 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12249 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12250 icelim=0
12251 RETURN
12252 END IF
12253
12254 keystx='checkinput'
12255 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12256 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12257 icheck=1
12258 IF (nums > 0) icheck=nint(dnum(1),mpi)
12259 RETURN
12260 END IF
12261
12262 keystx='checkparametergroups'
12263 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12264 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12265 ichkpg=1
12266 RETURN
12267 END IF
12268
12269 keystx='monitorresiduals'
12270 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12271 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12272 imonit=3
12273 IF (nums > 0) imonit=nint(dnum(1),mpi)
12274 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12275 RETURN
12276 END IF
12277
12278 keystx='monitorpulls'
12279 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12280 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12281 imonit=3
12282 imonmd=1
12283 IF (nums > 0) imonit=nint(dnum(1),mpi)
12284 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12285 RETURN
12286 END IF
12287
12288 keystx='monitorprogress'
12289 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12290 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12291 monpg1=1
12292 monpg2=1024
12293 IF (nums > 0) monpg1=max(1,nint(dnum(1),mpi))
12294 IF (nums > 1) monpg2=max(1,nint(dnum(2),mpi))
12295 RETURN
12296 END IF
12297
12298 keystx='scaleerrors'
12299 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12300 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12301 iscerr=1
12302 IF (nums > 0) dscerr(1:2)=dnum(1)
12303 IF (nums > 1) dscerr(2)=dnum(2)
12304 RETURN
12305 END IF
12306
12307 keystx='iterateentries'
12308 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12309 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12310 iteren=huge(iteren)
12311 IF (nums > 0) iteren=nint(dnum(1),mpi)
12312 RETURN
12313 END IF
12314
12315 keystx='threads'
12316 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12317 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12318 iomp=0
12319 !$ IOMP=1
12320 !$ IF (IOMP.GT.0) THEN
12321 !$ IF (NUMS.GE.1.AND.DNUM(1).GT.0.) MTHRD =NINT(dnum(1),mpi)
12322 !$ MTHRDR=MTHRD
12323 !$ IF (NUMS.GE.2.AND.DNUM(2).GT.0.) MTHRDR=NINT(dnum(2),mpi)
12324 !$ ELSE
12325 WRITE(*,*) 'WARNING: multithreading not available'
12326 !$ ENDIF
12327 RETURN
12328 END IF
12329
12330 keystx='compress'
12331 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12332 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12333 WRITE(*,*) 'WARNING: keyword COMPRESS is obsolete (compression is default)'
12334 RETURN
12335 END IF
12336
12337 ! still experimental
12338 !keystx='extendedStorage'
12339 !mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12340 !IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12341 ! mextnd=1
12342 ! RETURN
12343 !END IF
12344
12345 keystx='countrecords'
12346 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12347 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12348 mcount=1
12349 RETURN
12350 END IF
12351
12352 keystx='errlabels'
12353 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12354 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12355 nl=min(nums,100-mnrsel)
12356 DO k=1,nl
12357 lbmnrs(mnrsel+k)=nint(dnum(k),mpi)
12358 END DO
12359 mnrsel=mnrsel+nl
12360 RETURN
12361 END IF
12362
12363 keystx='pairentries'
12364 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12365 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12366 ! This option could be implemented to get rid of parameter pairs
12367 ! that have very few entries - to save matrix memory size.
12368 IF (nums > 0.AND.dnum(1) > 0.0) THEN
12369 mreqpe=nint(dnum(1),mpi)
12370 IF (nums >= 2.AND.dnum(2) >= dnum(1)) mhispe=nint(dnum(2),mpi)
12371 IF (nums >= 3.AND.dnum(3) >= dnum(1)) msngpe=nint(dnum(3),mpi)
12372 END IF
12373 RETURN
12374 END IF
12375
12376 keystx='wolfe'
12377 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12378 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12379 wolfc1=real(dnum(1),mps)
12380 wolfc2=real(dnum(2),mps)
12381 RETURN
12382 END IF
12383
12384 ! GF added:
12385 ! convergence tolerance for minres:
12386 keystx='mrestol'
12387 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12388 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12389 IF(nums > 0) THEN
12390 IF (dnum(1) < 1.0e-10_mpd.OR.dnum(1) > 1.0e-04_mpd) THEN
12391 WRITE(*,*) 'ERROR: need 1.0D-10 <= MRESTL ', &
12392 '<= 1.0D-04, but get ', dnum(1)
12393 ELSE
12394 mrestl=dnum(1)
12395 END IF
12396 END IF
12397 RETURN
12398 END IF
12399 ! GF added end
12400
12401 keystx='mrestranscond'
12402 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12403 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12404 IF(nums > 0) THEN
12405 mrtcnd = dnum(1)
12406 END IF
12407 RETURN
12408 END IF
12409
12410 keystx='mresmode'
12411 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12412 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12413 IF(nums > 0) THEN
12414 mrmode = int(dnum(1),mpi)
12415 END IF
12416 RETURN
12417 END IF
12418
12419 keystx='nofeasiblestart'
12420 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12421 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12422 nofeas=1 ! do not make parameters feasible at start
12423 RETURN
12424 END IF
12425
12426 keystx='histprint'
12427 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12428 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12429 nhistp=1 ! print histograms
12430 RETURN
12431 END IF
12432
12433 keystx='readerroraseof' ! treat (C) read errors as eof
12434 mat=matint(text(ia:ib),keystx,npat,ntext)
12435 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12436 ireeof=1
12437 RETURN
12438 END IF
12439
12440#ifdef LAPACK64
12441 keystx='LAPACKwitherrors' ! calculate parameter errors with LAPACK
12442 mat=matint(text(ia:ib),keystx,npat,ntext)
12443 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12444 ilperr=1
12445 RETURN
12446 END IF
12447#ifdef PARDISO
12448 keystx='debugPARDISO' ! enable debug for Intel oneMKL PARDISO
12449 mat=matint(text(ia:ib),keystx,npat,ntext)
12450 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12451 ipddbg=1
12452 RETURN
12453 END IF
12454
12455 keystx='blocksizePARDISO' ! use BSR3 for Intel oneMKL PARDISO, list of (increasing) block sizes to be tried
12456 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12457 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12458 nl=min(nums,10-mpdbsz)
12459 DO k=1,nl
12460 IF (nint(dnum(k),mpi) > 0) THEN
12461 IF (mpdbsz == 0) THEN
12462 mpdbsz=mpdbsz+1
12463 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12464 ELSE IF (nint(dnum(k),mpi) > ipdbsz(mpdbsz)) THEN
12465 mpdbsz=mpdbsz+1
12466 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12467 END IF
12468 END IF
12469 END DO
12470 RETURN
12471 END IF
12472#endif
12473#endif
12474 keystx='fortranfiles'
12475 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12476 IF(mat == max(npat,ntext)) RETURN
12477
12478 keystx='Cfiles'
12479 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12480 IF(mat == max(npat,ntext)) RETURN
12481
12482 keystx='closeandreopen'
12483 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12484 IF(mat == max(npat,ntext)) RETURN
12485
12486 keystx=keylst(1)
12487 nkey=1 ! unknown keyword
12488 IF(nums /= 0) nkey=0
12489
12490 WRITE(*,*) ' '
12491 WRITE(*,*) '**************************************************'
12492 WRITE(*,*) ' '
12493 WRITE(*,*) 'Unknown keyword(s): ',text(1:min(nab,50))
12494 WRITE(*,*) ' '
12495 WRITE(*,*) '**************************************************'
12496 WRITE(*,*) ' '
12497 lunkno=lunkno+1
12498
12499 END IF
12500 ! result: NKEY = -1 blank
12501 ! NKEY = 0 numerical data, no text keyword or unknown
12502 ! NKEY > 0 keyword NKEY from list, keyword = KEYSTX
12503
12504
12505 ! content/lastcontent
12506 ! -------------------
12507 ! blank -1
12508 ! data 0
12509 ! keyword
12510 ! unknown 1
12511 ! parameter 2
12512 ! constraint 3
12513 ! measurement 4
12514 ! method 5
12515
12516
1251710 IF(nkey > 0) THEN ! new keyword
12518 lkey=nkey
12519 IF(lkey == 2) THEN ! parameter
12520 IF(nums == 3) THEN
12521 lpvs=nint(dnum(1),mpi) ! label
12522 IF(lpvs /= 0) THEN
12523 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12524 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12525 ELSE
12526 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12527 END IF
12528 ELSE IF(nums /= 0) THEN
12529 kkey=1 ! switch to "unknown" ?
12530 WRITE(*,*) 'Wrong text in line',nline
12531 WRITE(*,*) 'Status: new parameter'
12532 WRITE(*,*) '> ',text(1:nab)
12533 END IF
12534 ELSE IF(lkey == 3) THEN ! constraint
12535 ! WRITE(*,*) 'Keyword is constraint!',NUMS,' numerical data'
12536 IF(nums >= 1.AND.nums <= 2) THEN ! start constraint
12537 lpvs=-nline ! r = r.h.s. value
12538 CALL additem(lenconstraints,listconstraints,lpvs,dnum(1))
12539 lpvs=-1 ! constraint
12540 IF(iwcons > 0) lpvs=-2 ! weighted constraint
12541 plvs=0.0
12542 IF(nums == 2) plvs=dnum(2) ! sigma
12543 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12544 ELSE
12545 kkey=1 ! switch to "unknown"
12546 WRITE(*,*) 'Wrong text in line',nline
12547 WRITE(*,*) 'Status: new keyword constraint'
12548 WRITE(*,*) '> ',text(1:nab)
12549 END IF
12550 ELSE IF(lkey == 4) THEN ! measurement
12551 IF(nums == 2) THEN ! start measurement
12552 nummeasurements=nummeasurements+1
12553 lpvs=-nline ! r = r.h.s. value
12554 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(1))
12555 lpvs=-1 ! sigma
12556 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(2))
12557 ELSE
12558 kkey=1 ! switch to "unknown"
12559 WRITE(*,*) 'Wrong text in line',nline
12560 WRITE(*,*) 'Status: new keyword measurement'
12561 WRITE(*,*) '> ',text(1:nab)
12562 END IF
12563 ELSE IF(lkey == 5.AND.keyb < keyc) THEN ! method with text argument
12564 miter=mitera
12565 IF(nums >= 1) miter=nint(dnum(1),mpi)
12566 IF(miter >= 1) mitera=miter
12567 dflim=real(dnum(2),mps)
12568 lkey=0
12569 DO i=1,nmeth
12570 keystx=methxt(i)
12571 mat=matint(text(keyb+1:keyc),keystx,npat,ntext) ! comparison
12572 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12573 IF(i == 1) THEN ! diagonalization
12574 metsol=2
12575 matsto=1
12576 ELSE IF(i == 2) THEN ! inversion
12577 metsol=1
12578 matsto=1
12579 ELSE IF(i == 3) THEN ! fullMINRES
12580 metsol=4
12581 matsto=1
12582 ELSE IF(i == 4) THEN ! sparseMINRES
12583 metsol=4
12584 matsto=2
12585 ELSE IF(i == 5) THEN ! fullMINRES-QLP
12586 metsol=5
12587 matsto=1
12588 ELSE IF(i == 6) THEN ! sparseMINRES-QLP
12589 metsol=5
12590 matsto=2
12591 ELSE IF(i == 7) THEN ! decomposition
12592 metsol=3
12593 matsto=1
12594#ifdef LAPACK64
12595 ELSE IF(i == 8) THEN ! fullLAPACK factorization
12596 metsol=7
12597 matsto=1
12598 ELSE IF(i == 9) THEN ! unpackedLAPACK factorization
12599 metsol=8
12600 matsto=0
12601#ifdef PARDISO
12602 ELSE IF(i == 10) THEN ! Intel oneMKL PARDISO (sparse matrix (CSR3 or BSR3, upper triangle))
12603 metsol=9
12604 matsto=3
12605#endif
12606#endif
12607 END IF
12608 END IF
12609 END DO
12610 END IF
12611 ELSE IF(nkey == 0) THEN ! data for continuation
12612 IF(lkey == 2) THEN ! parameter
12613 IF(nums >= 3) THEN ! store data from this line
12614 lpvs=nint(dnum(1),mpi) ! label
12615 IF(lpvs /= 0) THEN
12616 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12617 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12618 ELSE
12619 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12620 END IF
12621 ELSE IF(nums > 1.AND.nums < 3) THEN
12622 kkey=1 ! switch to "unknown" ?
12623 WRITE(*,*) 'Wrong text in line',nline
12624 WRITE(*,*) 'Status continuation parameter'
12625 WRITE(*,*) '> ',text(1:nab)
12626 END IF
12627
12628 ELSE IF(lkey == 3) THEN ! constraint
12629 ier=0
12630 DO i=1,nums,2
12631 label=nint(dnum(i),mpi)
12632 IF(label <= 0) ier=1
12633 END DO
12634 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12635 IF(ier == 0) THEN
12636 DO i=1,nums,2
12637 lpvs=nint(dnum(i),mpi) ! label
12638 plvs=dnum(i+1) ! factor
12639 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12640 END DO
12641 ELSE
12642 kkey=0
12643 WRITE(*,*) 'Wrong text in line',nline
12644 WRITE(*,*) 'Status continuation constraint'
12645 WRITE(*,*) '> ',text(1:nab)
12646 END IF
12647
12648 ELSE IF(lkey == 4) THEN ! measurement
12649 ! WRITE(*,*) 'continuation < ',NUMS
12650 ier=0
12651 DO i=1,nums,2
12652 label=nint(dnum(i),mpi)
12653 IF(label <= 0) ier=1
12654 END DO
12655 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12656 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12657 IF(ier == 0) THEN
12658 DO i=1,nums,2
12659 lpvs=nint(dnum(i),mpi) ! label
12660 plvs=dnum(i+1) ! factor
12661 CALL additem(lenmeasurements,listmeasurements,lpvs,plvs)
12662 END DO
12663 ELSE
12664 kkey=0
12665 WRITE(*,*) 'Wrong text in line',nline
12666 WRITE(*,*) 'Status continuation measurement'
12667 WRITE(*,*) '> ',text(1:nab)
12668 END IF
12669 ELSE IF(lkey == 6) THEN ! comment
12670 IF(nums == 1) THEN
12671 lpvs=nint(dnum(1),mpi) ! label
12672 IF(lpvs /= 0) THEN
12673 ! skip label
12674 DO j=ia,ib
12675 IF (text(j:j) == ' ') EXIT
12676 END DO
12677 ctext=text(j:ib)
12678 CALL additemc(lencomments,listcomments,lpvs,ctext)
12679 ELSE
12680 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12681 END IF
12682 ELSE IF(nums /= 0) THEN
12683 kkey=1 ! switch to "unknown"
12684 WRITE(*,*) 'Wrong text in line',nline
12685 WRITE(*,*) 'Status: continuation comment'
12686 WRITE(*,*) '> ',text(1:nab)
12687 END IF
12688#ifdef LAPACK64
12689#ifdef PARDISO
12690 ELSE IF(lkey == 7) THEN ! Intel oneMKL PARDISO parameters
12691 ier=0
12692 DO i=1,nums,2
12693 label=nint(dnum(i),mpi)
12694 IF(label <= 0.OR.label > 64) ier=1
12695 END DO
12696 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12697 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12698 IF(ier == 0) THEN
12699 DO i=1,nums,2
12700 lpvs=nint(dnum(i),mpi) ! label
12701 ipvs=nint(dnum(i+1),mpi) ! parameter
12702 CALL additemi(lenpardiso,listpardiso,lpvs,ipvs)
12703 END DO
12704 ELSE
12705 kkey=0
12706 WRITE(*,*) 'Wrong text in line',nline
12707 WRITE(*,*) 'Status continuation measurement'
12708 WRITE(*,*) '> ',text(1:nab)
12709 END IF
12710#endif
12711#endif
12712 END IF
12713 END IF
12714END SUBROUTINE intext
12715
12723SUBROUTINE additem(length,list,label,value)
12724 USE mpdef
12725 USE mpdalc
12726
12727 INTEGER(mpi), INTENT(IN OUT) :: length
12728 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12729 INTEGER(mpi), INTENT(IN) :: label
12730 REAL(mpd), INTENT(IN) :: value
12731
12732 INTEGER(mpl) :: newSize
12733 INTEGER(mpl) :: oldSize
12734 TYPE(listitem), DIMENSION(:), ALLOCATABLE :: tempList
12735
12736 IF (label > 0.AND.value == 0.) RETURN ! skip zero for valid labels
12737 IF (length == 0 ) THEN ! initial list with size = 100
12738 newsize = 100
12739 CALL mpalloc(list,newsize,' list ')
12740 ENDIF
12741 oldsize=size(list,kind=mpl)
12742 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12743 newsize = oldsize + oldsize/5 + 100
12744 CALL mpalloc(templist,oldsize,' temp. list ')
12745 templist=list
12746 CALL mpdealloc(list)
12747 CALL mpalloc(list,newsize,' list ')
12748 list(1:oldsize)=templist(1:oldsize)
12749 CALL mpdealloc(templist)
12750 ENDIF
12751 ! add to end of list
12752 length=length+1
12753 list(length)%label=label
12754 list(length)%value=value
12755
12756END SUBROUTINE additem
12757
12765SUBROUTINE additemc(length,list,label,text)
12766 USE mpdef
12767 USE mpdalc
12768
12769 INTEGER(mpi), INTENT(IN OUT) :: length
12770 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12771 INTEGER(mpi), INTENT(IN) :: label
12772 CHARACTER(len = itemCLen), INTENT(IN) :: text
12773
12774 INTEGER(mpl) :: newSize
12775 INTEGER(mpl) :: oldSize
12776 TYPE(listitemc), DIMENSION(:), ALLOCATABLE :: tempList
12777
12778 IF (label > 0.AND.text == '') RETURN ! skip empty text for valid labels
12779 IF (length == 0 ) THEN ! initial list with size = 100
12780 newsize = 100
12781 CALL mpalloc(list,newsize,' list ')
12782 ENDIF
12783 oldsize=size(list,kind=mpl)
12784 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12785 newsize = oldsize + oldsize/5 + 100
12786 CALL mpalloc(templist,oldsize,' temp. list ')
12787 templist=list
12788 CALL mpdealloc(list)
12789 CALL mpalloc(list,newsize,' list ')
12790 list(1:oldsize)=templist(1:oldsize)
12791 CALL mpdealloc(templist)
12792 ENDIF
12793 ! add to end of list
12794 length=length+1
12795 list(length)%label=label
12796 list(length)%text=text
12797
12798END SUBROUTINE additemc
12799
12807SUBROUTINE additemi(length,list,label,ivalue)
12808 USE mpdef
12809 USE mpdalc
12810
12811 INTEGER(mpi), INTENT(IN OUT) :: length
12812 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12813 INTEGER(mpi), INTENT(IN) :: label
12814 INTEGER(mpi), INTENT(IN) :: ivalue
12815
12816 INTEGER(mpl) :: newSize
12817 INTEGER(mpl) :: oldSize
12818 TYPE(listitemi), DIMENSION(:), ALLOCATABLE :: tempList
12819
12820 IF (length == 0 ) THEN ! initial list with size = 100
12821 newsize = 100
12822 CALL mpalloc(list,newsize,' list ')
12823 ENDIF
12824 oldsize=size(list,kind=mpl)
12825 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12826 newsize = oldsize + oldsize/5 + 100
12827 CALL mpalloc(templist,oldsize,' temp. list ')
12828 templist=list
12829 CALL mpdealloc(list)
12830 CALL mpalloc(list,newsize,' list ')
12831 list(1:oldsize)=templist(1:oldsize)
12832 CALL mpdealloc(templist)
12833 ENDIF
12834 ! add to end of list
12835 length=length+1
12836 list(length)%label=label
12837 list(length)%ivalue=ivalue
12838
12839END SUBROUTINE additemi
12840
12842SUBROUTINE mstart(text)
12843 USE mpdef
12844 USE mpmod, ONLY: textl
12845
12846 IMPLICIT NONE
12847 INTEGER(mpi) :: i
12848 INTEGER(mpi) :: ka
12849 INTEGER(mpi) :: kb
12850 INTEGER(mpi) :: l
12851 CHARACTER (LEN=*), INTENT(IN) :: text
12852 CHARACTER (LEN=16) :: textc
12853 SAVE
12854 ! ...
12855 DO i=1,74
12856 textl(i:i)='_'
12857 END DO
12858 l=len(text)
12859 ka=(74-l)/2
12860 kb=ka+l-1
12861 textl(ka:kb)=text(1:l)
12862 WRITE(*,*) ' '
12863 WRITE(*,*) textl
12864 WRITE(*,*) ' '
12865 textc=text(1:l)//'-end'
12866
12867 DO i=1,74
12868 textl(i:i)='_'
12869 END DO
12870 l=l+4
12871 ka=(74-l)/2
12872 kb=ka+l-1
12873 textl(ka:kb)=textc(1:l)
12874 RETURN
12875END SUBROUTINE mstart
12876
12878SUBROUTINE mend
12879 USE mpmod, ONLY: textl
12880
12881 IMPLICIT NONE
12882 WRITE(*,*) ' '
12883 WRITE(*,*) textl
12884 CALL petime
12885 WRITE(*,*) ' '
12886END SUBROUTINE mend
12887
12894
12895SUBROUTINE mvopen(lun,fname)
12896 USE mpdef
12897
12898 IMPLICIT NONE
12899 INTEGER(mpi) :: l
12900 INTEGER(mpi), INTENT(IN) :: lun
12901 CHARACTER (LEN=*), INTENT(IN) :: fname
12902 CHARACTER (LEN=33) :: nafile
12903 CHARACTER (LEN=33) :: nbfile
12904 LOGICAL :: ex
12905 SAVE
12906 ! ...
12907 l=len(fname)
12908 IF(l > 32) THEN
12909 CALL peend(17,'Aborted, file name too long')
12910 stop 'File name too long '
12911 END IF
12912 nafile=fname
12913 nafile(l+1:l+1)='~'
12914
12915 INQUIRE(file=nafile(1:l),exist=ex)
12916 IF(ex) THEN
12917 INQUIRE(file=nafile(1:l+1),exist=ex)
12918 IF(ex) THEN
12919 CALL system('rm '//nafile)
12920 END IF
12921 nbfile=nafile
12922 nafile(l+1:l+1)=' '
12923 CALL system('mv '//nafile//nbfile)
12924 END IF
12925 OPEN(unit=lun,file=fname)
12926END SUBROUTINE mvopen
12927
12931
12932SUBROUTINE petime
12933 USE mpdef
12934
12935 IMPLICIT NONE
12936 REAL, DIMENSION(2) :: ta
12937 REAL etime
12938 REAL :: rst
12939 REAL :: delta
12940 REAL :: rstp
12941 REAL :: secnd1
12942 REAL :: secnd2
12943 INTEGER :: ncount
12944 INTEGER :: nhour1
12945 INTEGER :: minut1
12946 INTEGER :: nsecd1
12947 INTEGER :: nhour2
12948 INTEGER :: minut2
12949 INTEGER :: nsecd2
12950
12951 SAVE
12952 DATA ncount/0/
12953 ! ...
12954 ncount=ncount+1
12955 rst=etime(ta)
12956 IF(ncount > 1) THEN
12957 delta=rst
12958 nsecd1=int(delta,mpi) ! -> integer
12959 nhour1=nsecd1/3600
12960 minut1=nsecd1/60-60*nhour1
12961 secnd1=delta-60*(minut1+60*nhour1)
12962 delta=rst-rstp
12963 nsecd2=int(delta,mpi) ! -> integer
12964 nhour2=nsecd2/3600
12965 minut2=nsecd2/60-60*nhour2
12966 secnd2=delta-60*(minut2+60*nhour2)
12967 WRITE(*,101) nhour1,minut1,secnd1, nhour2,minut2,secnd2
12968 END IF
12969
12970 rstp=rst
12971 RETURN
12972101 FORMAT(i4,' h',i3,' min',f5.1,' sec total',18x,'elapsed', &
12973 i4,' h',i3,' min',f5.1,' sec')
12974END SUBROUTINE petime ! print
12975
12982
12983SUBROUTINE peend(icode, cmessage)
12984 USE mpdef
12985
12986 IMPLICIT NONE
12987 INTEGER(mpi), INTENT(IN) :: icode
12988 CHARACTER (LEN=*), INTENT(IN) :: cmessage
12989
12990 CALL mvopen(9,'millepede.end')
12991 WRITE(9,101) icode, cmessage
12992101 FORMAT(1x,i4,3x,a)
12993 CLOSE(9)
12994 RETURN
12995
12996END SUBROUTINE peend
12997
13004SUBROUTINE binopn(kfile, ithr, ierr)
13005 USE mpmod
13006
13007 IMPLICIT NONE
13008 INTEGER(mpi), INTENT(IN) :: kfile
13009 INTEGER(mpi), INTENT(IN) :: ithr
13010 INTEGER(mpi), INTENT(OUT) :: ierr
13011
13012 INTEGER(mpi), DIMENSION(13) :: ibuff
13013 INTEGER(mpi) :: ioff
13014 INTEGER(mpi) :: ios
13015 INTEGER(mpi) :: k
13016 INTEGER(mpi) :: lfn
13017 INTEGER(mpi) :: lun
13018 INTEGER(mpi) :: moddate
13019 CHARACTER (LEN=1024) :: fname
13020 CHARACTER (LEN=7) :: cfile
13021 INTEGER stat
13022
13023#ifdef READ_C_FILES
13024 INTERFACE
13025 SUBROUTINE openc(filename, lfn, lun, ios) BIND(c)
13026 USE iso_c_binding
13027 CHARACTER(kind=c_char), DIMENSION(*), INTENT(IN) :: filename
13028 INTEGER(c_int), INTENT(IN), VALUE :: lfn
13029 INTEGER(c_int), INTENT(IN), VALUE :: lun
13030 INTEGER(c_int), INTENT(INOUT) :: ios
13031 END SUBROUTINE openc
13032 END INTERFACE
13033#endif
13034
13035 ierr=0
13036 lun=ithr
13037 ! modification date (=0: open for first time, >0: reopen, <0: unknown )
13038 moddate=yfd(kfile)
13039 ! file name
13040 ioff=sfd(1,kfile)
13041 lfn=sfd(2,kfile)
13042 DO k=1,lfn
13043 fname(k:k)=tfd(ioff+k)
13044 END DO
13045 !print *, " opening binary ", kfile, ithr, moddate, " : ", fname(1:lfn)
13046 ! open
13047 ios=0
13048 IF(kfile <= nfilf) THEN
13049 ! Fortran file
13050 lun=kfile+10
13051 OPEN(lun,file=fname(1:lfn),iostat=ios, form='UNFORMATTED')
13052 print *, ' lun ', lun, ios
13053#ifdef READ_C_FILES
13054 ELSE
13055 ! C file
13056 CALL openc(fname(1:lfn),lfn,lun,ios)
13057#else
13058 WRITE(*,*) 'Opening of C-files not supported.'
13059 ierr=1
13060 RETURN
13061#endif
13062 END IF
13063 IF(ios /= 0) THEN
13064 ierr=1
13065 WRITE(*,*) 'Open error for file ',fname(1:lfn), ios
13066 IF (moddate /= 0) THEN
13067 WRITE(cfile,'(I7)') kfile
13068 CALL peend(15,'Aborted, open error(s) for binary file ' // cfile)
13069 stop 'PEREAD: open error'
13070 ENDIF
13071 RETURN
13072 END IF
13073 ! get status
13074 ios=stat(fname(1:lfn),ibuff)
13075 !print *, ' STAT ', ios, ibuff(10), moddate
13076 IF(ios /= 0) THEN
13077 ierr=1
13078 WRITE(*,*) 'STAT error for file ',fname(1:lfn), ios
13079 ibuff(10)=-1
13080 END IF
13081 ! check/store modification date
13082 IF (moddate /= 0) THEN
13083 IF (ibuff(10) /= moddate) THEN
13084 WRITE(cfile,'(I7)') kfile
13085 CALL peend(19,'Aborted, binary file modified (date) ' // cfile)
13086 stop 'PEREAD: file modified'
13087 END IF
13088 ELSE
13089 yfd(kfile)=ibuff(10)
13090 END IF
13091 RETURN
13092
13093END SUBROUTINE binopn
13094
13100SUBROUTINE bincls(kfile, ithr)
13101 USE mpmod
13102
13103 IMPLICIT NONE
13104 INTEGER(mpi), INTENT(IN) :: kfile
13105 INTEGER(mpi), INTENT(IN) :: ithr
13106
13107 INTEGER(mpi) :: lun
13108
13109#ifdef READ_C_FILES
13110 INTERFACE
13111 SUBROUTINE closec(lun) BIND(c)
13112 USE iso_c_binding
13113 INTEGER(c_int), INTENT(IN), VALUE :: lun
13114 END SUBROUTINE closec
13115 END INTERFACE
13116#endif
13117
13118 lun=ithr
13119 !print *, " closing binary ", kfile, ithr
13120 IF(kfile <= nfilf) THEN ! Fortran file
13121 lun=kfile+10
13122 CLOSE(lun)
13123#ifdef READ_C_FILES
13124 ELSE ! C file
13125 CALL closec(lun)
13126#endif
13127 END IF
13128
13129END SUBROUTINE bincls
13130
13135SUBROUTINE binrwd(kfile)
13136 USE mpmod
13137
13138 IMPLICIT NONE
13139 INTEGER(mpi), INTENT(IN) :: kfile
13140
13141 INTEGER(mpi) :: lun
13142
13143#ifdef READ_C_FILES
13144 INTERFACE
13145 SUBROUTINE resetc(lun) BIND(c)
13146 USE iso_c_binding
13147 INTEGER(c_int), INTENT(IN), VALUE :: lun
13148 END SUBROUTINE resetc
13149 END INTERFACE
13150#endif
13151
13152 !print *, " rewinding binary ", kfile
13153 IF (kfile <= nfilf) THEN
13154 lun=kfile+10
13155 rewind lun
13156#ifdef READ_C_FILES
13157 ELSE
13158 lun=kfile-nfilf
13159 CALL resetc(lun)
13160#endif
13161 END IF
13162
13163END SUBROUTINE binrwd
13164
13166SUBROUTINE ckpgrp
13167 USE mpmod
13168 USE mpdalc
13169
13170 IMPLICIT NONE
13171 INTEGER(mpi) :: i
13172 INTEGER(mpi) :: ipgrp
13173 INTEGER(mpi) :: irank
13174 INTEGER(mpi) :: isize
13175 INTEGER(mpi) :: ivoff
13176 INTEGER(mpi) :: itgbi
13177 INTEGER(mpi) :: j
13178 INTEGER(mpi) :: msize
13179 INTEGER(mpi), PARAMETER :: mxsize = 1000
13180 INTEGER(mpl):: ij
13181 INTEGER(mpl):: length
13182
13183 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
13184 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
13185 REAL(mpd), DIMENSION(:), ALLOCATABLE :: resParGroup
13186 REAL(mpd), DIMENSION(:), ALLOCATABLE :: blockParGroup
13187 REAL(mpd) :: matij
13188 SAVE
13189
13190 ! maximal group size
13191 msize=0
13192 DO ipgrp=1,nvpgrp
13193 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13194 IF (isize <= mxsize) THEN
13195 msize=max(msize,isize)
13196 ELSE
13197 print *, ' CKPGRP: par. group', ipgrp, ' not checked -- too large: ', isize
13198 END IF
13199 END DO
13200 IF (msize == 0) RETURN
13201
13202 ! (matrix) block for parameter groups
13203 length=int(msize,mpl)*(int(msize,mpl)+1)/2
13204 CALL mpalloc(blockpargroup,length,'(matrix) block for parameter groups (D)')
13205 length=msize
13206 CALL mpalloc(respargroup,length,'residuals for parameter groups (D)') ! double aux 1
13207 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
13208 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
13209
13210 respargroup=0
13211 print *
13212 print *,' CKPGRP par. group first label size rank'
13213 DO ipgrp=1,nvpgrp
13214 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13215 IF (isize > mxsize) cycle
13216 ! copy matrix block
13217 ivoff=globalallindexgroups(ipgrp)-1
13218 ij=0
13219 DO i=1,isize
13220 DO j=1,i
13221 ij=ij+1
13222 blockpargroup(ij)=matij(ivoff+i,ivoff+j)
13223 END DO
13224 END DO
13225 ! inversion of matrix block
13226 CALL sqminv(blockpargroup,respargroup,isize,irank, auxvectord, auxvectori)
13227 !
13229 IF (isize == irank) THEN
13230 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank
13231 ELSE
13232 ndefpg=ndefpg+1
13233 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank, ' rank deficit !!!'
13234 END IF
13235 END DO
13236
13237 ! clean up
13238 CALL mpdealloc(auxvectord)
13239 CALL mpdealloc(auxvectori)
13240 CALL mpdealloc(respargroup)
13241 CALL mpdealloc(blockpargroup)
13242
13243END SUBROUTINE ckpgrp
13244
13246SUBROUTINE chkmat
13247 USE mpmod
13248
13249 IMPLICIT NONE
13250 INTEGER(mpl) :: i
13251 INTEGER(mpl) :: nan
13252 INTEGER(mpl) :: neg
13253
13254 print *, ' Checking global matrix(D) for NANs ', size(globalmatd,kind=mpl)
13255 nan=0
13256 DO i=1,size(globalmatd,kind=mpl)
13257 IF(.NOT.(globalmatd(i) <= 0.0_mpd).AND..NOT.(globalmatd(i) > 0.0_mpd)) THEN
13258 nan=nan+1
13259 print *, ' i, nan ', i, nan
13260 END IF
13261 END DO
13262
13263 IF (matsto > 1) RETURN
13264 print *
13265 print *, ' Checking diagonal elements ', nagb
13266 neg=0
13267 DO i=1,nagb
13268 IF(.NOT.(globalmatd(globalrowoffsets(i)+i) > 0.0_mpd)) THEN
13269 neg=neg+1
13270 print *, ' i, neg ', i, neg
13271 END IF
13272 END DO
13273 print *
13274 print *, ' CHKMAT summary ', nan, neg
13275 print *
13276
13277END SUBROUTINE chkmat
13278
13279
13280! ----- accurate summation ----(from mpnum) ---------------------------------
13281
13291
13292SUBROUTINE addsums(ithrd, chi2, ndf, dw)
13293 USE mpmod
13294
13295 IMPLICIT NONE
13296 REAL(mpd), INTENT(IN) :: chi2
13297 INTEGER(mpi), INTENT(IN) :: ithrd
13298 INTEGER(mpi), INTENT(IN) :: ndf
13299 REAL(mpd), INTENT(IN) :: dw
13300
13301 INTEGER(mpl) ::nadd
13302 REAL(mpd) ::add
13303 ! ...
13304 add=chi2*dw ! apply (file) weight
13305 nadd=int(add,mpl) ! convert to integer
13306 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+nadd ! sum integer
13307 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)+(add-real(nadd,mpd)) ! sum remainder
13308 IF(globalchi2sumd(ithrd) > 16.0_mpd) THEN ! + - 16
13309 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)-16.0_mpd
13310 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+16_mpl
13311 END IF
13312 globalndfsum(ithrd)=globalndfsum(ithrd)+int(ndf,mpl)
13313 globalndfsumw(ithrd)=globalndfsumw(ithrd)+real(ndf,mpd)*dw
13314 RETURN
13315END SUBROUTINE addsums
13316
13324
13325SUBROUTINE getsums(chi2, ndf, wndf)
13326 USE mpmod
13327
13328 IMPLICIT NONE
13329 REAL(mpd), INTENT(OUT) ::chi2
13330 INTEGER(mpl), INTENT(OUT) ::ndf
13331 REAL(mpd), INTENT(OUT) ::wndf
13332 ! ...
13333 chi2=sum(globalchi2sumd)+real(sum(globalchi2sumi),mpd)
13334 ndf=sum(globalndfsum)
13335 wndf=sum(globalndfsumw)
13336 globalchi2sumd=0.0_mpd
13337 globalchi2sumi=0_mpl
13338 globalndfsum=0_mpl
13339 globalndfsumw=0.0_mpd
13340 RETURN
13341END SUBROUTINE getsums
allocate array
Definition: mpdalc.f90:36
deallocate array
Definition: mpdalc.f90:42
subroutine ptlopt(nf, m, slopes, steps)
Get details.
Definition: linesrch.f90:259
subroutine ptline(n, x, f, g, s, step, info)
Perform linesearch.
Definition: linesrch.f90:90
subroutine ptldef(gtole, stmax, minfe, maxfe)
Initialize line search.
Definition: linesrch.f90:233
subroutine ptlprt(lunp)
Print line search data.
Definition: linesrch.f90:295
subroutine pcbits(npgrp, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:1018
subroutine ndbits(npgrp, ndims, nsparr, ihst)
Analyze bit fields.
Definition: mpbits.f90:302
subroutine clbits(in, jreqpe, jhispe, jsngpe, jextnd, idimb, ispc)
Calculate bit (field) array size, encoding.
Definition: mpbits.f90:179
subroutine plbits(in, inar, inac, idimb)
Calculate bit field array size (PARDISO).
Definition: mpbits.f90:252
subroutine spbits(npgrp, nsparr, nsparc)
Create sparsity information.
Definition: mpbits.f90:1205
subroutine irbits(i, j)
Fill bit fields (counters, rectangular part).
Definition: mpbits.f90:146
subroutine clbmap(in)
Clear (additional) bit map.
Definition: mpbits.f90:1342
subroutine inbmap(im, jm)
Fill bit map.
Definition: mpbits.f90:1374
subroutine ckbits(npgrp, ndims)
Check sparsity of matrix.
Definition: mpbits.f90:1112
subroutine ggbmap(ipgrp, npair, npgrp)
Get paired (parameter) groups from map.
Definition: mpbits.f90:1454
subroutine prbits(npgrp, nsparr)
Analyze bit fields.
Definition: mpbits.f90:919
subroutine gpbmap(ngroup, npgrp, npair)
Get pairs (statistic) from map.
Definition: mpbits.f90:1408
subroutine pblbits(npgrp, ibsize, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:752
subroutine pbsbits(npgrp, ibsize, nnzero, nblock, nbkrow)
Analyze bit fields.
Definition: mpbits.f90:575
subroutine inbits(im, jm, inc)
Fill bit fields (counters, triangular part).
Definition: mpbits.f90:70
subroutine hmplun(lunw)
unit for output
Definition: mphistab.f90:329
subroutine gmpdef(ig, ityp, text)
book, reset XY storage
Definition: mphistab.f90:702
subroutine gmpxy(ig, x, y)
add (X,Y) pair
Definition: mphistab.f90:767
subroutine hmpdef(ih, xa, xb, text)
book, reset histogram
Definition: mphistab.f90:122
subroutine gmplun(lunw)
unit for output
Definition: mphistab.f90:975
subroutine gmpxyd(ig, x, y, dx, dy)
add (X,Y,DX,DY)
Definition: mphistab.f90:782
subroutine hmpwrt(ih)
write histogram text file
Definition: mphistab.f90:341
subroutine gmpwrt(ig)
write XY text file
Definition: mphistab.f90:987
subroutine hmpldf(ih, text)
book, reset log histogram
Definition: mphistab.f90:158
subroutine gmprnt(ig)
print XY data
Definition: mphistab.f90:869
subroutine hmpent(ih, x)
entry flt.pt.
Definition: mphistab.f90:183
subroutine hmplnt(ih, ix)
entry integer
Definition: mphistab.f90:223
subroutine gmpms(ig, x, y)
mean sigma(X) from Y
Definition: mphistab.f90:805
subroutine hmprnt(ih)
print, content vert
Definition: mphistab.f90:254
subroutine monend()
End monitoring.
Definition: mpmon.f90:83
subroutine monini(l, n1, n2)
Initialize monitoring.
Definition: mpmon.f90:43
subroutine sqmibb2(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag)
Band bordered matrix.
Definition: mpnum.f90:3373
subroutine dbavat(v, a, w, n, m, iopt)
A V AT product (similarity).
Definition: mpnum.f90:1390
subroutine sqminl(v, b, n, nrank, diag, next, vk, mon)
Matrix inversion for LARGE matrices.
Definition: mpnum.f90:231
subroutine devsol(n, diag, u, b, x, work)
Solution by diagonalization.
Definition: mpnum.f90:650
subroutine dbsvxl(v, a, b, n)
Product LARGE symmetric matrix, vector.
Definition: mpnum.f90:1309
subroutine devrot(n, diag, u, v, work, iwork)
Diagonalization.
Definition: mpnum.f90:370
subroutine sort22l(a, b, n)
Quick sort 2 with index.
Definition: mpnum.f90:1982
subroutine dbavats(v, a, is, w, n, m, iopt, sc)
A V AT product (similarity, sparse).
Definition: mpnum.f90:1471
subroutine chslv2(g, x, n)
Solve A*x=b using Cholesky decomposition.
Definition: mpnum.f90:954
subroutine sort1k(a, n)
Quick sort 1.
Definition: mpnum.f90:1715
subroutine sqminv(v, b, n, nrank, diag, next)
Matrix inversion and solution.
Definition: mpnum.f90:98
subroutine presols(p, n, b, nm, cu, a, l, s, x, y)
Constrained (sparse) preconditioner, solution.
Definition: mpnum.f90:2981
subroutine sqmibb(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag)
Bordered band matrix.
Definition: mpnum.f90:3117
subroutine devinv(n, diag, u, v)
Inversion by diagonalization.
Definition: mpnum.f90:697
subroutine equdecs(n, m, b, nm, ls, c, india, l, nrkd, nrkd2)
Decomposition of (sparse) equilibrium systems.
Definition: mpnum.f90:2487
subroutine chdec2(g, n, nrank, evmax, evmin, mon)
Cholesky decomposition (LARGE pos.
Definition: mpnum.f90:892
subroutine sort2k(a, n)
Quick sort 2.
Definition: mpnum.f90:1800
subroutine devsig(n, diag, u, b, coef)
Calculate significances.
Definition: mpnum.f90:612
subroutine dbsvx(v, a, b, n)
Product symmetric matrix, vector.
Definition: mpnum.f90:1265
subroutine equslvs(n, m, b, nm, c, india, l, x)
Solution of (sparse) equilibrium systems (after decomposition).
Definition: mpnum.f90:2614
subroutine precons(p, n, b, nm, c, cu, a, l, s, nrkd)
Constrained (sparse) preconditioner, decomposition.
Definition: mpnum.f90:2882
subroutine sort2i(a, n)
Quick sort 2 with index.
Definition: mpnum.f90:1893
subroutine qlpssq(aprod, B, m, t)
Partial similarity transformation by Q(t).
Definition: mpqldec.f90:696
subroutine qldecb(a, bpar, bcon, rcon)
QL decomposition (for disjoint block matrix).
Definition: mpqldec.f90:216
subroutine qlmlq(x, m, t)
Multiply left by Q(t) (per block).
Definition: mpqldec.f90:395
subroutine qlsetb(ib)
Set block.
Definition: mpqldec.f90:997
subroutine qlbsub(d, y)
Backward substitution (per block).
Definition: mpqldec.f90:970
subroutine qlini(n, m, l, s, k)
Initialize QL decomposition.
Definition: mpqldec.f90:58
subroutine qlgete(emin, emax)
Get eigenvalues.
Definition: mpqldec.f90:934
subroutine qlssq(aprod, A, s, roff, t)
Similarity transformation by Q(t).
Definition: mpqldec.f90:564
subroutine mptest
Generate test files.
Definition: mptest1.f90:79
subroutine mptst2(imodel)
Generate test files.
Definition: mptest2.f90:112
integer(mpi) function matint(pat, text, npat, ntext)
Approximate string matching.
Definition: mptext.f90:309
subroutine ratext(text, nums, dnum, mnum)
Translate text.
Definition: mptext.f90:51
subroutine rltext(text, ia, ib, nab)
Analyse text range.
Definition: mptext.f90:256
MINRES solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite and/...
subroutine, public minres(n, Aprod, Msolve, b, shift, checkA, precon, x, itnlim, nout, rtol, istop, itn, Anorm, Acond, rnorm, Arnorm, ynorm)
Solution of linear equation system.
MINRESQLP solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite a...
subroutine, public minresqlp(n, Aprod, b, shift, Msolve, disable, nout, itnlim, rtol, maxxnorm, trancond, Acondlim, x, istop, itn, rnorm, Arnorm, xnorm, Anorm, Acond)
Solution of linear equation system or least squares problem.
(De)Allocate vectors and arrays.
Definition: mpdalc.f90:24
integer(mpl) maxwordsalloc
peak dynamic memory allocation (words)
Definition: mpdalc.f90:30
integer(mpi) printflagalloc
print flag for dynamic allocations
Definition: mpdalc.f90:33
Definition of constants.
Definition: mpdef.f90:24
integer, parameter mpl
long integer
Definition: mpdef.f90:36
integer, parameter mps
single precision
Definition: mpdef.f90:37
integer, parameter mpi
integer
Definition: mpdef.f90:35
Parameters, variables, dynamic arrays.
Definition: mpmod.f90:28
integer(mpl), dimension(:), allocatable csr3columnlist
list of columns for sparse matrix
Definition: mpmod.f90:281
integer(mpl) mszpcc
(integrated block) matrix size for constraint matrix for preconditioner
Definition: mpmod.f90:144
real(mpd), dimension(:), allocatable workspaceeigenvectors
workspace eigen vectors
Definition: mpmod.f90:230
real(mpd), dimension(:), allocatable globalparameter
global parameters (start values + sum(x_i))
Definition: mpmod.f90:196
integer(mpl) nrecal
number of records
Definition: mpmod.f90:166
integer(mpi), dimension(:), allocatable localglobalmap
matrix correlating local and global par, map (counts)
Definition: mpmod.f90:312
type(listitem), dimension(:), allocatable listparameters
list of parameters from steering file
Definition: mpmod.f90:329
integer(mpi), dimension(:), allocatable vecparblockconoffsets
global par block (constraint) offsets
Definition: mpmod.f90:296
real(mpd), dimension(:), allocatable lapacktau
LAPACK TAU (QL decomp.)
Definition: mpmod.f90:236
integer(mpl) mszprd
(integrated block) matrix size for (constraint) product matrix
Definition: mpmod.f90:142
integer(mpi) lunmon
unit for monitoring output file
Definition: mpmod.f90:126
real(mpd), dimension(:), allocatable vecconsresiduals
residuals of constraints
Definition: mpmod.f90:242
integer(mpl) nrec1
record number with largest residual
Definition: mpmod.f90:53
integer(mpi) iskpec
flag for skipping empty constraints (no variable parameters)
Definition: mpmod.f90:106
integer(mpi) mnrsel
number of MINRES error labels in LBMNRS (calc err, corr with SOLGLO)
Definition: mpmod.f90:89
real(mps) actfun
actual function change
Definition: mpmod.f90:67
integer(mpi), dimension(:), allocatable globalindexusage
indices of global par in record
Definition: mpmod.f90:289
real(mps) regpre
default presigma
Definition: mpmod.f90:72
integer(mpi) mnrsit
total number of MINRES internal iterations
Definition: mpmod.f90:93
integer(mpi), dimension(10) ipdbsz
PARDISO, list of block sizes to be tried (by PBSBITS)
Definition: mpmod.f90:183
integer(mpi) metsol
solution method (1: inversion, 2: diagonalization, 3: decomposition, 4: MINRES, 5: MINRES-QLP,...
Definition: mpmod.f90:34
integer(mpi) nagbn
max number of global paramters per record
Definition: mpmod.f90:145
character(len=74) textl
name of current MP 'module' (step)
Definition: mpmod.f90:157
integer(mpi) nloopn
number of data reading, fitting loops
Definition: mpmod.f90:43
integer(mpl) sumrecords
sum of records
Definition: mpmod.f90:188
integer(mpi) mreqpe
min number of pair entries
Definition: mpmod.f90:80
integer(mpi) memdbg
debug flag for memory management
Definition: mpmod.f90:96
integer(mpi), dimension(100) lbmnrs
MINRES error labels.
Definition: mpmod.f90:177
integer(mpi) ncgrp
number of (disjoint) constraint groups
Definition: mpmod.f90:139
real(mpd) mrtcnd
transition (QR -> QLP) (matrix) condition for MINRES-QLP
Definition: mpmod.f90:62
real(mpd), dimension(:), allocatable vbk
local fit 'matrix for border solution'
Definition: mpmod.f90:305
real(mps) prange
range (-PRANGE..PRANGE) for histograms of pulls, norm.
Definition: mpmod.f90:97
integer(mpi) matsto
(global) matrix storage mode (0: unpacked, 1: full = packed, 2: sparse(custom), 3: sparse(CSR3,...
Definition: mpmod.f90:35
integer(mpi), dimension(:,:), allocatable matconssort
keys and index for sorting
Definition: mpmod.f90:247
real(mpd), dimension(:), allocatable lapackwork
LAPACK work array.
Definition: mpmod.f90:237
integer(mpi) monpg1
progress monitoring, repetition rate start value
Definition: mpmod.f90:116
integer(mpi), dimension(:,:), allocatable readbufferinfo
buffer management (per thread)
Definition: mpmod.f90:283
integer(mpi) nhistp
flag for histogram printout
Definition: mpmod.f90:65
integer(mpl), dimension(:), allocatable csr3rowoffsets
row offsets for column list
Definition: mpmod.f90:280
real(mpd), dimension(:), allocatable globalparcopy
copy of global parameters
Definition: mpmod.f90:197
real(mpd), dimension(:), allocatable lapackql
LAPACK QL (QL decomp.)
Definition: mpmod.f90:235
real(mpd), dimension(2) dscerr
scaling factors for errors of 'global' and 'local' measurement
Definition: mpmod.f90:112
real(mps) chhuge
cut in terms of 3-sigma for unreasonable data, all iterations
Definition: mpmod.f90:50
integer(mpi), dimension(:), allocatable sparsematrixcolumns
(compressed) list of columns for sparse matrix
Definition: mpmod.f90:277
integer(mpl), dimension(:,:), allocatable sparsematrixoffsets
row offsets for column list, sparse matrix elements
Definition: mpmod.f90:278
integer(mpi) iteren
entries cut is iterated for parameters with less entries (if > mreqenf)
Definition: mpmod.f90:105
integer(mpi), dimension(:,:), allocatable matconsranges
parameter ranges for constraints
Definition: mpmod.f90:246
integer(mpi) lunkno
flag for unkown keywords
Definition: mpmod.f90:46
integer(mpi), dimension(:), allocatable scflag
local fit workspace (I)
Definition: mpmod.f90:308
real(mpd), parameter measbinsize
bins size for monitoring
Definition: mpmod.f90:176
integer(mpi) mdebug
debug flag (number of records to print)
Definition: mpmod.f90:38
integer(mpi) npblck
number of (disjoint) parameter blocks (>1: block diagonal storage)
Definition: mpmod.f90:138
real(mpd), dimension(:), allocatable matconsproduct
product matrix of constraints
Definition: mpmod.f90:241
integer(mpi), dimension(:), allocatable yfd
binary file: modification date
Definition: mpmod.f90:360
integer(mpi) nxlow
(max of) global parameters with too few accepted entries for icalcm=1
Definition: mpmod.f90:171
integer(mpl) ndgb
number of global derivatives read
Definition: mpmod.f90:152
real(mps) value1
largest residual
Definition: mpmod.f90:55
integer(mpi) ipddbg
flag for debugging Intel oneMKL PARDISO
Definition: mpmod.f90:121
real(mpd), dimension(:), allocatable localcorrections
local fit corrections (to residuals)
Definition: mpmod.f90:310
integer(mpl) nrec3
(1.) record number with error
Definition: mpmod.f90:79
real(mps) chirem
cut in terms of 3-sigma cut, other iterations, approaching 1.
Definition: mpmod.f90:49
real(mpd), dimension(:), allocatable localglobalmatrix
matrix correlating local and global par, content
Definition: mpmod.f90:311
integer(mpi) mhispe
upper bound for pair entry histogrammimg
Definition: mpmod.f90:81
integer(mpi) nfgb
number of fit parameters
Definition: mpmod.f90:132
integer(mpi), dimension(:,:), allocatable kfd
(1,.)= number of records in file, (2,..)= file order
Definition: mpmod.f90:351
real(mpd), dimension(:), allocatable globalchi2sumd
fractional part of Chi2 sum
Definition: mpmod.f90:219
integer(mpi) icheck
flag for checking input only (no solution determined)
Definition: mpmod.f90:103
integer(mpi), dimension(:), allocatable jfd
file: number of accepted records
Definition: mpmod.f90:353
integer(mpl) nrecer
record with error (rank deficit or Not-a-Number) for printout
Definition: mpmod.f90:78
integer(mpi) matmon
record interval for monitoring of (sparse) matrix construction
Definition: mpmod.f90:86
integer(mpi) nbndx
max band width for local fit
Definition: mpmod.f90:77
type(listitem), dimension(:), allocatable listconstraints
list of constraints from steering file
Definition: mpmod.f90:333
real(mpd), dimension(:), allocatable globalmatd
global matrix 'A' (double, full or sparse)
Definition: mpmod.f90:205
real(mpr8), dimension(:), allocatable readbufferdatad
double data
Definition: mpmod.f90:287
type(listitem), dimension(:), allocatable listmeasurements
list of (external) measurements from steering file
Definition: mpmod.f90:336
integer(mpi) lsinfo
line search: returned information
Definition: mpmod.f90:162
integer(mpi) nregul
regularization flag
Definition: mpmod.f90:70
integer(mpi) nfilw
number of weighted binary files
Definition: mpmod.f90:369
integer(mpi) ndefpg
number of parameter groups with rank deficit (from inversion)
Definition: mpmod.f90:168
integer(mpi), dimension(:), allocatable paircounter
number of paired parameters (in equations)
Definition: mpmod.f90:292
integer(mpi) nummeasurements
number of (external) measurements from steering file
Definition: mpmod.f90:334
integer(mpi), dimension(0:3) nrejec
rejected events
Definition: mpmod.f90:154
integer(mpl) nrec2
record number with largest chi^2/Ndf
Definition: mpmod.f90:54
integer(mpi) ndimbuf
default read buffer size (I/F words, half record length)
Definition: mpmod.f90:370
real(mpd) fvalue
function value (chi2 sum) solution
Definition: mpmod.f90:178
real(mpd), dimension(:), allocatable globalcorrections
correction x_i (from A*x_i=b_i in iteration i)
Definition: mpmod.f90:198
real(mps), dimension(:), allocatable cfd
file: chi2 sum
Definition: mpmod.f90:356
real(mps) regula
regularization parameter, add regula * norm(global par.) to objective function
Definition: mpmod.f90:71
integer(mpi) nspc
number of precision for sparse global matrix (1=D, 2=D+F)
Definition: mpmod.f90:173
integer(mpi) nfilc
number of C binary files
Definition: mpmod.f90:368
integer(mpi) nagb
number of all parameters (var.
Definition: mpmod.f90:131
integer(mpi) nmiss1
rank deficit for constraints
Definition: mpmod.f90:169
integer(mpi), dimension(:), allocatable globalparhashtable
global parameters hash table
Definition: mpmod.f90:259
integer(mpi) nalow
(sum of) global parameters with too few accepted entries
Definition: mpmod.f90:170
integer(mpi) iscerr
flag for scaling of errors
Definition: mpmod.f90:111
real(mpd) sumndf
weighted sum(ndf)
Definition: mpmod.f90:180
integer(mpi), dimension(2) nbndr
number of records with bordered band matrix for local fit (upper/left, lower/right)
Definition: mpmod.f90:75
integer(mpl), dimension(:), allocatable lapackipiv
LAPACK IPIV (pivot)
Definition: mpmod.f90:238
integer(mpi) iterat
iterations in solution
Definition: mpmod.f90:69
real(mpd) flines
function value line search
Definition: mpmod.f90:179
integer(mpi), dimension(:), allocatable meashists
measurement histograms (100 bins per thread)
Definition: mpmod.f90:254
integer(mpi), dimension(:), allocatable globalindexranges
global par ranges
Definition: mpmod.f90:294
integer(mpi) mthrd
number of (OpenMP) threads
Definition: mpmod.f90:84
integer(mpi) mbandw
band width of preconditioner matrix
Definition: mpmod.f90:44
integer(mpl) lplwrk
length of LAPACK WORK array
Definition: mpmod.f90:234
real(mps) dwcut
down-weight fraction cut
Definition: mpmod.f90:57
integer(mpl), dimension(:), allocatable globalcounter
global counter (entries in 'x')
Definition: mpmod.f90:209
real(mps), dimension(:), allocatable globalmatf
global matrix 'A' (float part for compressed sparse)
Definition: mpmod.f90:206
integer(mpi), dimension(:,:), allocatable matconsgroups
start of constraint groups, parameter range
Definition: mpmod.f90:248
real(mps), dimension(0:8) times
cpu time counters
Definition: mpmod.f90:155
integer(mpi) minrecordsinblock
min.
Definition: mpmod.f90:190
integer(mpi), dimension(:), allocatable localglobalstructure
matrix correlating local and global par, (sparsity) structure
Definition: mpmod.f90:313
real(mpd), dimension(:), allocatable globalndfsumw
weighted NDF sum
Definition: mpmod.f90:222
integer(mpi) naeqn
max number of equations (measurements) per record
Definition: mpmod.f90:147
integer(mpi) nfilb
number of binary files
Definition: mpmod.f90:366
real(mpd), dimension(:), allocatable vzru
local fit 'border solution'
Definition: mpmod.f90:306
real(mpd), dimension(:), allocatable globalparpreweight
weight from pre-sigma
Definition: mpmod.f90:201
integer(mpi) ictest
test mode '-t'
Definition: mpmod.f90:33
real(mpd), dimension(:), allocatable vbdr
local fit border part of 'A'
Definition: mpmod.f90:303
integer(mpi) mdebg2
number of measurements for record debug printout
Definition: mpmod.f90:39
integer(mpi), dimension(:,:), allocatable globaltotindexgroups
Definition: mpmod.f90:273
integer(mpi), dimension(:), allocatable vecconsgroupcounts
counter for constraint groups
Definition: mpmod.f90:249
real(mps) deltim
cpu time difference
Definition: mpmod.f90:164
integer(mpi) igcorr
flag for output of global correlations for inversion, =0: none
Definition: mpmod.f90:95
integer(mpi), dimension(-8:0) globalparheader
global parameters (mapping) header
Definition: mpmod.f90:262
integer(mpi) lencomments
length of list of (global parameter) comments from steering file
Definition: mpmod.f90:337
integer(mpl), dimension(:), allocatable offprecond
preconditioner (block matrix) offsets
Definition: mpmod.f90:217
real(mpd), dimension(:), allocatable vecconssolution
solution for constraint elimination
Definition: mpmod.f90:243
integer(mpi) nfiles
number of files
Definition: mpmod.f90:365
integer(mpi) ipcntr
flag for output of global parameter counts (entries), =0: none, =1: local fits, >1: binary files
Definition: mpmod.f90:100
integer(mpl) negb
number of equations read with global parameters
Definition: mpmod.f90:151
integer(mpi) keepopen
flag for keeping binary files open
Definition: mpmod.f90:113
real(mpd), dimension(:), allocatable workspacediagonalization
workspace diag.
Definition: mpmod.f90:228
real(mps), dimension(:), allocatable wfd
binary file: weight
Definition: mpmod.f90:358
real(mpd), dimension(:), allocatable matprecond
preconditioner matrix (band and other parts)
Definition: mpmod.f90:214
integer(mpi) ntgb
total number of global parameters
Definition: mpmod.f90:129
real(mps) angras
angle between gradient and search direction
Definition: mpmod.f90:68
type(listitemc), dimension(:), allocatable listcomments
list of comments from steering file
Definition: mpmod.f90:338
integer(mpi) mthrdr
number of threads for reading binary files
Definition: mpmod.f90:92
integer(mpi) numreadbuffer
number of buffers (records) in (read) block
Definition: mpmod.f90:186
integer(mpi) imonmd
monitoring mode: 0:residuals (normalized to average error), 1:pulls
Definition: mpmod.f90:110
character(len=1024) filnam
name of steering file
Definition: mpmod.f90:361
integer(mpi) lunlog
unit for logfile
Definition: mpmod.f90:127
integer(mpi) ncblck
number of (non overlapping) constraint blocks
Definition: mpmod.f90:140
real(mps), dimension(3) fcache
read cache, average fill level; write cache; dynamic size
Definition: mpmod.f90:91
real(mps) wolfc2
C_2 of strong Wolfe condition.
Definition: mpmod.f90:60
real(mpd), dimension(:), allocatable workspacerow
(pivot) row of global matrix (for global corr.)
Definition: mpmod.f90:226
integer(mpi) maxrecordsinblock
max.
Definition: mpmod.f90:191
real(mpd) mrestl
tolerance criterion for MINRES-QLP
Definition: mpmod.f90:61
real(mpd), dimension(:), allocatable globalparpresigma
pre-sigma for global parameters
Definition: mpmod.f90:200
integer(mpi) icelim
flag for using elimination (instead of multipliers) for constraints
Definition: mpmod.f90:102
integer(mpi) mitera
number of iterations
Definition: mpmod.f90:42
integer(mpi) lenpardiso
length of list of Intel oneMKL PARDISO parameters (indices 1..64)
Definition: mpmod.f90:341
integer(mpi) nbdrx
max border size for local fit
Definition: mpmod.f90:76
integer(mpi), dimension(:,:), allocatable globalparlabelindex
global parameters label, total -> var.
Definition: mpmod.f90:257
real(mpd), dimension(:), allocatable scdiag
local fit workspace (D)
Definition: mpmod.f90:307
integer(mpi), dimension(:), allocatable readbufferdatai
integer data
Definition: mpmod.f90:285
integer(mpi) mextnd
flag for extended storage (both 'halves' of sym.
Definition: mpmod.f90:83
integer(mpi), dimension(:,:), allocatable sfd
offset (1,..), length (2,..) of binary file name in tfd
Definition: mpmod.f90:359
integer(mpi) lenconstraints
length of list of constraints from steering file
Definition: mpmod.f90:332
integer(mpi), dimension(:), allocatable blockprecond
preconditioner (constraint) blocks
Definition: mpmod.f90:216
integer(mpi) lenparameters
list items from steering file
Definition: mpmod.f90:328
integer(mpi) lprecm
additional flag for preconditioner (band) matrix (>0: preserve rank by skyline matrix)
Definition: mpmod.f90:45
integer(mpi) ndefec
rank deficit for global matrix (from inversion)
Definition: mpmod.f90:167
integer(mpl) nrecp2
record number with printout
Definition: mpmod.f90:52
integer(mpl) nrec
number of records read
Definition: mpmod.f90:148
integer(mpi), dimension(:,:), allocatable matparblockoffsets
global par block offsets (parameter, constraint blocks)
Definition: mpmod.f90:295
integer(mpl) nrecpr
record number with printout
Definition: mpmod.f90:51
integer(mpl), dimension(:), allocatable ifd
file: integrated record numbers (=offset)
Definition: mpmod.f90:352
integer(mpi) nofeas
flag for skipping making parameters feasible
Definition: mpmod.f90:64
integer(mpi) matbsz
(global) matrix (fixed) block size, only used for BSR3 storage mode (Intel oneMKL PARDISO)
Definition: mpmod.f90:36
integer(mpi) nfnam
length of sterring file name
Definition: mpmod.f90:362
real rstart
cpu start time for solution iterations
Definition: mpmod.f90:163
integer(mpi), dimension(:), allocatable writebufferindices
write buffer for indices
Definition: mpmod.f90:317
integer(mpi) iforce
switch to SUBITO for (global) rank defects if zero
Definition: mpmod.f90:94
real(mpd), dimension(:), allocatable workspacelinesearch
workspace line search
Definition: mpmod.f90:227
integer(mpi), dimension(:), allocatable globalparvartototal
global parameters variable -> total index
Definition: mpmod.f90:260
real(mpd), dimension(:), allocatable clmat
local fit matrix 'A' (in A*x=b)
Definition: mpmod.f90:299
integer(mpi), dimension(:), allocatable lfd
length of file name
Definition: mpmod.f90:349
integer(mpi) ntpgrp
number of parameter groups
Definition: mpmod.f90:135
character, dimension(:), allocatable tfd
file names (concatenation)
Definition: mpmod.f90:363
integer(mpi) ncgbe
number of empty constraints (no variable parameters)
Definition: mpmod.f90:134
integer(mpi) mprint
print flag (0: minimal, 1: normal, >1: more)
Definition: mpmod.f90:37
integer(mpi), dimension(:), allocatable vecconsstart
start of constraint in listConstraints (unsorted input)
Definition: mpmod.f90:245
integer(mpi) nummeas
number of measurement groups for monitoring
Definition: mpmod.f90:175
integer(mpi) lvllog
log level
Definition: mpmod.f90:128
integer(mpi), dimension(3) nprecond
number of constraints (blocks), matrix size for preconditioner
Definition: mpmod.f90:143
integer(mpi) nalcn
max number of local paramters per record
Definition: mpmod.f90:146
integer(mpi), dimension(:), allocatable globalparcomments
global parameters comments
Definition: mpmod.f90:203
integer(mpi) mreqenf
required number of entries (for variable global parameter from binary Files)
Definition: mpmod.f90:40
real(mps) value2
largest chi^2/Ndf
Definition: mpmod.f90:56
integer(mpi) icalcm
calculation mode (for XLOOPN) , >0: calculate matrix
Definition: mpmod.f90:74
integer(mpi) mcount
flag for grouping and counting global parameters on equlation (0) or record (1) level
Definition: mpmod.f90:115
real(mps), dimension(:), allocatable ofd
file: option
Definition: mpmod.f90:357
integer(mpi) ireeof
flag for treating (binary file) read errors as end-of-file
Definition: mpmod.f90:114
integer(mpi) ifile
current file (index)
Definition: mpmod.f90:364
real(mps) delfun
expected function change
Definition: mpmod.f90:66
integer(mpi) iitera
MINRES iterations.
Definition: mpmod.f90:160
integer(mpl) skippedrecords
number of skipped records (buffer too small)
Definition: mpmod.f90:189
integer(mpi) lenmeasurements
length of list of (external) measurements from steering file
Definition: mpmod.f90:335
real(mps) wolfc1
C_1 of strong Wolfe condition.
Definition: mpmod.f90:59
real(mpd), dimension(:), allocatable aux
local fit 'solutions for border rows'
Definition: mpmod.f90:304
integer(mpi) napgrp
number of all parameter groups (variable + Lagrange mult.)
Definition: mpmod.f90:137
integer(mpl) nrecd
number of records read containing doubles
Definition: mpmod.f90:149
integer(mpi), dimension(:,:), allocatable localequations
indices (ISJAJB) for local equations (measurements)
Definition: mpmod.f90:309
integer(mpi), dimension(:), allocatable globalallpartogroup
all parameters variable -> group index
Definition: mpmod.f90:261
integer(mpi), dimension(:), allocatable backindexusage
list of global par in record
Definition: mpmod.f90:290
integer(mpi), dimension(:), allocatable ibandh
local fit 'band width histogram' (band size autodetection)
Definition: mpmod.f90:300
integer(mpi) isubit
subito flag '-s'
Definition: mpmod.f90:58
integer(mpi), dimension(:), allocatable indprecond
preconditioner pointer array
Definition: mpmod.f90:215
real(mps) dflim
convergence limit
Definition: mpmod.f90:153
integer(mpi) ncache
buffer size for caching (default 100MB per thread)
Definition: mpmod.f90:90
integer(mpi) mxrec
max number of records
Definition: mpmod.f90:85
integer(mpi) mpdbsz
PARDISO, number of block sizes to be tried (by PBSBITS)
Definition: mpmod.f90:182
integer(mpi) lfitnp
local fit: number of iteration to calculate pulls
Definition: mpmod.f90:87
integer(mpl), dimension(:), allocatable globalparlabelcounter
global parameters label counters
Definition: mpmod.f90:258
integer(mpi) lcalcm
last calclation mode
Definition: mpmod.f90:172
real(mpd), dimension(:), allocatable globalvector
global vector 'x' (in A*x=b)
Definition: mpmod.f90:207
real(mpd), dimension(:), allocatable writebufferupdates
write buffer for update matrices
Definition: mpmod.f90:318
integer(mpi) irslvrc
flag for resolving redundancy constraints (two equivalent parameter groups)
Definition: mpmod.f90:107
real(mpd), dimension(:), allocatable workspaced
(general) workspace (D)
Definition: mpmod.f90:224
integer(mpl) neqn
number of equations (measurements) read
Definition: mpmod.f90:150
integer(mpi) measbins
number of bins per measurement for monitoring
Definition: mpmod.f90:109
integer(mpl) mszcon
(integrated block) matrix size for constraint matrix
Definition: mpmod.f90:141
integer(mpi), dimension(:), allocatable nfd
index (line) in (steering) file
Definition: mpmod.f90:350
integer(mpi) ilperr
flag to calculate parameter errors with LAPACK
Definition: mpmod.f90:119
integer(mpi) numblocks
number of (read) blocks
Definition: mpmod.f90:187
integer(mpi) ncgb
number of constraints
Definition: mpmod.f90:133
integer(mpi), dimension(:,:), allocatable matconsblocks
start of constraint blocks, parameter range
Definition: mpmod.f90:251
real(mpd), dimension(:), allocatable workspaceeigenvalues
workspace eigen values
Definition: mpmod.f90:229
integer(mpi) lhuber
Huber down-weighting flag.
Definition: mpmod.f90:47
integer(mpi) nvgb
number of variable global parameters
Definition: mpmod.f90:130
integer(mpi) nfilf
number of Fortran binary files
Definition: mpmod.f90:367
integer(mpi), dimension(:), allocatable measindex
mapping of 1.
Definition: mpmod.f90:253
integer(mpi) istopa
MINRES istop (convergence)
Definition: mpmod.f90:161
integer(mpi), dimension(:), allocatable mfd
file mode: cbinary =1, text =2, fbinary=3
Definition: mpmod.f90:348
real(mpd), dimension(:), allocatable blvec
local fit vector 'b' (in A*x=b), replaced by 'x'
Definition: mpmod.f90:298
logical newite
flag for new iteration
Definition: mpmod.f90:158
integer(mpi) nrderr
number of binary files with read errors
Definition: mpmod.f90:181
real(mpd), dimension(:), allocatable measres
average measurement error
Definition: mpmod.f90:255
real(mpd), dimension(:), allocatable vecxav
vector x for AVPROD (A*x=b)
Definition: mpmod.f90:211
real(mpd), dimension(:), allocatable globalparstart
start value for global parameters
Definition: mpmod.f90:199
integer(mpi), dimension(-6:6) writebufferheader
write buffer header (-6..-1: updates, 1..6: indices)
Definition: mpmod.f90:319
integer(mpi) monpg2
progress monitoring, repetition rate max increase
Definition: mpmod.f90:117
integer(mpl), dimension(:), allocatable globalrowoffsets
row offsets for full or unpacked matrix
Definition: mpmod.f90:208
integer(mpi) lenpresigmas
length of list of pre-sigmas from steering file
Definition: mpmod.f90:330
integer(mpi) npresg
number of pre-sigmas
Definition: mpmod.f90:165
integer(mpi), dimension(:), allocatable appearancecounter
appearance statistics for global par (first/last file,record)
Definition: mpmod.f90:291
integer(mpi) nvpgrp
number of variable parameter groups
Definition: mpmod.f90:136
integer(mpi), dimension(:), allocatable xfd
file: max.
Definition: mpmod.f90:355
integer(mpi) mreqena
required number of entries (for variable global parameter from Accepted local fits)
Definition: mpmod.f90:41
real(mps), dimension(:,:), allocatable writebufferdata
write buffer data (largest residual, Chi2/ndf, per thread)
Definition: mpmod.f90:316
real(mpd), dimension(:), allocatable workspacediag
diagonal of global matrix (for global corr.)
Definition: mpmod.f90:225
integer(mpl) ndfsum
sum(ndf)
Definition: mpmod.f90:159
integer(mpi) lenglobalvec
length of global vector 'b' (A*x=b)
Definition: mpmod.f90:192
real(mps) stepl
step length (line search)
Definition: mpmod.f90:156
integer(mpi) msngpe
upper bound for pair entry single precision storage
Definition: mpmod.f90:82
real(mpd), dimension(:), allocatable vecbav
vector b for AVPROD (A*x=b)
Definition: mpmod.f90:212
integer(mpl), dimension(:), allocatable globalchi2sumi
integer part of Chi2 sum
Definition: mpmod.f90:220
integer(mpl) ipdmem
memory (kB) used by Intel oneMKL PARDISO
Definition: mpmod.f90:343
integer(mpi), dimension(:), allocatable readbufferpointer
pointer to used buffers
Definition: mpmod.f90:284
integer(mpi), dimension(:), allocatable workspacei
(general) workspace (I)
Definition: mpmod.f90:231
integer(mpi), dimension(:), allocatable globalparcons
global parameters (number of) constraints
Definition: mpmod.f90:202
integer(mpi), dimension(:,:), allocatable writebufferinfo
write buffer management (per thread)
Definition: mpmod.f90:315
integer(mpl), dimension(:), allocatable globalndfsum
NDF sum.
Definition: mpmod.f90:221
integer(mpi) matrit
matrix calculation up to iteration MATRIT
Definition: mpmod.f90:73
real(mpd), dimension(:), allocatable vbnd
local fit band part of 'A'
Definition: mpmod.f90:302
real(mpr4), dimension(:), allocatable readbufferdataf
float data
Definition: mpmod.f90:286
type(listitemi), dimension(:), allocatable listpardiso
list of Intel oneMKL PARDISO parameters
Definition: mpmod.f90:342
integer(mpi) lfitbb
local fit: check for bordered band matrix (if >0)
Definition: mpmod.f90:88
integer(mpi) lsearch
iterations (solutions) with line search: >2: all, =2: all with (next) Chi2 cut scaling factor =1....
Definition: mpmod.f90:98
integer(mpi), dimension(:), allocatable dfd
file: ndf sum
Definition: mpmod.f90:354
integer(mpi) ichkpg
flag for checking (rank of) parameter groups
Definition: mpmod.f90:104
type(listitem), dimension(:), allocatable listpresigmas
list of pre-sgmas from steering file
Definition: mpmod.f90:331
integer(mpi), dimension(:), allocatable globalallindexgroups
Definition: mpmod.f90:274
integer(mpi) mrmode
MINRES-QLP mode (0: QR+QLP, 1: only QR, 2: only QLP factorization)
Definition: mpmod.f90:63
real(mps) chicut
cut in terms of 3-sigma cut, first iteration
Definition: mpmod.f90:48
integer(mpi) imonit
flag for monitoring residuals per local fit cycle (=0: none, <0: all, bit 0: first,...
Definition: mpmod.f90:108
Parameters and data.
Definition: mptest1.f90:35
real(mps), dimension(nplan) dvd
rel.
Definition: mptest1.f90:53
real(mps), dimension(nplan) del
shift (position deviation) (alignment parameter)
Definition: mptest1.f90:52
integer(mpi), parameter nplan
Definition: mptest1.f90:41
Parameters and data.
Definition: mptest2.f90:57
integer(mpi), parameter nmx
number of modules in x direction
Definition: mptest2.f90:65
real(mps), dimension(ntot) sdevx
shift in x (alignment parameter)
Definition: mptest2.f90:82
real(mps), dimension(ntot) sdevy
shift in y (alignment parameter)
Definition: mptest2.f90:83
integer(mpi), parameter nmy
number of modules in y direction
Definition: mptest2.f90:67
integer(mpi), parameter nlyr
number of detector layers
Definition: mptest2.f90:63
integer(mpi), parameter ntot
total number of modules
Definition: mptest2.f90:68
Keyword position.
Definition: mptext.f90:29
integer(mpi) keyb
end (position) of first keyword
Definition: mptext.f90:35
integer(mpi) keya
start (position) of first keyword
Definition: mptext.f90:34
integer(mpi) keyc
end (position) of last keyword
Definition: mptext.f90:36
subroutine ploopb(lunp)
Print iteration line.
Definition: pede.f90:3791
subroutine mchdec
Solution by Cholesky decomposition.
Definition: pede.f90:8906
subroutine bincls(kfile, ithr)
Close binary file.
Definition: pede.f90:13101
subroutine prpcon
Prepare constraints.
Definition: pede.f90:1903
subroutine mminrs
Solution with MINRES.
Definition: pede.f90:9920
subroutine mcsolv(n, x, y)
Solution for zero band width preconditioner.
Definition: pede.f90:10124
subroutine mupdat(i, j, add)
Update element of global matrix.
Definition: pede.f90:4013
subroutine peend(icode, cmessage)
Print exit code.
Definition: pede.f90:12984
subroutine loopn
Loop with fits and sums.
Definition: pede.f90:3350
subroutine loop1
First data loop (get global labels).
Definition: pede.f90:6806
subroutine feasma
Matrix for feasible solution.
Definition: pede.f90:2203
subroutine xloopn
Standard solution algorithm.
Definition: pede.f90:10178
subroutine ploopa(lunp)
Print title for iteration.
Definition: pede.f90:3770
subroutine isjajb(nst, is, ja, jb, jsp)
Decode Millepede record.
Definition: pede.f90:3299
subroutine additem(length, list, label, value)
add item to list
Definition: pede.f90:12724
subroutine mgupdt(i, j1, j2, il, jl, n, sub)
Update global matrix for parameter group.
Definition: pede.f90:4098
subroutine lpavat(t)
Similarity transformation by Q(t).
Definition: pede.f90:9438
subroutine binrwd(kfile)
Rewind binary file.
Definition: pede.f90:13136
subroutine zdiags
Covariance matrix for diagonalization (,correction of eigenvectors).
Definition: pede.f90:9883
subroutine solglo(ivgbi)
Error for single global parameter from MINRES.
Definition: pede.f90:1364
subroutine upone
Update, redefine hash indices.
Definition: pede.f90:6672
subroutine pargrp(inds, inde)
Parameter group info update for block of parameters.
Definition: pede.f90:3181
subroutine prtglo
Print final log file.
Definition: pede.f90:5291
subroutine monres
Monitor input residuals.
Definition: pede.f90:8495
subroutine intext(text, nline)
Interprete text.
Definition: pede.f90:11862
integer(mpl) function ijadd(itema, itemb)
Index for sparse storage (custom).
Definition: pede.f90:6305
subroutine mdiags
Solution by diagonalization.
Definition: pede.f90:9734
program mptwo
Millepede II main program Pede.
Definition: pede.f90:875
subroutine prtstat
Print input statistic.
Definition: pede.f90:5476
real(mpd) function matij(itema, itemb)
Get matrix element at (i,j).
Definition: pede.f90:6412
subroutine grpcon
Group constraints.
Definition: pede.f90:1605
subroutine loopbf(nrej, numfil, naccf, chi2f, ndff)
Loop over records in read buffer (block), fits and sums.
Definition: pede.f90:4266
subroutine peread(more)
Read (block of) records from binary files.
Definition: pede.f90:2539
subroutine filetx
Interprete text files.
Definition: pede.f90:11539
integer(mpi) function iprime(n)
largest prime number < N.
Definition: pede.f90:6774
subroutine ploopc(lunp)
Print sub-iteration line.
Definition: pede.f90:3848
integer(mpl) function ijcsr3(itema, itemb)
Index for sparse storage (CSR3).
Definition: pede.f90:6354
subroutine useone
Make usable (sort items and redefine hash indices).
Definition: pede.f90:6742
subroutine mvopen(lun, fname)
Open file.
Definition: pede.f90:12896
subroutine chkrej
Check rejection details.
Definition: pede.f90:10999
subroutine avprd0(n, l, x, b)
Product symmetric (sub block) matrix times vector.
Definition: pede.f90:5876
subroutine addsums(ithrd, chi2, ndf, dw)
Accurate summation.
Definition: pede.f90:13293
subroutine solgloqlp(ivgbi)
Error for single global parameter from MINRES-QLP.
Definition: pede.f90:1448
subroutine lpqldec(a, emin, emax)
QL decomposition.
Definition: pede.f90:9322
subroutine addcst
Add constraint information to matrix and vector.
Definition: pede.f90:1531
subroutine petime
Print times.
Definition: pede.f90:12933
subroutine mstart(text)
Start of 'module' printout.
Definition: pede.f90:12843
subroutine mend
End of 'module' printout.
Definition: pede.f90:12879
subroutine anasps
Analyse sparsity structure.
Definition: pede.f90:6044
subroutine minver
Solution by matrix inversion.
Definition: pede.f90:8793
subroutine peprep(mode)
Prepare records.
Definition: pede.f90:2890
integer(mpi) function ijprec(itema, itemb)
Precision for storage of parameter groups.
Definition: pede.f90:6276
subroutine explfc(lunit)
Print explanation of iteration table.
Definition: pede.f90:3922
subroutine getsums(chi2, ndf, wndf)
Get accurate sums.
Definition: pede.f90:13326
subroutine chkmat
Check global matrix.
Definition: pede.f90:13247
subroutine binopn(kfile, ithr, ierr)
Open binary file.
Definition: pede.f90:13005
subroutine pepgrp
Parameter group info update.
Definition: pede.f90:3057
subroutine sechms(deltat, nhour, minut, secnd)
Time conversion.
Definition: pede.f90:6557
integer(mpi) function inone(item)
Translate labels to indices (for global parameters).
Definition: pede.f90:6602
subroutine avprds(n, l, x, is, ie, b)
Product symmetric (sub block) matrix times sparse vector.
Definition: pede.f90:5662
subroutine avprod(n, x, b)
Product symmetric matrix times vector.
Definition: pede.f90:6138
subroutine ijpgrp(itema, itemb, ij, lr, iprc)
Index (region length and precision) for sparse storage of parameter groups.
Definition: pede.f90:6178
subroutine loop1i
Iteration of first data loop.
Definition: pede.f90:7169
subroutine mhalf2
Fill 2nd half of matrix for extended storage.
Definition: pede.f90:6470
subroutine ckpgrp
Check (rank of) parameter groups.
Definition: pede.f90:13167
subroutine additemi(length, list, label, ivalue)
add item to list
Definition: pede.f90:12808
subroutine mminrsqlp
Solution with MINRES-QLP.
Definition: pede.f90:10018
subroutine filetc
Interprete command line option, steering file.
Definition: pede.f90:11063
subroutine feasib(concut, iact)
Make parameters feasible.
Definition: pede.f90:2378
subroutine mspardiso
Solution with Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO.
Definition: pede.f90:9529
subroutine mdutrf
Solution by factorization.
Definition: pede.f90:9153
subroutine mdptrf
Solution by factorization.
Definition: pede.f90:9018
subroutine mvsolv(n, x, y)
Solution for finite band width preconditioner.
Definition: pede.f90:10145
subroutine vmprep(msize)
Prepare storage for vectors and matrices.
Definition: pede.f90:8596
subroutine ploopd(lunp)
Print solution line.
Definition: pede.f90:3896
subroutine pechk(ibuf, nerr)
Check Millepede record.
Definition: pede.f90:2985
subroutine loop2
Second data loop (number of derivatives, global label pairs).
Definition: pede.f90:7281
integer(mpi) function nufile(fname)
Inquire on file.
Definition: pede.f90:11805
subroutine additemc(length, list, label, text)
add character item to list
Definition: pede.f90:12766
void resetc(int nFileIn)
Rewind file.
Definition: readc.c:185
void initc(int nFiles)
Initialises the 'global' variables used for file handling.
Definition: readc.c:91
void closec(int nFileIn)
Close file.
Definition: readc.c:168
void readc(double *bufferDouble, float *bufferFloat, int *bufferInt, int *lengthBuffers, int nFileIn, int *errorFlag)
Read record from file.
Definition: readc.c:219
void openc(const char *fileName, int lfn, int nFileIn, int *errorFlag)
Open file.
Definition: readc.c:110
list items from steering file
Definition: mpdef.f90:40
character list items from steering file
Definition: mpdef.f90:47
integer list items from steering file
Definition: mpdef.f90:52