Millepede-II V04-17-06
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
283
570
571
831
869
912
913#ifdef SCOREP_USER_ENABLE
914#include "scorep/SCOREP_User.inc"
915#endif
916
918PROGRAM mptwo
919 USE mpmod
920 USE mpdalc
921 USE mptest1, ONLY: nplan,del,dvd
922 USE mptest2, ONLY: nlyr,nmx,nmy,sdevx,sdevy,ntot
923
924 IMPLICIT NONE
925 REAL(mps) :: andf
926 REAL(mps) :: c2ndf
927 REAL(mps) :: deltat
928 REAL(mps) :: diff
929 REAL(mps) :: err
930 REAL(mps) :: gbu
931 REAL(mps) :: gmati
932 REAL(mps) :: rej
933 REAL :: rloop1
934 REAL :: rloop2
935 REAL :: rstext
936 REAL(mps) :: secnd
937 REAL :: rst
938 REAL :: rstp
939 REAL, DIMENSION(2) :: ta
940 INTEGER(mpi) :: i
941 INTEGER(mpi) :: ii
942 INTEGER(mpi) :: iopnmp
943 INTEGER(mpi) :: ix
944 INTEGER(mpi) :: ixv
945 INTEGER(mpi) :: iy
946 INTEGER(mpi) :: k
947 INTEGER(mpi) :: kfl
948 INTEGER(mpi) :: lun
949 INTEGER :: minut
950 INTEGER :: nhour
951 INTEGER(mpi) :: nmxy
952 INTEGER(mpi) :: nrc
953 INTEGER(mpi) :: nsecnd
954 INTEGER(mpi) :: ntsec
955
956 CHARACTER (LEN=24) :: chdate
957 CHARACTER (LEN=24) :: chost
958#ifdef LAPACK64
959 CHARACTER (LEN=6) :: c6
960 INTEGER major, minor, patch
961#endif
962
963 INTEGER(mpl) :: rows
964 INTEGER(mpl) :: cols
965
966 REAL(mpd) :: sums(9)
967 !$ INTEGER(mpi) :: OMP_GET_NUM_PROCS,OMP_GET_MAX_THREADS
968 !$ INTEGER(mpi) :: MXTHRD
969 !$ INTEGER(mpi) :: NPROC
970
971 REAL etime
972
973 SAVE
974 ! ...
975 rstp=etime(ta)
976 CALL fdate(chdate)
977
978 ! millepede monitoring file
979 lunmon=0
980 ! millepede.log file
981 lunlog=8
982 lvllog=1
983 CALL mvopen(lunlog,'millepede.log')
984 CALL getenv('HOSTNAME',chost)
985 IF (chost(1:1) == ' ') CALL getenv('HOST',chost)
986 WRITE(*,*) '($Id: dd0c569a1aafb6f6eb2f26b9b9537a685639ca25 $)'
987 iopnmp=0
988 !$ iopnmp=1
989 !$ WRITE(*,*) 'using OpenMP (TM)'
990#ifdef LAPACK64
991 CALL ilaver( major,minor, patch )
992 WRITE(*,110) lapack64, major,minor, patch
993110 FORMAT(' using LAPACK64 with ',(a),', version ',i0,'.',i0,'.',i0)
994#ifdef PARDISO
995 WRITE(*,*) 'using Intel oneMKL PARDISO'
996#endif
997#endif
998#ifdef __GFORTRAN__
999 WRITE(*,111) __gnuc__ , __gnuc_minor__ , __gnuc_patchlevel__
1000111 FORMAT(' compiled with gcc ',i0,'.',i0,'.',i0)
1001#endif
1002#ifdef __PGIC__
1003 WRITE(*,111) __pgic__ , __pgic_minor__ , __pgic_patchlevel__
1004111 FORMAT(' compiled with pgi ',i0,'.',i0,'.',i0)
1005#endif
1006#ifdef SCOREP_USER_ENABLE
1007 WRITE(*,*) 'instrumenting Score-P user regions'
1008#endif
1009 WRITE(*,*) ' '
1010 WRITE(*,*) ' < Millepede II-P starting ... ',chdate
1011 WRITE(*,*) ' ',chost
1012 WRITE(*,*) ' '
1013
1014 WRITE(8,*) '($Id: dd0c569a1aafb6f6eb2f26b9b9537a685639ca25 $)'
1015 WRITE(8,*) ' '
1016 WRITE(8,*) 'Log-file Millepede II-P ', chdate
1017 WRITE(8,*) ' ', chost
1018
1019 CALL peend(-1,'Still running or crashed')
1020 ! read command line and text files
1021
1022 CALL filetc ! command line and steering file analysis
1023 CALL filetx ! read text files
1024 ! dummy call for dynamic memory allocation
1025 CALL gmpdef(0,nfilb,'dummy call')
1026
1027 IF (icheck > 0) THEN
1028 WRITE(*,*) '!!! Checking input only, no calculation of a solution !!!'
1029 WRITE(8,*) '!!! Checking input only, no calculation of a solution !!!'
1030 END IF
1031 lvllog=mprint ! export print level
1032 IF (memdbg > 0) printflagalloc=1 ! debug memory management
1033 !$ WRITE(*,*)
1034 !$ NPROC=1
1035 !$ MXTHRD=1
1036 !$ NPROC=OMP_GET_NUM_PROCS() ! number of processors available
1037 !$ CALL OMP_SET_NUM_THREADS(MTHRD) ! set max number of threads to MTHRD
1038 !$ MXTHRD=OMP_GET_MAX_THREADS() ! get max number of threads back
1039 !$ WRITE(*,*) 'Number of processors available: ', NPROC
1040 !$ WRITE(*,*) 'Maximum number of OpenMP threads: ', MXTHRD
1041 !$ WRITE(*,*) 'Number of threads for processing: ', MTHRD
1042 !$ IF (MXREC.GT.0) MTHRDR=1 ! to get allways the same MXREC records
1043 !$ IF (ICHECK.GT.1) MTHRDR=1 ! to get allways the same order of records
1044 !$ WRITE(*,*) 'Number of threads for reading: ', MTHRDR
1045 !$POMP INST INIT ! start profiling with ompP
1046#ifdef LAPACK64
1047 IF(iopnmp > 0) THEN
1048 CALL getenv('OMP_NUM_THREADS',c6)
1049 ELSE
1050 CALL getenv(lapack64//'_NUM_THREADS',c6)
1051 END IF
1052 IF (c6(1:1) == ' ') THEN
1053 IF(iopnmp > 0) THEN
1054 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty OMP_NUM_THREADS)'
1055 ELSE
1056 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty ',lapack64//'_NUM_THREADS)'
1057 END IF
1058 ELSE
1059 WRITE(*,*) 'Number of threads for LAPACK: ', c6
1060 END IF
1061#endif
1062 cols=mthrd
1063 CALL mpalloc(globalchi2sumd,cols,'fractional part of Chi2 sum')
1064 globalchi2sumd=0.0_mpd
1065 CALL mpalloc(globalchi2sumi,cols,'integer part of Chi2 sum')
1066 globalchi2sumi=0_mpl
1067 CALL mpalloc(globalndfsum,cols,'NDF sum')
1068 globalndfsum=0_mpl
1069 CALL mpalloc(globalndfsumw,cols,'weighted NDF sum')
1070 globalndfsumw=0.0_mpd
1071
1072 IF (ncache < 0) THEN
1073 ncache=25000000*mthrd ! default cache size (100 MB per thread)
1074 ENDIF
1075 rows=6; cols=mthrdr
1076 CALL mpalloc(readbufferinfo,rows,cols,'read buffer header')
1077 ! histogram file
1078 lun=7
1079 CALL mvopen(lun,'millepede.his')
1080 CALL hmplun(lun) ! unit for histograms
1081 CALL gmplun(lun) ! unit for xy data
1082
1083 ! debugging
1084 IF(nrecpr /= 0.OR.nrecp2 /= 0) THEN
1085 CALL mvopen(1,'mpdebug.txt')
1086 END IF
1087
1088 rstext=etime(ta)
1089 times(0)=rstext-rstp ! time for text processing
1090
1091 ! preparation of data sub-arrays
1092
1093 CALL loop1
1094 rloop1=etime(ta)
1095 times(1)=rloop1-rstext ! time for LOOP1
1096
1097 CALL loop2
1098 IF(chicut /= 0.0) THEN
1099 WRITE(8,*) 'Chi square cut equiv 3 st.dev applied ...'
1100 WRITE(8,*) ' in first iteration with factor',chicut
1101 WRITE(8,*) ' in second iteration with factor',chirem
1102 WRITE(8,*) ' (reduced by sqrt in next iterations)'
1103 END IF
1104
1105 IF(lhuber /= 0) THEN
1106 WRITE(8,*) 'Down-weighting of outliers in', lhuber,' iterations'
1107 WRITE(8,*) 'Cut on downweight fraction',dwcut
1108 END IF
1109
1110 rloop2=etime(ta)
1111 times(2)=rloop2-rloop1 ! time for LOOP2
1112
1113 IF(icheck > 0) THEN
1114 CALL prtstat
1115 IF (ncgbe < 0) THEN
1116 CALL peend(5,'Ended without solution (empty constraints)')
1117 ELSE
1118 CALL peend(0,'Ended normally')
1119 END IF
1120 GOTO 99 ! only checking input
1121 END IF
1122
1123 ! use different solution methods
1124
1125 CALL mstart('Iteration') ! Solution module starting
1126
1127 CALL xloopn ! all methods
1128
1129 ! ------------------------------------------------------------------
1130
1131 IF(nloopn > 2.AND.nhistp /= 0) THEN ! last iteration
1132 CALL hmprnt(3) ! scaled residual of single measurement (with global deriv.)
1133 CALL hmprnt(12) ! scaled residual of single measurement (no global deriv.)
1134 CALL hmprnt(4) ! chi^2/Ndf
1135 END IF
1136 IF(nloopn > 2) THEN
1137 CALL hmpwrt(3)
1138 CALL hmpwrt(12)
1139 CALL hmpwrt(4)
1140 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
1141 IF (nloopn <= lfitnp) THEN
1142 CALL hmpwrt(13)
1143 CALL hmpwrt(14)
1144 CALL gmpwrt(5)
1145 END IF
1146 END IF
1147 IF(nhistp /= 0) THEN
1148 CALL gmprnt(1)
1149 CALL gmprnt(2)
1150 END IF
1151 CALL gmpwrt(1) ! output of xy data
1152 CALL gmpwrt(2) ! output of xy data
1153 ! 'track quality' per binary file
1154 IF (nfilb > 1) THEN
1155 CALL gmpdef(6,1,'log10(#records) vs file number')
1156 CALL gmpdef(7,1,'final rejection fraction vs file number')
1157 CALL gmpdef(8,1, &
1158 'final <Chi^2/Ndf> from accepted local fits vs file number')
1159 CALL gmpdef(9,1, '<Ndf> from accepted local fits vs file number')
1160
1161 DO i=1,nfilb
1162 kfl=kfd(2,i)
1163 nrc=-kfd(1,i)
1164 IF (nrc > 0) THEN
1165 rej=real(nrc-jfd(kfl),mps)/real(nrc,mps)
1166 CALL gmpxy(6,real(kfl,mps),log10(real(nrc,mps))) ! log10(#records) vs file
1167 CALL gmpxy(7,real(kfl,mps),rej) ! rejection fraction vs file
1168 END IF
1169 IF (jfd(kfl) > 0) THEN
1170 c2ndf=cfd(kfl)/real(jfd(kfl),mps)
1171 CALL gmpxy(8,real(kfl,mps),c2ndf) ! <Chi2/NDF> vs file
1172 andf=real(dfd(kfl),mps)/real(jfd(kfl),mps)
1173 CALL gmpxy(9,real(kfl,mps),andf) ! <NDF> vs file
1174 END IF
1175 END DO
1176 IF(nhistp /= 0) THEN
1177 CALL gmprnt(6)
1178 CALL gmprnt(7)
1179 CALL gmprnt(8)
1180 CALL gmprnt(9)
1181 END IF
1182 CALL gmpwrt(6) ! output of xy data
1183 CALL gmpwrt(7) ! output of xy data
1184 CALL gmpwrt(8) ! output of xy data
1185 CALL gmpwrt(9) ! output of xy data
1186 END IF
1187
1188 IF(ictest == 1) THEN
1189 WRITE(*,*) ' '
1190 WRITE(*,*) 'Misalignment test wire chamber'
1191 WRITE(*,*) ' '
1192
1193 CALL hmpdef( 9,-0.0015,+0.0015,'True - fitted displacement')
1194 CALL hmpdef(10,-0.0015,+0.0015,'True - fitted Vdrift')
1195 DO i=1,4
1196 sums(i)=0.0_mpd
1197 END DO
1198 DO i=1,nplan
1199 diff=real(-del(i)-globalparameter(i),mps)
1200 sums(1)=sums(1)+diff
1201 sums(2)=sums(2)+diff*diff
1202 diff=real(-dvd(i)-globalparameter(100+i),mps)
1203 sums(3)=sums(3)+diff
1204 sums(4)=sums(4)+diff*diff
1205 END DO
1206 sums(1)=0.01_mpd*sums(1)
1207 sums(2)=sqrt(0.01_mpd*sums(2))
1208 sums(3)=0.01_mpd*sums(3)
1209 sums(4)=sqrt(0.01_mpd*sums(4))
1210 WRITE(*,143) 'Parameters 1 - 100: mean =',sums(1), 'rms =',sums(2)
1211 WRITE(*,143) 'Parameters 101 - 200: mean =',sums(3), 'rms =',sums(4)
1212143 FORMAT(6x,a28,f9.6,3x,a5,f9.6)
1213 WRITE(*,*) ' '
1214 WRITE(*,*) ' '
1215 WRITE(*,*) ' I label simulated fitted diff'
1216 WRITE(*,*) ' -------------------------------------------- '
1217 DO i=1,100
1218 WRITE(*,102) i,globalparlabelindex(1,i),-del(i),globalparameter(i),-del(i)-globalparameter(i)
1219 diff=real(-del(i)-globalparameter(i),mps)
1220 CALL hmpent( 9,diff)
1221 END DO
1222 DO i=101,200
1223 WRITE(*,102) i,globalparlabelindex(1,i),-dvd(i-100),globalparameter(i),-dvd(i-100)-globalparameter(i)
1224 diff=real(-dvd(i-100)-globalparameter(i),mps)
1225 CALL hmpent(10,diff)
1226 END DO
1227 IF(nhistp /= 0) THEN
1228 CALL hmprnt( 9)
1229 CALL hmprnt(10)
1230 END IF
1231 CALL hmpwrt( 9)
1232 CALL hmpwrt(10)
1233 END IF
1234 IF(ictest > 1) THEN
1235 WRITE(*,*) ' '
1236 WRITE(*,*) 'Misalignment test Si tracker'
1237 WRITE(*,*) ' '
1238
1239 CALL hmpdef( 9,-0.0025,+0.0025,'True - fitted displacement X')
1240 CALL hmpdef(10,-0.025,+0.025,'True - fitted displacement Y')
1241 DO i=1,9
1242 sums(i)=0.0_mpd
1243 END DO
1244 nmxy=nmx*nmy
1245 ix=0
1246 iy=ntot
1247 DO i=1,nlyr
1248 DO k=1,nmxy
1249 ix=ix+1
1250 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1251 sums(1)=sums(1)+1.0_mpd
1252 sums(2)=sums(2)+diff
1253 sums(3)=sums(3)+diff*diff
1254 ixv=globalparlabelindex(2,ix)
1255 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1256 ii=(ixv*ixv+ixv)/2
1257 gmati=real(globalmatd(ii),mps)
1258 err=sqrt(abs(gmati))
1259 diff=diff/err
1260 sums(7)=sums(7)+1.0_mpd
1261 sums(8)=sums(8)+diff
1262 sums(9)=sums(9)+diff*diff
1263 END IF
1264 END DO
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 sums(4)=sums(4)+1.0_mpd
1270 sums(5)=sums(5)+diff
1271 sums(6)=sums(6)+diff*diff
1272 ixv=globalparlabelindex(2,iy)
1273 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1274 ii=(ixv*ixv+ixv)/2
1275 gmati=real(globalmatd(ii),mps)
1276 err=sqrt(abs(gmati))
1277 diff=diff/err
1278 sums(7)=sums(7)+1.0_mpd
1279 sums(8)=sums(8)+diff
1280 sums(9)=sums(9)+diff*diff
1281 END IF
1282 END DO
1283 END IF
1284 END DO
1285 sums(2)=sums(2)/sums(1)
1286 sums(3)=sqrt(sums(3)/sums(1))
1287 sums(5)=sums(5)/sums(4)
1288 sums(6)=sqrt(sums(6)/sums(4))
1289 WRITE(*,143) 'Parameters 1 - 500: mean =',sums(2), 'rms =',sums(3)
1290 WRITE(*,143) 'Parameters 501 - 700: mean =',sums(5), 'rms =',sums(6)
1291 IF (sums(7) > 0.5_mpd) THEN
1292 sums(8)=sums(8)/sums(7)
1293 sums(9)=sqrt(sums(9)/sums(7))
1294 WRITE(*,143) 'Parameter pulls, all: mean =',sums(8), 'rms =',sums(9)
1295 END IF
1296 WRITE(*,*) ' '
1297 WRITE(*,*) ' '
1298 WRITE(*,*) ' I label simulated fitted diff'
1299 WRITE(*,*) ' -------------------------------------------- '
1300 ix=0
1301 iy=ntot
1302 DO i=1,nlyr
1303 DO k=1,nmxy
1304 ix=ix+1
1305 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1306 CALL hmpent( 9,diff)
1307 WRITE(*,102) ix,globalparlabelindex(1,ix),-sdevx((i-1)*nmxy+k),globalparameter(ix),-diff
1308 END DO
1309 END DO
1310 DO i=1,nlyr
1311 IF (mod(i,3) == 1) THEN
1312 DO k=1,nmxy
1313 iy=iy+1
1314 diff=real(-sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1315 CALL hmpent(10,diff)
1316 WRITE(*,102) iy,globalparlabelindex(1,iy),-sdevy((i-1)*nmxy+k),globalparameter(iy),-diff
1317 END DO
1318 END IF
1319 END DO
1320 IF(nhistp /= 0) THEN
1321 CALL hmprnt( 9)
1322 CALL hmprnt(10)
1323 END IF
1324 CALL hmpwrt( 9)
1325 CALL hmpwrt(10)
1326 END IF
1327
1328 IF(nrec1+nrec2 > 0) THEN
1329 WRITE(8,*) ' '
1330 IF(nrec1 > 0) THEN
1331 WRITE(8,*) 'Record',nrec1,' has largest residual:',value1
1332 END IF
1333 IF(nrec2 > 0) THEN
1334 WRITE(8,*) 'Record',nrec2,' has largest Chi^2/Ndf:',value2
1335 END IF
1336 END IF
1337 IF(nrec3 < huge(nrec3)) THEN
1338 WRITE(8,*) 'Record',nrec3, ' is first with error (rank deficit/NaN)'
1339 END IF
134099 WRITE(8,*) ' '
1341 IF (iteren > mreqenf) THEN
1342 WRITE(8,*) 'In total 3 +',nloopn,' loops through the data files'
1343 ELSE
1344 WRITE(8,*) 'In total 2 +',nloopn,' loops through the data files'
1345 ENDIF
1346 IF (mnrsit > 0) THEN
1347 WRITE(8,*) ' '
1348 WRITE(8,*) 'In total ',mnrsit,' internal MINRES iterations'
1349 END IF
1350
1351 WRITE(8,103) times(0),times(1),times(2),times(4),times(7), &
1352 times(5),times(8),times(3),times(6)
1353
1354 rst=etime(ta)
1355 deltat=rst-rstp
1356 ntsec=nint(deltat,mpi)
1357 CALL sechms(deltat,nhour,minut,secnd)
1358 nsecnd=nint(secnd,mpi) ! round
1359 WRITE(8,*) 'Total time =',ntsec,' seconds =',nhour,' h',minut, &
1360 ' m',nsecnd,' seconds'
1361 CALL fdate(chdate)
1362 WRITE(8,*) 'end ', chdate
1363 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1364 WRITE(8,*) ' '
1365 WRITE(8,105) gbu
1366
1367 ! Rejects ----------------------------------------------------------
1368
1369 IF(sum(nrejec) /= 0) THEN
1370 WRITE(8,*) ' '
1371 WRITE(8,*) 'Data records rejected in last iteration: '
1372 CALL prtrej(8)
1373 WRITE(8,*) ' '
1374 END IF
1375 IF (icheck <= 0) CALL explfc(8)
1376
1377 WRITE(*,*) ' '
1378 WRITE(*,*) ' < Millepede II-P ending ... ', chdate ! with exit code',ITEXIT,' >'
1379 WRITE(*,*) ' '
1380 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1381 WRITE(*,105) gbu
1382#ifdef LAPACK64
1383#ifdef PARDISO
1384 IF(ipdmem > 0) WRITE(*,106) real(ipdmem,mps)*1.e-6
1385106 FORMAT(' PARDISO dyn. memory allocation: ',f11.6,' GB')
1386#endif
1387#endif
1388 WRITE(*,*) ' '
1389 ! close files
1390 CLOSE(unit=7) ! histogram file
1391 CLOSE(unit=8) ! log file
1392
1393 ! post processing?
1394 IF (lenpostproc > 0) THEN
1395 WRITE(*,*) 'Postprocessing:'
1396 IF (lenpostproc >= 80) THEN
1397 WRITE(*,*) cpostproc(1:38) // ' .. ' // cpostproc(lenpostproc-37:lenpostproc)
1398 ELSE
1399 WRITE(*,*) cpostproc(1:lenpostproc)
1400 ENDIF
1401 WRITE(*,*) ' '
1402 CALL system(cpostproc(1:lenpostproc))
1403 END IF
1404
1405102 FORMAT(2x,i4,i10,2x,3f10.5)
1406103 FORMAT(' Times [in sec] for text processing',f12.3/ &
1407 ' LOOP1',f12.3/ &
1408 ' LOOP2',f12.3/ &
1409 ' func. value ',f12.3,' *',f4.0/ &
1410 ' func. value, global matrix, solution',f12.3,' *',f4.0/ &
1411 ' new solution',f12.3,' *',f4.0/)
1412105 FORMAT(' Peak dynamic memory allocation: ',f11.6,' GB')
1413END PROGRAM mptwo ! Mille
1414
1421
1422SUBROUTINE solglo(ivgbi)
1423 USE mpmod
1424 USE minresmodule, ONLY: minres
1425
1426 IMPLICIT NONE
1427 REAL(mps) :: par
1428 REAL(mps) :: dpa
1429 REAL(mps) :: err
1430 REAL(mps) :: gcor2
1431 INTEGER(mpi) :: iph
1432 INTEGER(mpi) :: istop
1433 INTEGER(mpi) :: itgbi
1434 INTEGER(mpi) :: itgbl
1435 INTEGER(mpi) :: itn
1436 INTEGER(mpi) :: itnlim
1437 INTEGER(mpi) :: nout
1438
1439 INTEGER(mpi), INTENT(IN) :: ivgbi
1440
1441 REAL(mpd) :: shift
1442 REAL(mpd) :: rtol
1443 REAL(mpd) :: anorm
1444 REAL(mpd) :: acond
1445 REAL(mpd) :: arnorm
1446 REAL(mpd) :: rnorm
1447 REAL(mpd) :: ynorm
1448 REAL(mpd) :: gmati
1449 REAL(mpd) :: diag
1450 REAL(mpd) :: matij
1451 LOGICAL :: checka
1452 EXTERNAL avprod, mcsolv, mvsolv
1453 SAVE
1454 DATA iph/0/
1455 ! ...
1456 IF(iph == 0) THEN
1457 iph=1
1458 WRITE(*,101)
1459 END IF
1460 itgbi=globalparvartototal(ivgbi)
1461 itgbl=globalparlabelindex(1,itgbi)
1462
1463 globalvector=0.0_mpd ! reset rhs vector IGVEC
1464 globalvector(ivgbi)=1.0_mpd
1465
1466 ! NOUT =6
1467 nout =0
1468 itnlim=200
1469 shift =0.0_mpd
1470 rtol = mrestl ! from steering
1471 checka=.false.
1472
1473
1474 IF(mbandw == 0) THEN ! default preconditioner
1475 CALL minres(nagb, avprod, mcsolv, globalvector, shift, checka ,.true. , &
1476 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1477
1478 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1479 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.true. , &
1480 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1481 ELSE
1482 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.false. , &
1483 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1484 END IF
1485
1486 par=real(globalparameter(itgbi),mps)
1487 dpa=real(par-globalparstart(itgbi),mps)
1488 gmati=globalcorrections(ivgbi)
1489 err=sqrt(abs(real(gmati,mps)))
1490 IF(gmati < 0.0_mpd) err=-err
1491 diag=matij(ivgbi,ivgbi)
1492 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1493 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1494101 FORMAT(1x,' label parameter presigma differ', &
1495 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1496102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1497END SUBROUTINE solglo
1498
1505
1506SUBROUTINE solgloqlp(ivgbi)
1507 USE mpmod
1508 USE minresqlpmodule, ONLY: minresqlp
1509
1510 IMPLICIT NONE
1511 REAL(mps) :: par
1512 REAL(mps) :: dpa
1513 REAL(mps) :: err
1514 REAL(mps) :: gcor2
1515 INTEGER(mpi) :: iph
1516 INTEGER(mpi) :: istop
1517 INTEGER(mpi) :: itgbi
1518 INTEGER(mpi) :: itgbl
1519 INTEGER(mpi) :: itn
1520 INTEGER(mpi) :: itnlim
1521 INTEGER(mpi) :: nout
1522
1523 INTEGER(mpi), INTENT(IN) :: ivgbi
1524
1525 REAL(mpd) :: shift
1526 REAL(mpd) :: rtol
1527 REAL(mpd) :: mxxnrm
1528 REAL(mpd) :: trcond
1529 REAL(mpd) :: gmati
1530 REAL(mpd) :: diag
1531 REAL(mpd) :: matij
1532
1533 EXTERNAL avprod, mcsolv, mvsolv
1534 SAVE
1535 DATA iph/0/
1536 ! ...
1537 IF(iph == 0) THEN
1538 iph=1
1539 WRITE(*,101)
1540 END IF
1541 itgbi=globalparvartototal(ivgbi)
1542 itgbl=globalparlabelindex(1,itgbi)
1543
1544 globalvector=0.0_mpd ! reset rhs vector IGVEC
1545 globalvector(ivgbi)=1.0_mpd
1546
1547 ! NOUT =6
1548 nout =0
1549 itnlim=200
1550 shift =0.0_mpd
1551 rtol = mrestl ! from steering
1552 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
1553 IF(mrmode == 1) THEN
1554 trcond = 1.0_mpd/epsilon(trcond) ! only QR
1555 ELSE IF(mrmode == 2) THEN
1556 trcond = 1.0_mpd ! only QLP
1557 ELSE
1558 trcond = mrtcnd ! QR followed by QLP
1559 END IF
1560
1561 IF(mbandw == 0) THEN ! default preconditioner
1562 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mcsolv, nout=nout, &
1563 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1564 x=globalcorrections, istop=istop, itn=itn)
1565 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1566 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mvsolv, nout=nout, &
1567 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1568 x=globalcorrections, istop=istop, itn=itn)
1569 ELSE
1570 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, nout=nout, &
1571 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1572 x=globalcorrections, istop=istop, itn=itn)
1573 END IF
1574
1575 par=real(globalparameter(itgbi),mps)
1576 dpa=real(par-globalparstart(itgbi),mps)
1577 gmati=globalcorrections(ivgbi)
1578 err=sqrt(abs(real(gmati,mps)))
1579 IF(gmati < 0.0_mpd) err=-err
1580 diag=matij(ivgbi,ivgbi)
1581 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1582 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1583101 FORMAT(1x,' label parameter presigma differ', &
1584 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1585102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1586END SUBROUTINE solgloqlp
1587
1589SUBROUTINE addcst
1590 USE mpmod
1591
1592 IMPLICIT NONE
1593 REAL(mpd) :: climit
1594 REAL(mpd) :: factr
1595 REAL(mpd) :: sgm
1596
1597 INTEGER(mpi) :: i
1598 INTEGER(mpi) :: icgb
1599 INTEGER(mpi) :: irhs
1600 INTEGER(mpi) :: itgbi
1601 INTEGER(mpi) :: ivgb
1602 INTEGER(mpi) :: j
1603 INTEGER(mpi) :: jcgb
1604 INTEGER(mpi) :: l
1605 INTEGER(mpi) :: label
1606 INTEGER(mpi) :: nop
1607 INTEGER(mpi) :: inone
1608
1609 REAL(mpd) :: rhs
1610 REAL(mpd) :: drhs(4)
1611 INTEGER(mpi) :: idrh (4)
1612 SAVE
1613 ! ...
1614 nop=0
1615 IF(lenconstraints == 0) RETURN ! no constraints
1616 climit=1.0e-5 ! limit for printout
1617 irhs=0 ! number of values in DRHS(.), to be printed
1618
1619 DO jcgb=1,ncgb
1620 icgb=matconssort(3,jcgb) ! unsorted constraint index
1621 i=vecconsstart(icgb)
1622 rhs=listconstraints(i )%value ! right hand side
1623 sgm=listconstraints(i+1)%value ! sigma parameter
1624 DO j=i+2,vecconsstart(icgb+1)-1
1625 label=listconstraints(j)%label
1626 factr=listconstraints(j)%value
1627 itgbi=inone(label) ! -> ITGBI= index of parameter label
1628 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1629
1630 IF(icalcm == 1.AND.nagb > nvgb.AND.ivgb > 0) THEN
1631 CALL mupdat(nvgb+jcgb,ivgb,factr) ! add to matrix
1632 END IF
1633
1634 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
1635 END DO
1636 IF(abs(rhs) > climit) THEN
1637 irhs=irhs+1
1638 idrh(irhs)=jcgb
1639 drhs(irhs)=rhs
1640 nop=1
1641 IF(irhs == 4) THEN
1642 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1643 irhs=0
1644 END IF
1645 END IF
1646 vecconsresiduals(jcgb)=rhs
1647 IF (nagb > nvgb) globalvector(nvgb+jcgb)=rhs
1648 END DO
1649
1650 IF(irhs /= 0) THEN
1651 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1652 END IF
1653 IF(nop == 0) RETURN
1654 WRITE(*,102) ' Constraints: only equation values >', climit,' are printed'
1655101 FORMAT(' ',4(i6,g11.3))
1656102 FORMAT(a,g11.2,a)
1657END SUBROUTINE addcst
1658
1663SUBROUTINE grpcon
1664 USE mpmod
1665 USE mpdalc
1666
1667 IMPLICIT NONE
1668 INTEGER(mpi) :: i
1669 INTEGER(mpi) :: icgb
1670 INTEGER(mpi) :: icgrp
1671 INTEGER(mpi) :: ioff
1672 INTEGER(mpi) :: itgbi
1673 INTEGER(mpi) :: j
1674 INTEGER(mpi) :: jcgb
1675 INTEGER(mpi) :: label
1676 INTEGER(mpi) :: labelf
1677 INTEGER(mpi) :: labell
1678 INTEGER(mpi) :: last
1679 INTEGER(mpi) :: line1
1680 INTEGER(mpi) :: ncon
1681 INTEGER(mpi) :: ndiff
1682 INTEGER(mpi) :: npar
1683 INTEGER(mpi) :: inone
1684 INTEGER(mpi) :: itype
1685 INTEGER(mpi) :: ncgbd
1686 INTEGER(mpi) :: ncgbr
1687 INTEGER(mpi) :: ncgbw
1688 INTEGER(mpi) :: ncgrpd
1689 INTEGER(mpi) :: ncgrpr
1690 INTEGER(mpi) :: next
1691
1692 INTEGER(mpl):: length
1693 INTEGER(mpl) :: rows
1694
1695 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsOffsets
1696 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsList
1697 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParOffsets
1698 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParList
1699 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1700
1701 ncgb=0
1702 ncgbw=0
1703 IF(lenconstraints == 0) RETURN ! no constraints
1704
1705 i=0
1706 last=0
1707 itype=0
1708 ! find next constraint header and count nr of constraints
1709 DO WHILE(i < lenconstraints)
1710 i=i+1
1711 label=listconstraints(i)%label
1712 IF(last < 0.AND.label < 0) THEN
1713 ncgb=ncgb+1
1714 itype=-label
1715 IF(itype == 2) ncgbw=ncgbw+1
1716 END IF
1717 last=label
1718 IF(label > 0) THEN
1719 itgbi=inone(label) ! -> ITGBI= index of parameter label
1720 globalparcons(itgbi)=globalparcons(itgbi)+1
1721 END IF
1722 IF(label > 0.AND.itype == 2) THEN ! weighted constraints
1723 itgbi=inone(label) ! -> ITGBI= index of parameter label
1725 END IF
1726 END DO
1727
1728 WRITE(*,*)
1729 IF (ncgbw == 0) THEN
1730 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files'
1731 ELSE
1732 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files,',ncgbw, 'weighted'
1733 END IF
1734 WRITE(*,*)
1735
1736 ! keys and index for sorting of constraints
1737 length=ncgb+1; rows=3
1738 CALL mpalloc(matconssort,rows,length,'keys and index for sorting (I)')
1739 matconssort(1,ncgb+1)=ntgb+1
1740 ! start of constraint in list
1741 CALL mpalloc(vecconsstart,length,'start of constraint in list (I)')
1743 ! start and parameter range of constraint groups
1744 CALL mpalloc(matconsgroups,rows,length,'start of constraint groups, par. range (I)')
1745 ! parameter ranges (all, variable) of constraints
1746 length=ncgb; rows=4
1747 CALL mpalloc(matconsranges,rows,length,'parameter ranges for constraint (I)')
1748
1749 length=ncgb; rows=3
1750 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1751 matconsgroupindex=0
1752 length=ncgb+1
1753 CALL mpalloc(vecconsparoffsets,length,'offsets for global par list for cons. (I)')
1754 length=ntgb+1
1755 CALL mpalloc(vecparconsoffsets,length,'offsets for cons. list for global par. (I)')
1756 vecparconsoffsets(1)=0
1757 DO i=1,ntgb
1758 vecparconsoffsets(i+1)=vecparconsoffsets(i)+globalparcons(i)
1759 END DO
1761
1762 length=vecparconsoffsets(ntgb+1)
1763 CALL mpalloc(vecconsparlist,length,'global par. list for constraint (I)')
1764 CALL mpalloc(vecparconslist,length,'constraint list for global par. (I)')
1765
1766 ! prepare
1767 i=1
1768 ioff=0
1769 vecconsparoffsets(1)=ioff
1770 DO icgb=1,ncgb
1771 ! new constraint
1772 vecconsstart(icgb)=i
1773 line1=-listconstraints(i)%label
1774 npar=0
1775 i=i+2
1776 DO
1777 label=listconstraints(i)%label
1778 itgbi=inone(label) ! -> ITGBI= index of parameter label
1779 ! list of constraints for 'itgbi'
1780 globalparcons(itgbi)=globalparcons(itgbi)+1
1781 vecparconslist(vecparconsoffsets(itgbi)+globalparcons(itgbi))=icgb
1782 npar=npar+1
1783 vecconsparlist(ioff+npar)=itgbi
1784 i=i+1
1785 IF(i > lenconstraints) EXIT
1786 IF(listconstraints(i)%label < 0) EXIT
1787 END DO
1788 ! sort to find duplicates
1789 CALL sort1k(vecconsparlist(ioff+1),npar)
1790 last=-1
1791 ndiff=0
1792 DO j=1,npar
1793 next=vecconsparlist(ioff+j)
1794 IF (next /= last) THEN
1795 ndiff=ndiff+1
1796 vecconsparlist(ioff+ndiff) = next
1797 END IF
1798 last=next
1799 END DO
1800 matconsranges(1,icgb)=vecconsparlist(ioff+1) ! min parameter
1801 matconsranges(3,icgb)=vecconsparlist(ioff+1) ! min parameter
1802 ioff=ioff+ndiff
1803 matconsranges(2,icgb)=vecconsparlist(ioff) ! max parameter
1804 matconsranges(4,icgb)=vecconsparlist(ioff) ! max parameter
1805 vecconsparoffsets(icgb+1)=ioff
1806 END DO
1808
1809 ! sort (by first, last parameter)
1810 DO icgb=1,ncgb
1811 matconssort(1,icgb)=matconsranges(1,icgb) ! first par.
1812 matconssort(2,icgb)=matconsranges(2,icgb) ! last par.
1813 matconssort(3,icgb)=icgb ! index
1814 END DO
1815 CALL sort2i(matconssort,ncgb)
1816
1817 IF (icheck>1) THEN
1818 print *, ' Constraint #parameters first par. last par. first line'
1819 END IF
1820 ! split into disjoint groups
1821 ncgrp=0
1823 DO jcgb=1,ncgb
1824 icgb=matconssort(3,jcgb)
1825 IF (icheck>0) THEN
1826 npar=vecconsparoffsets(icgb+1)-vecconsparoffsets(icgb)
1827 line1=-listconstraints(vecconsstart(icgb))%label
1828 labelf=globalparlabelindex(1,matconsranges(1,icgb))
1829 labell=globalparlabelindex(1,matconsranges(2,icgb))
1830 print *, jcgb, npar, labelf, labell, line1
1831 END IF
1832 ! already part of group?
1833 icgrp=matconsgroupindex(1,icgb)
1834 IF (icgrp == 0) THEN
1835 ! check all parameters
1836 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1837 itgbi=vecconsparlist(i)
1838 ! check all related constraints
1839 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1840 icgrp=matconsgroupindex(1,vecparconslist(j))
1841 ! already part of group?
1842 IF (icgrp > 0) EXIT
1843 END DO
1844 IF (icgrp > 0) EXIT
1845 END DO
1846 IF (icgrp == 0) THEN
1847 ! new group
1848 ncgrp=ncgrp+1
1849 icgrp=ncgrp
1850 END IF
1851 END IF
1852 ! add to group
1853 matconsgroupindex(2,icgb)=jcgb
1854 matconsgroupindex(3,icgb)=icgb
1855 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1856 itgbi=vecconsparlist(i)
1857 globalparcons(itgbi)=icgrp
1858 ! mark all related constraints
1859 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1860 matconsgroupindex(1,vecparconslist(j))=icgrp
1861 END DO
1862 END DO
1863 END DO
1864 WRITE(*,*) 'GRPCON:',ncgrp,' disjoint constraints groups built'
1865
1866 ! sort by group number
1867 CALL sort2i(matconsgroupindex,ncgb)
1868
1869 matconsgroups(1,1:ncgrp)=0
1870 DO jcgb=1,ncgb
1871 ! set up matConsSort
1872 icgb=matconsgroupindex(3,jcgb)
1873 matconssort(1,jcgb)=matconsranges(1,icgb)
1874 matconssort(2,jcgb)=matconsranges(2,icgb)
1875 matconssort(3,jcgb)=icgb
1876 ! set up matConsGroups
1877 icgrp=matconsgroupindex(1,jcgb)
1878 IF (matconsgroups(1,icgrp) == 0) THEN
1879 matconsgroups(1,icgrp)=jcgb
1880 matconsgroups(2,icgrp)=matconsranges(1,icgb)
1881 matconsgroups(3,icgrp)=matconsranges(2,icgb)
1882 ELSE
1883 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
1884 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
1885 END IF
1886 END DO
1887 matconsgroups(1,ncgrp+1)=ncgb+1
1888 matconsgroups(2,ncgrp+1)=ntgb+1
1889
1890 ! check for redundancy constraint groups
1891 ncgbr=0
1892 ncgrpr=0
1893 ncgbd=0
1894 ncgrpd=0
1895 IF (icheck>0) THEN
1896 print *
1897 print *, ' cons.group first con. first par. last par. #cons #par'
1898 ENDIF
1899 DO icgrp=1,ncgrp
1900 npar=0
1901 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1902 IF (globalparcons(i) == icgrp) npar=npar+1
1903 END DO
1904 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
1905 IF (icheck>0) THEN
1906 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1907 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1908 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ncon, npar
1909 END IF
1910 ! redundancy constraints?
1911 IF (ncon == npar) THEN
1912 IF (irslvrc > 0) THEN
1913 ncgrpr=ncgrpr+1
1914 ncgbr=ncgbr+ncon
1915 IF (icheck > 0) THEN
1916 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1917 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1918 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group resolved'
1919 END IF
1920 ! flag redundant parameters
1921 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1922 IF (globalparcons(i) == icgrp) globalparcons(i)=-icgrp
1923 END DO
1924 ! flag constraint group
1925 matconsgroups(2,icgrp)=ntgb+1
1926 matconsgroups(3,icgrp)=ntgb
1927 ELSE
1928 ncgrpd=ncgrpd+1
1929 ncgbd=ncgbd+ncon
1930 IF (icheck > 0) THEN
1931 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1932 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1933 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group redundant'
1934 END IF
1935 END IF
1936 END IF
1937 END DO
1938 IF (ncgrpr > 0) THEN
1939 WRITE(*,*) 'GRPCON:',ncgbr,' redundancy constraints in ', ncgrpr, ' groups resolved'
1940 ! all constraint groups resolved ?
1941 IF (ncgrpr == ncgrp) ncgrp=0
1942 ENDIF
1943 IF (ncgrpd > 0) THEN
1944 WRITE(*,*) 'GRPCON:',ncgbd,' redundancy constraints in ', ncgrpd, ' groups detected'
1945 ENDIF
1946 WRITE(*,*)
1947
1948 ! clean up
1949 CALL mpdealloc(vecparconslist)
1950 CALL mpdealloc(vecconsparlist)
1951 CALL mpdealloc(vecparconsoffsets)
1952 CALL mpdealloc(vecconsparoffsets)
1953 CALL mpdealloc(matconsgroupindex)
1954
1955END SUBROUTINE grpcon
1956
1960
1961SUBROUTINE prpcon
1962 USE mpmod
1963 USE mpdalc
1964
1965 IMPLICIT NONE
1966 INTEGER(mpi) :: i
1967 INTEGER(mpi) :: icgb
1968 INTEGER(mpi) :: icgrp
1969 INTEGER(mpi) :: ifrst
1970 INTEGER(mpi) :: ilast
1971 INTEGER(mpi) :: isblck
1972 INTEGER(mpi) :: itgbi
1973 INTEGER(mpi) :: ivgb
1974 INTEGER(mpi) :: j
1975 INTEGER(mpi) :: jcgb
1976 INTEGER(mpi) :: jfrst
1977 INTEGER(mpi) :: label
1978 INTEGER(mpi) :: labelf
1979 INTEGER(mpi) :: labell
1980 INTEGER(mpi) :: ncon
1981 INTEGER(mpi) :: ngrp
1982 INTEGER(mpi) :: npar
1983 INTEGER(mpi) :: ncnmxb
1984 INTEGER(mpi) :: ncnmxg
1985 INTEGER(mpi) :: nprmxb
1986 INTEGER(mpi) :: nprmxg
1987 INTEGER(mpi) :: inone
1988 INTEGER(mpi) :: nvar
1989
1990 INTEGER(mpl):: length
1991 INTEGER(mpl) :: rows
1992
1993 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1994
1995 ncgbe=0
1996 !
1997 ! constraint groups already built in GRPCON based on steering,
1998 ! now care about fixed parameters
1999 !
2000 IF(ncgrp == 0) THEN ! no constraints groups
2001 ncgb=0
2002 ncblck=0
2003 RETURN
2004 END IF
2005
2006 length=ncgrp+1; rows=3
2007 ! start and parameter range of constraint blocks
2008 CALL mpalloc(matconsblocks,rows,length,'start of constraint blocks, par. range (I)')
2009
2010 length=ncgb; rows=3
2011 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
2012 matconsgroupindex=0
2013
2014 ! check for empty constraints, redefine (accepted/active) constraints and groups
2015 ngrp=0
2016 ncgb=0
2017 DO icgrp=1,ncgrp
2018 ncon=ncgb
2019 ! resolved group ?
2020 IF (matconsgroups(2,icgrp) > matconsgroups(3,icgrp)) cycle
2021 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2022 icgb=matconssort(3,jcgb)
2023 i=vecconsstart(icgb)+2
2024 npar=0
2025 nvar=0
2026 matconsranges(1,icgb)=ntgb
2027 matconsranges(2,icgb)=1
2028 DO
2029 label=listconstraints(i)%label
2030 itgbi=inone(label) ! -> ITGBI= index of parameter label
2031 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2032 npar=npar+1
2033 IF(ivgb > 0) THEN
2034 nvar=nvar+1
2035 matconsranges(1,icgb)=min(matconsranges(1,icgb),itgbi)
2036 matconsranges(2,icgb)=max(matconsranges(2,icgb),itgbi)
2037 ENDIF
2038 i=i+1
2039 IF(i > lenconstraints) EXIT
2040 IF(listconstraints(i)%label < 0) EXIT
2041 END DO
2042 IF (nvar == 0) THEN
2043 ncgbe=ncgbe+1
2044 ! reset range
2045 matconsranges(1,icgb)=matconsranges(3,icgb)
2046 matconsranges(2,icgb)=matconsranges(4,icgb)
2047 END IF
2048 IF (nvar > 0 .OR. iskpec == 0) THEN
2049 ! constraint accepted (or kept)
2050 ncgb=ncgb+1
2051 matconsgroupindex(1,ncgb)=ngrp+1
2052 matconsgroupindex(2,ncgb)=icgb
2053 matconsgroupindex(3,ncgb)=nvar
2054 END IF
2055 END DO
2056 IF (ncgb > ncon) ngrp=ngrp+1
2057 END DO
2058 ncgrp=ngrp
2059
2060 IF (ncgbe > 0) THEN
2061 IF (iskpec > 0) THEN
2062 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints skipped'
2063 ELSE
2064 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints detected, to be fixed !!!'
2065 WRITE(*,*) ' (use option "skipemptycons" to skip those)'
2066 IF (icheck == 0) THEN
2067 icheck=2 ! switch to '-C'
2068 ncgbe=-ncgbe ! indicate that
2069 WRITE(*,*)
2070 WRITE(*,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2071 WRITE(8,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2072 WRITE(*,*)
2073 END IF
2074 END IF
2075 END IF
2076 WRITE(*,*) 'PRPCON:',ncgb,' constraints accepted'
2077 WRITE(*,*)
2078
2079 IF(ncgb == 0) RETURN ! no constraints left
2080
2081 ! already sorted by group number
2082
2083 matconsgroups(1,1:ncgrp)=0
2084 DO jcgb=1,ncgb
2085 ! set up matConsSort
2086 icgb=matconsgroupindex(2,jcgb)
2087 matconssort(1,jcgb)=matconsranges(1,icgb)
2088 matconssort(2,jcgb)=matconsranges(2,icgb)
2089 matconssort(3,jcgb)=icgb
2090 ! set up matConsGroups
2091 icgrp=matconsgroupindex(1,jcgb)
2092 IF (matconsgroups(1,icgrp) == 0) THEN
2093 matconsgroups(1,icgrp)=jcgb
2094 matconsgroups(2,icgrp)=matconsranges(1,icgb)
2095 matconsgroups(3,icgrp)=matconsranges(2,icgb)
2096 ELSE
2097 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
2098 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
2099 END IF
2100 END DO
2101 matconsgroups(1,ncgrp+1)=ncgb+1
2102 matconsgroups(2,ncgrp+1)=ntgb+1
2103
2104 ! loop over constraints groups, combine into non overlapping blocks
2105 ncblck=0
2106 ncnmxg=0
2107 nprmxg=0
2108 ncnmxb=0
2109 nprmxb=0
2110 mszcon=0
2111 mszprd=0
2112 isblck=1
2113 ilast=0
2114 IF (icheck > 0) THEN
2115 WRITE(*,*)
2116 IF (icheck > 1) &
2117 WRITE(*,*) ' Cons. sorted index #var.par. first line first label last label'
2118 WRITE(*,*) ' Cons. group index first cons. last cons. first label last label'
2119 WRITE(*,*) ' Cons. block index first group last group first label last label'
2120 END IF
2121 DO icgrp=1,ncgrp
2122 IF (icheck > 1) THEN
2123 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2124 icgb=matconssort(3,jcgb)
2125 nvar=matconsgroupindex(3,jcgb)
2126 labelf=globalparlabelindex(1,matconssort(1,jcgb))
2127 labell=globalparlabelindex(1,matconssort(2,jcgb))
2128 IF (nvar > 0) THEN
2129 WRITE(*,*) ' Cons. sorted', jcgb, nvar, &
2130 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2131 ELSE
2132 WRITE(*,*) ' Cons. sorted', jcgb, ' empty (0)', &
2133 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2134 END IF
2135 END DO
2136 END IF
2137 IF (icheck > 0) THEN
2138 !ivgb=globalParLabelIndex(2,matConsGroups(2,icgrp)) ! -> index of variable global parameter
2139 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
2140 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
2141 WRITE(*,*) ' Cons. group ', icgrp, matconsgroups(1,icgrp), &
2142 matconsgroups(1,icgrp+1)-1, labelf, labell
2143 ENDIF
2144 ! combine into non overlapping blocks
2145 ilast=max(ilast, matconsgroups(3,icgrp))
2146 IF (matconsgroups(2,icgrp+1) > ilast) THEN
2147 ncblck=ncblck+1
2148 ifrst=matconsgroups(2,isblck)
2150 matconsblocks(2,ncblck)=ifrst ! save first parameter in block
2151 matconsblocks(3,ncblck)=ilast ! save last parameter in block
2152 ! update matConsSort
2153 jfrst=matconsgroups(2,icgrp)
2154 DO i=icgrp,isblck,-1
2155 DO j=matconsgroups(1,i),matconsgroups(1,i+1)-1
2156 ! non zero range (from group)
2157 matconsranges(1,j)=matconsgroups(2,i)
2159 ! storage range (from max group, ilast)
2160 jfrst=min(jfrst,matconsgroups(2,i))
2161 matconsranges(3,j)=jfrst
2162 matconsranges(4,j)=ilast
2163 END DO
2164 END DO
2165 IF (icheck > 0) THEN
2166 labelf=globalparlabelindex(1,ifrst)
2167 labell=globalparlabelindex(1,ilast)
2168 WRITE(*,*) ' Cons. block ', ncblck, isblck, icgrp, labelf, labell
2169 ENDIF
2170 ! reset for new block
2171 isblck=icgrp+1
2172 END IF
2173 END DO
2175
2176 ! convert from total parameter index to index of variable global parameter
2177 DO i=1,ncblck
2178 ifrst=globalparlabelindex(2,matconsblocks(2,i)) ! -> index of variable global parameter
2179 ilast=globalparlabelindex(2,matconsblocks(3,i)) ! -> index of variable global parameter
2180 IF (ifrst > 0) THEN
2181 matconsblocks(2,i)=ifrst
2182 matconsblocks(3,i)=ilast
2183 ! statistics
2184 ncon=matconsblocks(1,i+1)-matconsblocks(1,i)
2185 npar=ilast+1-ifrst
2186 ncnmxb=max(ncnmxb,ncon)
2187 nprmxb=max(nprmxb,npar)
2188 ! update index ranges
2189 globalindexranges(ifrst)=max(globalindexranges(ifrst),ilast)
2190 ELSE
2191 ! empty
2192 matconsblocks(2,i)=1
2193 matconsblocks(3,i)=0
2194 END IF
2195 END DO
2196 DO icgrp=1,ncgrp
2197 ifrst=globalparlabelindex(2,matconsgroups(2,icgrp)) ! -> index of variable global parameter
2198 ilast=globalparlabelindex(2,matconsgroups(3,icgrp)) ! -> index of variable global parameter
2199 IF (ifrst > 0) THEN
2200 matconsgroups(2,icgrp)=ifrst
2201 matconsgroups(3,icgrp)=ilast
2202 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2203 DO i=1,4
2204 ivgb=globalparlabelindex(2,matconsranges(i,jcgb)) ! -> index of variable global parameter
2205 matconsranges(i,jcgb)=ivgb
2206 END DO
2207 END DO
2208 ! storage sizes, statistics
2209 jcgb=matconsgroups(1,icgrp) ! first cons.
2210 ncon=matconsgroups(1,icgrp+1)-jcgb
2211 npar=matconsranges(4,jcgb)+1-matconsranges(3,jcgb)
2212 ncnmxg=max(ncnmxg,ncon)
2213 nprmxg=max(nprmxg,npar)
2214 mszcon=mszcon+int(ncon,mpl)*int(npar,mpl) ! (sum of) block size for constraint matrix
2215 mszprd=mszprd+int(ncon,mpl)*int(ncon+1,mpl)/2 ! (sum of) block size for product matrix
2216 ELSE
2217 ! empty
2218 matconsgroups(2,icgrp)=1
2219 matconsgroups(3,icgrp)=0
2220 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2221 matconsranges(1,jcgb)=1
2222 matconsranges(2,jcgb)=0
2223 matconsranges(3,jcgb)=1
2224 matconsranges(4,jcgb)=0
2225 END DO
2226 END IF
2227 END DO
2228
2229 ! clean up
2230 CALL mpdealloc(matconsgroupindex)
2231
2232 ! save constraint group for global parameters
2234 DO icgrp=1,ncgrp
2235 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2236 ! index in list
2237 icgb=matconssort(3,jcgb)
2238 DO j=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
2239 label=listconstraints(j)%label
2240 itgbi=inone(label) ! -> ITGBI= index of parameter label
2241 globalparcons(itgbi)=icgrp ! save constraint group
2242 END DO
2243 END DO
2244 END DO
2245
2246 IF (ncgrp+icheck > 1) THEN
2247 WRITE(*,*)
2248 WRITE(*,*) 'PRPCON: constraints split into ', ncgrp, '(disjoint) groups,'
2249 WRITE(*,*) ' groups combined into ', ncblck, '(non overlapping) blocks'
2250 WRITE(*,*) ' max group size (cons., par.) ', ncnmxg, nprmxg
2251 WRITE(*,*) ' max block size (cons., par.) ', ncnmxb, nprmxb
2252 IF (icheck > 0) WRITE(*,*) ' total block matrix sizes ', mszcon, mszprd
2253 END IF
2254
2255END SUBROUTINE prpcon
2256
2260
2261SUBROUTINE feasma
2262 USE mpmod
2263 USE mpdalc
2264
2265 IMPLICIT NONE
2266 REAL(mpd) :: factr
2267 REAL(mpd) :: sgm
2268 INTEGER(mpi) :: i
2269 INTEGER(mpi) :: icgb
2270 INTEGER(mpi) :: icgrp
2271 INTEGER(mpl) :: ij
2272 INTEGER(mpi) :: ifirst
2273 INTEGER(mpi) :: ilast
2274 INTEGER(mpl) :: ioffc
2275 INTEGER(mpl) :: ioffp
2276 INTEGER(mpi) :: irank
2277 INTEGER(mpi) :: ipar0
2278 INTEGER(mpi) :: itgbi
2279 INTEGER(mpi) :: ivgb
2280 INTEGER(mpi) :: j
2281 INTEGER(mpi) :: jcgb
2282 INTEGER(mpl) :: ll
2283 INTEGER(mpi) :: label
2284 INTEGER(mpi) :: ncon
2285 INTEGER(mpi) :: npar
2286 INTEGER(mpi) :: nrank
2287 INTEGER(mpi) :: inone
2288
2289 REAL(mpd):: rhs
2290 REAL(mpd):: evmax
2291 REAL(mpd):: evmin
2292 INTEGER(mpl):: length
2293 REAL(mpd), DIMENSION(:), ALLOCATABLE :: matConstraintsT
2294 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
2295 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
2296 SAVE
2297 ! ...
2298
2299 IF(ncgb == 0) RETURN ! no constraints
2300
2301 ! product matrix A A^T (A is stored as transposed)
2302 length=mszprd
2303 CALL mpalloc(matconsproduct, length, 'product matrix of constraints (blocks)')
2304 matconsproduct=0.0_mpd
2305 length=ncgb
2306 CALL mpalloc(vecconsresiduals, length, 'residuals of constraints')
2307 CALL mpalloc(vecconssolution, length, 'solution for constraints')
2308 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
2309 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
2310 ! constraint matrix A (A is stored as transposed)
2311 length = mszcon
2312 CALL mpalloc(matconstraintst,length,'transposed matrix of constraints (blocks)')
2313 matconstraintst=0.0_mpd
2314
2315 ! loop over sorted constraints, fill matrices, get rank, inverted product matrix (in groups)
2316 ioffc=0 ! group offset in constraint matrix
2317 ioffp=0 ! group offset in product matrix
2318 nrank=0
2319 DO icgrp=1,ncgrp
2320 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2321 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2322 ncon=ilast+1-ifirst
2323 ipar0=matconsranges(3,ifirst)-1 ! parameter offset
2324 npar=matconsranges(4,ifirst)-ipar0 ! number of parameters
2325 IF (npar <= 0) THEN
2326 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, 0, ' (empty)'
2327 cycle ! skip empty groups/cons.
2328 END IF
2329 DO jcgb=ifirst,ilast
2330 ! index in list
2331 icgb=matconssort(3,jcgb)
2332 ! fill constraint matrix
2333 i=vecconsstart(icgb)
2334 rhs=listconstraints(i )%value ! right hand side
2335 sgm=listconstraints(i+1)%value ! sigma parameter
2336 DO j=i+2,vecconsstart(icgb+1)-1
2337 label=listconstraints(j)%label
2338 factr=listconstraints(j)%value
2339 itgbi=inone(label) ! -> ITGBI= index of parameter label
2340 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2341 IF(ivgb > 0) matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)= &
2342 matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)+factr ! matrix element
2343 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2344 END DO
2345 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2346 END DO
2347
2348 ! get rank of groups
2349 DO ll=ioffc+1,ioffc+npar
2350 ij=ioffp
2351 DO i=1,ncon
2352 DO j=1,i
2353 ij=ij+1
2354 matconsproduct(ij)=matconsproduct(ij)+ &
2355 matconstraintst(int(i-1,mpl)*int(npar,mpl)+ll)* &
2356 matconstraintst(int(j-1,mpl)*int(npar,mpl)+ll)
2357 END DO
2358 END DO
2359 END DO
2360 ! inversion of product matrix of constraints
2361 CALL sqminv(matconsproduct(ioffp+1:ij),vecconsresiduals(ifirst:ilast),ncon,irank, auxvectord, auxvectori)
2362 IF (icheck > 1 .OR. irank < ncon) THEN
2363 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, irank
2364 IF (irank < ncon) THEN
2365 WRITE(*,*) ' .. rank deficit !! '
2366 WRITE(*,*) ' E.g. fix all parameters and remove all constraints related to label ', &
2368 END IF
2369 END IF
2370 nrank=nrank+irank
2371 ioffc=ioffc+int(npar,mpl)*int(ncon,mpl)
2372 ioffp=ij
2373 END DO
2374
2375 nmiss1=ncgb-nrank
2376
2377 WRITE(*,*) ' '
2378 WRITE(*,*) 'Rank of product matrix of constraints is',nrank, &
2379 ' for',ncgb,' constraint equations'
2380 WRITE(8,*) 'Rank of product matrix of constraints is',nrank, &
2381 ' for',ncgb,' constraint equations'
2382 IF(nrank < ncgb) THEN
2383 WRITE(*,*) 'Warning: insufficient constraint equations!'
2384 WRITE(8,*) 'Warning: insufficient constraint equations!'
2385 IF (iforce == 0) THEN
2386 isubit=1
2387 WRITE(*,*) ' --> enforcing SUBITO mode'
2388 WRITE(8,*) ' --> enforcing SUBITO mode'
2389 END IF
2390 END IF
2391
2392 ! QL decomposition
2393 IF (nfgb < nvgb) THEN
2394 print *
2395 print *, 'QL decomposition of constraints matrix'
2396 ! monitor progress
2397 IF(monpg1 > 0) THEN
2398 WRITE(lunlog,*) 'QL decomposition of constraints matrix'
2400 END IF
2401 IF(icelim < 2) THEN ! True unless unpacked LAPACK
2402 ! QL decomposition
2404 ! loop over parameter blocks
2406 ! check eignevalues of L
2407 CALL qlgete(evmin,evmax)
2408#ifdef LAPACK64
2409 ELSE
2410 CALL lpqldec(matconstraintst,evmin,evmax)
2411#endif
2412 END IF
2413 IF(monpg1 > 0) CALL monend()
2414 print *, ' largest |eigenvalue| of L: ', evmax
2415 print *, ' smallest |eigenvalue| of L: ', evmin
2416 IF (evmin == 0.0_mpd.AND.icheck == 0) THEN
2417 CALL peend(27,'Aborted, singular QL decomposition of constraints matrix')
2418 stop 'FEASMA: stopping due to singular QL decomposition of constraints matrix'
2419 END IF
2420 END IF
2421
2422 CALL mpdealloc(matconstraintst)
2423 CALL mpdealloc(auxvectord)
2424 CALL mpdealloc(auxvectori)
2425
2426 RETURN
2427END SUBROUTINE feasma ! matrix for feasible solution
2428
2436SUBROUTINE feasib(concut,iact)
2437 USE mpmod
2438 USE mpdalc
2439
2440 IMPLICIT NONE
2441 REAL(mpd) :: factr
2442 REAL(mpd) :: sgm
2443 INTEGER(mpi) :: i
2444 INTEGER(mpi) :: icgb
2445 INTEGER(mpi) :: icgrp
2446 INTEGER(mpi) :: iter
2447 INTEGER(mpi) :: itgbi
2448 INTEGER(mpi) :: ivgb
2449 INTEGER(mpi) :: ieblck
2450 INTEGER(mpi) :: isblck
2451 INTEGER(mpi) :: ifirst
2452 INTEGER(mpi) :: ilast
2453 INTEGER(mpi) :: j
2454 INTEGER(mpi) :: jcgb
2455 INTEGER(mpi) :: label
2456 INTEGER(mpi) :: inone
2457 INTEGER(mpi) :: ncon
2458
2459 REAL(mps), INTENT(IN) :: concut
2460 INTEGER(mpi), INTENT(OUT) :: iact
2461
2462 REAL(mpd) :: rhs
2463 REAL(mpd) ::sum1
2464 REAL(mpd) ::sum2
2465 REAL(mpd) ::sum3
2466
2467 REAL(mpd), DIMENSION(:), ALLOCATABLE :: vecCorrections
2468 SAVE
2469
2470 iact=0
2471 IF(ncgb == 0) RETURN ! no constraints
2472
2473 DO iter=1,2
2474 vecconsresiduals=0.0_mpd
2475
2476 ! calculate right constraint equation discrepancies
2477 DO jcgb=1,ncgb
2478 icgb=matconssort(3,jcgb) ! unsorted constraint index
2479 i=vecconsstart(icgb)
2480 rhs=listconstraints(i )%value ! right hand side
2481 sgm=listconstraints(i+1)%value ! sigma parameter
2482 DO j=i+2,vecconsstart(icgb+1)-1
2483 label=listconstraints(j)%label
2484 factr=listconstraints(j)%value
2485 itgbi=inone(label) ! -> ITGBI= index of parameter label
2486 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2487 ENDDO
2488 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2489 END DO
2490
2491 ! constraint equation discrepancies -------------------------------
2492
2493 sum1=0.0_mpd
2494 sum2=0.0_mpd
2495 sum3=0.0_mpd
2496 DO icgb=1,ncgb
2497 sum1=sum1+vecconsresiduals(icgb)**2
2498 sum2=sum2+abs(vecconsresiduals(icgb))
2499 sum3=max(sum3,abs(vecconsresiduals(icgb)))
2500 END DO
2501 sum1=sqrt(sum1/real(ncgb,mpd))
2502 sum2=sum2/real(ncgb,mpd)
2503
2504 IF(iter == 1.AND.sum1 < concut) RETURN ! do nothing if correction small
2505
2506 IF(iter == 1.AND.ncgb <= 12) THEN
2507 WRITE(*,*) ' '
2508 WRITE(*,*) 'Constraint equation discrepancies:'
2509 WRITE(*,101) (icgb,vecconsresiduals(icgb),icgb=1,ncgb)
2510101 FORMAT(4x,4(i5,g12.4))
2511 WRITE(*,103) concut
2512103 FORMAT(10x,' Cut on rms value is',g8.1)
2513 END IF
2514
2515 IF(iact == 0) THEN
2516 WRITE(*,*) ' '
2517 WRITE(*,*) 'Improve constraints'
2518 END IF
2519 iact=1
2520
2521 WRITE(*,102) iter,sum1,sum2,sum3
2522102 FORMAT(i6,' rms',g12.4,' avrg_abs',g12.4,' max_abs',g12.4)
2523
2524 CALL mpalloc(veccorrections,int(nvgb,mpl),'constraint corrections')
2525 veccorrections=0.0_mpd
2526
2527 ! multiply (group-wise) inverse matrix and constraint vector
2528 isblck=0
2529 DO icgrp=1,ncgrp
2530 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2531 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2532 ncon=ilast+1-ifirst
2533 ieblck=isblck+(ncon*(ncon+1))/2
2534 CALL dbsvx(matconsproduct(isblck+1:ieblck),vecconsresiduals(ifirst:ilast),vecconssolution(ifirst:ilast),ncon)
2535 isblck=ieblck
2536 END DO
2537
2538 DO jcgb=1,ncgb
2539 icgb=matconssort(3,jcgb) ! unsorted constraint index
2540 i=vecconsstart(icgb)
2541 rhs=listconstraints(i )%value ! right hand side
2542 sgm=listconstraints(i+1)%value ! sigma parameter
2543 DO j=i+2,vecconsstart(icgb+1)-1
2544 label=listconstraints(j)%label
2545 factr=listconstraints(j)%value
2546 itgbi=inone(label) ! -> ITGBI= index of parameter label
2547 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2548 IF(ivgb > 0) THEN
2549 veccorrections(ivgb)=veccorrections(ivgb)+vecconssolution(jcgb)*factr
2550 END IF
2551 ENDDO
2552 END DO
2553
2554 DO i=1,nvgb ! add corrections
2555 itgbi=globalparvartototal(i)
2556 globalparameter(itgbi)=globalparameter(itgbi)+veccorrections(i)
2557 END DO
2558
2559 CALL mpdealloc(veccorrections)
2560
2561 END DO ! iteration 1 and 2
2562
2563END SUBROUTINE feasib ! make parameters feasible
2564
2597SUBROUTINE peread(more)
2598 USE mpmod
2599
2600 IMPLICIT NONE
2601 INTEGER(mpi) :: i
2602 INTEGER(mpi) :: iact
2603 INTEGER(mpi) :: ierrc
2604 INTEGER(mpi) :: ierrf
2605 INTEGER(mpi) :: ioffp
2606 INTEGER(mpi) :: ios
2607 INTEGER(mpi) :: ithr
2608 INTEGER(mpi) :: jfile
2609 INTEGER(mpi) :: jrec
2610 INTEGER(mpi) :: k
2611 INTEGER(mpi) :: kfile
2612 INTEGER(mpi) :: l
2613 INTEGER(mpi) :: lun
2614 INTEGER(mpi) :: mpri
2615 INTEGER(mpi) :: n
2616 INTEGER(mpi) :: nact
2617 INTEGER(mpi) :: nbuf
2618 INTEGER(mpi) :: ndata
2619 INTEGER(mpi) :: noff
2620 INTEGER(mpi) :: noffs
2621 INTEGER(mpi) :: npointer
2622 INTEGER(mpi) :: npri
2623 INTEGER(mpi) :: nr
2624 INTEGER(mpi) :: nrc
2625 INTEGER(mpi) :: nrd
2626 INTEGER(mpi) :: nrpr
2627 INTEGER(mpi) :: nthr
2628 INTEGER(mpi) :: ntot
2629 INTEGER(mpi) :: maxRecordSize
2630 INTEGER(mpi) :: maxRecordFile
2631
2632 INTEGER(mpi), INTENT(OUT) :: more
2633
2634 LOGICAL :: lprint
2635 LOGICAL :: floop
2636 LOGICAL :: eof
2637 REAL(mpd) :: ds0
2638 REAL(mpd) :: ds1
2639 REAL(mpd) :: ds2
2640 REAL(mpd) :: dw
2641 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
2642 CHARACTER (LEN=7) :: cfile
2643 SAVE
2644
2645#ifdef READ_C_FILES
2646 INTERFACE
2647 SUBROUTINE readc(bufferD, bufferF, bufferI, bufferLength, lun, err) BIND(c)
2648 USE iso_c_binding
2649 REAL(c_double), DIMENSION(*), INTENT(OUT) :: bufferD
2650 REAL(c_float), DIMENSION(*), INTENT(OUT) :: bufferF
2651 INTEGER(c_int), DIMENSION(*), INTENT(OUT) :: bufferI
2652 INTEGER(c_int), INTENT(INOUT) :: bufferLength
2653 INTEGER(c_int), INTENT(IN), VALUE :: lun
2654 INTEGER(c_int), INTENT(OUT) :: err
2655 END SUBROUTINE readc
2656 END INTERFACE
2657#endif
2658
2659 DATA lprint/.true./
2660 DATA floop/.true./
2661 DATA npri / 0 /, mpri / 1000 /
2662 ! ...
2663 IF(ifile == 0) THEN ! start/restart
2664 nrec=0
2665 nrecd=0
2666 ntot=0
2667 sumrecords=0
2669 numblocks=0
2672 readbufferinfo=0 ! reset management info
2673 nrpr=1
2674 nthr=mthrdr
2675 nact=0 ! active threads (have something still to read)
2676 DO k=1,nthr
2677 IF (ifile < nfilb) THEN
2678 ifile=ifile+1
2680 readbufferinfo(2,k)=nact
2681 nact=nact+1
2682 END IF
2683 END DO
2684 END IF
2685 npointer=size(readbufferpointer)/nact
2686 ndata=size(readbufferdatai)/nact
2687 more=-1
2688 DO k=1,nthr
2689 iact=readbufferinfo(2,k)
2690 readbufferinfo(4,k)=0 ! reset counter
2691 readbufferinfo(5,k)=iact*ndata ! reset offset
2692 END DO
2693 numblocks=numblocks+1 ! new block
2694
2695 !$OMP PARALLEL &
2696 !$OMP DEFAULT(PRIVATE) &
2697 !$OMP SHARED(readBufferInfo,readBufferPointer,readBufferDataI,readBufferDataD, &
2698 !$OMP readBufferDataF,nPointer,nData,skippedRecords,ndimbuf,NTHR,NFILF,FLOOP, &
2699 !$OMP IFD,KFD,IFILE,NFILB,WFD,XFD,icheck,keepOpen,ireeof,nrderr) NUM_THREADS(NTHR)
2700 ! NUM_THREADS(NTHR) moved to previuos line to make OPARI2 used by scorep-8.4. happy
2701 ithr=1
2702 !$ ITHR=OMP_GET_THREAD_NUM()+1 ! thread number
2703 jfile=readbufferinfo(1,ithr) ! file index
2704 iact =readbufferinfo(2,ithr) ! active thread number
2705 jrec =readbufferinfo(3,ithr) ! records read
2706 ioffp=iact*npointer
2707 noffs=(ithr-1)*ndimbuf ! offset for intermediate float buffer
2708
2709 files: DO WHILE (jfile > 0)
2710 kfile=kfd(2,jfile)
2711 ! open again
2712 IF (keepopen < 1 .AND. readbufferinfo(3,ithr) == 0) THEN
2713 CALL binopn(kfile,ithr,ios)
2714 END IF
2715 records: DO
2716 nbuf=readbufferinfo(4,ithr)+1
2717 noff=readbufferinfo(5,ithr)+2 ! 2 header words per record
2718 nr=ndimbuf
2719 IF(kfile <= nfilf) THEN ! Fortran file
2720 lun=kfile+10
2721 READ(lun,iostat=ierrf) n,(readbufferdataf(noffs+i),i=1,min(n/2,nr)),&
2722 (readbufferdatai(noff+i),i=1,min(n/2,nr))
2723 nr=n/2
2724 ! convert to double
2725 IF (nr <= ndimbuf) THEN
2726 DO i=1,nr
2727 readbufferdatad(noff+i)=real(readbufferdataf(noffs+i),mpr8)
2728 END DO
2729 END IF
2730 ! IF (ierrf < 0) REWIND lun ! end-of-file ! CHK use binrwd()
2731 eof=(ierrf /= 0)
2732 ELSE ! C file
2733 lun=kfile-nfilf
2734 IF (keepopen < 1) lun=ithr
2735#ifdef READ_C_FILES
2736 CALL readc(readbufferdatad(noff+1),readbufferdataf(noffs+1),readbufferdatai(noff+1),nr,lun,ierrc)
2737 n=nr+nr
2738 IF (ierrc > 4) readbufferinfo(6,ithr)=readbufferinfo(6,ithr)+1
2739#else
2740 ierrc=0
2741#endif
2742 eof=(ierrc <= 0.AND.ierrc /= -4) ! allow buffer overruns -> skip record
2743 IF(eof.AND.ierrc < 0) THEN
2744 WRITE(*,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2745 WRITE(8,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2746 IF (icheck <= 0 .AND. ireeof <=0) THEN ! stop unless 'checkinput' mode or 'readerroraseof'
2747 WRITE(cfile,'(I7)') kfile
2748 CALL peend(18,'Aborted, read error(s) for binary file ' // cfile)
2749 stop 'PEREAD: stopping due to read errors (bad record, wrong file type?)'
2750 END IF
2751 IF (kfd(1,jfile) == 1) THEN ! count files with read errors in first loop
2752 !$OMP ATOMIC
2753 nrderr=nrderr+1
2754 END IF
2755 END IF
2756 END IF
2757 IF(eof) EXIT records ! end-of-files or error
2758
2759 jrec=jrec+1
2760 readbufferinfo(3,ithr)=jrec
2761 IF(floop) THEN
2762 xfd(jfile)=max(xfd(jfile),n)
2763 IF(ithr == 1) THEN
2764 CALL hmplnt(1,n)
2765 IF(readbufferdatai(noff+1) /= 0) CALL hmpent(8,real(readbufferdatai(noff+1),mps))
2766 END IF
2767 END IF
2768
2769 IF (nr <= ndimbuf) THEN
2770 readbufferinfo(4,ithr)=nbuf
2771 readbufferinfo(5,ithr)=noff+nr
2772
2773 readbufferpointer(ioffp+nbuf)=noff ! pointer to start of buffer
2774 readbufferdatai(noff )=noff+nr ! pointer to end of buffer
2775 readbufferdatai(noff-1)=jrec ! local record number
2776 readbufferdatad(noff )=real(kfile,mpr8) ! file number
2777 readbufferdatad(noff-1)=real(wfd(kfile),mpr8) ! weight
2778
2779 IF ((noff+nr+2+ndimbuf >= ndata*(iact+1)).OR.(nbuf >= npointer)) EXIT files ! buffer full
2780 ELSE
2781 !$OMP ATOMIC
2783 cycle records
2784 END IF
2785
2786 END DO records
2787
2788 readbufferinfo(1,ithr)=-jfile ! flag eof
2789 IF (keepopen < 1) THEN ! close again
2790 CALL bincls(kfile,ithr)
2791 ELSE ! rewind
2792 CALL binrwd(kfile)
2793 END IF
2794 IF (kfd(1,jfile) == 1) THEN
2795 print *, 'PEREAD: file ', kfile, 'read the first time, found',jrec,' records'
2796 kfd(1,jfile)=-jrec
2797 ELSE
2798 !PRINT *, 'PEREAD: file ', kfile, 'records', jrec, -kfd(1,jfile)
2799 IF (-kfd(1,jfile) /= jrec) THEN
2800 WRITE(cfile,'(I7)') kfile
2801 CALL peend(19,'Aborted, binary file modified (length) ' // cfile)
2802 stop 'PEREAD: file modified (length)'
2803 END IF
2804 END IF
2805 ! take next file
2806 !$OMP CRITICAL
2807 IF (ifile < nfilb) THEN
2808 ifile=ifile+1
2809 jrec=0
2810 readbufferinfo(1,ithr)=ifile
2811 readbufferinfo(3,ithr)=jrec
2812 END IF
2813 !$OMP END CRITICAL
2814 jfile=readbufferinfo(1,ithr)
2815
2816 END DO files
2817 !$OMP END PARALLEL
2818 ! compress pointers
2819 nrd=readbufferinfo(4,1) ! buffers from 1 .thread
2820 DO k=2,nthr
2821 iact =readbufferinfo(2,k)
2822 ioffp=iact*npointer
2823 nbuf=readbufferinfo(4,k)
2824 DO l=1,nbuf
2825 readbufferpointer(nrd+l)=readbufferpointer(ioffp+l)
2826 END DO
2827 nrd=nrd+nbuf
2828 END DO
2829
2830 more=0
2831 DO k=1,nthr
2832 jfile=readbufferinfo(1,k)
2833 IF (jfile > 0) THEN ! no eof yet
2834 readbufferinfo(2,k)=more
2835 more=more+1
2836 ELSE
2837 ! no more files, thread retires
2838 readbufferinfo(1,k)=0
2839 readbufferinfo(2,k)=-1
2840 readbufferinfo(3,k)=0
2842 readbufferinfo(6,k)=0
2843 END IF
2844 END DO
2845 ! record limit ?
2846 IF (mxrec > 0.AND.(ntot+nrd) >= mxrec) THEN
2847 nrd=mxrec-ntot
2848 more=-1
2849 DO k=1,nthr
2850 jfile=readbufferinfo(1,k)
2851 IF (jfile > 0) THEN ! rewind or close files
2852 nrc=readbufferinfo(3,k)
2853 IF (kfd(1,jfile) == 1) kfd(1,jfile)=-nrc
2854 kfile=kfd(2,jfile)
2855 IF (keepopen < 1) THEN ! close again
2856 CALL bincls(kfile,k)
2857 ELSE ! rewind
2858 CALL binrwd(kfile)
2859 END IF
2860 END IF
2861 END DO
2862 END IF
2863
2864 ntot=ntot+nrd
2865 nrec=ntot
2866 numreadbuffer=nrd
2867
2871
2872 DO WHILE (nloopn == 0.AND.ntot >= nrpr)
2873 WRITE(*,*) ' Record ',nrpr
2874 IF (nrpr < 100000) THEN
2875 nrpr=nrpr*10
2876 ELSE
2877 nrpr=nrpr+100000
2878 END IF
2879 END DO
2880
2881 IF (ncache > 0.AND.nloopn <= 1.AND. npri < mpri.AND.mprint > 1) THEN
2882 npri=npri+1
2883 IF (npri == 1) WRITE(*,100)
2884 WRITE(*,101) nrec, nrd, more ,ifile
2885100 FORMAT(/' PeRead records active file' &
2886 /' total block threads number')
2887101 FORMAT(' PeRead',4i10)
2888 END IF
2889
2890 IF (more <= 0) THEN
2891 ifile=0
2892 IF (floop) THEN
2893 ! check for file weights
2894 ds0=0.0_mpd
2895 ds1=0.0_mpd
2896 ds2=0.0_mpd
2897 maxrecordsize=0
2898 maxrecordfile=0
2899 DO k=1,nfilb
2900 IF (xfd(k) > maxrecordsize) THEN
2901 maxrecordsize=xfd(k)
2902 maxrecordfile=k
2903 END IF
2904 dw=real(-kfd(1,k),mpd)
2905 IF (wfd(k) /= 1.0) nfilw=nfilw+1
2906 ds0=ds0+dw
2907 ds1=ds1+dw*real(wfd(k),mpd)
2908 ds2=ds2+dw*real(wfd(k)**2,mpd)
2909 END DO
2910 print *, 'PEREAD: file ', maxrecordfile, 'with max record size ', maxrecordsize
2911 IF (nfilw > 0.AND.ds0 > 0.0_mpd) THEN
2912 ds1=ds1/ds0
2913 ds2=ds2/ds0-ds1*ds1
2914 DO lun=6,lunlog,2
2915 WRITE(lun,177) nfilw,real(ds1,mps),real(ds2,mps)
2916177 FORMAT(/' !!!!!',i4,' weighted binary files', &
2917 /' !!!!! mean, variance of weights =',2g12.4)
2918 END DO
2919 END IF
2920 ! integrate record numbers
2921 DO k=2,nfilb
2922 ifd(k)=ifd(k-1)-kfd(1,k-1)
2923 END DO
2924 ! sort
2925 IF (nthr > 1) CALL sort2k(kfd,nfilb)
2926 IF (skippedrecords > 0) THEN
2927 print *, 'PEREAD skipped records: ', skippedrecords
2928 ndimbuf=maxrecordsize/2 ! adjust buffer size
2929 END IF
2930 END IF
2931 lprint=.false.
2932 floop=.false.
2933 IF (ncache > 0.AND.nloopn <= 1.AND.mprint > 0) &
2935179 FORMAT(/' Read cache usage (#blocks, #records, ', &
2936 'min,max records/block'/17x,i10,i12,2i10)
2937 END IF
2938 RETURN
2939
2940END SUBROUTINE peread
2941
2949SUBROUTINE peprep(mode)
2950 USE mpmod
2951
2952 IMPLICIT NONE
2953
2954 INTEGER(mpi), INTENT(IN) :: mode
2955
2956 INTEGER(mpi) :: ibuf
2957 INTEGER(mpi) :: ichunk
2958 INTEGER(mpi) :: ist
2959 INTEGER(mpi) :: itgbi
2960 INTEGER(mpi) :: j
2961 INTEGER(mpi) :: ja
2962 INTEGER(mpi) :: jb
2963 INTEGER(mpi) :: jsp
2964 INTEGER(mpi) :: nst
2965 INTEGER(mpi), PARAMETER :: maxbad = 100 ! max number of bad records with print out
2966 INTEGER(mpi) :: nbad
2967 INTEGER(mpi) :: nerr
2968 INTEGER(mpi) :: inone
2969
2970 IF (mode > 0) THEN
2971#ifdef __PGIC__
2972 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
2973 ichunk=256
2974#else
2975 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
2976#endif
2977 ! parallelize record loop
2978 !$OMP PARALLEL DO &
2979 !$OMP DEFAULT(PRIVATE) &
2980 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,ICHUNK,iscerr,dscerr) &
2981 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
2982 DO ibuf=1,numreadbuffer ! buffer for current record
2983 ist=readbufferpointer(ibuf)+1
2985 DO ! loop over measurements
2986 CALL isjajb(nst,ist,ja,jb,jsp)
2987 IF(jb == 0) EXIT
2988 DO j=1,ist-jb
2989 readbufferdatai(jb+j)=inone( readbufferdatai(jb+j) ) ! translate to index
2990 END DO
2991 ! scale error ?
2992 IF (iscerr > 0) THEN
2993 IF (jb < ist) THEN
2994 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(1) ! 'global' measurement
2995 ELSE
2996 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(2) ! 'local' measurement
2997 END IF
2998 END IF
2999 END DO
3000 END DO
3001 !$OMP END PARALLEL DO
3002 END IF
3003
3004 !$POMP INST BEGIN(peprep)
3005#ifdef SCOREP_USER_ENABLE
3006 scorep_user_region_by_name_begin("UR_peprep", scorep_user_region_type_common)
3007#endif
3008 IF (mode <= 0) THEN
3009 nbad=0
3010 DO ibuf=1,numreadbuffer ! buffer for current record
3011 CALL pechk(ibuf,nerr)
3012 IF(nerr > 0) THEN
3013 nbad=nbad+1
3014 IF(nbad >= maxbad) EXIT
3015 ELSE
3016 ist=readbufferpointer(ibuf)+1
3018 DO ! loop over measurements
3019 CALL isjajb(nst,ist,ja,jb,jsp)
3020 IF(jb == 0) EXIT
3021 neqn=neqn+1
3022 IF(jb == ist) cycle
3023 negb=negb+1
3024 ndgb=ndgb+(ist-jb)
3025 DO j=1,ist-jb
3026 itgbi=inone( readbufferdatai(jb+j) ) ! generate index
3027 END DO
3028 END DO
3029 END IF
3030 END DO
3031 IF(nbad > 0) THEN
3032 CALL peend(20,'Aborted, bad binary records')
3033 stop 'PEREAD: stopping due to bad records'
3034 END IF
3035 END IF
3036#ifdef SCOREP_USER_ENABLE
3037 scorep_user_region_by_name_end("UR_peprep")
3038#endif
3039 !$POMP INST END(peprep)
3040
3041END SUBROUTINE peprep
3042
3050SUBROUTINE pechk(ibuf, nerr)
3051 USE mpmod
3052
3053 IMPLICIT NONE
3054 INTEGER(mpi) :: i
3055 INTEGER(mpi) :: is
3056 INTEGER(mpi) :: ist
3057 INTEGER(mpi) :: ioff
3058 INTEGER(mpi) :: ja
3059 INTEGER(mpi) :: jb
3060 INTEGER(mpi) :: jsp
3061 INTEGER(mpi) :: nan
3062 INTEGER(mpi) :: nst
3063
3064 INTEGER(mpi), INTENT(IN) :: ibuf
3065 INTEGER(mpi), INTENT(OUT) :: nerr
3066 SAVE
3067 ! ...
3068
3069 ist=readbufferpointer(ibuf)+1
3071 nerr=0
3072 is=ist
3073 jsp=0
3074 outer: DO WHILE(is < nst)
3075 ja=0
3076 jb=0
3077 inner1: DO
3078 is=is+1
3079 IF(is > nst) EXIT outer
3080 IF(readbufferdatai(is) == 0) EXIT inner1 ! found 1. marker
3081 END DO inner1
3082 ja=is
3083 inner2: DO
3084 is=is+1
3085 IF(is > nst) EXIT outer
3086 IF(readbufferdatai(is) == 0) EXIT inner2 ! found 2. marker
3087 END DO inner2
3088 jb=is
3089 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3090 ! special data
3091 jsp=jb ! pointer to special data
3092 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3093 cycle outer
3094 END IF
3095 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3096 is=is+1
3097 END DO
3098 END DO outer
3099 IF(is > nst) THEN
3100 ioff = readbufferpointer(ibuf)
3101 WRITE(*,100) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi)
3102100 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' is broken !!!')
3103 nerr=nerr+1
3104 ENDIF
3105 nan=0
3106 DO i=ist, nst
3107 IF(.NOT.(readbufferdatad(i) <= 0.0_mpr8).AND..NOT.(readbufferdatad(i) > 0.0_mpr8)) nan=nan+1
3108 END DO
3109 IF(nan > 0) THEN
3110 ioff = readbufferpointer(ibuf)
3111 WRITE(*,101) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi), nan
3112101 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' contains ', i6, ' NaNs !!!')
3113 nerr= nerr+2
3114 ENDIF
3115
3116END SUBROUTINE pechk
3117
3122SUBROUTINE pepgrp
3123 USE mpmod
3124 USE mpdalc
3125
3126 IMPLICIT NONE
3127
3128 INTEGER(mpi) :: ibuf
3129 INTEGER(mpi) :: ichunk
3130 INTEGER(mpi) :: iproc
3131 INTEGER(mpi) :: ioff
3132 INTEGER(mpi) :: ioffbi
3133 INTEGER(mpi) :: ist
3134 INTEGER(mpi) :: itgbi
3135 INTEGER(mpi) :: j
3136 INTEGER(mpi) :: ja
3137 INTEGER(mpi) :: jb
3138 INTEGER(mpi) :: jsp
3139 INTEGER(mpi) :: nalg
3140 INTEGER(mpi) :: neqna
3141 INTEGER(mpi) :: nnz
3142 INTEGER(mpi) :: nst
3143 INTEGER(mpi) :: nzero
3144 INTEGER(mpi) :: inone
3145 INTEGER(mpl) :: length
3146 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
3147
3148 CALL useone ! make (INONE) usable
3149 globalparheader(-2)=-1 ! set flag to inhibit further updates
3150 ! need back index
3151 IF (mcount > 0) THEN
3152 length=globalparheader(-1)*mthrd
3153 CALL mpalloc(backindexusage,length,'global variable-index array')
3155 END IF
3156 nzero=0
3157#ifdef __PGIC__
3158 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
3159 ichunk=256
3160#else
3161 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
3162#endif
3163 ! parallelize record loop
3164 !$OMP PARALLEL DO &
3165 !$OMP DEFAULT(PRIVATE) &
3166 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,backIndexUsage,globalParHeader,ICHUNK,MCOUNT) &
3167 !$OMP REDUCTION(+:NZERO) &
3168 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
3169 DO ibuf=1,numreadbuffer ! buffer for current record
3170 ist=readbufferpointer(ibuf)+1
3172 IF (mcount > 0) THEN
3173 ! count per record
3174 iproc=0
3175 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
3176 ioffbi=globalparheader(-1)*iproc
3177 nalg=0
3178 ioff=readbufferpointer(ibuf)
3179 DO ! loop over measurements
3180 CALL isjajb(nst,ist,ja,jb,jsp)
3181 IF(jb == 0) EXIT
3182 IF (ist > jb) THEN
3183 DO j=1,ist-jb
3184 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3185 nzero=nzero+1
3186 cycle ! skip 'zero global derivatives' for counting and grouping
3187 END IF
3188 itgbi=inone( readbufferdatai(jb+j) ) ! translate to index
3189 IF (backindexusage(ioffbi+itgbi) == 0) THEN
3190 nalg=nalg+1
3191 readbufferdatai(ioff+nalg)=itgbi
3192 backindexusage(ioffbi+itgbi)=nalg
3193 END IF
3194 END DO
3195 END IF
3196 END DO
3197 ! reset back index
3198 DO j=1,nalg
3199 itgbi=readbufferdatai(ioff+j)
3200 backindexusage(ioffbi+itgbi)=0
3201 END DO
3202 ! sort (record)
3203 CALL sort1k(readbufferdatai(ioff+1),nalg)
3204 readbufferdatai(ioff)=ioff+nalg
3205 ELSE
3206 ! count per equation
3207 nalg=1 ! reserve space for counter 'nnz'
3208 ioff=readbufferpointer(ibuf)
3209 neqna=0 ! number of accepted equations
3210 DO ! loop over measurements
3211 CALL isjajb(nst,ist,ja,jb,jsp)
3212 IF(jb == 0) EXIT
3213 IF (ist > jb) THEN
3214 nnz=0 ! number of non-zero derivatives
3215 DO j=1,ist-jb
3216 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3217 nzero=nzero+1
3218 cycle ! skip 'zero global derivatives' for counting and grouping
3219 END IF
3220 nnz=nnz+1
3221 readbufferdatai(ioff+nalg+nnz)=inone( readbufferdatai(jb+j) ) ! translate to index
3222 END DO
3223 IF (nnz == 0) cycle ! nothing for this equation
3224 readbufferdatai(ioff+nalg)=nnz
3225 ! sort (equation)
3226 CALL sort1k(readbufferdatai(ioff+nalg+1),nnz)
3227 nalg=nalg+nnz+1
3228 ! count (accepted) equations
3229 neqna=neqna+1
3230 END IF
3231 END DO
3232 readbufferdatai(ioff)=neqna
3233 END IF
3234 END DO
3235 !$OMP END PARALLEL DO
3236 nzgb=nzgb+nzero
3237
3238 !$POMP INST BEGIN(pepgrp)
3239#ifdef SCOREP_USER_ENABLE
3240 scorep_user_region_by_name_begin("UR_pepgrp", scorep_user_region_type_common)
3241#endif
3242 DO ibuf=1,numreadbuffer ! buffer for current record
3243 ist=readbufferpointer(ibuf)+1
3245 IF (mcount == 0) THEN
3246 ! equation level
3247 DO j=1,nst! loop over measurements
3248 nnz=readbufferdatai(ist)
3249 CALL pargrp(ist+1,ist+nnz)
3250 ist=ist+nnz+1
3251 END DO
3252 ELSE
3253 ! record level, group
3254 CALL pargrp(ist,nst)
3255 ENDIF
3256 END DO
3257 ! free back index
3258 IF (mcount > 0) THEN
3260 END IF
3261#ifdef SCOREP_USER_ENABLE
3262 scorep_user_region_by_name_end("UR_pepgrp")
3263#endif
3264 !$POMP INST END(pepgrp)
3265 globalparheader(-2)=0 ! reset flag to reenable further updates
3266
3267END SUBROUTINE pepgrp
3268
3276SUBROUTINE pargrp(inds,inde)
3277 USE mpmod
3278
3279 IMPLICIT NONE
3280
3281 INTEGER(mpi) :: istart
3282 INTEGER(mpi) :: itgbi
3283 INTEGER(mpi) :: j
3284 INTEGER(mpi) :: jstart
3285 INTEGER(mpi) :: jtgbi
3286 INTEGER(mpi) :: lstart
3287 INTEGER(mpi) :: ltgbi
3288
3289 INTEGER(mpi), INTENT(IN) :: inds
3290 INTEGER(mpi), INTENT(IN) :: inde
3291
3292 IF (inds > inde) RETURN
3293
3294 ltgbi=-1
3295 lstart=-1
3296 ! build up groups
3297 DO j=inds,inde
3298 itgbi=readbufferdatai(j)
3299 globalparlabelcounter(itgbi)=globalparlabelcounter(itgbi)+1 ! count entries
3300 istart=globalparlabelindex(3,itgbi) ! label of group start
3301 IF (istart == 0) THEN ! not yet in group
3302 IF (itgbi /= ltgbi+1) THEN ! start group
3304 ELSE
3305 IF (lstart == 0) THEN ! extend group
3307 ELSE ! start group
3308 globalparlabelindex(3,itgbi)=globalparlabelindex(1,itgbi)
3309 END IF
3310 END IF
3311 END IF
3312 ltgbi=itgbi
3313 lstart=istart
3314 END DO
3315 ! split groups:
3316 ! - start inside group?
3317 itgbi=readbufferdatai(inds)
3318 istart=globalparlabelindex(3,itgbi) ! label of group start
3319 jstart=globalparlabelindex(1,itgbi) ! label of first parameter
3320 IF (istart /= jstart) THEN ! start new group
3321 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3322 globalparlabelindex(3,itgbi) = jstart
3323 itgbi=itgbi+1
3324 IF (itgbi > globalparheader(-1)) EXIT
3325 END DO
3326 END IF
3327 ! - not neigbours anymore
3328 ltgbi=readbufferdatai(inds)
3329 DO j=inds+1,inde
3330 itgbi=readbufferdatai(j)
3331 IF (itgbi /= ltgbi+1) THEN
3332 ! split after ltgbi
3333 lstart=globalparlabelindex(3,ltgbi) ! label of last group start
3334 jtgbi=ltgbi+1 ! new group after ltgbi
3335 jstart=globalparlabelindex(1,jtgbi)
3336 DO WHILE (globalparlabelindex(3,jtgbi) == lstart)
3337 globalparlabelindex(3,jtgbi) = jstart
3338 jtgbi=jtgbi+1
3339 IF (jtgbi > globalparheader(-1)) EXIT
3340 IF (jtgbi == itgbi) jstart=globalparlabelindex(1,jtgbi)
3341 END DO
3342 ! split at itgbi
3343 jtgbi=itgbi
3344 istart=globalparlabelindex(3,jtgbi) ! label of group start
3345 jstart=globalparlabelindex(1,jtgbi) ! label of first parameter
3346 IF (istart /= jstart) THEN ! start new group
3347 DO WHILE (globalparlabelindex(3,jtgbi) == istart)
3348 globalparlabelindex(3,jtgbi) = jstart
3349 jtgbi=jtgbi+1
3350 IF (jtgbi > globalparheader(-1)) EXIT
3351 END DO
3352 END IF
3353 ENDIF
3354 ltgbi=itgbi
3355 END DO
3356 ! - end inside group?
3357 itgbi=readbufferdatai(inde)
3358 IF (itgbi < globalparheader(-1)) THEN
3359 istart=globalparlabelindex(3,itgbi) ! label of group start
3360 itgbi=itgbi+1
3361 jstart=globalparlabelindex(1,itgbi) ! label of new group start
3362 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3363 globalparlabelindex(3,itgbi) = jstart
3364 itgbi=itgbi+1
3365 IF (itgbi > globalparheader(-1)) EXIT
3366 END DO
3367 END IF
3368
3369END SUBROUTINE pargrp
3370
3393SUBROUTINE isjajb(nst,is,ja,jb,jsp)
3394 USE mpmod
3395
3396 IMPLICIT NONE
3397
3398 INTEGER(mpi), INTENT(IN) :: nst
3399 INTEGER(mpi), INTENT(IN OUT) :: is
3400 INTEGER(mpi), INTENT(OUT) :: ja
3401 INTEGER(mpi), INTENT(OUT) :: jb
3402 INTEGER(mpi), INTENT(OUT) :: jsp
3403 SAVE
3404 ! ...
3405
3406 jsp=0
3407 DO
3408 ja=0
3409 jb=0
3410 IF(is >= nst) RETURN
3411 DO
3412 is=is+1
3413 IF(readbufferdatai(is) == 0) EXIT
3414 END DO
3415 ja=is
3416 DO
3417 is=is+1
3418 IF(readbufferdatai(is) == 0) EXIT
3419 END DO
3420 jb=is
3421 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3422 ! special data
3423 jsp=jb ! pointer to special data
3424 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3425 cycle
3426 END IF
3427 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3428 is=is+1
3429 END DO
3430 EXIT
3431 END DO
3432
3433END SUBROUTINE isjajb
3434
3435
3436!***********************************************************************
3437! LOOPN ...
3443
3444SUBROUTINE loopn
3445 USE mpmod
3446
3447 IMPLICIT NONE
3448 REAL(mpd) :: dsum
3449 REAL(mps) :: elmt
3450 REAL(mpd) :: factrj
3451 REAL(mpd) :: factrk
3452 REAL(mps) :: peakd
3453 REAL(mps) :: peaki
3454 REAL(mps) :: ratae
3455 REAL(mpd) :: rhs
3456 REAL(mps) :: rloop
3457 REAL(mpd) :: sgm
3458 REAL(mps) :: used
3459 REAL(mps) :: usei
3460 REAL(mpd) :: weight
3461 INTEGER(mpi) :: i
3462 INTEGER(mpi) :: ia
3463 INTEGER(mpi) :: ib
3464 INTEGER(mpi) :: ioffb
3465 INTEGER(mpi) :: ipr
3466 INTEGER(mpi) :: itgbi
3467 INTEGER(mpi) :: itgbij
3468 INTEGER(mpi) :: itgbik
3469 INTEGER(mpi) :: ivgb
3470 INTEGER(mpi) :: ivgbij
3471 INTEGER(mpi) :: ivgbik
3472 INTEGER(mpi) :: j
3473 INTEGER(mpi) :: k
3474 INTEGER(mpi) :: lastit
3475 INTEGER(mpi) :: lun
3476 INTEGER(mpi) :: ncrit
3477 INTEGER(mpi) :: ngras
3478 INTEGER(mpi) :: nparl
3479 INTEGER(mpi) :: nr
3480 INTEGER(mpl) :: nrej
3481 INTEGER(mpi) :: inone
3482 INTEGER(mpi) :: ilow
3483 INTEGER(mpi) :: nlow
3484 INTEGER(mpi) :: nzero
3485 LOGICAL :: btest
3486
3487 REAL(mpd):: adder
3488 REAL(mpd)::funref
3489 REAL(mpd)::matij
3490
3491 SAVE
3492 ! ...
3493
3494 ! ----- book and reset ---------------------------------------------
3495 IF(nloopn == 0) THEN ! first call
3496 lastit=-1
3497 iitera=0
3498 END IF
3499
3500 nloopn=nloopn+1 ! increase loop counter
3501 funref=0.0_mpd
3502
3503 IF(nloopn == 1) THEN ! book histograms for 1. iteration
3504 CALL gmpdef(1,4,'Function value in iterations')
3505 IF (metsol == 4 .OR. metsol == 5) THEN ! extend to GMRES, i.e. 6?
3506 CALL gmpdef(2,3,'Number of MINRES steps vs iteration nr')
3507 END IF
3508 CALL hmpdef( 5,0.0,0.0,'Number of degrees of freedom')
3509 CALL hmpdef(11,0.0,0.0,'Number of local parameters')
3510 CALL hmpdef(16,0.0,24.0,'LOG10(cond(band part decomp.)) local fit ')
3511 CALL hmpdef(23,0.0,0.0, 'SQRT of diagonal elements without presigma')
3512 CALL hmpdef(24,0.0,0.0, 'Log10 of off-diagonal elements')
3513 CALL hmpdef(25,0.0,0.0, 'Relative individual pre-sigma')
3514 CALL hmpdef(26,0.0,0.0, 'Relative global pre-sigma')
3515 END IF
3516
3517
3518 CALL hmpdef(3,-prange,prange, & ! book
3519 'Normalized residuals of single (global) measurement')
3520 CALL hmpdef(12,-prange,prange, & ! book
3521 'Normalized residuals of single (local) measurement')
3522 CALL hmpdef(13,-prange,prange, & ! book
3523 'Pulls of single (global) measurement')
3524 CALL hmpdef(14,-prange,prange, & ! book
3525 'Pulls of single (local) measurement')
3526 CALL hmpdef(4,0.0,0.0,'Chi^2/Ndf after local fit')
3527 CALL gmpdef(4,5,'location, dispersion (res.) vs record nr')
3528 CALL gmpdef(5,5,'location, dispersion (pull) vs record nr')
3529
3530 ! WRITE(*,*) 'LOOPN ', NLOOPN, ' executing ICALCM=', ICALCM
3531
3532 ! reset
3533
3534 globalvector=0.0_mpd ! reset rhs vector IGVEC
3536 IF(icalcm == 1) THEN
3537 globalmatd=0.0_mpd
3538 globalmatf=0.
3539 IF (metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) matprecond=0.0_mpd
3540 END IF
3541
3542 IF(nloopn == 2) CALL hmpdef(6,0.0,0.0,'Down-weight fraction')
3543
3544 newite=.false.
3545 IF(iterat /= lastit) THEN ! new iteration
3546 newite=.true.
3547 funref=fvalue
3548 IF(nloopn > 1) THEN
3549 nrej=sum(nrejec)
3550 ! CALL MEND
3551 IF(iterat == 1) THEN
3553 ELSE IF(iterat >= 1) THEN
3554 chicut=sqrt(chicut)
3555 IF(chicut /= 0.0.AND.chicut < 1.5) chicut=1.0
3556 IF(chicut /= 0.0.AND.nrej == 0) chicut=1.0
3557 END IF
3558 END IF
3559 ! WRITE(*,111) ! header line
3560 END IF
3561
3562 nrejec=0 ! reset reject counter
3563 DO k=3,6
3564 writebufferheader(k)=0 ! cache usage
3565 writebufferheader(-k)=0
3566 END DO
3567 ! statistics per binary file
3568 DO i=1,nfilb
3569 jfd(i)=0
3570 cfd(i)=0.0
3571 dfd(i)=0
3572 END DO
3573
3574 IF (imonit /= 0) meashists=0 ! reset monitoring histograms
3575
3576 ! ----- read next data ----------------------------------------------
3577 DO
3578 CALL peread(nr) ! read records
3579 CALL peprep(1) ! prepare records
3581 IF (nr <= 0) EXIT ! next block of events ?
3582 END DO
3583 ! sum up RHS (over threads) once (reduction in LOOPBF: summation for each block)
3584 ioffb=0
3585 DO ipr=2,mthrd
3586 ioffb=ioffb+lenglobalvec
3587 DO k=1,lenglobalvec
3590 END DO
3591 END DO
3592
3593 IF (icalcm == 1) THEN
3594 ! PRINT *, ' cache/w ',(writeBufferHeader(-K),K=3,6),(writeBufferHeader(K),K=3,6)
3595 nparl=writebufferheader(3)
3596 ncrit=writebufferheader(4)
3597 used=real(writebufferheader(-5),mps)/real(writebufferheader(-3),mps)*0.1
3598 usei=real(writebufferheader(5),mps)/real(writebufferheader(3),mps)*0.1
3599 peakd=real(writebufferheader(-6),mps)*0.1
3600 peaki=real(writebufferheader(6),mps)*0.1
3601 WRITE(*,111) nparl,ncrit,usei,used,peaki,peakd
3602111 FORMAT(' Write cache usage (#flush,#overrun,<levels>,', &
3603 'peak(levels))'/2i7,',',4(f6.1,'%'))
3604 ! fill part of MINRES preconditioner matrix from binary files (formerly in mgupdt)
3605 IF (metsol >= 4.AND.metsol < 7) THEN
3606 IF (mbandw == 0) THEN
3607 ! default preconditioner (diagonal)
3608 DO i=1, nvgb
3609 matprecond(i)=matij(i,i)
3610 END DO
3611 ELSE IF (mbandw > 0) THEN
3612 ! band matrix
3613 DO i=1, nvgb
3614 ia=indprecond(i) ! index of diagonal element
3615 DO j=max(1,i-mbandw+1),i
3616 matprecond(ia-i+j)=matij(i,j)
3617 END DO
3618 END DO
3619 END IF
3620 END IF
3621 IF (ichkpg > 0) THEN
3622 ! check parameter groups
3623 CALL ckpgrp
3624 END IF
3625 END IF
3626
3627 ! check entries/counters
3628 nlow=0
3629 ilow=1
3630 nzero=0
3631 DO i=1,nvgb
3632 IF(globalcounter(i) == 0) nzero=nzero+1
3633 IF(globalcounter(i) < mreqena) THEN
3634 nlow=nlow+1
3635 IF(globalcounter(i) < globalcounter(ilow)) ilow=i
3636 END IF
3637 END DO
3638 IF(nlow > 0) THEN
3639 nalow=nalow+nlow
3640 IF(icalcm == 1) nxlow=max(nxlow,nlow) ! for matrix construction ?
3641 itgbi=globalparvartototal(ilow)
3642 print *
3643 print *, " ... warning ..."
3644 print *, " global parameters with too few (< MREQENA) accepted entries: ", nlow
3645 print *, " minimum entries: ", globalcounter(ilow), " for label ", globalparlabelindex(1,itgbi)
3646 print *
3647 END IF
3648 IF(icalcm == 1 .AND. nzero > 0) THEN
3649 ndefec = nzero ! rank defect
3650 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfgb, &
3651 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3652 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfgb, &
3653 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3654 IF (iforce == 0) THEN
3655 isubit=1
3656 WRITE(*,*) ' --> enforcing SUBITO mode'
3657 WRITE(lun,*) ' --> enforcing SUBITO mode'
3658 END IF
3659 END IF
3660
3661 ! ----- after end-of-data add contributions from pre-sigma ---------
3662
3663 IF(nloopn == 1) THEN
3664 ! plot diagonal elements
3665 elmt=0.0
3666 DO i=1,nvgb ! diagonal elements
3667 elmt=real(matij(i,i),mps)
3668 IF(elmt > 0.0) CALL hmpent(23,1.0/sqrt(elmt))
3669 END DO
3670 END IF
3671
3672
3673
3674 ! add pre-sigma contributions to matrix diagonal
3675
3676 ! WRITE(*,*) 'Adding to diagonal ICALCM IND6',ICALCM,IND6
3677
3678 IF(icalcm == 1) THEN
3679 DO ivgb=1,nvgb ! add evtl. pre-sigma
3680 ! WRITE(*,*) 'Index ',IVGB,IVGB,QM(IND6+IVGB)
3681 IF(globalparpreweight(ivgb) /= 0.0) THEN
3682 IF(ivgb > 0) CALL mupdat(ivgb,ivgb,globalparpreweight(ivgb))
3683 END IF
3684 END DO
3685 END IF
3686
3687 CALL hmpwrt(23)
3688 CALL hmpwrt(24)
3689 CALL hmpwrt(25)
3690 CALL hmpwrt(26)
3691
3692
3693 ! add regularization term to F and to rhs --------------------------
3694
3695 ! WRITE(*,*) 'NREGUL ',NREGUL,NLOOPN
3696
3697 IF(nregul /= 0) THEN ! add regularization term to F and to rhs
3698 DO ivgb=1,nvgb
3699 itgbi=globalparvartototal(ivgb) ! global parameter index
3701 adder=globalparpreweight(ivgb)*globalparameter(itgbi)**2
3702 CALL addsums(1, adder, 0, 1.0_mpl)
3703 END DO
3704 END IF
3705
3706
3707 ! ----- add contributions from "measurement" -----------------------
3708
3709
3710 i=1
3711 DO WHILE (i <= lenmeasurements)
3712 rhs=listmeasurements(i )%value ! right hand side
3713 sgm=listmeasurements(i+1)%value ! sigma parameter
3714 i=i+2
3715 weight=0.0
3716 IF(sgm > 0.0) weight=1.0/sgm**2
3717
3718 dsum=-rhs
3719
3720 ! loop over label/factor pairs
3721 ia=i
3722 DO
3723 i=i+1
3724 IF(i > lenmeasurements) EXIT
3725 IF(listmeasurements(i)%label < 0) EXIT
3726 END DO
3727 ib=i-1
3728
3729 DO j=ia,ib
3730 factrj=listmeasurements(j)%value
3731 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3732 IF(itgbij /= 0) THEN
3733 dsum=dsum+factrj*globalparameter(itgbij) ! update residuum
3734 END IF
3735 END DO
3736 DO j=ia,ib
3737 factrj=listmeasurements(j)%value
3738 IF (factrj == 0.0_mpd) cycle ! skip zero factors
3739 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3740 ! add to vector
3741 ivgbij=0
3742 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
3743 IF(ivgbij > 0) THEN
3744 globalvector(ivgbij)=globalvector(ivgbij) -weight*dsum*factrj ! vector
3745 globalcounter(ivgbij)=globalcounter(ivgbij)+1
3746 END IF
3747
3748 IF(icalcm == 1.AND.ivgbij > 0) THEN
3749 DO k=ia,j
3750 factrk=listmeasurements(k)%value
3751 itgbik=inone(listmeasurements(k)%label) ! total parameter index
3752 ! add to matrix
3753 ivgbik=0
3754 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
3755 IF(ivgbij > 0.AND.ivgbik > 0) THEN !
3756 CALL mupdat(ivgbij,ivgbik,weight*factrj*factrk)
3757 END IF
3758 END DO
3759 END IF
3760 END DO
3761
3762 adder=weight*dsum**2
3763 CALL addsums(1, adder, 1, 1.0_mpl)
3764
3765 END DO
3766
3767 ! ----- printout ---------------------------------------------------
3768
3769
3770 ! get accurate sum (Chi^2, (w)NDF)
3772
3773 flines=0.5_mpd*fvalue ! Likelihood function value
3774 rloop=iterat+0.01*nloopn
3775 actfun=real(funref-fvalue,mps)
3776 IF(nloopn == 1) actfun=0.0
3777 ngras=nint(angras,mpi)
3778 ratae=0.0 !!!
3779 IF(delfun /= 0.0) THEN
3780 ratae=min(99.9,actfun/delfun) !!!
3781 ratae=max(-99.9,ratae)
3782 END IF
3783
3784 ! rejects ...
3785
3786 nrej =sum(nrejec)
3787 IF(nloopn == 1) THEN
3788 IF(nrej /= 0) THEN
3789 WRITE(*,*) ' '
3790 WRITE(*,*) 'Data records rejected in initial loop:'
3791 CALL prtrej(6)
3792 END IF
3793 END IF
3794
3795 IF(newite.AND.iterat == 2) THEN
3796 IF(nrecpr /= 0.OR.nrecp2 /= 0) nrecer=nrec3
3797 IF(nrecpr < 0) THEN
3799 END IF
3800 IF(nrecp2 < 0) THEN
3802 END IF
3803 END IF
3804
3805 IF(nloopn <= 2) THEN
3806 IF(nhistp /= 0) THEN
3807 ! CALL HMPRNT(3) ! scaled residual of single measurement
3808 ! CALL HMPRNT(12) ! scaled residual of single measurement
3809 ! CALL HMPRNT(4) ! chi^2/Ndf
3810 END IF
3811 CALL hmpwrt(3)
3812 CALL hmpwrt(12)
3813 CALL hmpwrt(4)
3814 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
3815 IF (nloopn <= lfitnp) THEN
3816 CALL hmpwrt(13)
3817 CALL hmpwrt(14)
3818 CALL gmpwrt(5) ! location, dispersion (pull) as a function of record nr
3819 END IF
3820 END IF
3821 ! IF(NLOOPN.EQ.2.AND.NHISTP.NE.0) CALL HMPRNT(6)
3822 IF(nloopn == 2) CALL hmpwrt(6)
3823 IF(nloopn <= 1) THEN
3824 ! IF(NHISTP.NE.0) CALL HMPRNT(5) ! number of degrees of freedom
3825 ! IF(NHISTP.NE.0) CALL HMPRNT(11) ! Nlocal
3826 CALL hmpwrt(5)
3827 CALL hmpwrt(11)
3828 CALL hmpwrt(16)
3829 END IF
3830
3831 ! local fit: band matrix structure !?
3832 IF (nloopn == 1.AND.nbndr(1)+nbndr(2) > 0) THEN
3833 DO lun=6,8,2
3834 WRITE(lun,*) ' '
3835 WRITE(lun,*) ' === local fits have bordered band matrix structure ==='
3836 IF (nbndr(1) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(1),'number of records (upper/left border)'
3837 IF (nbndr(2) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(2),'number of records (lower/right border)'
3838 WRITE(lun,101) ' NBDRX',nbdrx,'max border size'
3839 WRITE(lun,101) ' NBNDX',nbndx,'max band width'
3840 END DO
3841 END IF
3842
3843 lastit=iterat
3844
3845 ! monitoring of residuals
3846 IF (imonit < 0 .OR. (nloopn == 1 .AND. btest(imonit,0))) CALL monres
3847
3848101 FORMAT(1x,a8,' =',i14,' = ',a)
3849! 101 FORMAT(' LOOPN',I6,' Function value',F22.8,10X,I6,' records')
3850! 102 FORMAT(' incl. constraint penalty',F22.8)
3851! 103 FORMAT(I13,3X,A,G12.4)
3852END SUBROUTINE loopn ! loop with fits
3853
3857
3858SUBROUTINE ploopa(lunp)
3859 USE mpmod
3860
3861 IMPLICIT NONE
3862
3863 INTEGER(mpi), INTENT(IN) :: lunp
3864 ! ..
3865 WRITE(lunp,*) ' '
3866 WRITE(lunp,101) ! header line
3867 WRITE(lunp,102) ! header line
3868101 FORMAT(' it fc',' fcn_value dfcn_exp slpr costh iit st', &
3869 ' ls step cutf',1x,'rejects hhmmss FMS')
3870102 FORMAT(' -- --',' ----------- -------- ---- ----- --- --', &
3871 ' -- ----- ----',1x,'------- ------ ---')
3872 RETURN
3873END SUBROUTINE ploopa ! title for iteration
3874
3878
3879SUBROUTINE ploopb(lunp)
3880 USE mpmod
3881
3882 IMPLICIT NONE
3883 INTEGER(mpi) :: ma
3884 INTEGER :: minut
3885 INTEGER(mpi) :: nfa
3886 INTEGER :: nhour
3887 INTEGER(mpl) :: nrej
3888 INTEGER(mpi) :: nsecnd
3889 REAL(mps) :: ratae
3890 REAL :: rstb
3891 REAL(mps) :: secnd
3892 REAL(mps) :: slopes(3)
3893 REAL(mps) :: steps(3)
3894 REAL, DIMENSION(2) :: ta
3895 REAl etime
3896
3897 INTEGER(mpi), INTENT(IN) :: lunp
3898
3899 CHARACTER (LEN=4):: ccalcm(4)
3900 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3901 SAVE
3902
3903 nrej=sum(nrejec) ! rejects
3904 IF(nrej > 9999999) nrej=9999999
3905 rstb=etime(ta)
3906 deltim=rstb-rstart
3907 CALL sechms(deltim,nhour,minut,secnd) ! time
3908 nsecnd=nint(secnd,mpi)
3909 IF(iterat == 0) THEN
3910 WRITE(lunp,103) iterat,nloopn,fvalue, &
3911 chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3912 ELSE
3913 IF (lsinfo == 10) THEN ! line search skipped
3914 WRITE(lunp,105) iterat,nloopn,fvalue,delfun, &
3915 iitera,istopa,chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3916 ELSE
3917 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3918 ratae=max(-99.9,min(99.9,slopes(2)/slopes(1)))
3919 stepl=steps(2)
3920 WRITE(lunp,104) iterat,nloopn,fvalue,delfun,ratae,angras, &
3921 iitera,istopa,lsinfo,stepl, chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3922 ENDIF
3923 END IF
3924103 FORMAT(i3,i3,e12.5,38x,f5.1, 1x,i7, i3,i2.2,i2.2,a4)
3925104 FORMAT(i3,i3,e12.5,1x,e8.2,f6.3,f6.3,i5,2i3,f6.3,f5.1, &
3926 1x,i7, i3,i2.2,i2.2,a4)
3927105 FORMAT(i3,i3,e12.5,1x,e8.2,12x,i5,i3,9x,f5.1, &
3928 1x,i7, i3,i2.2,i2.2,a4)
3929 RETURN
3930END SUBROUTINE ploopb ! iteration line
3931
3935
3936SUBROUTINE ploopc(lunp)
3937 USE mpmod
3938
3939 IMPLICIT NONE
3940 INTEGER(mpi) :: ma
3941 INTEGER(mpi) :: minut
3942 INTEGER(mpi) :: nfa
3943 INTEGER(mpi) :: nhour
3944 INTEGER(mpl) :: nrej
3945 INTEGER(mpi) :: nsecnd
3946 REAL(mps) :: ratae
3947 REAL :: rstb
3948 REAL(mps) :: secnd
3949 REAL(mps) :: slopes(3)
3950 REAL(mps) :: steps(3)
3951 REAL, DIMENSION(2) :: ta
3952 REAL etime
3953
3954 INTEGER(mpi), INTENT(IN) :: lunp
3955 CHARACTER (LEN=4):: ccalcm(4)
3956 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3957 SAVE
3958
3959 nrej=sum(nrejec) ! rejects
3960 IF(nrej > 9999999) nrej=9999999
3961 rstb=etime(ta)
3962 deltim=rstb-rstart
3963 CALL sechms(deltim,nhour,minut,secnd) ! time
3964 nsecnd=nint(secnd,mpi)
3965 IF (lsinfo == 10) THEN ! line search skipped
3966 WRITE(lunp,104) nloopn,fvalue,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3967 ELSE
3968 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3969 ratae=abs(slopes(2)/slopes(1))
3970 stepl=steps(2)
3971 WRITE(lunp,105) nloopn,fvalue, ratae,lsinfo, &
3972 stepl,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3973 END IF
3974104 FORMAT(3x,i3,e12.5,9x, 35x, i7, i3,i2.2,i2.2,a4)
3975105 FORMAT(3x,i3,e12.5,9x, f6.3,14x,i3,f6.3,6x, i7, i3,i2.2,i2.2,a4)
3976 RETURN
3977
3978END SUBROUTINE ploopc ! sub-iteration line
3979
3983
3984SUBROUTINE ploopd(lunp)
3985 USE mpmod
3986 IMPLICIT NONE
3987 INTEGER :: minut
3988 INTEGER :: nhour
3989 INTEGER(mpi) :: nsecnd
3990 REAL :: rstb
3991 REAL(mps) :: secnd
3992 REAL, DIMENSION(2) :: ta
3993 REAL etime
3994
3995 INTEGER(mpi), INTENT(IN) :: lunp
3996 CHARACTER (LEN=4):: ccalcm(4)
3997 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3998 SAVE
3999 rstb=etime(ta)
4000 deltim=rstb-rstart
4001 CALL sechms(deltim,nhour,minut,secnd) ! time
4002 nsecnd=nint(secnd,mpi)
4003
4004 WRITE(lunp,106) nhour,minut,nsecnd,ccalcm(lcalcm)
4005106 FORMAT(69x,i3,i2.2,i2.2,a4)
4006 RETURN
4007END SUBROUTINE ploopd
4008
4010SUBROUTINE explfc(lunit)
4011 USE mpdef
4012 USE mpmod, ONLY: metsol
4013
4014 IMPLICIT NONE
4015 INTEGER(mpi) :: lunit
4016 WRITE(lunit,*) ' '
4017 WRITE(lunit,102) 'Explanation of iteration table'
4018 WRITE(lunit,102) '=============================='
4019 WRITE(lunit,101) 'it', &
4020 'iteration number. Global parameters are improved for it > 0.'
4021 WRITE(lunit,102) 'First function evaluation is called iteraton 0.'
4022 WRITE(lunit,101) 'fc', 'number of function evaluations.'
4023 WRITE(lunit,101) 'fcn_value', 'value of 2 x Likelihood function (LF).'
4024 WRITE(lunit,102) 'The final value is the chi^2 value of the fit and should'
4025 WRITE(lunit,102) 'be about equal to the NDF (see below).'
4026 WRITE(lunit,101) 'dfcn_exp', &
4027 'expected reduction of the value of the Likelihood function (LF)'
4028 WRITE(lunit,101) 'slpr', 'ratio of the actual slope to inital slope.'
4029 WRITE(lunit,101) 'costh', &
4030 'cosine of angle between search direction and -gradient'
4031 IF (metsol == 4) THEN
4032 WRITE(lunit,101) 'iit', &
4033 'number of internal iterations in MINRES algorithm'
4034 WRITE(lunit,101) 'st', 'stop code of MINRES algorithm'
4035 WRITE(lunit,102) '< 0: rhs is very special, with beta2 = 0'
4036 WRITE(lunit,102) '= 0: rhs b = 0, i.e. the exact solution is x = 0'
4037 WRITE(lunit,102) '= 1 requested accuracy achieved, as determined by rtol'
4038 WRITE(lunit,102) '= 2 reasonable accuracy achieved, given eps'
4039 WRITE(lunit,102) '= 3 x has converged to an eigenvector'
4040 WRITE(lunit,102) '= 4 matrix ill-conditioned (Acond has exceeded 0.1/eps)'
4041 WRITE(lunit,102) '= 5 the iteration limit was reached'
4042 WRITE(lunit,102) '= 6 Matrix x vector does not define a symmetric matrix'
4043 WRITE(lunit,102) '= 7 Preconditioner does not define a symmetric matrix'
4044 ELSEIF (metsol == 5) THEN
4045 WRITE(lunit,101) 'iit', &
4046 'number of internal iterations in MINRES-QLP algorithm'
4047 WRITE(lunit,101) 'st', 'stop code of MINRES-QLP algorithm'
4048 WRITE(lunit,102) '= 1: beta_{k+1} < eps, iteration k is the final Lanczos step.'
4049 WRITE(lunit,102) '= 2: beta2 = 0. If M = I, b and x are eigenvectors of A.'
4050 WRITE(lunit,102) '= 3: beta1 = 0. The exact solution is x = 0.'
4051 WRITE(lunit,102) '= 4: A solution to (poss. singular) Ax = b found, given rtol.'
4052 WRITE(lunit,102) '= 5: A solution to (poss. singular) Ax = b found, given eps.'
4053 WRITE(lunit,102) '= 6: Pseudoinverse solution for singular LS problem, given rtol.'
4054 WRITE(lunit,102) '= 7: Pseudoinverse solution for singular LS problem, given eps.'
4055 WRITE(lunit,102) '= 8: The iteration limit was reached.'
4056 WRITE(lunit,102) '= 9: The operator defined by Aprod appears to be unsymmetric.'
4057 WRITE(lunit,102) '=10: The operator defined by Msolve appears to be unsymmetric.'
4058 WRITE(lunit,102) '=11: The operator defined by Msolve appears to be indefinite.'
4059 WRITE(lunit,102) '=12: xnorm has exceeded maxxnorm or will exceed it next iteration.'
4060 WRITE(lunit,102) '=13: Acond has exceeded Acondlim or 0.1/eps.'
4061 WRITE(lunit,102) '=14: Least-squares problem but no converged solution yet.'
4062 WRITE(lunit,102) '=15: A null vector obtained, given rtol.'
4063 ENDIF
4064 WRITE(lunit,101) 'ls', 'line search info'
4065 WRITE(lunit,102) '< 0 recalculate function'
4066 WRITE(lunit,102) '= 0: N or STP lt 0 or step not descending'
4067 WRITE(lunit,102) '= 1: Linesearch convergence conditions reached'
4068 WRITE(lunit,102) '= 2: interval of uncertainty at lower limit'
4069 WRITE(lunit,102) '= 3: max nr of line search calls reached'
4070 WRITE(lunit,102) '= 4: step at the lower bound'
4071 WRITE(lunit,102) '= 5: step at the upper bound'
4072 WRITE(lunit,102) '= 6: rounding error limitation'
4073 WRITE(lunit,101) 'step', &
4074 'the factor for the Newton step during the line search. Usually'
4075 WRITE(lunit,102) &
4076 'a value of 1 gives a sufficient reduction of the LF. Oherwise'
4077 WRITE(lunit,102) 'other step values are tried.'
4078 WRITE(lunit,101) 'cutf', &
4079 'cut factor. Local fits are rejected, if their chi^2 value'
4080 WRITE(lunit,102) &
4081 'is larger than the 3-sigma chi^2 value times the cut factor.'
4082 WRITE(lunit,102) 'A cut factor of 1 is used finally, but initially a larger'
4083 WRITE(lunit,102) 'factor may be used. A value of 0.0 means no cut.'
4084 WRITE(lunit,101) 'rejects', 'total number of rejected local fits.'
4085 WRITE(lunit,101) 'hmmsec', 'the time in hours (h), minutes (mm) and seconds.'
4086 WRITE(lunit,101) 'FMS', 'calculation of Function value, Matrix, Solution.'
4087 WRITE(lunit,*) ' '
4088
4089101 FORMAT(a9,' = ',a)
4090102 FORMAT(13x,a)
4091END SUBROUTINE explfc
4092
4100
4101SUBROUTINE mupdat(i,j,add) !
4102 USE mpmod
4103
4104 IMPLICIT NONE
4105
4106 INTEGER(mpi), INTENT(IN) :: i
4107 INTEGER(mpi), INTENT(IN) :: j
4108 REAL(mpd), INTENT(IN) :: add
4109
4110 INTEGER(mpl):: ijadd
4111 INTEGER(mpl):: ijcsr3
4112 INTEGER(mpl):: ia
4113 INTEGER(mpl):: ja
4114 INTEGER(mpl):: ij
4115 ! ...
4116 IF(i <= 0.OR.j <= 0.OR. add == 0.0_mpd) RETURN
4117 ia=max(i,j) ! larger
4118 ja=min(i,j) ! smaller
4119 ij=0
4120 IF(matsto == 3) THEN
4121 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
4122 ij=ijcsr3(i,j) ! inline code requires same time
4123 IF (ij > 0) globalmatd(ij)=globalmatd(ij)+add
4124 RETURN
4125 ELSE ! sparse symmetric matrix (BSR3)
4126 ! block index
4127 ij=ijcsr3((i-1)/matbsz+1,(j-1)/matbsz+1)
4128 IF (ij > 0) THEN
4129 ! index of first element in block
4130 ij=(ij-1)*matbsz*matbsz+1
4131 ! adjust index for position in block
4132 ij=ij+mod(int(ia-1,mpi),matbsz)*matbsz+mod(int(ja-1,mpi),matbsz)
4133 globalmatd(ij)=globalmatd(ij)+add
4134 ENDIF
4135 RETURN
4136 END IF
4137 ELSE IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4138 ij=ijadd(i,j) ! inline code requires same time
4139 IF (ij == 0) RETURN ! pair is suppressed
4140 IF (ij > 0) THEN
4141 globalmatd(ij)=globalmatd(ij)+add
4142 ELSE
4143 globalmatf(-ij)=globalmatf(-ij)+real(add,mps)
4144 END IF
4145 ELSE ! full or unpacked (block diagonal) symmetric matrix
4146 ! global (ia,ib) to local (row,col) in block
4147 ij=globalrowoffsets(ia)+ja
4148 globalmatd(ij)=globalmatd(ij)+add
4149 END IF
4150 ! MINRES preconditioner
4151 IF(metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) THEN
4152 ij=0 ! no update
4153 IF(ia <= nvgb) THEN ! variable global parameter
4154 IF(mbandw > 0) THEN ! band matrix for Cholesky decomposition
4155 ij=indprecond(ia)-ia+ja
4156 IF(ia > 1.AND.ij <= indprecond(ia-1)) ij=0
4157 ELSE ! default preconditioner (diagonal)
4158 IF(ja == ia) ij=ia
4159 END IF
4160 ELSE ! Lagrange multiplier
4161 ij=offprecond(ia-nvgb)+ja
4162 END IF
4163 ! bad index?
4164 IF(ij < 0.OR.ij > size(matprecond)) THEN
4165 CALL peend(23,'Aborted, bad matrix index')
4166 stop 'mupdat: bad index'
4167 END IF
4168 ! update?
4169 IF(ij /= 0) matprecond(ij)=matprecond(ij)+add
4170 END IF
4171END SUBROUTINE mupdat
4172
4173
4185
4186SUBROUTINE mgupdt(i,j1,j2,il,jl,n,sub)
4187 USE mpmod
4188
4189 IMPLICIT NONE
4190
4191 INTEGER(mpi), INTENT(IN) :: i
4192 INTEGER(mpi), INTENT(IN) :: j1
4193 INTEGER(mpi), INTENT(IN) :: j2
4194 INTEGER(mpi), INTENT(IN) :: il
4195 INTEGER(mpi), INTENT(IN) :: jl
4196 INTEGER(mpi), INTENT(IN) :: n
4197 REAL(mpd), INTENT(IN) :: sub((n*n+n)/2)
4198
4199 INTEGER(mpl):: ij
4200 INTEGER(mpl):: ioff
4201 INTEGER(mpi):: ia
4202 INTEGER(mpi):: ia1
4203 INTEGER(mpi):: ib
4204 INTEGER(mpi):: iblast
4205 INTEGER(mpi):: iblock
4206 INTEGER(mpi):: ijl
4207 INTEGER(mpi):: iprc
4208 INTEGER(mpi):: ir
4209 INTEGER(mpi):: ja
4210 INTEGER(mpi):: jb
4211 INTEGER(mpi):: jblast
4212 INTEGER(mpi):: jblock
4213 INTEGER(mpi):: jc
4214 INTEGER(mpi):: jc1
4215 INTEGER(mpi):: jpg
4216 INTEGER(mpi):: k
4217 INTEGER(mpi):: lr
4218 INTEGER(mpi):: nc
4219
4220 INTEGER(mpl) ijcsr3
4221 ! ...
4222 IF(i <= 0.OR.j1 <= 0.OR.j2 > i) RETURN
4223
4224 IF(matsto == 3) THEN ! sparse symmetric matrix (CSR3, upper triangle)
4225 ja=globalallindexgroups(i) ! first (global) column
4226 jb=globalallindexgroups(i+1)-1 ! last (global) column
4227 ia1=globalallindexgroups(j1) ! first (global) row
4228 ! loop over groups (now in same column)
4229 DO jpg=j1,j2
4230 ia=globalallindexgroups(jpg) ! first (global) row in group
4231 ib=globalallindexgroups(jpg+1)-1 ! last (global) row in group
4232 IF (matbsz < 2) THEN
4233 ! CSR3
4234 ij=ijcsr3(ia,ja)
4235 IF (ij == 0) THEN
4236 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc, matsto
4237 stop
4238 END IF
4239 ioff=ij-ja ! offset
4240 DO ir=ia,ib
4241 jc1=max(ir,ja)
4242 k=il+jc1-ja
4243 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4244 DO jc=jc1,jb
4245 globalmatd(ioff+jc)=globalmatd(ioff+jc)-sub(ijl)
4246 ijl=ijl+k
4247 k=k+1
4248 END DO
4249 ioff=ioff+csr3rowoffsets(ir+1)-csr3rowoffsets(ir)-1
4250 END DO
4251 ELSE
4252 ! BSR3
4253 iblast=-1
4254 jblast=-1
4255 ioff=0
4256 DO ir=ia,ib
4257 iblock=(ir-1)/matbsz+1
4258 jc1=max(ir,ja)
4259 k=il+jc1-ja
4260 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4261 DO jc=jc1,jb
4262 jblock=(jc-1)/matbsz+1
4263 ! index of first element in (new) block
4264 IF (jblock /= jblast.OR.iblock /= iblast) THEN
4265 ioff=(ijcsr3(iblock,jblock)-1)*matbsz*matbsz+1
4266 iblast=iblock
4267 jblast=jblock
4268 END IF
4269 ! adjust index for position in block
4270 ij=ioff+mod(int(ir-1,mpi),matbsz)+mod(int(jc-1,mpi),matbsz)*matbsz
4271 globalmatd(ij)=globalmatd(ij)-sub(ijl)
4272 ijl=ijl+k
4273 k=k+1
4274 END DO
4275 END DO
4276 END IF
4277 END DO
4278 RETURN
4279 END IF
4280
4281 ! lower triangle
4282 ia=globalallindexgroups(i) ! first (global) row
4283 ib=globalallindexgroups(i+1)-1 ! last (global) row
4284 ja=globalallindexgroups(j1) ! first (global) column
4285 jb=globalallindexgroups(j2+1)-1 ! last (global) column
4286
4287 IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4288 CALL ijpgrp(i,j1,ij,lr,iprc) ! index of first element of group 'j1'
4289 IF (ij == 0) THEN
4290 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc,matsto
4291 stop
4292 END IF
4293 k=il
4294 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4295 DO ir=ia,ib
4296 nc=min(ir,jb)-ja ! number of columns -1
4297 IF (jb >= ir) THEN ! diagonal element
4298 globalmatd(ir)=globalmatd(ir)-sub(ijl+jl+nc)
4299 nc=nc-1
4300 END IF
4301 ! off-diagonal elements
4302 IF (iprc == 1) THEN
4303 globalmatd(ij:ij+nc)=globalmatd(ij:ij+nc)-sub(ijl+jl:ijl+jl+nc)
4304 ELSE
4305 globalmatf(ij:ij+nc)=globalmatf(ij:ij+nc)-real(sub(ijl+jl:ijl+jl+nc),mps)
4306 END IF
4307 ij=ij+lr
4308 ijl=ijl+k
4309 k=k+1
4310 END DO
4311 ELSE ! full or unpacked (block diagonal) symmetric matrix
4312 k=il
4313 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4314 DO ir=ia,ib
4315 ! global (ir,0) to local (row,col) in block
4316 ij=globalrowoffsets(ir)
4317 nc=min(ir,jb)-ja ! number of columns -1
4318 globalmatd(ij+ja:ij+ja+nc)=globalmatd(ij+ja:ij+ja+nc)-sub(ijl+jl:ijl+jl+nc)
4319 ijl=ijl+k
4320 k=k+1
4321 END DO
4322 END IF
4323
4324END SUBROUTINE mgupdt
4325
4326
4353
4354SUBROUTINE loopbf(nrej,numfil,naccf,chi2f,ndff)
4355 USE mpmod
4356
4357 IMPLICIT NONE
4358 REAL(mpd) :: cauchy
4359 REAL(mps) :: chichi
4360 REAL(mps) :: chlimt
4361 REAL(mps) :: chndf
4362 REAL(mpd) :: chuber
4363 REAL(mpd) :: down
4364 REAL(mpd) :: pull
4365 REAL(mpd) :: r1
4366 REAL(mpd) :: r2
4367 REAL(mps) :: rec
4368 REAL(mpd) :: rerr
4369 REAL(mpd) :: resid
4370 REAL(mps) :: resing
4371 REAL(mpd) :: resmax
4372 REAL(mpd) :: rmeas
4373 REAL(mpd) :: rmloc
4374 REAL(mpd) :: suwt
4375 REAL(mps) :: used
4376 REAL(mpd) :: wght
4377 REAL(mps) :: chindl
4378 INTEGER(mpi) :: i
4379 INTEGER(mpi) :: ia
4380 INTEGER(mpi) :: ib
4381 INTEGER(mpi) :: ibuf
4382 INTEGER(mpi) :: ichunk
4383 INTEGER(mpl) :: icmn
4384 INTEGER(mpl) :: icost
4385 INTEGER(mpi) :: id
4386 INTEGER(mpi) :: idiag
4387 INTEGER(mpi) :: ieq
4388 INTEGER(mpi) :: iext
4389 INTEGER(mpi) :: ij
4390 INTEGER(mpi) :: ije
4391 INTEGER(mpi) :: ijn
4392 INTEGER(mpi) :: ik
4393 INTEGER(mpi) :: ike
4394 INTEGER(mpi) :: il
4395 INTEGER(mpi) :: im
4396 INTEGER(mpi) :: imeas
4397 INTEGER(mpi) :: in
4398 INTEGER(mpi) :: inv
4399 INTEGER(mpi) :: ioffb
4400 INTEGER(mpi) :: ioffc
4401 INTEGER(mpi) :: ioffd
4402 INTEGER(mpi) :: ioffe
4403 INTEGER(mpi) :: ioffi
4404 INTEGER(mpi) :: ioffq
4405 INTEGER(mpi) :: iprc
4406 INTEGER(mpi) :: iprcnx
4407 INTEGER(mpi) :: iprdbg
4408 INTEGER(mpi) :: iproc
4409 INTEGER(mpi) :: irbin
4410 INTEGER(mpi) :: isize
4411 INTEGER(mpi) :: ist
4412 INTEGER(mpi) :: iter
4413 INTEGER(mpi) :: itgbi
4414 INTEGER(mpi) :: ivgbj
4415 INTEGER(mpi) :: ivgbk
4416 INTEGER(mpi) :: ivpgrp
4417 INTEGER(mpi) :: j
4418 INTEGER(mpi) :: j1
4419 INTEGER(mpi) :: ja
4420 INTEGER(mpi) :: jb
4421 INTEGER(mpi) :: jk
4422 INTEGER(mpi) :: jl
4423 INTEGER(mpi) :: jl1
4424 INTEGER(mpi) :: jn
4425 INTEGER(mpi) :: jnx
4426 INTEGER(mpi) :: joffd
4427 INTEGER(mpi) :: joffi
4428 INTEGER(mpi) :: jproc
4429 INTEGER(mpi) :: jrc
4430 INTEGER(mpi) :: jsp
4431 INTEGER(mpi) :: k
4432 INTEGER(mpi) :: kbdr
4433 INTEGER(mpi) :: kbdrx
4434 INTEGER(mpi) :: kbnd
4435 INTEGER(mpi) :: kfl
4436 INTEGER(mpi) :: kx
4437 INTEGER(mpi) :: lvpgrp
4438 INTEGER(mpi) :: mbdr
4439 INTEGER(mpi) :: mbnd
4440 INTEGER(mpi) :: mside
4441 INTEGER(mpi) :: nalc
4442 INTEGER(mpi) :: nalg
4443 INTEGER(mpi) :: nan
4444 INTEGER(mpi) :: nb
4445 INTEGER(mpi) :: ndf
4446 INTEGER(mpi) :: ndown
4447 INTEGER(mpi) :: neq
4448 INTEGER(mpi) :: nfred
4449 INTEGER(mpi) :: nfrei
4450 INTEGER(mpi) :: ngg
4451 INTEGER(mpi) :: nprdbg
4452 INTEGER(mpi) :: nrank
4453 INTEGER(mpl) :: nrc
4454 INTEGER(mpi) :: nst
4455 INTEGER(mpi) :: nter
4456 INTEGER(mpi) :: nweig
4457 INTEGER(mpi) :: ngrp
4458 INTEGER(mpi) :: npar
4459
4460 INTEGER(mpl), INTENT(IN OUT) :: nrej(6)
4461 INTEGER(mpi), INTENT(IN) :: numfil
4462 INTEGER(mpi), INTENT(IN OUT) :: naccf(numfil)
4463 REAL(mps), INTENT(IN OUT) :: chi2f(numfil)
4464 INTEGER(mpi), INTENT(IN OUT) :: ndff(numfil)
4465
4466 REAL(mps) :: cndl10
4467 REAL(mpd) :: dchi2
4468 REAL(mpd) :: dvar
4469 REAL(mpd) :: dw1
4470 REAL(mpd) :: dw2
4471 REAL(mpd) :: evdmin
4472 REAL(mpd) :: evdmax
4473 REAL(mpd) :: summ
4474 INTEGER(mpi) :: ijprec
4475
4476 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
4477
4478 LOGICAL:: lprnt
4479 LOGICAL::lhist
4480
4481 CHARACTER (LEN=3):: chast
4482 DATA chuber/1.345_mpd/ ! constant for Huber down-weighting
4483 DATA cauchy/2.3849_mpd/ ! constant for Cauchy down-weighting
4484 SAVE chuber,cauchy
4485 ! ...
4486
4487 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
4488 ! reset header, 3 words per thread:
4489 ! number of entries, offset to data, indices
4492 nprdbg=0
4493 iprdbg=-1
4494
4495 ! parallelize record loop
4496 ! private copy of NREJ,.. for each thread, combined at end, init with 0.
4497 !$OMP PARALLEL DO &
4498 !$OMP DEFAULT(PRIVATE) &
4499 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI, &
4500 !$OMP readBufferDataD,writeBufferHeader,writeBufferInfo, &
4501 !$OMP writeBufferData,writeBufferIndices,writeBufferUpdates,globalVector,globalCounter, &
4502 !$OMP globalParameter,globalParLabelIndex,globalIndexUsage,backIndexUsage, &
4503 !$OMP measBins,numMeas,measIndex,measRes,measHists,globalAllParToGroup,globalAllIndexGroups, &
4504 !$OMP localCorrections,localEquations,ifd, &
4505 !$OMP NAGB,NVGB,NAGBN,ICALCM,ICHUNK,NLOOPN,NRECER,NPRDBG,IPRDBG, &
4506 !$OMP NEWITE,CHICUT,LHUBER,CHUBER,ITERAT,NRECPR,MTHRD,NSPC,NAEQN, &
4507 !$OMP DWCUT,CHHUGE,NRECP2,CAUCHY,LFITNP,LFITBB,IMONIT,IMONMD,MONPG1,LUNLOG,MDEBUG,CNDLMX) &
4508 !$OMP REDUCTION(+:NREJ,NBNDR,NACCF,CHI2F,NDFF) &
4509 !$OMP REDUCTION(MAX:NBNDX,NBDRX) &
4510 !$OMP REDUCTION(MIN:NREC3) &
4511 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
4512 DO ibuf=1,numreadbuffer ! buffer for current record
4513 jrc=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
4514 kfl=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
4515 nrc=ifd(kfl)+jrc ! global record number
4516 dw1=real(readbufferdatad(readbufferpointer(ibuf)-1),mpd) ! weight
4517 dw2=sqrt(dw1)
4518
4519 iproc=0
4520 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
4521 ioffb=nagb*iproc ! offset 'f'.
4522 ioffc=nagbn*iproc ! offset 'c'.
4523 ioffe=nvgb*iproc ! offset 'e'
4524 ioffd=writebufferheader(-1)*iproc+writebufferinfo(2,iproc+1) ! offset data
4525 ioffi=writebufferheader(1)*iproc+writebufferinfo(3,iproc+1)+3 ! offset indices
4526 ioffq=naeqn*iproc ! offset equations (measurements)
4527 ! ----- reset ------------------------------------------------------
4528 lprnt=.false.
4529 lhist=(iproc == 0)
4530 rec=real(nrc,mps) ! floating point value
4531 IF(nloopn == 1.AND.mod(nrc,100000_mpl) == 0) THEN
4532 WRITE(*,*) 'Record',nrc,' ... still reading'
4533 IF(monpg1>0) WRITE(lunlog,*) 'Record',nrc,' ... still reading'
4534 END IF
4535
4536 ! printout/debug only for one thread at a time
4537
4538
4539 ! flag for record printout -----------------------------------------
4540
4541 lprnt=.false.
4542 IF(newite.AND.(iterat == 1.OR.iterat == 3)) THEN
4543 IF(nrc == nrecpr) lprnt=.true.
4544 IF(nrc == nrecp2) lprnt=.true.
4545 IF(nrc == nrecer) lprnt=.true.
4546 END IF
4547 IF (lprnt)THEN
4548 !$OMP ATOMIC
4549 nprdbg=nprdbg+1 ! number of threads with debug
4550 IF (nprdbg == 1) iprdbg=iproc ! first thread with debug
4551 IF (iproc /= iprdbg) lprnt=.false.
4552 ! print *, ' LPRNT ', NRC, NPRDBG, IPRDBG, IPROC, LPRNT
4553 END IF
4554 IF(lprnt) THEN
4555 WRITE(1,*) ' '
4556 WRITE(1,*) '------------------ Loop',nloopn, &
4557 ': Printout for record',nrc,iproc
4558 WRITE(1,*) ' '
4559 END IF
4560
4561 ! ----- print data -------------------------------------------------
4562
4563 IF(lprnt) THEN
4564 imeas=0 ! local derivatives
4565 ist=readbufferpointer(ibuf)+1
4567 DO ! loop over measurements
4568 CALL isjajb(nst,ist,ja,jb,jsp)
4569 IF(ja == 0) EXIT
4570 IF(imeas == 0) WRITE(1,1121)
4571 imeas=imeas+1
4572 WRITE(1,1122) imeas,readbufferdatad(ja),readbufferdatad(jb), &
4573 (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
4574 END DO
45751121 FORMAT(/'Measured value and local derivatives'/ &
4576 ' i measured std_dev index...derivative ...')
45771122 FORMAT(i3,2g12.4,3(i3,g12.4)/(27x,3(i3,g12.4)))
4578
4579 imeas=0 ! global derivatives
4580 ist=readbufferpointer(ibuf)+1
4582 DO ! loop over measurements
4583 CALL isjajb(nst,ist,ja,jb,jsp)
4584 IF(ja == 0) EXIT
4585 IF(imeas == 0) WRITE(1,1123)
4586 imeas=imeas+1
4587 IF (jb < ist) THEN
4588 IF(ist-jb > 2) THEN
4589 WRITE(1,1124) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4590 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4591 ELSE
4592 WRITE(1,1125) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4593 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4594 END IF
4595 END IF
4596 END DO
45971123 FORMAT(/'Global derivatives'/ &
4598 ' i label gindex vindex derivative ...')
45991124 FORMAT(i3,2(i9,i7,i7,g12.4)/(3x,2(i9,i7,i7,g12.4)))
46001125 FORMAT(i3,2(i9,i7,i7,g12.4))
4601 END IF
4602
4603 ! ----- first loop -------------------------------------------------
4604 ! ------ prepare local fit ------
4605 ! count local and global derivates
4606 ! subtract actual alignment parameters from the measured data
4607
4608 IF(lprnt) THEN
4609 WRITE(1,*) ' '
4610 WRITE(1,*) 'Data corrections using values of global parameters'
4611 WRITE(1,*) '=================================================='
4612 WRITE(1,101)
4613 END IF
4614 nalg=0 ! count number of global derivatives
4615 nalc=0 ! count number of local derivatives
4616 neq=0 ! count number of equations
4617
4618 ist=readbufferpointer(ibuf)+1
4620 DO ! loop over measurements
4621 CALL isjajb(nst,ist,ja,jb,jsp)
4622 IF(ja == 0) EXIT
4623 rmeas=real(readbufferdatad(ja),mpd) ! data
4624 neq=neq+1 ! count equation
4625 localequations(1,ioffq+neq)=ja
4626 localequations(2,ioffq+neq)=jb
4627 localequations(3,ioffq+neq)=ist
4628 ! subtract global ... from measured value
4629 DO j=1,ist-jb ! global parameter loop
4630 itgbi=readbufferdatai(jb+j) ! global parameter label
4631 rmeas=rmeas-real(readbufferdatad(jb+j),mpd)*globalparameter(itgbi) ! subtract !!! reversed
4632 IF (icalcm == 1) THEN
4633 ij=globalparlabelindex(2,itgbi) ! -> index of variable global parameter
4634 IF(ij > 0) THEN
4635 ijn=backindexusage(ioffe+ij) ! get index of index
4636 IF(ijn == 0) THEN ! not yet included
4637 nalg=nalg+1 ! count
4638 globalindexusage(ioffc+nalg)=ij ! store global index
4639 backindexusage(ioffe+ij)=nalg ! store back index
4640 END IF
4641 END IF
4642 END IF
4643 END DO
4644 IF(lprnt) THEN
4645 IF (jb < ist) WRITE(1,102) neq,readbufferdatad(ja),rmeas,readbufferdatad(jb)
4646 END IF
4647 readbufferdatad(ja)=real(rmeas,mpr8) ! global contribution subtracted
4648 DO j=1,jb-ja-1 ! local parameter loop
4649 ij=readbufferdatai(ja+j)
4650 nalc=max(nalc,ij) ! number of local parameters
4651 END DO
4652 END DO
4653101 FORMAT(' index measvalue corrvalue sigma')
4654102 FORMAT(i6,2x,2g12.4,' +-',g12.4)
4655
4656 IF(nalc <= 0) GO TO 90
4657
4658 ngg=(nalg*nalg+nalg)/2
4659 ngrp=0
4660 IF (icalcm == 1) THEN
4661 localglobalmatrix(:nalg*nalc)=0.0_mpd ! reset global-local matrix
4662 localglobalmap(:nalg*nalc)=0 ! reset global-local map
4663 ! store parameter group indices
4664 CALL sort1k(globalindexusage(ioffc+1),nalg) ! sort global par.
4665 lvpgrp=-1
4666 npar=0
4667 DO k=1,nalg
4668 iext=globalindexusage(ioffc+k)
4669 backindexusage(ioffe+iext)=k ! update back index
4670 ivpgrp=globalallpartogroup(iext) ! group
4671 IF (ivpgrp /= lvpgrp) THEN
4672 ngrp=ngrp+1
4673 writebufferindices(ioffi+ngrp)=ivpgrp ! global par group indices
4674 lvpgrp=ivpgrp
4675 npar=npar+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4676 END IF
4677 END DO
4678 ! check NPAR==NALG
4679 IF (npar /= nalg) THEN
4680 print *, ' mismatch of number of global parameters ', nrc, nalg, npar, ngrp
4681 print *, globalindexusage(ioffc+1:ioffc+nalg)
4682 print *, writebufferindices(ioffi+1:ioffi+ngrp)
4683 j=0
4684 DO k=1,ngrp
4685 ivpgrp=writebufferindices(ioffi+k)
4686 j=j+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4687 IF (globalallpartogroup(globalindexusage(ioffc+j)) /= ivpgrp) &
4688 print *, ' bad group ', k, j, ivpgrp, globalindexusage(ioffc+j)
4689 END DO
4690 CALL peend(35,'Aborted, mismatch of number of global parameters')
4691 stop ' mismatch of number of global parameters '
4692 ENDIF
4693 ! index header
4694 writebufferindices(ioffi-2)=jrc ! record number in file
4695 writebufferindices(ioffi-1)=nalg ! number of global parameters
4696 writebufferindices(ioffi )=ngrp ! number of global par groups
4697 DO k=1,ngg
4698 writebufferupdates(ioffd+k)=0.0_mpd ! reset global-global matrix
4699 END DO
4700 END IF
4701 ! ----- iteration start and check ---------------------------------
4702
4703 nter=1 ! first loop without down-weighting
4704 IF(nloopn /= 1.AND.lhuber /= 0) nter=lhuber
4705 localcorrections(ioffq+1:ioffq+neq) = 0._mpd
4706
4707 ! check matrix for bordered band structure (MBDR+MBND+1 <= NALC)
4708 mbnd=-1
4709 mbdr=nalc
4710 mside=-1 ! side (1: upper/left border, 2: lower/right border)
4711 DO i=1, 2*nalc
4712 ibandh(i)=0
4713 END DO
4714 idiag=1
4715
4716 iter=0
4717 resmax=0.0
4718 DO WHILE(iter < nter) ! outlier suppresssion iteration loop
4719 iter=iter+1
4720 resmax=0.0
4721 IF(lprnt) THEN
4722 WRITE(1,*) ' '
4723 WRITE(1,*) 'Outlier-suppression iteration',iter,' of',nter
4724 WRITE(1,*) '=========================================='
4725 WRITE(1,*) ' '
4726 imeas=0
4727 END IF
4728
4729 ! ----- second loop ------------------------------------------------
4730 ! accumulate normal equations for local fit and determine solution
4731 DO i=1,nalc
4732 blvec(i)=0.0_mpd ! reset vector
4733 END DO
4734 DO i=1,(nalc*nalc+nalc)/2 ! GF: FIXME - not really, local parameter number...
4735 clmat(i)=0.0_mpd ! (p)reset matrix
4736 END DO
4737 ndown=0
4738 nweig=0
4739 cndl10=0.
4740 DO ieq=1,neq! loop over measurements
4741 ja=localequations(1,ioffq+ieq)
4742 jb=localequations(2,ioffq+ieq)
4743 rmeas=real(readbufferdatad(ja),mpd) ! data
4744 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4745 wght =1.0_mpd/rerr**2 ! weight from error
4746 nweig=nweig+1
4747 resid=rmeas-localcorrections(ioffq+ieq) ! subtract previous fit
4748 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4749 IF(iter <= 3) THEN
4750 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4751 wght=wght*chuber*rerr/abs(resid)
4752 ndown=ndown+1
4753 END IF
4754 ELSE ! Cauchy
4755 wght=wght/(1.0+(resid/rerr/cauchy)**2)
4756 END IF
4757 END IF
4758
4759 IF(lprnt.AND.iter /= 1.AND.nter /= 1) THEN
4760 chast=' '
4761 IF(abs(resid) > chuber*rerr) chast='* '
4762 IF(abs(resid) > 3.0*rerr) chast='** '
4763 IF(abs(resid) > 6.0*rerr) chast='***'
4764 IF(imeas == 0) WRITE(1,*) 'Second loop: accumulate'
4765 IF(imeas == 0) WRITE(1,103)
4766 imeas=imeas+1
4767 down=1.0/sqrt(wght)
4768 r1=resid/rerr
4769 r2=resid/down
4770 WRITE(1,104) imeas,rmeas,resid,rerr,r1,chast,r2
4771 END IF
4772103 FORMAT(' index corrvalue residuum sigma', &
4773 ' nresid cnresid')
4774104 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4775
4776 DO j=1,jb-ja-1 ! normal equations, local parameter loop
4777 ij=readbufferdatai(ja+j) ! local parameter index J
4778 blvec(ij)=blvec(ij)+wght*rmeas*real(readbufferdatad(ja+j),mpd)
4779 DO k=1,j
4780 ik=readbufferdatai(ja+k) ! local parameter index K
4781 jk=(ij*ij-ij)/2+ik ! index in symmetric matrix
4782 clmat(jk)=clmat(jk) & ! force double precision
4783 +wght*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)
4784 ! check for band matrix substructure
4785 IF (iter == 1) THEN
4786 id=iabs(ij-ik)+1
4787 im=min(ij,ik) ! upper/left border
4788 ibandh(id)=max(ibandh(id),im)
4789 im=min(nalc+1-ij,nalc+1-ik) ! lower/rght border (mirrored)
4790 ibandh(nalc+id)=max(ibandh(nalc+id),im)
4791 END IF
4792 END DO
4793 END DO
4794 END DO
4795 ! for non trivial fits check for bordered band matrix structure
4796 IF (iter == 1.AND.nalc > 5.AND.lfitbb > 0) THEN
4797 kx=-1
4798 kbdrx=0
4799 icmn=int(nalc,mpl)**3 ! cost (*6) should improve by at least factor 2
4800 ! upper/left border ?
4801 kbdr=0
4802 DO k=nalc,2,-1
4803 kbnd=k-2
4804 kbdr=max(kbdr,ibandh(k))
4805 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4806 IF (icost < icmn) THEN
4807 icmn=icost
4808 kx=k
4809 kbdrx=kbdr
4810 mside=1
4811 END IF
4812 END DO
4813 IF (kx < 0) THEN
4814 ! lower/right border instead?
4815 kbdr=0
4816 DO k=nalc,2,-1
4817 kbnd=k-2
4818 kbdr=max(kbdr,ibandh(k+nalc))
4819 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4820 IF (icost < icmn) THEN
4821 icmn=icost
4822 kx=k
4823 kbdrx=kbdr
4824 mside=2
4825 END IF
4826 END DO
4827 END IF
4828 IF (kx > 0) THEN
4829 mbnd=kx-2
4830 mbdr=kbdrx
4831 END IF
4832 END IF
4833
4834 IF (mbnd >= 0) THEN
4835 ! fast solution for border banded matrix (inverse for ICALCM>0)
4836 IF (nloopn == 1) THEN
4837 nbndr(mside)=nbndr(mside)+1
4838 nbdrx=max(nbdrx,mbdr)
4839 nbndx=max(nbndx,mbnd)
4840 END IF
4841
4842 inv=0
4843 IF (nloopn <= lfitnp.AND.iter == 1) inv=1 ! band part of inverse (for pulls)
4844 IF (icalcm == 1.OR.lprnt) inv=2 ! complete inverse
4845 IF (mside == 1) THEN
4846 CALL sqmibb(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4847 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4848 ELSE
4849 CALL sqmibb2(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4850 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4851 ENDIF
4852 ! log10(condition of band part)
4853 IF (evdmin > 0.0_mpl) cndl10=log10(real(evdmax/evdmin,mps))
4854 IF (lhist.AND.nloopn == 1) CALL hmpent(16,cndl10)
4855 ELSE
4856 ! full inversion and solution
4857 inv=2
4858 CALL sqminv(clmat,blvec,nalc,nrank,scdiag,scflag)
4859 END IF
4860 ! check for NaNs
4861 nan=0
4862 DO k=1, nalc
4863 IF ((.NOT.(blvec(k) <= 0.0_mpd)).AND. (.NOT.(blvec(k) > 0.0_mpd))) nan=nan+1
4864 END DO
4865
4866 IF(lprnt) THEN
4867 WRITE(1,*) ' '
4868 WRITE(1,*) 'Parameter determination:',nalc,' parameters,', ' rank=',nrank
4869 WRITE(1,*) '-----------------------'
4870 IF(ndown /= 0) WRITE(1,*) ' ',ndown,' data down-weighted'
4871 WRITE(1,*) ' '
4872 END IF
4873
4874 ! ----- third loop -------------------------------------------------
4875 ! calculate single residuals remaining after local fit and chi^2
4876
4877 summ=0.0_mpd
4878 suwt=0.0
4879 imeas=0
4880 DO ieq=1,neq! loop over measurements
4881 ja=localequations(1,ioffq+ieq)
4882 jb=localequations(2,ioffq+ieq)
4883 ist=localequations(3,ioffq+ieq)
4884 rmeas=real(readbufferdatad(ja),mpd) ! data (global contrib. subtracted)
4885 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4886 wght =1.0_mpd/rerr**2 ! weight from error
4887 rmloc=0.0 ! local fit result reset
4888 DO j=1,jb-ja-1 ! local parameter loop
4889 ij=readbufferdatai(ja+j)
4890 rmloc=rmloc+real(readbufferdatad(ja+j),mpd)*blvec(ij) ! local fit result
4891 END DO
4892 localcorrections(ioffq+ieq)=rmloc ! save local fit result
4893 rmeas=rmeas-rmloc ! reduced to residual
4894
4895 ! calculate pulls? (needs covariance matrix)
4896 IF(iter == 1.AND.inv > 0.AND.nloopn <= lfitnp) THEN
4897 dvar=0.0_mpd
4898 DO j=1,jb-ja-1
4899 ij=readbufferdatai(ja+j)
4900 jk=(ij*ij-ij)/2 ! index in symmetric matrix, row offset
4901 ! off diagonal (symmetric)
4902 DO k=1,j-1
4903 ik=readbufferdatai(ja+k)
4904 dvar=dvar+clmat(jk+ik)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)*2.0_mpd
4905 END DO
4906 ! diagonal
4907 dvar=dvar+clmat(jk+ij)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+j),mpd)
4908 END DO
4909 ! some variance left to define a pull?
4910 IF (0.999999_mpd/wght > dvar) THEN
4911 pull=rmeas/sqrt(1.0_mpd/wght-dvar)
4912 IF (lhist) THEN
4913 IF (jb < ist) THEN
4914 CALL hmpent(13,real(pull,mps)) ! histogram pull
4915 CALL gmpms(5,rec,real(pull,mps))
4916 ELSE
4917 CALL hmpent(14,real(pull,mps)) ! histogram pull
4918 END IF
4919 END IF
4920 ! monitoring
4921 IF (imonit /= 0) THEN
4922 IF (jb < ist) THEN
4923 ij=readbufferdatai(jb+1) ! group by first global label
4924 if (imonmd == 0) THEN
4925 irbin=min(measbins,max(1,int(pull*rerr/measres(ij)/measbinsize+0.5*real(measbins,mpd))))
4926 ELSE
4927 irbin=min(measbins,max(1,int(pull/measbinsize+0.5*real(measbins,mpd))))
4928 ENDIF
4929 irbin=irbin+measbins*(measindex(ij)-1+nummeas*iproc)
4930 meashists(irbin)=meashists(irbin)+1
4931 ENDIF
4932 ENDIF
4933 END IF
4934 END IF
4935
4936 IF(iter == 1.AND.jb < ist.AND.lhist) &
4937 CALL gmpms(4,rec,real(rmeas/rerr,mps)) ! residual (with global deriv.)
4938
4939 dchi2=wght*rmeas*rmeas
4940 ! DCHIT=DCHI2
4941 resid=rmeas
4942 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4943 IF(iter <= 3) THEN
4944 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4945 wght=wght*chuber*rerr/abs(resid)
4946 dchi2=2.0*chuber*(abs(resid)/rerr-0.5*chuber)
4947 END IF
4948 ELSE
4949 wght=wght/(1.0_mpd+(resid/rerr/cauchy)**2)
4950 dchi2=log(1.0_mpd+(resid/rerr/cauchy)**2)*cauchy**2
4951 END IF
4952 END IF
4953
4954 down=1.0/sqrt(wght)
4955
4956 ! SUWT=SUWT+DCHI2/DCHIT
4957 suwt=suwt+rerr/down
4958 IF(lprnt) THEN
4959 chast=' '
4960 IF(abs(resid) > chuber*rerr) chast='* '
4961 IF(abs(resid) > 3.0*rerr) chast='** '
4962 IF(abs(resid) > 6.0*rerr) chast='***'
4963 IF(imeas == 0) WRITE(1,*) 'Third loop: single residuals'
4964 IF(imeas == 0) WRITE(1,105)
4965 imeas=imeas+1
4966 r1=resid/rerr
4967 r2=resid/down
4968 IF(resid < 0.0) r1=-r1
4969 IF(resid < 0.0) r2=-r2
4970 WRITE(1,106) imeas,readbufferdatad(ja),rmeas,rerr,r1,chast,r2
4971 END IF
4972105 FORMAT(' index corrvalue residuum sigma', &
4973 ' nresid cnresid')
4974106 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4975
4976 IF(iter == nter) THEN
4977 readbufferdatad(ja)=real(rmeas,mpr8) ! store remaining residual
4978 resmax=max(resmax,abs(rmeas)/rerr)
4979 END IF
4980
4981 IF(iter == 1.AND.lhist) THEN
4982 IF (jb < ist) THEN
4983 CALL hmpent( 3,real(rmeas/rerr,mps)) ! histogram norm residual
4984 ELSE
4985 CALL hmpent(12,real(rmeas/rerr,mps)) ! histogram norm residual
4986 END IF
4987 END IF
4988 summ=summ+dchi2 ! accumulate chi-square sum
4989 END DO
4990
4991 ndf=neq-nrank
4992 resing=(real(nweig,mps)-real(suwt,mps))/real(nweig,mps)
4993 IF (lhist) THEN
4994 IF(iter == 1) CALL hmpent( 5,real(ndf,mps)) ! histogram Ndf
4995 IF(iter == 1) CALL hmpent(11,real(nalc,mps)) ! histogram Nlocal
4996 IF(nloopn == 2.AND.iter == nter) CALL hmpent(6,resing)
4997 END IF
4998 IF(lprnt) THEN
4999 WRITE(1,*) ' '
5000 WRITE(1,*) 'Chi^2=',summ,' at',ndf,' degrees of freedom: ', &
5001 '3-sigma limit is',chindl(3,ndf)*real(ndf,mps)
5002 WRITE(1,*) suwt,' is sum of factors, compared to',nweig, &
5003 ' Downweight fraction:',resing
5004 END IF
5005 IF(nan > 0) THEN
5006 nrej(1)=nrej(1)+1 ! count cases
5007 IF (nrec3 == huge(nrec3)) nrec3=nrc
5008 IF(lprnt) THEN
5009 WRITE(1,*) ' NaNs ', nalc, nrank, nan
5010 WRITE(1,*) ' ---> rejected!'
5011 END IF
5012 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-1 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5013 GO TO 90
5014 END IF
5015 IF(nrank /= nalc) THEN
5016 nrej(2)=nrej(2)+1 ! count cases
5017 IF (nrec3 == huge(nrec3)) nrec3=nrc
5018 IF(lprnt) THEN
5019 WRITE(1,*) ' rank deficit', nalc, nrank
5020 WRITE(1,*) ' ---> rejected!'
5021 END IF
5022 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-2 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5023 GO TO 90
5024 END IF
5025 IF(cndl10 > cndlmx) THEN
5026 nrej(3)=nrej(3)+1 ! count cases
5027 IF (nrec3 == huge(nrec3)) nrec3=nrc
5028 IF(lprnt) THEN
5029 WRITE(1,*) ' too large condition(band part) ', nalc, nrank, cndl10
5030 WRITE(1,*) ' ---> rejected!'
5031 END IF
5032 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-3 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5033 GO TO 90
5034 END IF
5035 IF(ndf <= 0) THEN
5036 nrej(4)=nrej(4)+1 ! count cases
5037 IF(lprnt) THEN
5038 WRITE(1,*) ' Ndf<=0', nalc, nrank, ndf
5039 WRITE(1,*) ' ---> rejected!'
5040 END IF
5041 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-4 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5042 GO TO 90
5043 END IF
5044
5045 chndf=real(summ/real(ndf,mpd),mps)
5046
5047 IF(iter == 1.AND.lhist) CALL hmpent(4,chndf) ! histogram chi^2/Ndf
5048 END DO ! outlier iteration loop
5049
5050 ! ----- reject eventually ------------------------------------------
5051
5052 IF(newite.AND.iterat == 2) THEN ! find record with largest Chi^2/Ndf
5053 IF(nrecp2 < 0.AND.chndf > writebufferdata(2,iproc+1)) THEN
5054 writebufferdata(2,iproc+1)=chndf
5055 writebufferinfo(8,iproc+1)=jrc
5056 writebufferinfo(9,iproc+1)=kfl
5057 END IF
5058 END IF
5059
5060 chichi=chindl(3,ndf)*real(ndf,mps)
5061 ! GF IF(SUMM.GT.50.0*CHICHI) THEN ! huge
5062 ! CHK CHICUT<0: NO cut (1st iteration)
5063 IF(chicut >= 0.0) THEN
5064 IF(summ > chhuge*chichi) THEN ! huge
5065 nrej(5)=nrej(5)+1 ! count cases with huge chi^2
5066 IF(lprnt) THEN
5067 WRITE(1,*) ' ---> rejected!'
5068 END IF
5069 GO TO 90
5070 END IF
5071
5072 IF(chicut > 0.0) THEN
5073 chlimt=chicut*chichi
5074 ! WRITE(*,*) 'chi^2 ',SUMM,CHLIMT,CHICUT,CHINDL(3,NDF),NDF
5075 IF(summ > chlimt) THEN
5076 IF(lprnt) THEN
5077 WRITE(1,*) ' ---> rejected!'
5078 END IF
5079 ! add to FVALUE
5080 dchi2=chlimt ! total contribution limit
5081 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5082 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5083 GO TO 90
5084 END IF
5085 END IF
5086 END IF
5087
5088 IF(lhuber > 1.AND.dwcut /= 0.0.AND.resing > dwcut) THEN
5089 ! add to FVALUE
5090 dchi2=summ ! total contribution
5091 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5092 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5093 ! WRITE(*,*) 'Downweight fraction cut ',RESING,DWCUT,SUMM
5094 IF(lprnt) THEN
5095 WRITE(1,*) ' ---> rejected!'
5096 END IF
5097 GO TO 90
5098 END IF
5099
5100 IF(newite.AND.iterat == 2) THEN ! find record with largest residual
5101 IF(nrecpr < 0.AND.resmax > writebufferdata(1,iproc+1)) THEN
5102 writebufferdata(1,iproc+1)=real(resmax,mps)
5103 writebufferinfo(6,iproc+1)=jrc
5104 writebufferinfo(7,iproc+1)=kfl
5105 END IF
5106 END IF
5107 ! 'track quality' per binary file: accepted records
5108 naccf(kfl)=naccf(kfl)+1
5109 ndff(kfl) =ndff(kfl) +ndf
5110 chi2f(kfl)=chi2f(kfl)+chndf
5111
5112 ! ----- fourth loop ------------------------------------------------
5113 ! update of global matrix and vector according to the "Millepede"
5114 ! principle, from the global/local information
5115
5116 summ=0.0_mpd
5117 DO ieq=1,neq! loop over measurements
5118 ja=localequations(1,ioffq+ieq)
5119 jb=localequations(2,ioffq+ieq)
5120 ist=localequations(3,ioffq+ieq)
5121 rmeas=real(readbufferdatad(ja),mpd) ! data residual
5122 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
5123 wght =1.0_mpd/rerr**2 ! weight from measurement error
5124 dchi2=wght*rmeas*rmeas ! least-square contribution
5125
5126 IF(nloopn /= 1.AND.lhuber /= 0) THEN ! check residual
5127 resid=abs(rmeas)
5128 IF(resid > chuber*rerr) THEN
5129 wght=wght*chuber*rerr/resid ! down-weighting
5130 dchi2=2.0*chuber*(resid/rerr-0.5*chuber) ! modified contribution
5131 END IF
5132 END IF
5133 ! sum up
5134 summ=summ+dchi2
5135
5136 ! global-global matrix contribution: add directly to gg-matrix
5137
5138 DO j=1,ist-jb
5139 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5140 IF (readbufferdatad(jb+j) == 0.0_mpd) cycle ! skip zero global derivatives
5141 IF(ivgbj > 0) THEN
5142 globalvector(ioffb+ivgbj)=globalvector(ioffb+ivgbj) &
5143 +dw1*wght*rmeas*real(readbufferdatad(jb+j),mpd) ! vector !!! reverse
5144 globalcounter(ioffb+ivgbj)=globalcounter(ioffb+ivgbj)+1
5145 IF(icalcm == 1) THEN
5146 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5147 DO k=1,j
5149 IF(ivgbk > 0) THEN
5150 ike=backindexusage(ioffe+ivgbk) ! get index of index, non-zero
5151 ia=max(ije,ike) ! larger
5152 ib=min(ije,ike) ! smaller
5153 ij=ib+(ia*ia-ia)/2
5154 writebufferupdates(ioffd+ij)=writebufferupdates(ioffd+ij) &
5155 -dw1*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(jb+k),mpd)
5156 END IF
5157 END DO
5158 END IF
5159 END IF
5160 END DO
5161
5162 ! normal equations - rectangular matrix for global/local pars
5163 ! global-local matrix contribution: accumulate rectangular matrix
5164 IF (icalcm /= 1) cycle
5165 DO j=1,ist-jb
5166 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5167 IF(ivgbj > 0) THEN
5168 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5169 DO k=1,jb-ja-1
5170 ik=readbufferdatai(ja+k) ! local index
5171 jk=ik+(ije-1)*nalc ! matrix index
5173 dw2*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(ja+k),mpd)
5175 END DO
5176 END IF
5177 END DO
5178 END DO
5179 ! add to total objective function
5180 CALL addsums(iproc+1, summ, ndf, dw1)
5181
5182 ! ----- final matrix update ----------------------------------------
5183 ! update global matrices and vectors
5184 IF(icalcm /= 1) GO TO 90 ! matrix update
5185 ! (inverse local matrix) * (rectang. matrix) -> CORM
5186 ! T
5187 ! resulting symmetrix matrix = G * Gamma^{-1} * G
5188
5189 ! check sparsity of localGlobalMatrix (with par. groups)
5190 isize=nalc+nalg+1 ! row/clolumn offsets
5191 ! check rows
5192 k=0 ! offset
5193 DO i=1, nalg
5194 localglobalstructure(i)=isize
5195 DO j=1, nalc
5196 IF (localglobalmap(k+j) > 0) THEN
5197 localglobalstructure(isize+1)=j ! column
5198 localglobalstructure(isize+2)=k+j ! index
5199 isize=isize+2
5200 ENDIF
5201 END DO
5202 k=k+nalc
5203 END DO
5204 ! <50% non-zero elements?
5205 IF (isize-localglobalstructure(1) < nalc*nalg) THEN
5206 ! check columns (too)
5207 DO j=1, nalc
5208 localglobalstructure(nalg+j)=isize
5209 k=0 ! offset
5210 DO i=1, nalg
5211 IF (localglobalmap(k+j) > 0) THEN
5212 localglobalstructure(isize+1)=i ! row
5213 localglobalstructure(isize+2)=k+j ! index
5214 isize=isize+2
5215 ENDIF
5216 k=k+nalc
5217 END DO
5218 END DO
5219 localglobalstructure(nalg+nalc+1)=isize
5221 ELSE
5222 CALL dbavat(clmat,localglobalmatrix,writebufferupdates(ioffd+1),nalc,nalg,1)
5223 END IF
5224 ! (rectang. matrix) * (local param vector) -> CORV
5225 ! resulting vector = G * q (q = local parameter)
5226 ! CALL DBGAX(DQ(IGLMA/2+1),BLVEC,DQ(ICORV/2+1),NALG,NALC) ! not done
5227 ! the vector update is not done, because after local fit it is zero!
5228
5229 ! update cache status
5230 writebufferinfo(1,iproc+1)=writebufferinfo(1,iproc+1)+1
5231 writebufferinfo(2,iproc+1)=writebufferinfo(2,iproc+1)+ngg
5232 writebufferinfo(3,iproc+1)=writebufferinfo(3,iproc+1)+ngrp+3
5233 ! check free space
5234 nfred=writebufferheader(-1)-writebufferinfo(2,iproc+1)-writebufferheader(-2)
5236 IF (nfred < 0.OR.nfrei < 0) THEN ! need to flush
5237 nb=writebufferinfo(1,iproc+1)
5238 joffd=writebufferheader(-1)*iproc ! offset data
5239 joffi=writebufferheader(1)*iproc+3 ! offset indices
5240 used=real(writebufferinfo(2,iproc+1),mps)/real(writebufferheader(-1),mps)
5241 writebufferinfo(4,iproc+1)=writebufferinfo(4,iproc+1) +nint(1000.0*used,mpi)
5242 used=real(writebufferinfo(3,iproc+1),mps)/real(writebufferheader(1),mps)
5243 writebufferinfo(5,iproc+1)=writebufferinfo(5,iproc+1) +nint(1000.0*used,mpi)
5244 !$OMP CRITICAL
5247
5248 DO ib=1,nb
5249 nalg=writebufferindices(joffi-1)
5250 il=1 ! row in update matrix
5251 DO in=1,writebufferindices(joffi)
5252 i=writebufferindices(joffi+in)
5253 j=writebufferindices(joffi+1) ! 1. group
5254 iprc=ijprec(i,j) ! group pair precision
5255 jl=1 ! col in update matrix
5256 ! start (rows) for continous groups
5257 j1=j
5258 jl1=jl
5259 ! other groups for row
5260 DO jn=2,in
5262 jnx=writebufferindices(joffi+jn) ! next group
5263 iprcnx=ijprec(i,jnx) ! group pair precision
5264 ! end of continous groups?
5265 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5266 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5267 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5268 ! restart continous groups
5269 j1=jnx ! new 1. column
5270 jl1=jl
5271 iprc=iprcnx
5272 END IF
5273 j=jnx ! last group
5274 END DO
5275 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5276 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5278 END DO
5279 joffd=joffd+(il*il-il)/2
5280 joffi=joffi+writebufferindices(joffi)+3
5281 END DO
5282 !$OMP END CRITICAL
5283 ! reset counter, pointers
5284 DO k=1,3
5285 writebufferinfo(k,iproc+1)=0
5286 END DO
5287 END IF
5288
528990 IF(lprnt) THEN
5290 WRITE(1,*) ' '
5291 WRITE(1,*) '------------------ End of printout for record',nrc
5292 WRITE(1,*) ' '
5293 END IF
5294
5295 DO i=1,nalg ! reset global index array
5296 iext=globalindexusage(ioffc+i)
5297 backindexusage(ioffe+iext)=0
5298 END DO
5299
5300 END DO
5301 !$OMP END PARALLEL DO
5302
5303 IF (icalcm == 1) THEN
5304 ! flush remaining matrices
5305 DO k=1,mthrd ! update statistics
5307 used=real(writebufferinfo(2,k),mps)/real(writebufferheader(-1),mps)
5308 writebufferinfo(4,k)=writebufferinfo(4,k)+nint(1000.0*used,mpi)
5311 writebufferinfo(4,k)=0
5313 used=real(writebufferinfo(3,k),mps)/real(writebufferheader(1),mps)
5314 writebufferinfo(5,k)=writebufferinfo(5,k)+nint(1000.0*used,mpi)
5317 writebufferinfo(5,k)=0
5318 END DO
5319
5320 !$OMP PARALLEL &
5321 !$OMP DEFAULT(PRIVATE) &
5322 !$OMP SHARED(writeBufferHeader,writeBufferInfo,writeBufferIndices,writeBufferUpdates,MTHRD) &
5323 !$OMP SHARED(globalAllParToGroup,globalAllIndexGroups,nspc)
5324 iproc=0
5325 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5326 DO jproc=0,mthrd-1
5327 nb=writebufferinfo(1,jproc+1)
5328 ! print *, ' flush end ', JPROC, NRC, NB
5329 joffd=writebufferheader(-1)*jproc ! offset data
5330 joffi=writebufferheader(1)*jproc+3 ! offset indices
5331 DO ib=1,nb
5332 ! print *, ' buf end ', JPROC,IB,writeBufferIndices(JOFFI-2),writeBufferIndices(JOFFI)
5333 nalg=writebufferindices(joffi-1)
5334 il=1 ! row in update matrix
5335 DO in=1,writebufferindices(joffi)
5336 i=writebufferindices(joffi+in)
5337 !$ IF (MOD(I,MTHRD).EQ.IPROC) THEN
5338 j=writebufferindices(joffi+1) ! 1. group
5339 iprc=ijprec(i,j) ! group pair precision
5340 jl=1 ! col in update matrix
5341 ! start (rows) for continous groups
5342 j1=j
5343 jl1=jl
5344 ! other groups for row
5345 DO jn=2,in
5347 jnx=writebufferindices(joffi+jn) ! next group
5348 iprcnx=ijprec(i,jnx) ! group pair precision
5349 ! end of continous groups?
5350 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5351 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5352 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5353 ! restart continous groups
5354 j1=jnx ! new 1. column
5355 jl1=jl
5356 iprc=iprcnx
5357 END IF
5358 j=jnx ! last group
5359 END DO
5360 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5361 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5362 !$ END IF
5364 END DO
5365 joffd=joffd+(il*il-il)/2
5366 joffi=joffi+writebufferindices(joffi)+3
5367 END DO
5368 END DO
5369 !$OMP END PARALLEL
5370 END IF
5371
5372 IF(newite.AND.iterat == 2) THEN ! get worst records (for printrecord -1 -1)
5373 IF (nrecpr < 0) THEN
5374 DO k=1,mthrd
5375 IF (writebufferdata(1,k) > value1) THEN
5378 END IF
5379 END DO
5380 END IF
5381 IF (nrecp2 < 0) THEN
5382 DO k=1,mthrd
5383 IF (writebufferdata(2,k) > value2) THEN
5386 END IF
5387 END DO
5388 END IF
5389 END IF
5390
5391END SUBROUTINE loopbf
5392
5393!***********************************************************************
5394
5397SUBROUTINE prtrej(lun)
5398 USE mpmod
5399
5400 IMPLICIT NONE
5401 INTEGER(mpi), INTENT(IN) :: lun
5402
5403 IF (nrejec(1)>0) WRITE(lun,*) nrejec(1), ' (local solution contains NaNs)'
5404 IF (nrejec(2)>0) WRITE(lun,*) nrejec(2), ' (local matrix with rank deficit)'
5405 IF (nrejec(3)>0) WRITE(lun,*) nrejec(3), ' (local matrix with ill condition)'
5406 IF (nrejec(4)>0) WRITE(lun,*) nrejec(4), ' (local fit with Ndf=0)'
5407 IF (nrejec(5)>0) WRITE(lun,*) nrejec(5), ' (local fit with huge Chi2(Ndf))'
5408 IF (nrejec(6)>0) WRITE(lun,*) nrejec(6), ' (local fit with large Chi2(Ndf))'
5409
5410END SUBROUTINE prtrej
5411
5412!***********************************************************************
5413
5426SUBROUTINE prtglo
5427 USE mpmod
5428
5429 IMPLICIT NONE
5430 REAL(mps):: dpa
5431 REAL(mps):: err
5432 REAL(mps):: gcor
5433 INTEGER(mpi) :: i
5434 INTEGER(mpi) :: icom
5435 INTEGER(mpl) :: icount
5436 INTEGER(mpi) :: ie
5437 INTEGER(mpi) :: iev
5438 INTEGER(mpi) :: ij
5439 INTEGER(mpi) :: imin
5440 INTEGER(mpi) :: iprlim
5441 INTEGER(mpi) :: isub
5442 INTEGER(mpi) :: itgbi
5443 INTEGER(mpi) :: itgbl
5444 INTEGER(mpi) :: ivgbi
5445 INTEGER(mpi) :: j
5446 INTEGER(mpi) :: label
5447 INTEGER(mpi) :: lup
5448 REAL(mps):: par
5449 LOGICAL :: lowstat
5450
5451 REAL(mpd):: diag
5452 REAL(mpd)::gmati
5453 REAL(mpd)::gcor2
5454 INTEGER(mpi) :: labele(3)
5455 REAL(mps):: compnt(3)
5456 SAVE
5457 ! ...
5458
5459 lup=09
5460 CALL mvopen(lup,'millepede.res')
5461
5462 WRITE(*,*) ' '
5463 WRITE(*,*) ' Result of fit for global parameters'
5464 WRITE(*,*) ' ==================================='
5465 WRITE(*,*) ' '
5466
5467 WRITE(*,101)
5468
5469 WRITE(lup,*) 'Parameter ! first 3 elements per line are', &
5470 ' significant (if used as input)'
5471
5472
5473 iprlim=10
5474 DO itgbi=1,ntgb ! all parameter variables
5475 itgbl=globalparlabelindex(1,itgbi)
5476 ivgbi=globalparlabelindex(2,itgbi)
5477 icom=globalparcomments(itgbi) ! comment
5478 IF (icom > 0) WRITE(lup,113) listcomments(icom)%text
5479 par=real(globalparameter(itgbi),mps) ! initial value
5480 icount=0 ! counts
5481 lowstat = .false.
5482 IF(ivgbi > 0) THEN
5483 icount=globalcounter(ivgbi) ! used in last iteration
5484 lowstat = (icount < mreqena) ! too few accepted entries
5485 dpa=real(globalparameter(itgbi)-globalparstart(itgbi),mps) ! difference
5486 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5487 gmati=globalmatd(globalrowoffsets(ivgbi)+ivgbi)
5488 err=sqrt(abs(real(gmati,mps)))
5489 IF(gmati < 0.0_mpd) err=-err
5490 diag=workspacediag(ivgbi)
5491 gcor=-1.0
5492 IF(gmati*diag > 0.0_mpd) THEN ! global correlation
5493 gcor2=1.0_mpd-1.0_mpd/(gmati*diag)
5494 IF(gcor2 >= 0.0_mpd.AND.gcor2 <= 1.0_mpd) gcor=real(sqrt(gcor2),mps)
5495 END IF
5496 END IF
5497 END IF
5498 IF(ipcntr > 1) icount=globalparlabelcounter(itgbi) ! from binary files
5499 IF(lowstat) icount=-(icount+1) ! flag 'lowstat' with icount < 0
5500 IF(ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5501 IF(itgbi <= iprlim) THEN
5502 IF(ivgbi <= 0) THEN
5503 WRITE(* ,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5504 ELSE
5505 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5506 IF (igcorr == 0) THEN
5507 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5508 ELSE
5509 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5510 END IF
5511 ELSE
5512 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5513 END IF
5514 END IF
5515 ELSE IF(itgbi == iprlim+1) THEN
5516 WRITE(* ,*) '... (further printout suppressed, but see log file)'
5517 END IF
5518
5519 ! file output
5520 IF(ivgbi <= 0) THEN
5521 IF (ipcntr /= 0) THEN
5522 WRITE(lup,110) itgbl,par,real(globalparpresigma(itgbi),mps),icount
5523 ELSE
5524 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5525 END IF
5526 ELSE
5527 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5528 IF (ipcntr /= 0) THEN
5529 WRITE(lup,112) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,icount
5530 ELSE IF (igcorr /= 0) THEN
5531 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5532 ELSE
5533 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5534 END IF
5535 ELSE
5536 IF (ipcntr /= 0) THEN
5537 WRITE(lup,111) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,icount
5538 ELSE
5539 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5540 END IF
5541 END IF
5542 END IF
5543 END DO
5544 rewind lup
5545 CLOSE(unit=lup)
5546
5547 IF(metsol == 2) THEN ! diagonalisation: write eigenvectors
5548 CALL mvopen(lup,'millepede.eve')
5549 imin=1
5550 DO i=nagb,1,-1
5551 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
5552 imin=i ! index of smallest pos. eigenvalue
5553 EXIT
5554 ENDIF
5555 END DO
5556 iev=0
5557
5558 DO isub=0,min(15,imin-1)
5559 IF(isub < 10) THEN
5560 i=imin-isub
5561 ELSE
5562 i=isub-9
5563 END IF
5564
5565 ! DO I=IMIN,MAX(1,IMIN-9),-1 ! backward loop, up to 10 vectors
5566 WRITE(*,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5567 WRITE(lup,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5568 DO j=1,nagb
5569 ij=j+(i-1)*nagb ! index with eigenvector array
5570 IF(j <= nvgb) THEN
5571 itgbi=globalparvartototal(j)
5572 label=globalparlabelindex(1,itgbi)
5573 ELSE
5574 label=nvgb-j ! label negative for constraints
5575 END IF
5576 iev=iev+1
5577 labele(iev)=label
5578 compnt(iev)=real(workspaceeigenvectors(ij),mps) ! component
5579 IF(iev == 3) THEN
5580 WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5581 iev=0
5582 END IF
5583 END DO
5584 IF(iev /= 0) WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5585 iev=0
5586 WRITE(lup,*) ' '
5587 END DO
5588 CLOSE(unit=lup)
5589
5590 END IF
5591
5592101 FORMAT(1x,' label parameter presigma differ', &
5593 ' error'/ 1x,'-----------',4x,4('-------------'))
5594102 FORMAT(i10,2x,4g14.5,f8.3)
5595103 FORMAT(3(i11,f11.7,2x))
5596110 FORMAT(i10,2x,2g14.5,28x,i12)
5597111 FORMAT(i10,2x,3g14.5,14x,i12)
5598112 FORMAT(i10,2x,4g14.5,i12)
5599113 FORMAT('!',a)
5600END SUBROUTINE prtglo ! print final log file
5601
5602!***********************************************************************
5603
5613SUBROUTINE prtstat
5614 USE mpmod
5615 USE mpdalc
5616
5617 IMPLICIT NONE
5618 REAL(mps):: par
5619 REAL(mps):: presig
5620 INTEGER(mpi) :: icom
5621 INTEGER(mpl) :: icount
5622 INTEGER(mpi) :: ifrst
5623 INTEGER(mpi) :: ilast
5624 INTEGER(mpi) :: inext
5625 INTEGER(mpi) :: itgbi
5626 INTEGER(mpi) :: itgbl
5627 INTEGER(mpi) :: itpgrp
5628 INTEGER(mpi) :: ivgbi
5629 INTEGER(mpi) :: lup
5630 INTEGER(mpi) :: icgrp
5631 INTEGER(mpi) :: ipgrp
5632 INTEGER(mpi) :: j
5633 INTEGER(mpi) :: jpgrp
5634 INTEGER(mpi) :: k
5635 INTEGER(mpi) :: label1
5636 INTEGER(mpi) :: label2
5637 INTEGER(mpi) :: ncon
5638 INTEGER(mpi) :: npair
5639 INTEGER(mpi) :: nstep
5640 CHARACTER :: c1
5641
5642 INTEGER(mpl):: length
5643
5644 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
5645
5646 INTERFACE ! needed for assumed-shape dummy arguments
5647 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
5648 USE mpdef
5649 INTEGER(mpi), INTENT(IN) :: ipgrp
5650 INTEGER(mpi), INTENT(OUT) :: npair
5651 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
5652 END SUBROUTINE ggbmap
5653 END INTERFACE
5654
5655 SAVE
5656 ! ...
5657
5658 lup=09
5659 CALL mvopen(lup,'millepede.res')
5660 WRITE(lup,*) '*** Results of checking input only, no solution performed ***'
5661 WRITE(lup,*) '! === global parameters ==='
5662 WRITE(lup,*) '! fixed-1: by pre-sigma, -2: by entries cut, -3: by iterated entries cut'
5663 IF (ipcntr < 0) THEN
5664 WRITE(lup,*) '! Label Value Pre-sigma SkippedEntries Cons. group Status '
5665 ELSE
5666 WRITE(lup,*) '! Label Value Pre-sigma Entries Cons. group Status '
5667 END IF
5668 !iprlim=10
5669 DO itgbi=1,ntgb ! all parameter variables
5670 itgbl=globalparlabelindex(1,itgbi)
5671 ivgbi=globalparlabelindex(2,itgbi)
5672 icom=globalparcomments(itgbi) ! comment
5673 IF (icom > 0) WRITE(lup,117) listcomments(icom)%text
5674 c1=' '
5675 IF (globalparlabelindex(3,itgbi) == itgbl) c1='>'
5676 par=real(globalparameter(itgbi),mps) ! initial value
5677 presig=real(globalparpresigma(itgbi),mps) ! initial presigma
5678 icount=globalparlabelcounter(itgbi) ! from binary files
5679 IF (ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5680 icgrp=globalparcons(itgbi) ! constraints group
5681
5682 IF (ivgbi <= 0) THEN
5683 ! not used
5684 IF (ivgbi == -4) THEN
5685 WRITE(lup,116) c1,itgbl,par,presig,icount,icgrp
5686 ELSE
5687 WRITE(lup,110) c1,itgbl,par,presig,icount,icgrp,ivgbi
5688 END IF
5689 ELSE
5690 ! variable
5691 WRITE(lup,111) c1,itgbl,par,presig,icount,icgrp
5692 END IF
5693 END DO
5694 ! appearance statistics
5695 IF (icheck > 1) THEN
5696 WRITE(lup,*) '!.'
5697 WRITE(lup,*) '!.Appearance statistics '
5698 WRITE(lup,*) '!. Label First file and record Last file and record #files #paired-par'
5699 DO itgbi=1,ntgb
5700 itpgrp=globalparlabelindex(4,itgbi)
5701 IF (itpgrp > 0) THEN
5702 WRITE(lup,112) globalparlabelindex(1,itgbi), (appearancecounter(itgbi*5+k), k=-4,0), paircounter(itpgrp)
5703 ELSE ! 'empty' parameter
5704 WRITE(lup,112) globalparlabelindex(1,itgbi)
5705 END IF
5706 END DO
5707 END IF
5708 IF (ncgrp > 0) THEN
5709 WRITE(lup,*) '* === constraint groups ==='
5710 IF (icheck == 1) THEN
5711 WRITE(lup,*) '* Group #Cons. Entries First label Last label'
5712 ELSE
5713 WRITE(lup,*) '* Group #Cons. Entries First label Last label Paired label range'
5714 length=ntpgrp+ncgrp
5715 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
5716 END IF
5717 DO icgrp=1, ncgrp
5718 IF (matconsgroups(2,icgrp) <= matconsgroups(3,icgrp)) THEN
5719 label1=globalparlabelindex(1,globalparvartototal(matconsgroups(2,icgrp))) ! first label
5720 label2=globalparlabelindex(1,globalparvartototal(matconsgroups(3,icgrp))) ! last label
5721 ELSE ! empty group/cons.
5722 label1=0
5723 label2=0
5724 END IF
5725 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
5726 WRITE(lup,113) icgrp, ncon,vecconsgroupcounts(icgrp),label1,label2
5727 IF (icheck > 1 .AND. label1 > 0) THEN
5728 ipgrp=globalparlabelindex(4,globalparvartototal(matconsgroups(2,icgrp))) ! first par. group
5729 ! get paired parameter groups
5730 CALL ggbmap(ntpgrp+icgrp,npair,vecpairedpargroups)
5731 vecpairedpargroups(npair+1)=0
5732 ifrst=0
5733 nstep=1
5734 DO j=1, npair
5735 jpgrp=vecpairedpargroups(j)
5736 inext=globaltotindexgroups(1,jpgrp)
5737 DO k=1,globaltotindexgroups(2,jpgrp)
5738 ! end of continous region ?
5739 IF (ifrst /= 0.AND.inext /= (ilast+nstep)) THEN
5740 label1=globalparlabelindex(1,ifrst)
5741 label2=globalparlabelindex(1,ilast)
5742 WRITE(lup,114) label1, label2
5743 ifrst=0
5744 END IF
5745 ! skip 'self-correlations'
5746 IF (globalparcons(inext) /= icgrp) THEN
5747 IF (ifrst == 0) ifrst=inext
5748 ilast=inext
5749 END IF
5750 inext=inext+1
5751 nstep=1
5752 END DO
5753 ! skip 'empty' parameter
5754 IF (jpgrp == vecpairedpargroups(j+1)-1) THEN
5755 nstep=globaltotindexgroups(1,vecpairedpargroups(j+1)) &
5756 -(globaltotindexgroups(1,jpgrp)+globaltotindexgroups(2,jpgrp)-1)
5757 END IF
5758 END DO
5759 IF (ifrst /= 0) THEN
5760 label1=globalparlabelindex(1,ifrst)
5761 label2=globalparlabelindex(1,ilast)
5762 WRITE(lup,114) label1, label2
5763 END IF
5764 END IF
5765 END DO
5766 IF (icheck > 1) THEN
5767 WRITE(lup,*) '*.'
5768 WRITE(lup,*) '*.Appearance statistics '
5769 WRITE(lup,*) '*. Group First file and record Last file and record #files'
5770 DO icgrp=1, ncgrp
5771 WRITE(lup,115) icgrp, (appearancecounter((ntgb+icgrp)*5+k), k=-4,0)
5772 END DO
5773 END IF
5774 END IF
5775
5776 rewind lup
5777 CLOSE(unit=lup)
5778
5779110 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' fixed',i2)
5780111 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' variable')
5781112 FORMAT(' !.',i10,6i11)
5782113 FORMAT(' * ',i6,i8,3i12)
5783114 FORMAT(' *:',48x,i12,' ..',i12)
5784115 FORMAT(' *.',i10,5i11)
5785116 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' redundant')
5786117 FORMAT(' !!',a)
5787END SUBROUTINE prtstat ! print input statistics
5788
5789
5803
5804SUBROUTINE avprds(n,l,x,is,ie,b)
5805 USE mpmod
5806
5807 IMPLICIT NONE
5808 INTEGER(mpi) :: i
5809 INTEGER(mpi) :: ia
5810 INTEGER(mpi) :: ia2
5811 INTEGER(mpi) :: ib
5812 INTEGER(mpi) :: ib2
5813 INTEGER(mpi) :: in
5814 INTEGER(mpi) :: ipg
5815 INTEGER(mpi) :: iproc
5816 INTEGER(mpi) :: ir
5817 INTEGER(mpi) :: j
5818 INTEGER(mpi) :: ja
5819 INTEGER(mpi) :: ja2
5820 INTEGER(mpi) :: jb
5821 INTEGER(mpi) :: jb2
5822 INTEGER(mpi) :: jn
5823 INTEGER(mpi) :: lj
5824
5825 INTEGER(mpi), INTENT(IN) :: n
5826 INTEGER(mpl), INTENT(IN) :: l
5827 REAL(mpd), INTENT(IN) :: x(n)
5828 INTEGER(mpi), INTENT(IN) :: is
5829 INTEGER(mpi), INTENT(IN) :: ie
5830 REAL(mpd), INTENT(OUT) :: b(n)
5831 INTEGER(mpl) :: k
5832 INTEGER(mpl) :: kk
5833 INTEGER(mpl) :: ku
5834 INTEGER(mpl) :: ll
5835 INTEGER(mpl) :: indij
5836 INTEGER(mpl) :: indid
5837 INTEGER(mpl) :: ij
5838 INTEGER(mpi) :: ichunk
5839 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5840 SAVE
5841 ! ...
5842
5843 ichunk=min((n+mthrd-1)/mthrd/8+1,128)
5844 IF(matsto /= 2) THEN
5845 ! full or unpacked (block diagonal) symmetric matrix
5846 ! parallelize row loop
5847 ! private copy of B(N) for each thread, combined at end, init with 0.
5848 ! slot of 128 'I' for next idle thread
5849 !$OMP PARALLEL DO &
5850 !$OMP PRIVATE(J,IJ) &
5851 !$OMP SCHEDULE(DYNAMIC,ichunk)
5852 DO i=1,n
5853 ij=globalrowoffsets(i+l)+l
5854 DO j=is,min(i,ie)
5855 b(i)=b(i)+globalmatd(ij+j)*x(j)
5856 END DO
5857 END DO
5858 !$OMP END PARALLEL DO
5859
5860 !$OMP PARALLEL DO &
5861 !$OMP PRIVATE(J,IJ) &
5862 !$OMP REDUCTION(+:B) &
5863 !$OMP SCHEDULE(DYNAMIC,ichunk)
5864 DO i=is,ie
5865 ij=globalrowoffsets(i+l)+l
5866 DO j=1,i-1
5867 b(j)=b(j)+globalmatd(ij+j)*x(i)
5868 END DO
5869 END DO
5870 !$OMP END PARALLEL DO
5871 ELSE
5872 ! sparse, compressed matrix
5873 IF(sparsematrixoffsets(2,1) /= n) THEN
5874 CALL peend(24,'Aborted, vector/matrix size mismatch')
5875 stop 'AVPRDS: mismatched vector and matrix'
5876 END IF
5877 ! parallelize row (group) loop
5878 ! slot of 1024 'I' for next idle thread
5879 !$OMP PARALLEL DO &
5880 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
5881 !$OMP PRIVATE(IA,IB,IN,JA,JB,IA2,IB2,JA2,JB2) &
5882 !$OMP REDUCTION(+:B) &
5883 !$OMP SCHEDULE(DYNAMIC,ichunk)
5884 DO ipg=1,napgrp
5885 iproc=0
5886 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5887 ! row group
5888 ia=globalallindexgroups(ipg) ! first (global) row
5889 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
5890 in=ib-ia+1 ! number of rows
5891 ! overlap
5892 ia2=max(ia,is)
5893 ib2=min(ib,ie)
5894 ! diagonal elements
5895 IF (ia2 <= ib2) b(ia2:ib2)=b(ia2:ib2)+globalmatd(ia2:ib2)*x(ia2:ib2)
5896 ! off-diagonals double precision
5897 ir=ipg
5898 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5899 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5900 ku=sparsematrixoffsets(1,ir+1)-kk
5901 indid=kk
5902 indij=ll
5903 IF (ku > 0) THEN
5904 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5905 DO i=ia,ib
5906 IF (i <= ie.AND.i >= is) THEN
5907 DO k=1,ku
5908 j=sparsematrixcolumns(indid+k)
5909 b(j)=b(j)+globalmatd(indij+k)*x(i)
5910 END DO
5911 END IF
5912 DO k=1,ku
5913 j=sparsematrixcolumns(indid+k)
5914 IF (j <= ie.AND.j >= is) THEN
5915 b(i)=b(i)+globalmatd(indij+k)*x(j)
5916 END IF
5917 END DO
5918 indij=indij+ku
5919 END DO
5920 ELSE
5921 ! regions of continous column groups
5922 DO k=2,ku-2,2
5923 j=sparsematrixcolumns(indid+k) ! first group
5924 ja=globalallindexgroups(j) ! first (global) column
5925 lj=sparsematrixcolumns(indid+k-1) ! region offset
5926 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5927 jb=ja+jn-1 ! last (global) column
5928 ja2=max(ja,is)
5929 jb2=min(jb,ie)
5930 IF (ja2 <= jb2) THEN
5931 lj=1 ! index (in group region)
5932 DO i=ia,ib
5933 b(i)=b(i)+dot_product(globalmatd(indij+lj+ja2-ja:indij+lj+jb2-ja),x(ja2:jb2))
5934 lj=lj+jn
5935 END DO
5936 END IF
5937 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5938 lj=1
5939 DO j=ja,jb
5940 b(j)=b(j)+dot_product(globalmatd(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),x(ia2:ib2))
5941 lj=lj+1
5942 END DO
5943 END IF
5944 indij=indij+in*jn
5945 END DO
5946 END IF
5947 END IF
5948 ! mixed precision
5949 IF (nspc > 1) THEN
5950 ir=ipg+napgrp+1 ! off-diagonals single precision
5951 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5952 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5953 ku=sparsematrixoffsets(1,ir+1)-kk
5954 indid=kk
5955 indij=ll
5956 IF (ku == 0) cycle
5957 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5958 DO i=ia,ib
5959 IF (i <= ie.AND.i >= is) THEN
5960 DO k=1,ku
5961 j=sparsematrixcolumns(indid+k)
5962 b(j)=b(j)+globalmatf(indij+k)*x(i)
5963 END DO
5964 END IF
5965 DO k=1,ku
5966 j=sparsematrixcolumns(indid+k)
5967 IF (j <= ie.AND.j >= is) THEN
5968 b(i)=b(i)+globalmatf(indij+k)*x(j)
5969 END IF
5970 END DO
5971 indij=indij+ku
5972 END DO
5973 ELSE
5974 ! regions of continous column groups
5975 DO k=2,ku-2,2
5976 j=sparsematrixcolumns(indid+k) ! first group
5977 ja=globalallindexgroups(j) ! first (global) column
5978 lj=sparsematrixcolumns(indid+k-1) ! region offset
5979 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5980 jb=ja+jn-1 ! last (global) column
5981 ja2=max(ja,is)
5982 jb2=min(jb,ie)
5983 IF (ja2 <= jb2) THEN
5984 lj=1 ! index (in group region)
5985 DO i=ia,ib
5986 b(i)=b(i)+dot_product(real(globalmatf(indij+lj+ja2-ja:indij+lj+jb2-ja),mpd),x(ja2:jb2))
5987 lj=lj+jn
5988 END DO
5989 END IF
5990 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5991 lj=1
5992 DO j=ja,jb
5993 b(j)=b(j)+dot_product(real(globalmatf(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),mpd),x(ia2:ib2))
5994 lj=lj+1
5995 END DO
5996 END IF
5997 indij=indij+in*jn
5998 END DO
5999 END IF
6000 END IF
6001 END DO
6002 ENDIF
6003
6004END SUBROUTINE avprds
6005
6017
6018SUBROUTINE avprd0(n,l,x,b)
6019 USE mpmod
6020
6021 IMPLICIT NONE
6022 INTEGER(mpi) :: i
6023 INTEGER(mpi) :: ia
6024 INTEGER(mpi) :: ib
6025 INTEGER(mpi) :: in
6026 INTEGER(mpi) :: ipg
6027 INTEGER(mpi) :: iproc
6028 INTEGER(mpi) :: ir
6029 INTEGER(mpi) :: j
6030 INTEGER(mpi) :: ja
6031 INTEGER(mpi) :: jb
6032 INTEGER(mpi) :: jn
6033 INTEGER(mpi) :: lj
6034
6035 INTEGER(mpi), INTENT(IN) :: n
6036 INTEGER(mpl), INTENT(IN) :: l
6037 REAL(mpd), INTENT(IN) :: x(n)
6038 REAL(mpd), INTENT(OUT) :: b(n)
6039 INTEGER(mpl) :: k
6040 INTEGER(mpl) :: kk
6041 INTEGER(mpl) :: ku
6042 INTEGER(mpl) :: ll
6043 INTEGER(mpl) :: indij
6044 INTEGER(mpl) :: indid
6045 INTEGER(mpl) :: ij
6046 INTEGER(mpi) :: ichunk
6047 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
6048 SAVE
6049 ! ...
6050 !$ DO i=1,n
6051 !$ b(i)=0.0_mpd ! reset 'global' B()
6052 !$ END DO
6053 ichunk=min((n+mthrd-1)/mthrd/8+1,1024)
6054 IF(matsto /= 2) THEN
6055 ! full or unpacked (block diagonal) symmetric matrix
6056 ! parallelize row loop
6057 ! private copy of B(N) for each thread, combined at end, init with 0.
6058 ! slot of 1024 'I' for next idle thread
6059 !$OMP PARALLEL DO &
6060 !$OMP PRIVATE(J,IJ) &
6061 !$OMP REDUCTION(+:B) &
6062 !$OMP SCHEDULE(DYNAMIC,ichunk)
6063 DO i=1,n
6064 ij=globalrowoffsets(i+l)+l
6065 b(i)=globalmatd(ij+i)*x(i)
6066 DO j=1,i-1
6067 b(j)=b(j)+globalmatd(ij+j)*x(i)
6068 b(i)=b(i)+globalmatd(ij+j)*x(j)
6069 END DO
6070 END DO
6071 !$OMP END PARALLEL DO
6072 ELSE
6073 ! sparse, compressed matrix
6074 IF(sparsematrixoffsets(2,1) /= n) THEN
6075 CALL peend(24,'Aborted, vector/matrix size mismatch')
6076 stop 'AVPRD0: mismatched vector and matrix'
6077 END IF
6078 ! parallelize row (group) loop
6079 ! slot of 1024 'I' for next idle thread
6080 !$OMP PARALLEL DO &
6081 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
6082 !$OMP PRIVATE(IA,IB,IN,JA,JB) &
6083 !$OMP REDUCTION(+:B) &
6084 !$OMP SCHEDULE(DYNAMIC,ichunk)
6085 DO ipg=1,napgrp
6086 iproc=0
6087 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
6088 ! row group
6089 ia=globalallindexgroups(ipg) ! first (global) row
6090 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6091 in=ib-ia+1 ! number of rows
6092 !
6093 ! diagonal elements
6094 b(ia:ib)=globalmatd(ia:ib)*x(ia:ib)
6095 ! off-diagonals double precision
6096 ir=ipg
6097 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6098 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6099 ku=sparsematrixoffsets(1,ir+1)-kk
6100 indid=kk
6101 indij=ll
6102 IF (ku > 0) THEN
6103 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6104 DO i=ia,ib
6105 DO k=1,ku
6106 j=sparsematrixcolumns(indid+k)
6107 b(j)=b(j)+globalmatd(indij+k)*x(i)
6108 b(i)=b(i)+globalmatd(indij+k)*x(j)
6109 END DO
6110 indij=indij+ku
6111 END DO
6112 ELSE
6113 ! regions of continous column groups
6114 DO k=2,ku-2,2
6115 j=sparsematrixcolumns(indid+k) ! first group
6116 ja=globalallindexgroups(j) ! first (global) column
6117 lj=sparsematrixcolumns(indid+k-1) ! region offset
6118 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6119 jb=ja+jn-1 ! last (global) column
6120 lj=1 ! index (in group region)
6121 DO i=ia,ib
6122 b(i)=b(i)+dot_product(globalmatd(indij+lj:indij+lj+jn-1),x(ja:jb))
6123 lj=lj+jn
6124 END DO
6125 IF (mextnd == 0) THEN
6126 lj=1
6127 DO j=ja,jb
6128 b(j)=b(j)+dot_product(globalmatd(indij+lj:indij+jn*in:jn),x(ia:ib))
6129 lj=lj+1
6130 END DO
6131 END IF
6132 indij=indij+in*jn
6133 END DO
6134 END IF
6135 END IF
6136 ! mixed precision
6137 IF (nspc > 1) THEN
6138 ir=ipg+napgrp+1 ! off-diagonals single precision
6139 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6140 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6141 ku=sparsematrixoffsets(1,ir+1)-kk
6142 indid=kk
6143 indij=ll
6144 IF (ku == 0) cycle
6145 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6146 DO i=ia,ib
6147 DO k=1,ku
6148 j=sparsematrixcolumns(indid+k)
6149 b(j)=b(j)+real(globalmatf(indij+k),mpd)*x(i)
6150 b(i)=b(i)+real(globalmatf(indij+k),mpd)*x(j)
6151 END DO
6152 indij=indij+ku
6153 END DO
6154 ELSE
6155 ! regions of continous column groups
6156 DO k=2,ku-2,2
6157 j=sparsematrixcolumns(indid+k) ! first group
6158 ja=globalallindexgroups(j) ! first (global) column
6159 lj=sparsematrixcolumns(indid+k-1) ! region offset
6160 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6161 jb=ja+jn-1 ! last (global) column
6162 lj=1 ! index (in group region)
6163 DO i=ia,ib
6164 b(i)=b(i)+dot_product(real(globalmatf(indij+lj:indij+lj+jn-1),mpd),x(ja:jb))
6165 lj=lj+jn
6166 END DO
6167 IF (mextnd == 0) THEN
6168 lj=1
6169 DO j=ja,jb
6170 b(j)=b(j)+dot_product(real(globalmatf(indij+lj:indij+jn*in:jn),mpd),x(ia:ib))
6171 lj=lj+1
6172 END DO
6173 END IF
6174 indij=indij+in*jn
6175 END DO
6176 END IF
6177 END IF
6178 END DO
6179 ENDIF
6180
6181END SUBROUTINE avprd0
6182
6183
6186SUBROUTINE anasps
6187 USE mpmod
6188
6189 IMPLICIT NONE
6190 INTEGER(mpi) :: ia
6191 INTEGER(mpi) :: ib
6192 INTEGER(mpi) :: ipg
6193 INTEGER(mpi) :: ir
6194 INTEGER(mpi) :: ispc
6195 INTEGER(mpi) :: lj
6196 REAL(mps) :: avg
6197
6198
6199 INTEGER(mpl) :: in
6200 INTEGER(mpl) :: jn
6201 INTEGER(mpl) :: k
6202 INTEGER(mpl) :: kk
6203 INTEGER(mpl) :: ku
6204 INTEGER(mpl) :: ll
6205 INTEGER(mpl) :: indid
6206 INTEGER(mpl), DIMENSION(12) :: icount
6207 SAVE
6208
6209 ! require sparse storage
6210 IF(matsto /= 2) RETURN
6211 ! reset
6212 icount=0
6213 icount(4)=huge(icount(4))
6214 icount(7)=huge(icount(7))
6215 icount(10)=huge(icount(10))
6216 ! loop over precisions
6217 DO ispc=1,nspc
6218 ! loop over row groups
6219 DO ipg=1,napgrp
6220 ! row group
6221 ia=globalallindexgroups(ipg) ! first (global) row
6222 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6223 in=ib-ia+1 ! number of rows
6224
6225 ir=ipg+(ispc-1)*(napgrp+1)
6226 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6227 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6228 ku=sparsematrixoffsets(1,ir+1)-kk
6229 indid=kk
6230 IF (ku == 0) cycle
6231 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6232 icount(1)=icount(1)+in
6233 icount(2)=icount(2)+in*ku
6234 ELSE
6235 ! regions of continous column groups
6236 DO k=2,ku-2,2
6237 lj=sparsematrixcolumns(indid+k-1) ! region offset
6238 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6239 icount(3)=icount(3)+1 ! block (region) counter
6240 icount(4)=min(icount(4),jn) ! min number of columns per block (region)
6241 icount(5)=icount(5)+jn ! sum number of columns per block (region)
6242 icount(6)=max(icount(6),jn) ! max number of columns per block (region)
6243 icount(7)=min(icount(7),in) ! min number of rows per block (region)
6244 icount(8)=icount(8)+in ! sum number of rows per block (region)
6245 icount(9)=max(icount(9),in) ! max number of rows per block (region)
6246 icount(10)=min(icount(10),in*jn) ! min number of elements per block (region)
6247 icount(11)=icount(11)+in*jn ! sum number of elements per block (region)
6248 icount(12)=max(icount(12),in*jn) ! max number of elements per block (region)
6249 END DO
6250 END IF
6251 END DO
6252 END DO
6253
6254 WRITE(*,*) "analysis of sparsity structure"
6255 IF (icount(1) > 0) THEN
6256 WRITE(*,101) "rows without compression/blocks ", icount(1)
6257 WRITE(*,101) " contained elements ", icount(2)
6258 ENDIF
6259 WRITE(*,101) "number of block matrices ", icount(3)
6260 avg=real(icount(5),mps)/real(icount(3),mps)
6261 WRITE(*,101) "number of columns (min,mean,max) ", icount(4), avg, icount(6)
6262 avg=real(icount(8),mps)/real(icount(3),mps)
6263 WRITE(*,101) "number of rows (min,mean,max) ", icount(7), avg, icount(9)
6264 avg=real(icount(11),mps)/real(icount(3),mps)
6265 WRITE(*,101) "number of elements (min,mean,max) ", icount(10), avg, icount(12)
6266101 FORMAT(2x,a34,i10,f10.3,i10)
6267
6268END SUBROUTINE anasps
6269
6279
6280SUBROUTINE avprod(n,x,b)
6281 USE mpmod
6282
6283 IMPLICIT NONE
6284
6285 INTEGER(mpi), INTENT(IN) :: n
6286 REAL(mpd), INTENT(IN) :: x(n)
6287 REAL(mpd), INTENT(OUT) :: b(n)
6288
6289 SAVE
6290 ! ...
6291 IF(n > nagb) THEN
6292 CALL peend(24,'Aborted, vector/matrix size mismatch')
6293 stop 'AVPROD: mismatched vector and matrix'
6294 END IF
6295 ! input to AVPRD0
6296 vecxav(1:n)=x
6297 vecxav(n+1:nagb)=0.0_mpd
6298 !use elimination for constraints ?
6299 IF(n < nagb) CALL qlmlq(vecxav,1,.false.) ! Q*x
6300 ! calclulate vecBav=globalMat*vecXav
6301 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
6302 !use elimination for constraints ?
6303 IF(n < nagb) CALL qlmlq(vecbav,1,.true.) ! Q^t*x
6304 ! output from AVPRD0
6305 b=vecbav(1:n)
6306
6307END SUBROUTINE avprod
6308
6309
6319
6320SUBROUTINE ijpgrp(itema,itemb,ij,lr,iprc)
6321 USE mpmod
6322
6323 IMPLICIT NONE
6324 INTEGER(mpi) :: ispc
6325 INTEGER(mpi) :: item1
6326 INTEGER(mpi) :: item2
6327 INTEGER(mpi) :: itemc
6328 INTEGER(mpi) :: jtem
6329 INTEGER(mpi) :: jtemn
6330 INTEGER(mpi) :: np
6331
6332 INTEGER(mpi), INTENT(IN) :: itema
6333 INTEGER(mpi), INTENT(IN) :: itemb
6334 INTEGER(mpl), INTENT(OUT) :: ij
6335 INTEGER(mpi), INTENT(OUT) :: lr
6336 INTEGER(mpi), INTENT(OUT) :: iprc
6337
6338 INTEGER(mpl) :: k
6339 INTEGER(mpl) :: kk
6340 INTEGER(mpl) :: kl
6341 INTEGER(mpl) :: ku
6342 INTEGER(mpl) :: ll
6343 ! ...
6344 ij=0
6345 lr=0
6346 iprc=0
6347 item1=max(itema,itemb) ! larger index
6348 item2=min(itema,itemb) ! smaller index
6349 IF(item2 <= 0.OR.item1 > napgrp) RETURN
6350 np=globalallindexgroups(item1+1)-globalallindexgroups(item1) ! size of group item1
6351 ! loop over precisions
6352 outer: DO ispc=1,nspc
6353 kk=sparsematrixoffsets(1,item1) ! offset (column lists)
6354 ll=sparsematrixoffsets(2,item1) ! offset (matrix)
6355 kl=1
6356 ku=sparsematrixoffsets(1,item1+1)-kk
6357 item1=item1+napgrp+1
6358 iprc=ispc
6359 IF (sparsematrixcolumns(kk+1) == 0) THEN ! compression ?
6360 ! compressed (list of continous regions of parameter groups (pairs of offset and 1. group index)
6361 kl=2
6362 ku=ku-2
6363 IF(ku < kl) cycle outer ! not found
6364 DO
6365 k=2*((kl+ku)/4) ! binary search
6366 jtem=sparsematrixcolumns(kk+k) ! first column (group) of region
6367 jtemn=sparsematrixcolumns(kk+k+2) ! first column (group) after region
6368 IF(item2 >= jtem.AND.item2 < jtemn) THEN
6369 ! length of region
6370 lr=sparsematrixcolumns(kk+k+1)-sparsematrixcolumns(kk+k-1)
6371 IF (globalallindexgroups(item2)-globalallindexgroups(jtem) >= lr) cycle outer ! outside region
6372 EXIT ! found
6373 END IF
6374 IF(item2 < jtem) THEN
6375 ku=k-2
6376 ELSE IF(item2 >= jtemn) THEN
6377 kl=k+2
6378 END IF
6379 IF(kl <= ku) cycle
6380 cycle outer ! not found
6381 END DO
6382 ! group offset in row
6383 ij=sparsematrixcolumns(kk+k-1)
6384 ! absolute offset
6385 ij=ll+ij*np+globalallindexgroups(item2)-globalallindexgroups(jtem)+1
6386
6387 ELSE
6388 ! simple column list
6389 itemc=globalallindexgroups(item2) ! first (col) index of group
6390 lr=int(ku,mpi) ! number of columns
6391 IF(ku < kl) cycle outer ! not found
6392 DO
6393 k=(kl+ku)/2 ! binary search
6394 jtem=sparsematrixcolumns(kk+k)
6395 IF(itemc == jtem) EXIT ! found
6396 IF(itemc < jtem) THEN
6397 ku=k-1
6398 ELSE IF(itemc > jtem) THEN
6399 kl=k+1
6400 END IF
6401 IF(kl <= ku) cycle
6402 cycle outer ! not found
6403 END DO
6404 ij=ll+k
6405
6406 END IF
6407 RETURN
6408 END DO outer
6409
6410END SUBROUTINE ijpgrp
6411
6417
6418FUNCTION ijprec(itema,itemb)
6419 USE mpmod
6420
6421 IMPLICIT NONE
6422
6423 INTEGER(mpi) :: lr
6424 INTEGER(mpl) :: ij
6425
6426 INTEGER(mpi), INTENT(IN) :: itema
6427 INTEGER(mpi), INTENT(IN) :: itemb
6428 INTEGER(mpi) :: ijprec
6429
6430 ! ...
6431 ijprec=1
6432 IF (matsto == 2.AND.nspc > 1) THEN ! sparse storage with mixed precision
6433 ! check groups
6434 CALL ijpgrp(itema,itemb,ij,lr,ijprec)
6435 END IF
6436
6437END FUNCTION ijprec
6438
6446
6447FUNCTION ijadd(itema,itemb) ! index using "d" and "z"
6448 USE mpmod
6449
6450 IMPLICIT NONE
6451
6452 INTEGER(mpi) :: item1
6453 INTEGER(mpi) :: item2
6454 INTEGER(mpi) :: ipg1
6455 INTEGER(mpi) :: ipg2
6456 INTEGER(mpi) :: lr
6457 INTEGER(mpi) :: iprc
6458
6459 INTEGER(mpi), INTENT(IN) :: itema
6460 INTEGER(mpi), INTENT(IN) :: itemb
6461
6462 INTEGER(mpl) :: ijadd
6463 INTEGER(mpl) :: ij
6464 ! ...
6465 ijadd=0
6466 item1=max(itema,itemb) ! larger index
6467 item2=min(itema,itemb) ! smaller index
6468 !print *, ' ijadd ', item1, item2
6469 IF(item2 <= 0.OR.item1 > nagb) RETURN
6470 IF(item1 == item2) THEN ! diagonal element
6471 ijadd=item1
6472 RETURN
6473 END IF
6474 ! ! off-diagonal element
6475 ! get parameter groups
6476 ipg1=globalallpartogroup(item1)
6477 ipg2=globalallpartogroup(item2)
6478 ! get offset for groups
6479 CALL ijpgrp(ipg1,ipg2,ij,lr,iprc)
6480 IF (ij == 0) RETURN
6481 ! add offset inside groups
6482 ijadd=ij+(item2-globalallindexgroups(ipg2))+(item1-globalallindexgroups(ipg1))*lr
6483 ! reduced precision?
6484 IF (iprc > 1) ijadd=-ijadd
6485
6486END FUNCTION ijadd
6487
6495
6496FUNCTION ijcsr3(itema,itemb) ! index using "d" and "z"
6497 USE mpmod
6498
6499 IMPLICIT NONE
6500
6501 INTEGER(mpi) :: item1
6502 INTEGER(mpi) :: item2
6503 INTEGER(mpi) :: jtem
6504
6505 INTEGER(mpi), INTENT(IN) :: itema
6506 INTEGER(mpi), INTENT(IN) :: itemb
6507
6508 INTEGER(mpl) :: ijcsr3
6509 INTEGER(mpl) :: kk
6510 INTEGER(mpl) :: ks
6511 INTEGER(mpl) :: ke
6512
6513 ! ...
6514 ijcsr3=0
6515 item1=max(itema,itemb) ! larger index
6516 item2=min(itema,itemb) ! smaller index
6517 !print *, ' ijadd ', item1, item2
6518 IF(item2 <= 0.OR.item1 > nagb) RETURN
6519 ! start of column list for row
6520 ks=csr3rowoffsets(item2)
6521 ! end of column list for row
6522 ke=csr3rowoffsets(item2+1)-1
6523 ! binary search
6524 IF(ke < ks) THEN
6525 ! empty list
6526 print *, ' IJCSR3 empty list ', item1, item2, ks, ke
6527 CALL peend(23,'Aborted, bad matrix index')
6528 stop 'ijcsr3: empty list'
6529 ENDIF
6530 DO
6531 kk=(ks+ke)/2 ! center of rgion
6532 jtem=int(csr3columnlist(kk),mpi)
6533 IF(item1 == jtem) EXIT ! found
6534 IF(item1 < jtem) THEN
6535 ke=kk-1
6536 ELSE
6537 ks=kk+1
6538 END IF
6539 IF(ks <= ke) cycle
6540 ! not found
6541 print *, ' IJCSR3 not found ', item1, item2, ks, ke
6542 CALL peend(23,'Aborted, bad matrix index')
6543 stop 'ijcsr3: not found'
6544 END DO
6545 ijcsr3=kk
6546END FUNCTION ijcsr3
6547
6553
6554FUNCTION matij(itema,itemb)
6555 USE mpmod
6556
6557 IMPLICIT NONE
6558
6559 INTEGER(mpi) :: item1
6560 INTEGER(mpi) :: item2
6561 INTEGER(mpl) :: i
6562 INTEGER(mpl) :: j
6563 INTEGER(mpl) :: ij
6564 INTEGER(mpl) :: ijadd
6565 INTEGER(mpl) :: ijcsr3
6566
6567 INTEGER(mpi), INTENT(IN) :: itema
6568 INTEGER(mpi), INTENT(IN) :: itemb
6569
6570 REAL(mpd) :: matij
6571 ! ...
6572 matij=0.0_mpd
6573 item1=max(itema,itemb) ! larger index
6574 item2=min(itema,itemb) ! smaller index
6575 IF(item2 <= 0.OR.item1 > nagb) RETURN
6576
6577 i=item1
6578 j=item2
6579
6580 IF(matsto < 2) THEN ! full or unpacked (block diagonal) symmetric matrix
6581 ij=globalrowoffsets(i)+j
6582 matij=globalmatd(ij)
6583 ELSE IF(matsto ==2) THEN ! sparse symmetric matrix (custom)
6584 ij=ijadd(item1,item2) ! inline code requires same time
6585 IF(ij > 0) THEN
6586 matij=globalmatd(ij)
6587 ELSE IF (ij < 0) THEN
6588 matij=real(globalmatf(-ij),mpd)
6589 END IF
6590 ELSE ! sparse symmetric matrix (CSR3)
6591 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
6592 ij=ijcsr3(item1,item2) ! inline code requires same time
6593 IF(ij > 0) matij=globalmatd(ij)
6594 ELSE ! sparse symmetric matrix (BSR3)
6595 ! block index
6596 ij=ijcsr3((item1-1)/matbsz+1,(item2-1)/matbsz+1)
6597 IF (ij > 0) THEN
6598 ! index of first element in block
6599 ij=(ij-1)*matbsz*matbsz+1
6600 ! adjust index for position in block
6601 ij=ij+mod(item1-1,matbsz)*matbsz+mod(item2-1,matbsz)
6602 matij=globalmatd(ij)
6603 ENDIF
6604 END IF
6605 END IF
6606
6607END FUNCTION matij
6608
6611
6612SUBROUTINE mhalf2
6613 USE mpmod
6614
6615 IMPLICIT NONE
6616 INTEGER(mpi) :: i
6617 INTEGER(mpi) :: ia
6618 INTEGER(mpi) :: ib
6619 INTEGER(mpi) :: ichunk
6620 INTEGER(mpi) :: in
6621 INTEGER(mpi) :: ipg
6622 INTEGER(mpi) :: ir
6623 INTEGER(mpi) :: ispc
6624 INTEGER(mpi) :: j
6625 INTEGER(mpi) :: ja
6626 INTEGER(mpi) :: jb
6627 INTEGER(mpi) :: jn
6628 INTEGER(mpi) :: lj
6629
6630 INTEGER(mpl) :: ij
6631 INTEGER(mpl) :: ijadd
6632 INTEGER(mpl) :: k
6633 INTEGER(mpl) :: kk
6634 INTEGER(mpl) :: ku
6635 INTEGER(mpl) :: ll
6636 ! ...
6637
6638 ichunk=min((napgrp+mthrd-1)/mthrd/8+1,1024)
6639
6640 DO ispc=1,nspc
6641 ! parallelize row loop
6642 ! slot of 1024 'I' for next idle thread
6643 !$OMP PARALLEL DO &
6644 !$OMP PRIVATE(I,IR,K,KK,LL,KU,IJ,J,LJ) &
6645 !$OMP PRIVATE(IA,IB,IN,JA,JB,JN) &
6646 !$OMP SCHEDULE(DYNAMIC,ichunk)
6647 DO ipg=1,napgrp
6648 ! row group
6649 ia=globalallindexgroups(ipg) ! first (global) row
6650 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6651 in=ib-ia+1 ! number of rows
6652 !
6653 ir=ipg+(ispc-1)*(napgrp+1)
6654 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6655 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6656 ku=sparsematrixoffsets(1,ir+1)-kk
6657 ! regions of continous column groups
6658 DO k=2,ku-2,2
6659 j=sparsematrixcolumns(kk+k) ! first group
6660 ja=globalallindexgroups(j) ! first (global) column
6661 lj=sparsematrixcolumns(kk+k-1) ! region offset
6662 jn=sparsematrixcolumns(kk+k+1)-lj ! number of columns
6663 jb=ja+jn-1 ! last (global) column
6664 ! skip first half
6665 IF (sparsematrixcolumns(kk+k+2) <= ipg) THEN
6666 ll=ll+in*jn
6667 cycle
6668 END IF
6669 ! at diagonal or in second half
6670 DO i=ia,ib ! loop over rows
6671 DO j=ja,jb ! loop over columns
6672 ll=ll+1
6673 IF (j > i) THEN
6674 ij=ijadd(i,j)
6675 IF (ispc==1) THEN
6676 globalmatd(ll)=globalmatd(ij)
6677 ELSE
6678 globalmatf(ll)=globalmatf(-ij)
6679 END IF
6680 END IF
6681 END DO
6682 END DO
6683 END DO
6684 END DO
6685 !$OMP END PARALLEL DO
6686 END DO
6687
6688END SUBROUTINE mhalf2
6689
6698
6699SUBROUTINE sechms(deltat,nhour,minut,secnd)
6700 USE mpdef
6701
6702 IMPLICIT NONE
6703 REAL(mps), INTENT(IN) :: deltat
6704 INTEGER(mpi), INTENT(OUT) :: minut
6705 INTEGER(mpi), INTENT(OUT):: nhour
6706 REAL(mps), INTENT(OUT):: secnd
6707 INTEGER(mpi) :: nsecd
6708 ! DELTAT = time in sec -> NHOUR,MINUT,SECND
6709 ! ...
6710 nsecd=nint(deltat,mpi) ! -> integer
6711 nhour=nsecd/3600
6712 minut=nsecd/60-60*nhour
6713 secnd=deltat-60*(minut+60*nhour)
6714END SUBROUTINE sechms
6715
6743
6744INTEGER(mpi) FUNCTION inone(item) ! translate 1-D identifier to nrs
6745 USE mpmod
6746 USE mpdalc
6747
6748 IMPLICIT NONE
6749 INTEGER(mpi), INTENT(IN) :: item
6750 INTEGER(mpi) :: j
6751 INTEGER(mpi) :: k
6752 INTEGER(mpi) :: iprime
6753 INTEGER(mpl) :: length
6754 INTEGER(mpl), PARAMETER :: four = 4
6755
6756 inone=0
6757 !print *, ' INONE ', item
6758 IF(item <= 0) RETURN
6759 IF(globalparheader(-1) == 0) THEN
6760 length=128 ! initial number
6761 CALL mpalloc(globalparlabelindex,four,length,'INONE: label & index')
6762 CALL mpalloc(globalparlabelcounter,length,'INONE: counter') ! updated in pargrp
6763 CALL mpalloc(globalparhashtable,2*length,'INONE: hash pointer')
6765 globalparheader(-0)=int(length,mpi) ! length of labels/indices
6766 globalparheader(-1)=0 ! number of stored items
6767 globalparheader(-2)=0 ! =0 during build-up
6768 globalparheader(-3)=int(length,mpi) ! next number
6769 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number
6770 globalparheader(-5)=0 ! number of overflows
6771 globalparheader(-6)=0 ! nr of variable parameters
6772 globalparheader(-8)=0 ! number of sorted items
6773 END IF
6774 outer: DO
6775 j=1+mod(item,globalparheader(-4))+globalparheader(-0)
6776 inner: DO ! normal case: find item
6777 k=j
6779 IF(j == 0) EXIT inner ! unused hash code
6780 IF(item == globalparlabelindex(1,j)) EXIT outer ! found
6781 END DO inner
6782 ! not found
6783 IF(globalparheader(-1) == globalparheader(-0).OR.globalparheader(-2) /= 0) THEN
6784 globalparheader(-5)=globalparheader(-5)+1 ! overflow
6785 j=0
6786 RETURN
6787 END IF
6788 globalparheader(-1)=globalparheader(-1)+1 ! increase number of elements
6790 j=globalparheader(-1)
6791 globalparhashtable(k)=j ! hash index
6792 globalparlabelindex(1,j)=item ! add new item
6793 globalparlabelindex(2,j)=0 ! reset index (for variable par.)
6794 globalparlabelindex(3,j)=0 ! reset group info (first label)
6795 globalparlabelindex(4,j)=0 ! reset group info (group index)
6796 globalparlabelcounter(j)=0 ! reset (long) counter
6797 IF(globalparheader(-1) /= globalparheader(-0)) EXIT outer
6798 ! update with larger dimension and redefine index
6800 CALL upone
6801 IF (lvllog > 1) WRITE(lunlog,*) 'INONE: array increased to', &
6802 globalparheader(-3),' words'
6803 END DO outer
6804
6805 ! counting now in pargrp
6806 !IF(globalParHeader(-2) == 0) THEN
6807 ! globalParLabelIndex(2,j)=globalParLabelIndex(2,j)+1 ! increase counter
6808 ! globalParHeader(-7)=globalParHeader(-7)+1
6809 !END IF
6810 inone=j
6811END FUNCTION inone
6812
6814SUBROUTINE upone
6815 USE mpmod
6816 USE mpdalc
6817
6818 IMPLICIT NONE
6819 INTEGER(mpi) :: i
6820 INTEGER(mpi) :: j
6821 INTEGER(mpi) :: k
6822 INTEGER(mpi) :: iprime
6823 INTEGER(mpi) :: nused
6824 LOGICAL :: finalUpdate
6825 INTEGER(mpl) :: oldLength
6826 INTEGER(mpl) :: newLength
6827 INTEGER(mpl), PARAMETER :: four = 4
6828 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArr
6829 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: tempVec
6830 SAVE
6831 ! ...
6832 finalupdate=(globalparheader(-3) == globalparheader(-1))
6833 IF(finalupdate) THEN ! final (cleanup) call
6834 IF (globalparheader(-1) > globalparheader(-8)) THEN
6837 END IF
6838 END IF
6839 ! save old LabelIndex
6840 nused = globalparheader(-1)
6841 oldlength = globalparheader(-0)
6842 CALL mpalloc(temparr,four,oldlength,'INONE: temp array')
6843 temparr(:,1:nused)=globalparlabelindex(:,1:nused)
6844 CALL mpalloc(tempvec,oldlength,'INONE: temp vector')
6845 tempvec(1:nused)=globalparlabelcounter(1:nused)
6849 ! create new LabelIndex
6850 newlength = globalparheader(-3)
6851 CALL mpalloc(globalparlabelindex,four,newlength,'INONE: label & index')
6852 CALL mpalloc(globalparlabelcounter,newlength,'INONE: counter')
6853 CALL mpalloc(globalparhashtable,2*newlength,'INONE: hash pointer')
6855 globalparlabelindex(:,1:nused) = temparr(:,1:nused) ! copy back saved content
6856 globalparlabelcounter(1:nused) = tempvec(1:nused) ! copy back saved content
6857 CALL mpdealloc(tempvec)
6858 CALL mpdealloc(temparr)
6859 globalparheader(-0)=int(newlength,mpi) ! length of labels/indices
6861 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number < LNDA
6862 ! redefine hash
6863 outer: DO i=1,globalparheader(-1)
6865 inner: DO
6866 k=j
6868 IF(j == 0) EXIT inner ! unused hash code
6869 IF(j == i) cycle outer ! found
6870 ENDDO inner
6872 END DO outer
6873 IF(.NOT.finalupdate) RETURN
6874
6875 globalparheader(-2)=1 ! set flag to inhibit further updates
6876 IF (lvllog > 1) THEN
6877 WRITE(lunlog,*) ' '
6878 WRITE(lunlog,*) 'INONE: array reduced to',newlength,' words'
6879 WRITE(lunlog,*) 'INONE:',globalparheader(-1),' items stored.'
6880 END IF
6881END SUBROUTINE upone ! update, redefine
6882
6884SUBROUTINE useone
6885 USE mpmod
6886
6887 IMPLICIT NONE
6888 INTEGER(mpi) :: i
6889 INTEGER(mpi) :: j
6890 INTEGER(mpi) :: k
6891 SAVE
6892 ! ...
6893 IF (globalparheader(-1) > globalparheader(-8)) THEN
6895 ! redefine hash
6897 outer: DO i=1,globalparheader(-1)
6899 inner: DO
6900 k=j
6902 IF(j == 0) EXIT inner ! unused hash code
6903 IF(j == i) cycle outer ! found
6904 ENDDO inner
6906 END DO outer
6908 END IF
6909END SUBROUTINE useone ! make usable
6910
6915
6916INTEGER(mpi) FUNCTION iprime(n)
6917 USE mpdef
6918
6919 IMPLICIT NONE
6920 INTEGER(mpi), INTENT(IN) :: n
6921 INTEGER(mpi) :: nprime
6922 INTEGER(mpi) :: nsqrt
6923 INTEGER(mpi) :: i
6924 ! ...
6925 SAVE
6926 nprime=n ! max number
6927 IF(mod(nprime,2) == 0) nprime=nprime+1 ! ... odd number
6928 outer: DO
6929 nprime=nprime-2 ! next lower odd number
6930 nsqrt=int(sqrt(real(nprime,mps)),mpi)
6931 DO i=3,nsqrt,2 !
6932 IF(i*(nprime/i) == nprime) cycle outer ! test prime number
6933 END DO
6934 EXIT outer ! found
6935 END DO outer
6936 iprime=nprime
6937END FUNCTION iprime
6938
6948SUBROUTINE loop1
6949 USE mpmod
6950 USE mpdalc
6951
6952 IMPLICIT NONE
6953 INTEGER(mpi) :: i
6954 INTEGER(mpi) :: idum
6955 INTEGER(mpi) :: in
6956 INTEGER(mpi) :: indab
6957 INTEGER(mpi) :: itgbi
6958 INTEGER(mpi) :: itgbl
6959 INTEGER(mpi) :: ivgbi
6960 INTEGER(mpi) :: j
6961 INTEGER(mpi) :: jgrp
6962 INTEGER(mpi) :: lgrp
6963 INTEGER(mpi) :: mqi
6964 INTEGER(mpi) :: nc31
6965 INTEGER(mpi) :: nr
6966 INTEGER(mpi) :: nwrd
6967 INTEGER(mpi) :: inone
6968 REAL(mpd) :: param
6969 REAL(mpd) :: presg
6970 REAL(mpd) :: prewt
6971
6972 INTEGER(mpl) :: length
6973 INTEGER(mpl) :: rows
6974 SAVE
6975 ! ...
6976 WRITE(lunlog,*) ' '
6977 WRITE(lunlog,*) 'LOOP1: starting'
6978 CALL mstart('LOOP1')
6979
6980 ! add labels from parameter, constraints, measurements, comments -------------
6981 DO i=1, lenparameters
6982 idum=inone(listparameters(i)%label)
6983 END DO
6984 DO i=1, lenpresigmas
6985 idum=inone(listpresigmas(i)%label)
6986 END DO
6987 DO i=1, lenconstraints
6988 idum=inone(listconstraints(i)%label)
6989 END DO
6990 DO i=1, lenmeasurements
6991 idum=inone(listmeasurements(i)%label)
6992 END DO
6993 DO i=1, lencomments
6994 idum=inone(listcomments(i)%label)
6995 END DO
6996
6997 IF(globalparheader(-1) /= 0) THEN
6998 WRITE(lunlog,*) 'LOOP1:',globalparheader(-1), ' labels from txt data stored'
6999 END IF
7000 WRITE(lunlog,*) 'LOOP1: reading data files'
7001
7002 neqn=0 ! number of equations
7003 negb=0 ! number of equations with global parameters
7004 ndgb=0 ! number of global derivatives
7005 nzgb=0 ! number of zero global derivatives
7006 DO
7007 DO j=1,globalparheader(-1)
7008 globalparlabelindex(2,j)=0 ! reset count
7009 END DO
7010
7011 CALL hmpldf(1,'Number of words/record in binary file')
7012 CALL hmpdef(8,0.0,60.0,'not_stored data per record')
7013 ! define read buffer
7014 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7015 nwrd=nc31+1
7016 IF(ndimbuf > nwrd) THEN
7017 CALL peend(20,'Aborted, bad binary records')
7018 stop 'LOOP1: length of binary record exceeds cache size, wrong file type?'
7019 END IF
7020 length=nwrd*mthrdr
7021 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7022 nwrd=nc31*10+2+ndimbuf
7023 length=nwrd*mthrdr
7024 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7025 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7026 ! to read (old) float binary files
7027 length=(ndimbuf+2)*mthrdr
7028 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7029
7030 ! read all data files and add all labels to global labels table ----
7031 IF(mprint /= 0) THEN
7032 WRITE(*,*) 'Read all binary data files:'
7033 END IF
7034
7035 DO
7036 CALL peread(nr) ! read records
7037 IF (skippedrecords == 0) THEN
7038 CALL peprep(0) ! prepare records
7039 CALL pepgrp ! update parameter group info
7040 END IF
7041 IF(nr <= 0) EXIT ! end of data?
7042 END DO
7043 ! release read buffer
7048 IF (skippedrecords == 0) THEN
7049 EXIT
7050 ELSE
7051 WRITE(lunlog,*) 'LOOP1: reading data files again'
7052 END IF
7053 END DO
7054
7055 IF(nhistp /= 0) THEN
7056 CALL hmprnt(1)
7057 CALL hmprnt(8)
7058 END IF
7059 CALL hmpwrt(1)
7060 CALL hmpwrt(8)
7061 ntgb = globalparheader(-1) ! total number of labels/parameters
7062 IF (ntgb == 0) THEN
7063 CALL peend(21,'Aborted, no labels/parameters defined')
7064 stop 'LOOP1: no labels/parameters defined'
7065 END IF
7066 CALL upone ! finalize the global label table
7067
7068 WRITE(lunlog,*) 'LOOP1:',ntgb, &
7069 ' is total number NTGB of labels/parameters'
7070 ! histogram number of entries per label ----------------------------
7071 CALL hmpldf(2,'Number of entries per label')
7072 DO j=1,ntgb
7073 CALL hmplnt(2,globalparlabelindex(2,j))
7074 END DO
7075 IF(nhistp /= 0) CALL hmprnt(2) ! print histogram
7076 CALL hmpwrt(2) ! write to his file
7077
7078 ! three subarrays for all global parameters ------------------------
7079 length=ntgb
7080 CALL mpalloc(globalparameter,length,'global parameters')
7081 globalparameter=0.0_mpd
7082 CALL mpalloc(globalparpresigma,length,'pre-sigmas') ! presigmas
7084 CALL mpalloc(globalparstart,length,'global parameters at start')
7086 CALL mpalloc(globalparcopy,length,'copy of global parameters')
7087 CALL mpalloc(globalparcons,length,'global parameter constraints')
7089 CALL mpalloc(globalparcomments,length,'global parameter comments')
7091
7092 DO i=1,lenparameters ! parameter start values
7093 param=listparameters(i)%value
7094 in=inone(listparameters(i)%label)
7095 IF(in /= 0) THEN
7096 globalparameter(in)=param
7097 globalparstart(in)=param
7098 ENDIF
7099 END DO
7100
7101 DO i=1, lencomments
7102 in=inone(listcomments(i)%label)
7103 IF(in /= 0) globalparcomments(in)=i
7104 END DO
7105
7106 npresg=0
7107 DO i=1,lenpresigmas ! pre-sigma values
7108 presg=listpresigmas(i)%value
7109 in=inone(listpresigmas(i)%label)
7110 IF(in /= 0) THEN
7111 IF(presg > 0.0) npresg=npresg+1 ! FIXME: check if enough 'entries'?
7112 globalparpresigma(in)=presg ! insert pre-sigma 0 or > 0
7113 END IF
7114 END DO
7115 WRITE(lunlog,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7116 WRITE(*,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7117 IF(npresg == 0) WRITE(*,*) 'Warning: no pre-sigmas defined'
7118
7119 ! build constraint groups, check for redundancy constrints
7120 CALL grpcon
7121
7122 ! determine flag variable (active) or fixed (inactive) -------------
7123
7124 indab=0
7125 DO i=1,ntgb
7126 IF (globalparpresigma(i) < 0.0) THEN
7127 globalparlabelindex(2,i)=-1 ! fixed (pre-sigma), not used in matrix (not active)
7128 ELSE IF(globalparlabelcounter(i) < mreqenf) THEN
7129 globalparlabelindex(2,i)=-2 ! fixed (entries cut), not used in matrix (not active)
7130 ELSE IF (globalparcons(i) < 0) THEN
7131 globalparlabelindex(2,i)=-4 ! fixed (redundant), not used in matrix (not active)
7132 ELSE
7133 indab=indab+1
7134 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7135 END IF
7136 END DO
7137 globalparheader(-6)=indab ! counted variable
7138 nvgb=indab ! nr of variable parameters
7139 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7140 IF(iteren > mreqenf) THEN
7141 IF (mcount == 0) THEN
7142 CALL loop1i ! iterate entries cut
7143 ELSE
7144 WRITE(lunlog,*) 'LOOP1: counting records, NO iteration of entries cut !'
7145 iteren=0
7146 END IF
7147 END IF
7148
7149 ! --- check for parameter groups
7150 CALL hmpdef(15,0.0,120.0,'Number of parameters per group')
7151 ntpgrp=0
7152 DO j=1,ntgb
7153 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7154 ! new group?
7156 globalparlabelindex(4,j)=ntpgrp ! relation total index -> group
7157 END DO
7158 ! check variable parameters
7159 nvpgrp=0
7160 lgrp=-1
7161 DO j=1,ntgb
7162 IF (globalparlabelindex(2,j) <= 0) cycle ! skip fixed parameter
7163 ! new group ?
7164 IF (globalparlabelindex(4,j) /= lgrp) nvpgrp=nvpgrp+1
7165 lgrp=globalparlabelindex(4,j)
7166 END DO
7167 length=ntpgrp; rows=2
7168 CALL mpalloc(globaltotindexgroups,rows,length,'parameter groups, 1. index and size')
7170 ! fill
7171 lgrp=-1
7172 DO j=1,ntgb
7173 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7174 jgrp=globalparlabelindex(4,j)
7175 IF (jgrp /= lgrp) globaltotindexgroups(1,jgrp)=j ! first (total) index
7176 globaltotindexgroups(2,jgrp)=globaltotindexgroups(2,jgrp)+1 ! (total) size
7177 lgrp=jgrp
7178 END DO
7179 DO j=1,ntpgrp
7180 CALL hmpent(15,real(globaltotindexgroups(2,j),mps))
7181 END DO
7182 IF(nhistp /= 0) CALL hmprnt(15) ! print histogram
7183 CALL hmpwrt(15) ! write to his file
7184 WRITE(lunlog,*) 'LOOP1:',ntpgrp, &
7185 ' is total number NTPGRP of label/parameter groups'
7186 !print *, ' globalTotIndexGroups ', globalTotIndexGroups
7187
7188 ! translation table of length NVGB of total global indices ---------
7189 length=nvgb
7190 CALL mpalloc(globalparvartototal,length,'translation table var -> total')
7191 indab=0
7192 DO i=1,ntgb
7193 IF(globalparlabelindex(2,i) > 0) THEN
7194 indab=indab+1
7195 globalparvartototal(indab)=i
7196 END IF
7197 END DO
7198
7199 ! regularization ---------------------------------------------------
7200 CALL mpalloc(globalparpreweight,length,'pre-sigmas weights') ! presigma weights
7201 WRITE(*,112) ' Default pre-sigma =',regpre, &
7202 ' (if no individual pre-sigma defined)'
7203 WRITE(*,*) 'Pre-sigma factor is',regula
7204
7205 IF(nregul == 0) THEN
7206 WRITE(*,*) 'No regularization will be done'
7207 ELSE
7208 WRITE(*,*) 'Regularization will be done, using factor',regula
7209 END IF
7210112 FORMAT(a,e9.2,a)
7211 IF (nvgb <= 0) THEN
7212 CALL peend(22,'Aborted, no variable global parameters')
7213 stop '... no variable global parameters'
7214 ENDIF
7215
7216 DO ivgbi=1,nvgb ! IVGBI = index of variable global parameter
7217 itgbi=globalparvartototal(ivgbi) ! ITGBI = global parameter index
7218 presg=globalparpresigma(itgbi) ! get pre-sigma
7219 prewt=0.0 ! pre-weight
7220 IF(presg > 0.0) THEN
7221 prewt=1.0/presg**2 ! 1/presigma^2
7222 ELSE IF(presg == 0.0.AND.regpre > 0.0) THEN
7223 prewt=1.0/real(regpre**2,mpd) ! default 1/presigma^2
7224 END IF
7225 globalparpreweight(ivgbi)=regula*prewt ! weight = factor / presigma^2
7226 END DO
7227
7228 ! WRITE(*,*) 'GlPa_index GlPa_label array1 array6'
7229 DO i=1,ntgb
7230 itgbl=globalparlabelindex(1,i)
7231 ivgbi=globalparlabelindex(2,i)
7232 IF(ivgbi > 0) THEN
7233 ! WRITE(*,111) I,ITGBL,QM(IND1+I),QM(IND6+IVGBI)
7234 ELSE
7235 ! WRITE(*,111) I,ITGBL,QM(IND1+I)
7236 END IF
7237 END DO
7238 ! 111 FORMAT(I5,I10,F10.5,E12.4)
7239 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7240 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7241 ! To avoid INT(mpi) overflows in diagonalization
7242 IF (metsol == 2.AND.nvgb >= 46340) THEN
7243 metsol=1
7244 WRITE(*,101) 'Too many variable parameters for diagonalization, fallback is inversion'
7245 END IF
7246
7247 ! print overview over important numbers ----------------------------
7248
7249 nrecal=nrec
7250 IF(mprint /= 0) THEN
7251 WRITE(*,*) ' '
7252 WRITE(*,101) ' NREC',nrec,'number of records'
7253 IF (nrecd > 0) WRITE(*,101) ' NRECD',nrec,'number of records containing doubles'
7254 WRITE(*,101) ' NEQN',neqn,'number of equations (measurements)'
7255 WRITE(*,101) ' NEGB',negb,'number of equations with global parameters'
7256 WRITE(*,101) ' NDGB',ndgb,'number of global derivatives'
7257 IF (nzgb > 0) THEN
7258 WRITE(*,101) ' NZGB',nzgb,'number of zero global der. (ignored in entry counts)'
7259 ENDIF
7260 IF (mcount == 0) THEN
7261 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7262 ELSE
7263 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7264 ENDIF
7265 IF(iteren > mreqenf) &
7266 WRITE(*,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7267 WRITE(*,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7268 IF (mreqpe > 1) WRITE(*,101) &
7269 'MREQPE',mreqpe,'required number of pair entries'
7270 IF (msngpe >= 1) WRITE(*,101) &
7271 'MSNGPE',msngpe,'max pair entries single prec. storage'
7272 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7273 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7274 IF(mprint > 1) THEN
7275 WRITE(*,*) ' '
7276 WRITE(*,*) 'Global parameter labels:'
7277 mqi=ntgb
7278 IF(mqi <= 100) THEN
7279 WRITE(*,*) (globalparlabelindex(2,i),i=1,mqi)
7280 ELSE
7281 WRITE(*,*) (globalparlabelindex(2,i),i=1,30)
7282 WRITE(*,*) ' ...'
7283 mqi=((mqi-20)/20)*20+1
7284 WRITE(*,*) (globalparlabelindex(2,i),i=mqi,ntgb)
7285 END IF
7286 END IF
7287 WRITE(*,*) ' '
7288 WRITE(*,*) ' '
7289 END IF
7290 WRITE(8,*) ' '
7291 WRITE(8,101) ' NREC',nrec,'number of records'
7292 IF (nrecd > 0) WRITE(8,101) ' NRECD',nrec,'number of records containing doubles'
7293 WRITE(8,101) ' NEQN',neqn,'number of equations (measurements)'
7294 WRITE(8,101) ' NEGB',negb,'number of equations with global parameters'
7295 WRITE(8,101) ' NDGB',ndgb,'number of global derivatives'
7296 IF (mcount == 0) THEN
7297 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7298 ELSE
7299 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7300 ENDIF
7301 IF(iteren > mreqenf) &
7302 WRITE(8,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7303 WRITE(8,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7304
7305 WRITE(lunlog,*) 'LOOP1: ending'
7306 WRITE(lunlog,*) ' '
7307 CALL mend
7308
7309101 FORMAT(1x,a8,' =',i14,' = ',a)
7310END SUBROUTINE loop1
7311
7319SUBROUTINE loop1i
7320 USE mpmod
7321 USE mpdalc
7322
7323 IMPLICIT NONE
7324 INTEGER(mpi) :: i
7325 INTEGER(mpi) :: ibuf
7326 INTEGER(mpi) :: ij
7327 INTEGER(mpi) :: indab
7328 INTEGER(mpi) :: ist
7329 INTEGER(mpi) :: j
7330 INTEGER(mpi) :: ja
7331 INTEGER(mpi) :: jb
7332 INTEGER(mpi) :: jsp
7333 INTEGER(mpi) :: nc31
7334 INTEGER(mpi) :: nr
7335 INTEGER(mpi) :: nlow
7336 INTEGER(mpi) :: nst
7337 INTEGER(mpi) :: nwrd
7338
7339 INTEGER(mpl) :: length
7340 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: newCounter
7341 SAVE
7342
7343 ! ...
7344 WRITE(lunlog,*) ' '
7345 WRITE(lunlog,*) 'LOOP1: iterating'
7346 WRITE(*,*) ' '
7347 WRITE(*,*) 'LOOP1: iterating'
7348
7349 length=ntgb
7350 CALL mpalloc(newcounter,length,'new entries counter')
7351 newcounter=0
7352
7353 ! define read buffer
7354 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7355 nwrd=nc31+1
7356 length=nwrd*mthrdr
7357 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7358 nwrd=nc31*10+2+ndimbuf
7359 length=nwrd*mthrdr
7360 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7361 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7362 ! to read (old) float binary files
7363 length=(ndimbuf+2)*mthrdr
7364 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7365
7366 DO
7367 CALL peread(nr) ! read records
7368 CALL peprep(1) ! prepare records
7369 DO ibuf=1,numreadbuffer ! buffer for current record
7370 ist=readbufferpointer(ibuf)+1
7372 nwrd=nst-ist+1
7373 DO ! loop over measurements
7374 CALL isjajb(nst,ist,ja,jb,jsp)
7375 IF(ja == 0.AND.jb == 0) EXIT
7376 IF(ja /= 0) THEN
7377 nlow=0
7378 DO j=1,ist-jb
7379 ij=readbufferdatai(jb+j) ! index of global parameter
7380 ij=globalparlabelindex(2,ij) ! change to variable parameter
7381 IF(ij == -2) nlow=nlow+1 ! fixed by entries cut
7382 END DO
7383 IF(nlow == 0) THEN
7384 DO j=1,ist-jb
7385 ij=readbufferdatai(jb+j) ! index of global parameter
7386 newcounter(ij)=newcounter(ij)+1 ! count again
7387 END DO
7388 ENDIF
7389 END IF
7390 END DO
7391 ! end-of-event
7392 END DO
7393 IF(nr <= 0) EXIT ! end of data?
7394 END DO
7395
7396 ! release read buffer
7401
7402 indab=0
7403 DO i=1,ntgb
7404 IF(globalparlabelindex(2,i) > 0) THEN
7405 IF(newcounter(i) >= mreqenf .OR. globalparlabelcounter(i) >= iteren) THEN
7406 indab=indab+1
7407 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7408 ELSE
7409 globalparlabelindex(2,i)=-3 ! fixed (iterated entries cut), not used in matrix (not active)
7410 END IF
7411 END IF
7412 END DO
7413 globalparheader(-6)=indab ! counted variable
7414 nvgb=indab ! nr of variable parameters
7415 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7416 CALL mpdealloc(newcounter)
7417
7418END SUBROUTINE loop1i
7419
7430
7431SUBROUTINE loop2
7432 USE mpmod
7433 USE mpdalc
7434
7435 IMPLICIT NONE
7436 REAL(mps) :: chin2
7437 REAL(mps) :: chin3
7438 REAL(mps) :: cpr
7439 REAL(mps) :: fsum
7440 REAL(mps) :: gbc
7441 REAL(mps) :: gbu
7442 INTEGER(mpi) :: i
7443 INTEGER(mpi) :: ia
7444 INTEGER(mpi) :: ib
7445 INTEGER(mpi) :: ibuf
7446 INTEGER(mpi) :: icblst
7447 INTEGER(mpi) :: icboff
7448 INTEGER(mpi) :: icgb
7449 INTEGER(mpi) :: icgrp
7450 INTEGER(mpi) :: icount
7451 INTEGER(mpi) :: iext
7452 INTEGER(mpi) :: ihis
7453 INTEGER(mpi) :: ij
7454 INTEGER(mpi) :: ij1
7455 INTEGER(mpi) :: ijn
7456 INTEGER(mpi) :: ioff
7457 INTEGER(mpi) :: ipoff
7458 INTEGER(mpi) :: iproc
7459 INTEGER(mpi) :: irecmm
7460 INTEGER(mpi) :: ist
7461 INTEGER(mpi) :: itgbi
7462 INTEGER(mpi) :: itgbij
7463 INTEGER(mpi) :: itgbik
7464 INTEGER(mpi) :: ivgbij
7465 INTEGER(mpi) :: ivgbik
7466 INTEGER(mpi) :: ivpgrp
7467 INTEGER(mpi) :: j
7468 INTEGER(mpi) :: ja
7469 INTEGER(mpi) :: jb
7470 INTEGER(mpi) :: jcgrp
7471 INTEGER(mpi) :: jext
7472 INTEGER(mpi) :: jcgb
7473 INTEGER(mpi) :: jrec
7474 INTEGER(mpi) :: jsp
7475 INTEGER(mpi) :: joff
7476 INTEGER(mpi) :: k
7477 INTEGER(mpi) :: kcgrp
7478 INTEGER(mpi) :: kfile
7479 INTEGER(mpi) :: l
7480 INTEGER(mpi) :: label
7481 INTEGER(mpi) :: labelf
7482 INTEGER(mpi) :: labell
7483 INTEGER(mpi) :: lvpgrp
7484 INTEGER(mpi) :: lu
7485 INTEGER(mpi) :: lun
7486 INTEGER(mpi) :: maeqnf
7487 INTEGER(mpi) :: nall
7488 INTEGER(mpi) :: naeqna
7489 INTEGER(mpi) :: naeqnf
7490 INTEGER(mpi) :: naeqng
7491 INTEGER(mpi) :: npdblk
7492 INTEGER(mpi) :: nc31
7493 INTEGER(mpi) :: ncachd
7494 INTEGER(mpi) :: ncachi
7495 INTEGER(mpi) :: ncachr
7496 INTEGER(mpi) :: ncon
7497 INTEGER(mpi) :: nda
7498 INTEGER(mpi) :: ndf
7499 INTEGER(mpi) :: ndfmax
7500 INTEGER(mpi) :: nfixed
7501 INTEGER(mpi) :: nggd
7502 INTEGER(mpi) :: nggi
7503 INTEGER(mpi) :: nmatmo
7504 INTEGER(mpi) :: noff
7505 INTEGER(mpi) :: npair
7506 INTEGER(mpi) :: npar
7507 INTEGER(mpi) :: nparmx
7508 INTEGER(mpi) :: nr
7509 INTEGER(mpi) :: nrece
7510 INTEGER(mpi) :: nrecf
7511 INTEGER(mpi) :: nrecmm
7512 INTEGER(mpi) :: nst
7513 INTEGER(mpi) :: nwrd
7514 INTEGER(mpi) :: inone
7515 INTEGER(mpi) :: inc
7516 REAL(mps) :: wgh
7517 REAL(mps) :: wolfc3
7518 REAL(mps) :: wrec
7519 REAL(mps) :: chindl
7520
7521 REAL(mpd)::dstat(3)
7522 REAL(mpd)::rerr
7523 INTEGER(mpl):: nblock
7524 INTEGER(mpl):: nbwrds
7525 INTEGER(mpl):: noff8
7526 INTEGER(mpl):: ndimbi
7527 INTEGER(mpl):: ndimsa(4)
7528 INTEGER(mpl):: ndgn
7529 INTEGER(mpl):: nnzero
7530 INTEGER(mpl):: matsiz(2)
7531 INTEGER(mpl):: matwords
7532 INTEGER(mpl):: mbwrds
7533 INTEGER(mpl):: length
7534 INTEGER(mpl):: rows
7535 INTEGER(mpl):: cols
7536 INTEGER(mpl), PARAMETER :: two=2
7537 INTEGER(mpi) :: maxGlobalPar = 0
7538 INTEGER(mpi) :: maxLocalPar = 0
7539 INTEGER(mpi) :: maxEquations = 0
7540
7541 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupList
7542 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupIndex
7543 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
7544 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecBlockCounts
7545
7546 INTERFACE ! needed for assumed-shape dummy arguments
7547 SUBROUTINE ndbits(npgrp,ndims,nsparr,ihst)
7548 USE mpdef
7549 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7550 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7551 INTEGER(mpl), DIMENSION(:,:), INTENT(OUT) :: nsparr
7552 INTEGER(mpi), INTENT(IN) :: ihst
7553 END SUBROUTINE ndbits
7554 SUBROUTINE ckbits(npgrp,ndims)
7555 USE mpdef
7556 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7557 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7558 END SUBROUTINE ckbits
7559 SUBROUTINE spbits(npgrp,nsparr,nsparc)
7560 USE mpdef
7561 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7562 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
7563 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: nsparc
7564 END SUBROUTINE spbits
7565 SUBROUTINE gpbmap(ngroup,npgrp,npair)
7566 USE mpdef
7567 INTEGER(mpi), INTENT(IN) :: ngroup
7568 INTEGER(mpi), DIMENSION(:,:), INTENT(IN) :: npgrp
7569 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npair
7570 END SUBROUTINE gpbmap
7571 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
7572 USE mpdef
7573 INTEGER(mpi), INTENT(IN) :: ipgrp
7574 INTEGER(mpi), INTENT(OUT) :: npair
7575 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
7576 END SUBROUTINE ggbmap
7577 SUBROUTINE pbsbits(npgrp,ibsize,nnzero,nblock,nbkrow)
7578 USE mpdef
7579 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7580 INTEGER(mpi), INTENT(IN) :: ibsize
7581 INTEGER(mpl), INTENT(OUT) :: nnzero
7582 INTEGER(mpl), INTENT(OUT) :: nblock
7583 INTEGER(mpi), DIMENSION(:),INTENT(OUT) :: nbkrow
7584 END SUBROUTINE pbsbits
7585 SUBROUTINE pblbits(npgrp,ibsize,nsparr,nsparc)
7586 USE mpdef
7587 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7588 INTEGER(mpi), INTENT(IN) :: ibsize
7589 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7590 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7591 END SUBROUTINE pblbits
7592 SUBROUTINE prbits(npgrp,nsparr)
7593 USE mpdef
7594 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7595 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparr
7596 END SUBROUTINE prbits
7597 SUBROUTINE pcbits(npgrp,nsparr,nsparc)
7598 USE mpdef
7599 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7600 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7601 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7602 END SUBROUTINE pcbits
7603 END INTERFACE
7604
7605 SAVE
7606
7607 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
7608
7609 ! ...
7610 WRITE(lunlog,*) ' '
7611 WRITE(lunlog,*) 'LOOP2: starting'
7612 CALL mstart('LOOP2')
7613
7614 ! two subarrays to get the global parameter indices, used in an event
7615 length=nvgb
7616 CALL mpalloc(globalindexusage,length,'global index')
7617 CALL mpalloc(backindexusage,length,'back index')
7619 CALL mpalloc(globalindexranges,length,'global index ranges')
7621
7622 length=ntgb
7623 CALL mpalloc(globalparlabelzeros,length,'global label with zero der. counters')
7625
7626 ! prepare constraints - determine number of constraints NCGB
7627 ! - sort and split into blocks
7628 ! - update globalIndexRanges
7629 CALL prpcon
7630
7631 IF (metsol == 3.AND.icelim <= 0) THEN
7632 ! decomposition: enforce elimination
7633 icelim=1
7634 WRITE(lunlog,*) ' Elimination for constraints enforced for solution by decomposition!'
7635 END IF
7636 IF (metsol == 9.AND.icelim > 0) THEN
7637 ! sparsePARDISO: enforce multipliers
7638 icelim=0
7639 WRITE(lunlog,*) ' Lagrange multipliers enforced for solution by sparsePARDISO!'
7640 END IF
7641 IF (matsto > 0.AND.icelim > 1) THEN
7642 ! decomposition: enforce elimination
7643 icelim=1
7644 WRITE(lunlog,*) ' Elimination for constraints with mpqldec enforced (LAPACK only for unpacked storage)!'
7645 END IF
7646 IF (icelim > 0) THEN ! elimination
7647 nagb=nvgb ! total number of parameters
7648 napgrp=nvpgrp ! total number of parameter groups
7649 nfgb=nvgb-ncgb ! number of fit parameters
7650 nprecond(1)=0 ! number of constraints for preconditioner
7651 nprecond(2)=nfgb ! matrix size for preconditioner
7652 nprecond(3)=0 ! number of constraint blocks for preconditioner
7653 ELSE ! Lagrange multipliers
7654 nagb=nvgb+ncgb ! total number of parameters
7655 napgrp=nvpgrp+ncgb ! total number of parameter groups
7656 nfgb=nagb ! number of fit parameters
7657 nprecond(1)=ncgb ! number of constraints for preconditioner
7658 nprecond(2)=nvgb ! matrix size for preconditioner
7659 nprecond(3)=ncblck ! number of constraint blocks for preconditioner
7660 ENDIF
7661 noff8=int(nagb,mpl)*int(nagb-1,mpl)/2
7662
7663 ! all (variable) parameter groups
7664 length=napgrp+1
7665 CALL mpalloc(globalallindexgroups,length,'all parameter groups, 1. index')
7667 ivpgrp=0
7668 lvpgrp=-1
7669 DO i=1,ntgb
7670 ij=globalparlabelindex(2,i)
7671 IF (ij <= 0) cycle ! variable ?
7672 IF (globalparlabelindex(4,i) /= lvpgrp) THEN
7673 ivpgrp=ivpgrp+1
7674 globalallindexgroups(ivpgrp)=ij ! first index
7675 lvpgrp=globalparlabelindex(4,i)
7676 END IF
7677 END DO
7678 ! Lagrange multipliers
7679 IF (napgrp > nvpgrp) THEN
7680 DO jcgb=1, ncgb
7681 ivpgrp=ivpgrp+1
7682 globalallindexgroups(ivpgrp)=nvgb+jcgb
7683 END DO
7684 END IF
7686 ! from all (variable) parameters to group
7687 length=nagb
7688 CALL mpalloc(globalallpartogroup,length,'translation table all (var) par -> group')
7690 DO i=1,napgrp
7693 END DO
7694 END DO
7695 IF (icheck > 2) THEN
7696 print *
7697 print *, ' Variable parameter groups ', nvpgrp
7698 DO i=1,nvpgrp
7700 k=globalparlabelindex(4,itgbi) ! (total) group index
7702 globalparlabelindex(1,itgbi)
7703 END DO
7704 print *
7705 END IF
7706
7707 ! read all data files and add all variable index pairs -------------
7708
7709 IF (icheck > 1) CALL clbmap(ntpgrp+ncgrp)
7710
7711 IF(matsto == 2) THEN
7712 ! MINRES, sparse storage
7713 CALL clbits(napgrp,mreqpe,mhispe,msngpe,mextnd,ndimbi,nspc) ! get dimension for bit storage, encoding, precision info
7714 END IF
7715 IF(matsto == 3) THEN
7716 ! PARDISO, upper triangle (parameter groups) incl. rectangular part (constraints)
7717 CALL plbits(nvpgrp,nvgb,ncgb,ndimbi) ! get dimension for bit storage, global parameters and constraints
7718 END IF
7719
7720 IF (imonit /= 0) THEN
7721 length=ntgb
7722 CALL mpalloc(measindex,length,'measurement counter/index')
7723 measindex=0
7724 CALL mpalloc(measres,length,'measurement resolution')
7725 measres=0.0_mps
7726 lunmon=9
7727 CALL mvopen(lunmon,'millepede.mon')
7728 ENDIF
7729
7730 ! for checking appearance
7731 IF (icheck > 1) THEN
7732 length=5*(ntgb+ncgrp)
7733 CALL mpalloc(appearancecounter,length,'appearance statistics')
7735 length=ntgb
7736 CALL mpalloc(paircounter,length,'pair statistics')
7737 paircounter=0
7738 END IF
7739
7740 ! checking constraint goups
7741 IF (icheck > 0.AND. ncgrp > 0) THEN
7742 length=ncgrp
7743 CALL mpalloc(vecconsgroupcounts,length,'counter for constraint groups')
7745 CALL mpalloc(vecconsgrouplist,length,'constraint group list')
7746 CALL mpalloc(vecconsgroupindex,length,'constraint group index')
7747 vecconsgroupindex=0
7748 END IF
7749
7750 ! reading events===reading events===reading events===reading events=
7751 nrece =0 ! 'empty' records (no variable global parameters)
7752 nrecf =0 ! records with fixed global parameters
7753 naeqng=0 ! count number of equations (with global der.)
7754 naeqnf=0 ! count number of equations ( " , fixed)
7755 naeqna=0 ! all
7756 WRITE(lunlog,*) 'LOOP2: start event reading'
7757 ! monitoring for sparse matrix?
7758 irecmm=0
7759 IF (matsto == 2.AND.matmon /= 0) THEN
7760 nmatmo=0
7761 IF (matmon > 0) THEN
7762 nrecmm=matmon
7763 ELSE
7764 nrecmm=1
7765 END IF
7766 END IF
7767 DO k=1,3
7768 dstat(k)=0.0_mpd
7769 END DO
7770 ! define read buffer
7771 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7772 nwrd=nc31+1
7773 length=nwrd*mthrdr
7774 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7775 nwrd=nc31*10+2+ndimbuf
7776 length=nwrd*mthrdr
7777 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7778 CALL mpalloc(readbufferdatad,length,'read buffer, real')
7779 ! to read (old) float binary files
7780 length=(ndimbuf+2)*mthrdr
7781 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7782
7783 DO
7784 CALL peread(nr) ! read records
7785 CALL peprep(1) ! prepare records
7786 ioff=0
7787 DO ibuf=1,numreadbuffer ! buffer for current record
7788 jrec=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
7789 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7790 nrec=ifd(kfile)+jrec ! global record number
7791 ! Printout for DEBUG
7792 IF(nrec <= mdebug) THEN
7793 nda=0
7794 wrec =real(readbufferdatad(readbufferpointer(ibuf)-1),mps) ! weight
7795 WRITE(*,*) ' '
7796 WRITE(*,*) 'Record number ',nrec,' from file ',kfile
7797 IF (wgh /= 1.0) WRITE(*,*) ' weight ',wrec
7798 ist=readbufferpointer(ibuf)+1
7800 DO ! loop over measurements
7801 CALL isjajb(nst,ist,ja,jb,jsp)
7802 IF(ja == 0) EXIT
7803 nda=nda+1
7804 IF(nda > mdebg2) THEN
7805 IF(nda == mdebg2+1) WRITE(*,*) '... and more data'
7806 cycle
7807 END IF
7808 WRITE(*,*) ' '
7809 WRITE(*,*) nda, ' Measured value =',readbufferdatad(ja),' +- ',readbufferdatad(jb)
7810 WRITE(*,*) 'Local derivatives:'
7811 WRITE(*,107) (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
7812107 FORMAT(6(i3,g12.4))
7813 IF (jb < ist) THEN
7814 WRITE(*,*) 'Global derivatives:'
7815 WRITE(*,108) (globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
7816 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
7817108 FORMAT(3i11,g12.4)
7818 END IF
7819 IF(nda == 1) THEN
7820 WRITE(*,*) 'total_par_label __label__ var_par_index derivative'
7821 END IF
7822 END DO
7823 WRITE(*,*) ' '
7824 END IF
7825
7826 nagbn =0 ! count number of global derivatives
7827 nalcn =0 ! count number of local derivatives
7828 naeqn =0 ! count number of equations
7829 icgrp =0 ! count constraint groups
7830 maeqnf=naeqnf
7831 ist=readbufferpointer(ibuf)+1
7833 nwrd=nst-ist+1
7834 DO ! loop over measurements
7835 CALL isjajb(nst,ist,ja,jb,jsp)
7836 IF(ja == 0.AND.jb == 0) EXIT
7837 naeqn=naeqn+1
7838 naeqna=naeqna+1
7839 IF(ja /= 0) THEN
7840 IF (ist > jb) THEN
7841 naeqng=naeqng+1
7842 ! monitoring, group measurements, sum up entries and errors
7843 IF (imonit /= 0) THEN
7844 rerr =real(readbufferdatad(jb),mpd) ! the error
7845 ij=readbufferdatai(jb+1) ! index of first global parameter, used to group measurements
7846 measindex(ij)=measindex(ij)+1
7847 measres(ij)=measres(ij)+rerr
7848 END IF
7849 END IF
7850 nfixed=0
7851 DO j=1,ist-jb
7852 ij=readbufferdatai(jb+j) ! index of global parameter
7853 IF (nzgb > 0) THEN
7854 ! count zero global derivatives
7855 IF (readbufferdatad(jb+j) == 0.0_mpl) globalparlabelzeros(ij)=globalparlabelzeros(ij)+1
7856 END IF
7857 ! check appearance
7858 IF (icheck > 1) THEN
7859 joff = 5*(ij-1)
7860 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7861 IF (appearancecounter(joff+1) == 0) THEN
7862 appearancecounter(joff+1) = kfile
7863 appearancecounter(joff+2) = jrec ! (local) record number
7864 END IF
7865 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=appearancecounter(joff+5)+1
7866 appearancecounter(joff+3) = kfile
7867 appearancecounter(joff+4) = jrec ! (local) record number
7868 ! count pairs
7869 DO k=1,j
7871 END DO
7872 jcgrp=globalparcons(ij)
7873 ! correlate constraint groups with 'other' parameter groups
7874 DO k=1,j
7875 kcgrp=globalparcons(readbufferdatai(jb+k))
7876 IF (kcgrp == jcgrp) cycle
7877 IF (jcgrp > 0) CALL inbmap(ntpgrp+jcgrp,globalparlabelindex(4,readbufferdatai(jb+k)))
7878 IF (kcgrp > 0) CALL inbmap(ntpgrp+kcgrp,globalparlabelindex(4,ij))
7879 END DO
7880 END IF
7881 ! check constraint groups
7882 IF (icheck > 0.AND.ncgrp > 0) THEN
7883 k=globalparcons(ij) ! constraint group
7884 IF (k > 0) THEN
7885 icount=naeqn
7886 IF (mcount > 0) icount=1 ! count records
7887 IF (vecconsgroupindex(k) == 0) THEN
7888 ! add to list
7889 icgrp=icgrp+1
7890 vecconsgrouplist(icgrp)=k
7891 ! check appearance
7892 IF (icheck > 1) THEN
7893 joff = 5*(ntgb+k-1)
7894 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7895 IF (appearancecounter(joff+1) == 0) THEN
7896 appearancecounter(joff+1) = kfile
7897 appearancecounter(joff+2) = jrec ! (local) record number
7898 END IF
7899 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=&
7900 appearancecounter(joff+5)+1
7901 appearancecounter(joff+3) = kfile
7902 appearancecounter(joff+4) = jrec ! (local) record number
7903 END IF
7904 END IF
7905 IF (vecconsgroupindex(k) < icount) THEN
7906 ! count
7907 vecconsgroupindex(k)=icount
7909 END IF
7910 END IF
7911 END IF
7912
7913 ij=globalparlabelindex(2,ij) ! change to variable parameter
7914 IF(ij > 0) THEN
7915 ijn=backindexusage(ij) ! get index of index
7916 IF(ijn == 0) THEN ! not yet included
7917 nagbn=nagbn+1 ! count
7918 globalindexusage(nagbn)=ij ! store variable index
7919 backindexusage(ij)=nagbn ! store back index
7920 END IF
7921 ELSE
7922 nfixed=nfixed+1
7923 END IF
7924 END DO
7925 IF (nfixed > 0) naeqnf=naeqnf+1
7926 END IF
7927
7928 IF(ja /= 0.AND.jb /= 0) THEN
7929 DO j=1,jb-ja-1 ! local parameters
7930 ij=readbufferdatai(ja+j)
7931 nalcn=max(nalcn,ij)
7932 END DO
7933 END IF
7934 END DO
7935
7936 ! end-of-event
7937 IF (naeqnf > maeqnf) nrecf=nrecf+1
7938 irecmm=irecmm+1
7939 ! end-of-event-end-of-event-end-of-event-end-of-event-end-of-event-e
7940
7941 maxglobalpar=max(nagbn,maxglobalpar) ! maximum number of global parameters
7942 maxlocalpar=max(nalcn,maxlocalpar) ! maximum number of local parameters
7943 maxequations=max(naeqn,maxequations) ! maximum number of equations
7944
7945 ! sample statistics for caching
7946 dstat(1)=dstat(1)+real((nwrd+2)*2,mpd) ! record size
7947 dstat(2)=dstat(2)+real(nagbn+2,mpd) ! indices,
7948 dstat(3)=dstat(3)+real(nagbn*nagbn+nagbn,mpd) ! data for MUPDAT
7949
7950 ! clear constraint groups index
7951 DO k=1, icgrp
7952 vecconsgroupindex(vecconsgrouplist(k))=0
7953 END DO
7954
7955 CALL sort1k(globalindexusage,nagbn) ! sort global par.
7956
7957 IF (nagbn == 0) THEN
7958 nrece=nrece+1
7959 ELSE
7960 ! update parameter range
7963 ENDIF
7964
7965 ! overwrite read buffer with lists of global labels
7966 ioff=ioff+1
7967 readbufferpointer(ibuf)=ioff
7968 readbufferdatai(ioff)=ioff+nagbn
7969 joff=ioff
7970 lvpgrp=-1
7971 DO i=1,nagbn ! reset global index array, store parameter groups
7972 iext=globalindexusage(i)
7973 backindexusage(iext)=0
7974 ivpgrp=globalallpartogroup(iext)
7975 !ivpgrp=iext
7976 IF (ivpgrp /= lvpgrp) THEN
7977 joff=joff+1
7978 readbufferdatai(joff)=ivpgrp
7979 lvpgrp=ivpgrp
7980 END IF
7981 END DO
7982 readbufferdatai(ioff)=joff
7983 ioff=joff
7984
7985 END DO
7986 ioff=0
7987
7988 IF (matsto == 3) THEN
7989 !$OMP PARALLEL &
7990 !$OMP DEFAULT(PRIVATE) &
7991 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7992 iproc=0
7993 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7994 DO ibuf=1,numreadbuffer
7995 ist=readbufferpointer(ibuf)+1
7997 DO i=ist,nst ! store all combinations
7998 iext=readbufferdatai(i) ! variable global index
7999 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct column per thread
8000 DO l=i,nst
8001 jext=readbufferdatai(l)
8002 CALL inbits(iext,jext,1) ! save space
8003 END DO
8004 !$ ENDIF
8005 END DO
8006 END DO
8007 !$OMP END PARALLEL
8008 END IF
8009 IF (matsto == 2) THEN
8010 !$OMP PARALLEL &
8011 !$OMP DEFAULT(PRIVATE) &
8012 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
8013 iproc=0
8014 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
8015 DO ibuf=1,numreadbuffer
8016 ist=readbufferpointer(ibuf)+1
8018 DO i=ist,nst ! store all combinations
8019 iext=readbufferdatai(i) ! variable global index
8020 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct rows per thread
8021 DO l=ist,i
8022 jext=readbufferdatai(l)
8023 CALL inbits(iext,jext,1) ! save space
8024 END DO
8025 !$ ENDIF
8026 END DO
8027 END DO
8028 !$OMP END PARALLEL
8029 ! monitoring
8030 IF (matmon /= 0.AND. &
8031 (irecmm >= nrecmm.OR.irecmm == mxrec)) THEN
8032 IF (nmatmo == 0) THEN
8033 WRITE(*,*)
8034 WRITE(*,*) 'Monitoring of sparse matrix construction'
8035 WRITE(*,*) ' records ........ off-diagonal elements ', &
8036 '....... compression memory'
8037 WRITE(*,*) ' non-zero used(double) used', &
8038 '(float) [%] [GB]'
8039 END IF
8040 nmatmo=nmatmo+1
8041 CALL ckbits(globalallindexgroups,ndimsa)
8042 gbc=1.0e-9*real((mpi*ndimsa(2)+mpd*ndimsa(3)+mps*ndimsa(4))/mpi*(bit_size(1_mpi)/8),mps) ! GB compressed
8043 gbu=1.0e-9*real(((mpi+mpd)*(ndimsa(3)+ndimsa(4)))/mpi*(bit_size(1_mpi)/8),mps) ! GB uncompressed
8044 cpr=100.0*gbc/gbu
8045 WRITE(*,1177) irecmm,ndimsa(1),ndimsa(3),ndimsa(4),cpr,gbc
80461177 FORMAT(i9,3i13,f10.2,f11.6)
8047 DO WHILE(irecmm >= nrecmm)
8048 IF (matmon > 0) THEN
8049 nrecmm=nrecmm+matmon
8050 ELSE
8051 nrecmm=nrecmm*2
8052 END IF
8053 END DO
8054 END IF
8055
8056 END IF
8057
8058 IF (nr <= 0) EXIT ! next block of events ?
8059 END DO
8060 ! release read buffer
8065
8066 WRITE(lunlog,*) 'LOOP2: event reading ended - end of data'
8067 DO k=1,3
8068 dstat(k)=dstat(k)/real(nrec,mpd)
8069 END DO
8070 ! end=of=data=end=of=data=end=of=data=end=of=data=end=of=data=end=of
8071
8072 IF (icheck > 0.AND. ncgrp > 0) THEN
8073 CALL mpdealloc(vecconsgroupindex)
8074 CALL mpdealloc(vecconsgrouplist)
8075 END IF
8076
8077 IF (icheck > 1) THEN
8079 END IF
8080 IF (icheck > 3) THEN
8081 length=ntpgrp+ncgrp
8082 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
8083 print *
8084 print *, ' Total parameter groups pairs', ntpgrp
8085 DO i=1,ntpgrp
8086 itgbi=globaltotindexgroups(1,i)
8087 CALL ggbmap(i,npair,vecpairedpargroups)
8088 k=globalparlabelindex(4,itgbi) ! (total) group index
8089 print *, i, itgbi, globalparlabelindex(1,itgbi), npair, ':', vecpairedpargroups(:npair)
8090 END DO
8091 print *
8092 END IF
8093
8094 ! check constraints
8095 IF(matsto == 2) THEN
8096
8097 ! constraints and index pairs with Lagrange multiplier
8098 inc=max(mreqpe, msngpe+1) ! keep constraints in double precision
8099
8100 ! loop over (sorted) constraints
8101 DO jcgb=1,ncgb
8102 icgb=matconssort(3,jcgb) ! unsorted constraint index
8103 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8104 label=listconstraints(i)%label
8105 itgbi=inone(label)
8106 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8107 IF(ij > 0 .AND. nagb > nvgb) THEN
8109 END IF
8110 END DO
8111 END DO
8112 END IF
8113 IF(matsto == 3) THEN
8114 ! loop over (sorted) constraints
8115 DO jcgb=1,ncgb
8116 icgb=matconssort(3,jcgb) ! unsorted constraint index
8117 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8118 label=listconstraints(i)%label
8119 itgbi=inone(label)
8120 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8121 IF(ij > 0.AND.listconstraints(i)%value /= 0.0_mpd) THEN
8122 ! non-zero coefficient
8123 CALL irbits(ij,jcgb)
8124 END IF
8125 END DO
8126 END DO
8127 END IF
8128
8129 ! check measurements
8130 IF(matsto == 2 .OR. matsto == 3) THEN
8131 ! measurements - determine index-pairs
8132
8133 i=1
8134 DO WHILE (i <= lenmeasurements)
8135 i=i+2
8136 ! loop over label/factor pairs
8137 ia=i
8138 DO
8139 i=i+1
8140 IF(i > lenmeasurements) EXIT
8141 IF(listmeasurements(i)%label < 0) EXIT
8142 END DO
8143 ib=i-1
8144
8145 DO j=ia,ib
8146 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8147 ! first index
8148 ivgbij=0
8149 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8150 DO k=ia,j
8151 itgbik=inone(listmeasurements(k)%label) ! total parameter index
8152 ! second index
8153 ivgbik=0
8154 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
8155 IF(ivgbij > 0.AND.ivgbik > 0) THEN
8157 IF (mprint > 1) WRITE(*,*) 'add index pair ',ivgbij,ivgbik
8158 END IF
8159 END DO
8160 END DO
8161
8162 END DO
8163 ELSE
8164 ! more checks for block diagonal structure
8165 ! loop over measurements
8166 i=1
8167 DO WHILE (i <= lenmeasurements)
8168 i=i+2
8169 ! loop over label/factor pairs
8170 ia=i
8171 DO
8172 i=i+1
8173 IF(i > lenmeasurements) EXIT
8174 IF(listmeasurements(i)%label < 0) EXIT
8175 END DO
8176 ib=i-1
8177 ij1=nvgb
8178 ijn=1
8179 DO j=ia,ib
8180 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8181 ! first index
8182 ij=0
8183 IF(itgbij /= 0) ij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8184 IF (ij > 0) THEN
8185 ij1=min(ij1,ij)
8186 ijn=max(ijn,ij)
8187 END IF
8188 END DO
8189 globalindexranges(ij1)=max(globalindexranges(ij1),ijn)
8190 END DO
8191
8192 END IF
8193
8194 nummeas=0 ! number of measurement groups
8195 IF (imonit /= 0) THEN
8196 DO i=1,ntgb
8197 IF (measindex(i) > 0) THEN
8199 measres(i) = measres(i)/real(measindex(i),mpd)
8200 measindex(i) = nummeas
8201 END IF
8202 END DO
8203 length=nummeas*mthrd*measbins
8204 CALL mpalloc(meashists,length,'measurement counter')
8205 END IF
8206
8207 ! check for block diagonal structure, count blocks
8208 npblck=0
8209 l=0
8210 DO i=1,nvgb
8211 IF (i > l) npblck=npblck+1
8212 l=max(l,globalindexranges(i))
8213 globalindexranges(i)=npblck ! block number
8214 END DO
8215
8216 length=npblck+1; rows=2
8217 ! parameter blocks
8218 CALL mpalloc(matparblockoffsets,rows,length,'global parameter blocks (I)')
8220 CALL mpalloc(vecparblockconoffsets,length,'global parameter blocks (I)')
8222 ! fill matParBlocks
8223 l=0
8224 DO i=1,nvgb
8225 IF (globalindexranges(i) > l) THEN
8226 l=globalindexranges(i) ! block number
8227 matparblockoffsets(1,l)=i-1 ! block offset
8228 END IF
8229 END DO
8231 nparmx=0
8232 DO i=1,npblck
8233 rows=matparblockoffsets(1,i+1)-matparblockoffsets(1,i)
8234 nparmx=max(nparmx,int(rows,mpi))
8235 END DO
8236
8237 ! connect constraint blocks
8238 DO i=1,ncblck
8239 ia=matconsblocks(2,i) ! first parameter in constraint block
8240 IF (ia > matconsblocks(3,i)) cycle
8241 ib=globalindexranges(ia) ! parameter block number
8242 matparblockoffsets(2,ib+1)=i
8243 END DO
8244
8245 ! use diagonal block matrix storage?
8246 IF (npblck > 1) THEN
8247 IF (icheck > 0) THEN
8248 WRITE(*,*)
8249 DO i=1,npblck
8250 ia=matparblockoffsets(1,i)
8251 ib=matparblockoffsets(1,i+1)
8252 ja=matparblockoffsets(2,i)
8253 jb=matparblockoffsets(2,i+1)
8256 WRITE(*,*) ' Parameter block', i, ib-ia, jb-ja, labelf, labell
8257 ENDDO
8258 ENDIF
8259 WRITE(lunlog,*)
8260 WRITE(lunlog,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8261 WRITE(*,*)
8262 WRITE(*,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8263 IF ((metsol == 1.OR.metsol == 3.OR.metsol>=7).AND.nagb == nvgb) THEN
8264 WRITE(*,*) 'Using block diagonal storage mode'
8265 ELSE
8266 ! keep single block = full matrix
8267 DO i=1,2
8269 END DO
8270 npblck=1
8271 DO i=1,nvgb
8273 END DO
8274 END IF
8275 END IF
8276
8277 ! print numbers ----------------------------------------------------
8278
8279 IF (nagb >= 65536) THEN
8280 noff=int(noff8/1000,mpi)
8281 ELSE
8282 noff=int(noff8,mpi)
8283 END IF
8284 ndgn=0
8285 matwords=0
8286 IF(matsto == 2) THEN
8287 ihis=0
8288 IF (mhispe > 0) THEN
8289 ihis=15
8290 CALL hmpdef(ihis,0.0,real(mhispe,mps), 'NDBITS: #off-diagonal elements')
8291 END IF
8292 length=(napgrp+1)*nspc
8293 CALL mpalloc(sparsematrixoffsets,two,length, 'sparse matrix row offsets')
8295 ndgn=ndimsa(3)+ndimsa(4) ! actual number of off-diagonal elements
8296 matwords=ndimsa(2)+length*4 ! size of sparsity structure
8297
8298 IF (mhispe > 0) THEN
8299 IF (nhistp /= 0) CALL hmprnt(ihis)
8300 CALL hmpwrt(ihis)
8301 END IF
8302 END IF
8303 IF (matsto == 3) THEN
8304 length=nagb+1
8305 CALL mpalloc(csr3rowoffsets,length, 'sparse matrix row offsets (CSR3)')
8306 IF (mpdbsz > 1) THEN
8307 ! BSR3, check (for optimal) block size
8308 mbwrds=0
8309 DO i=1,mpdbsz
8310 npdblk=(nagb-1)/ipdbsz(i)+1
8311 length=int(npdblk,mpl)
8312 CALL mpalloc(vecblockcounts,length, 'sparse matrix row offsets (CSR3)')
8313 CALL pbsbits(globalallindexgroups,ipdbsz(i),nnzero,nblock,vecblockcounts)
8314 nbwrds=2*int(nblock,mpl)*int(ipdbsz(i)*ipdbsz(i)+1,mpl) ! number of words needed
8315 IF ((i == 1).OR.(nbwrds < mbwrds)) THEN
8316 matbsz=ipdbsz(i)
8317 mbwrds=nbwrds
8318 csr3rowoffsets(1)=1
8319 DO k=1,npdblk
8320 csr3rowoffsets(k+1)=csr3rowoffsets(k)+vecblockcounts(k)
8321 END DO
8322 END IF
8323 CALL mpdealloc(vecblockcounts)
8324 END DO
8325 ELSE
8326 ! CSR3
8328 !csr3RowOffsets(nvgb+2:)=csr3RowOffsets(nvgb+1) ! Lagrange multipliers (empty)
8329 END IF
8330 END IF
8331
8332 nagbn=maxglobalpar ! max number of global parameters in one event
8333 nalcn=maxlocalpar ! max number of local parameters in one event
8334 naeqn=maxequations ! max number of equations in one event
8337 ! matrices for event matrices
8338 ! split up cache
8339 IF (fcache(2) == 0.0) THEN ! from data (DSTAT)
8340 fcache(1)=real(dstat(1),mps)*fcache(1) ! leave some part free for fluctuations
8341 fcache(2)=real(dstat(2),mps)
8342 fcache(3)=real(dstat(3),mps)
8343 END IF
8344 fsum=fcache(1)+fcache(2)+fcache(3)
8345 DO k=1,3
8346 fcache(k)=fcache(k)/fsum
8347 END DO
8348 ncachr=nint(real(ncache,mps)*fcache(1),mpi) ! read cache
8349 ! define read buffer
8350 nc31=ncachr/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
8351 nwrd=nc31+1
8352 length=nwrd*mthrdr
8353 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
8354 nwrd=nc31*10+2+ndimbuf
8355 length=nwrd*mthrdr
8356 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
8357 CALL mpalloc(readbufferdatad,length,'read buffer, real')
8358 ! to read (old) float binary files
8359 length=(ndimbuf+2)*mthrdr
8360 CALL mpalloc(readbufferdataf,length,'read buffer, float')
8361
8362 ncachi=nint(real(ncache,mps)*fcache(2),mpi) ! index cache
8363 ncachd=ncache-ncachr-ncachi ! data cache
8364 nggd=(nagbn*nagbn+nagbn)/2+ncachd/(2*mthrd) ! number of double
8365 nggi=2+nagbn+ncachi/mthrd ! number of ints
8366 length=nagbn*mthrd
8367 CALL mpalloc(globalindexusage,length, 'global parameters (dim =max/event)')
8368 length=nvgb*mthrd
8369 CALL mpalloc(backindexusage,length,'global variable-index array')
8371 length=nagbn*nalcn
8372 CALL mpalloc(localglobalmatrix,length,'local/global matrix, content')
8373 CALL mpalloc(localglobalmap,length,'local/global matrix, map (counts)')
8374 length=2*nagbn*nalcn+nagbn+nalcn+1
8375 CALL mpalloc(localglobalstructure,length,'local/global matrix, (sparsity) structure')
8376 length=nggd*mthrd
8377 CALL mpalloc(writebufferupdates,length,'symmetric update matrices')
8378 writebufferheader(-1)=nggd ! number of words per thread
8379 writebufferheader(-2)=(nagbn*nagbn+nagbn)/2 ! min free (double) words
8380 length=nggi*mthrd
8381 CALL mpalloc(writebufferindices,length,'symmetric update matrix indices')
8382 rows=9; cols=mthrd
8383 CALL mpalloc(writebufferinfo,rows,cols,'write buffer status (I)')
8384 rows=2; cols=mthrd
8385 CALL mpalloc(writebufferdata,rows,cols,'write buffer status (F)')
8386 writebufferheader(1)=nggi ! number of words per thread
8387 writebufferheader(2)=nagbn+3 ! min free words
8388
8389 ! print all relevant dimension parameters
8390
8391 DO lu=6,8,2 ! unit 6 and 8
8392
8393 WRITE(lu,*) ' '
8394 WRITE(lu,101) 'NTGB',ntgb,'total number of parameters'
8395 WRITE(lu,102) '(all parameters, appearing in binary files)'
8396 WRITE(lu,101) 'NVGB',nvgb,'number of variable parameters'
8397 WRITE(lu,102) '(appearing in fit matrix/vectors)'
8398 WRITE(lu,101) 'NAGB',nagb,'number of all parameters'
8399 WRITE(lu,102) '(including Lagrange multiplier or reduced)'
8400 WRITE(lu,101) 'NTPGRP',ntpgrp,'total number of parameter groups'
8401 WRITE(lu,101) 'NVPGRP',nvpgrp,'number of variable parameter groups'
8402 WRITE(lu,101) 'NFGB',nfgb,'number of fit parameters'
8403 IF(metsol >= 4.AND. metsol <7) THEN ! band matrix as MINRES preconditioner
8404 WRITE(lu,101) 'MBANDW',mbandw,'band width of preconditioner matrix'
8405 WRITE(lu,102) '(if <0, no preconditioner matrix)'
8406 END IF
8407 IF (nagb >= 65536) THEN
8408 WRITE(lu,101) 'NOFF/K',noff,'max number of off-diagonal elements'
8409 ELSE
8410 WRITE(lu,101) 'NOFF',noff,'max number of off-diagonal elements'
8411 END IF
8412 IF(ndgn /= 0) THEN
8413 IF (nagb >= 65536) THEN
8414 WRITE(lu,101) 'NDGN/K',ndgn/1000,'actual number of off-diagonal elements'
8415 ELSE
8416 WRITE(lu,101) 'NDGN',ndgn,'actual number of off-diagonal elements'
8417 ENDIF
8418 ENDIF
8419 WRITE(lu,101) 'NCGB',ncgb,'number of constraints'
8420 WRITE(lu,101) 'NAGBN',nagbn,'max number of global parameters in an event'
8421 WRITE(lu,101) 'NALCN',nalcn,'max number of local parameters in an event'
8422 WRITE(lu,101) 'NAEQN',naeqn,'max number of equations in an event'
8423 IF (mprint > 1) THEN
8424 WRITE(lu,101) 'NAEQNA',naeqna,'number of equations'
8425 WRITE(lu,101) 'NAEQNG',naeqng, &
8426 'number of equations with global parameters'
8427 WRITE(lu,101) 'NAEQNF',naeqnf, &
8428 'number of equations with fixed global parameters'
8429 WRITE(lu,101) 'NRECF',nrecf, &
8430 'number of records with fixed global parameters'
8431 END IF
8432 IF (nrece > 0) THEN
8433 WRITE(lu,101) 'NRECE',nrece, &
8434 'number of records without variable parameters'
8435 END IF
8436 IF (ncache > 0) THEN
8437 WRITE(lu,101) 'NCACHE',ncache,'number of words for caching'
8438 WRITE(lu,111) (fcache(k)*100.0,k=1,3)
8439111 FORMAT(22x,'cache splitting ',3(f6.1,' %'))
8440 END IF
8441 WRITE(lu,*) ' '
8442
8443 WRITE(lu,*) ' '
8444 WRITE(lu,*) 'Solution method and matrix-storage mode:'
8445 IF(metsol == 1) THEN
8446 WRITE(lu,*) ' METSOL = 1: matrix inversion'
8447 ELSE IF(metsol == 2) THEN
8448 WRITE(lu,*) ' METSOL = 2: diagonalization'
8449 ELSE IF(metsol == 3) THEN
8450 WRITE(lu,*) ' METSOL = 3: decomposition'
8451 ELSE IF(metsol == 4) THEN
8452 WRITE(lu,*) ' METSOL = 4: MINRES (rtol', mrestl,')'
8453 ELSE IF(metsol == 5) THEN
8454 WRITE(lu,*) ' METSOL = 5: MINRES-QLP (rtol', mrestl,')'
8455 ELSE IF(metsol == 6) THEN
8456 WRITE(lu,*) ' METSOL = 6: GMRES'
8457#ifdef LAPACK64
8458 ELSE IF(metsol == 7) THEN
8459 WRITE(lu,*) ' METSOL = 7: LAPACK factorization'
8460 ELSE IF(metsol == 8) THEN
8461 WRITE(lu,*) ' METSOL = 8: LAPACK factorization'
8462#ifdef PARDISO
8463 ELSE IF(metsol == 9) THEN
8464 WRITE(lu,*) ' METSOL = 9: Intel oneMKL PARDISO'
8465#endif
8466#endif
8467 END IF
8468 WRITE(lu,*) ' with',mitera,' iterations'
8469 IF(matsto == 0) THEN
8470 WRITE(lu,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
8471 ELSE IF(matsto == 1) THEN
8472 WRITE(lu,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
8473 ELSE IF(matsto == 2) THEN
8474 WRITE(lu,*) ' MATSTO = 2: sparse matrix (custom)'
8475 ELSE IF(matsto == 3) THEN
8476 IF (matbsz < 2) THEN
8477 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
8478 ELSE
8479 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
8480 WRITE(lu,*) ' block size', matbsz
8481 END IF
8482 END IF
8483 IF(npblck > 1) THEN
8484 WRITE(lu,*) ' block diagonal with', npblck, ' blocks'
8485 END IF
8486 IF(mextnd>0) WRITE(lu,*) ' with extended storage'
8487 IF(dflim /= 0.0) THEN
8488 WRITE(lu,103) 'Convergence assumed, if expected dF <',dflim
8489 END IF
8490 IF(ncgb > 0) THEN
8491 IF(nfgb < nvgb) THEN
8492 IF (icelim > 1) THEN
8493 WRITE(lu,*) 'Constraints handled by elimination with LAPACK'
8494 ELSE
8495 WRITE(lu,*) 'Constraints handled by elimination'
8496 END IF
8497 ELSE
8498 WRITE(lu,*) 'Constraints handled by Lagrange multipliers'
8499 ENDIF
8500 END IF
8501
8502 END DO ! print loop
8503
8504 IF(nalcn == 0) THEN
8505 CALL peend(28,'Aborted, no local parameters')
8506 stop 'LOOP2: stopping due to missing local parameters'
8507 END IF
8508
8509 ! Wolfe conditions
8510
8511 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8512 IF(wolfc1 == 0.0) wolfc1=1.0e-4
8513 IF(wolfc2 == 0.0) wolfc2=0.9
8514 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8515 IF(wolfc1 <= 0.0) wolfc1=1.0e-4
8516 IF(wolfc2 >= 1.0) wolfc2=0.9
8517 IF(wolfc1 > wolfc2) THEN ! exchange
8518 wolfc3=wolfc1
8520 wolfc2=wolfc3
8521 ELSE
8522 wolfc1=1.0e-4
8523 wolfc2=0.9
8524 END IF
8525 WRITE(*,105) wolfc1,wolfc2
8526 WRITE(lun,105) wolfc1,wolfc2
8527105 FORMAT(' Constants C1, C2 for Wolfe conditions:',g12.4,', ',g12.4)
8528
8529 ! prepare matrix and gradient storage ------------------------------
853032 matsiz=0 ! number of words for double, single precision storage
8531 IF (matsto == 3) THEN ! sparse matrix (CSR3, BSR3)
8532 npdblk=(nagb-1)/matbsz+1 ! number of row blocks
8533 length=csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
8534 matsiz(1)=length*int(matbsz*matbsz,mpl)
8535 matwords=(length+nagb+1)*2 ! size of sparsity structure
8536 CALL mpalloc(csr3columnlist,length,'sparse matrix column list (CSR3)')
8537 IF (matbsz > 1) THEN
8539 ELSE
8541 END IF
8542 ELSE IF (matsto == 2) THEN ! sparse matrix (custom)
8543 matsiz(1)=ndimsa(3)+nagb
8544 matsiz(2)=ndimsa(4)
8545 CALL mpalloc(sparsematrixcolumns,ndimsa(2),'sparse matrix column list')
8547 CALL anasps ! analyze sparsity structure
8548 ELSE ! full or unpacked matrix, optional block diagonal
8549 length=nagb
8550 CALL mpalloc(globalrowoffsets,length,'global row offsets (full or unpacked (block) storage)')
8551 ! loop over blocks (multiple blocks only with elimination !)
8553 DO i=1,npblck
8554 ipoff=matparblockoffsets(1,i)
8555 icboff=matparblockoffsets(2,i) ! constraint block offset
8556 icblst=matparblockoffsets(2,i+1) ! constraint block offset
8557 npar=matparblockoffsets(1,i+1)-ipoff ! size of block (number of parameters)
8558 IF (icblst > icboff) THEN
8559 ncon=matconsblocks(1,icblst+1)-matconsblocks(1,icboff+1) ! number of constraints in (parameter) block
8560 ELSE
8561 ncon=0
8562 ENDIF
8564 nall = npar; IF (icelim <= 0) nall=npar+ncon ! add Lagrange multipliers
8565 DO k=1,nall
8566 globalrowoffsets(ipoff+k)=matsiz(1)-ipoff
8567 IF (matsto == 1) THEN
8568 matsiz(1)=matsiz(1)+k ! full ('triangular')
8569 ELSE
8570 matsiz(1)=matsiz(1)+nall ! unpacked ('quadratic')
8571 END IF
8572 END DO
8573 END DO
8574 END IF
8575 matwords=matwords+matsiz(1)*2+matsiz(2) ! #words for matrix storage
8576
8577 CALL feasma ! prepare constraint matrices
8578
8579 IF (icheck <= 0) CALL vmprep(matsiz) ! prepare matrix and gradient storage
8580 WRITE(*,*) ' '
8581 IF (matwords < 250000) THEN
8582 WRITE(*,*) 'Size of global matrix: < 1 MB'
8583 ELSE
8584 WRITE(*,*) 'Size of global matrix:',int(real(matwords,mps)*4.0e-6,mpi),' MB'
8585 ENDIF
8586 ! print chi^2 cut tables
8587
8588 ndfmax=naeqn-1
8589 WRITE(lunlog,*) ' '
8590 WRITE(lunlog,*) ' Cut values of Chi^2/Ndf and Chi2,'
8591 WRITE(lunlog,*) ' corresponding to 2 and 3 standard deviations'
8592 WRITE(lunlog,*) ' Ndf Chi^2/Ndf(2) Chi^2(2) ', &
8593 ' Chi^2/Ndf(3) Chi^2(3)'
8594 ndf=0
8595 DO
8596 IF(ndf > naeqn) EXIT
8597 IF(ndf < 10) THEN
8598 ndf=ndf+1
8599 ELSE IF(ndf < 20) THEN
8600 ndf=ndf+2
8601 ELSE IF(ndf < 100) THEN
8602 ndf=ndf+5
8603 ELSE IF(ndf < 200) THEN
8604 ndf=ndf+10
8605 ELSE
8606 EXIT
8607 END IF
8608 chin2=chindl(2,ndf)
8609 chin3=chindl(3,ndf)
8610 WRITE(lunlog,106) ndf,chin2,chin2*real(ndf,mps),chin3, chin3*real(ndf,mps)
8611 END DO
8612
8613 WRITE(lunlog,*) 'LOOP2: ending'
8614 WRITE(lunlog,*) ' '
8615 ! warnings from check input mode
8616 IF (icheck > 0) THEN
8617 IF (ncgbe /= 0) THEN
8618 WRITE(*,199) ' '
8619 WRITE(*,199) ' '
8620 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8621 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8622 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8623 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8624 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8625 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8626 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8627 WRITE(*,199) ' '
8628 WRITE(*,*) ' Number of empty constraints =',abs(ncgbe), ', should be 0'
8629 WRITE(*,*) ' => please check constraint definition, mille data'
8630 WRITE(*,199) ' '
8631 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8632 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8633 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8634 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8635 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8636 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8637 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8638 WRITE(*,199) ' '
8639 END IF
8640 END IF
8641 CALL mend
8642101 FORMAT(1x,a8,' =',i14,' = ',a)
8643102 FORMAT(22x,a)
8644103 FORMAT(1x,a,g12.4)
8645106 FORMAT(i6,2(3x,f9.3,f12.1,3x))
8646199 FORMAT(7x,a)
8647END SUBROUTINE loop2
8648
8653SUBROUTINE monres
8654 USE mpmod
8655 USE mpdalc
8656
8657 IMPLICIT NONE
8658 INTEGER(mpi) :: i
8659 INTEGER(mpi) :: ij
8660 INTEGER(mpi) :: imed
8661 INTEGER(mpi) :: j
8662 INTEGER(mpi) :: k
8663 INTEGER(mpi) :: nent
8664 INTEGER(mpi), DIMENSION(measBins) :: isuml ! location
8665 INTEGER(mpi), DIMENSION(measBins) :: isums ! scale
8666 REAL(mps) :: amed
8667 REAL(mps) :: amad
8668
8669 INTEGER(mpl) :: ioff
8670 LOGICAL :: lfirst
8671 SAVE
8672 DATA lfirst /.true./
8673
8674 ! combine data from threads
8675 ioff=0
8676 DO i=2,mthrd
8677 ioff=ioff+measbins*nummeas
8678 DO j=1,measbins*nummeas
8679 meashists(j)=meashists(j)+meashists(ioff+j)
8680 END DO
8681 END DO
8682
8683 IF (lfirst) THEN
8684 IF (imonmd == 0) THEN
8685 WRITE(lunmon,'(A)') '*** Normalized residuals grouped by first global label (per local fit cycle) ***'
8686 ELSE
8687 WRITE(lunmon,'(A)') '*** Pulls grouped by first global label (per local fit cycle) ***'
8688 ENDIF
8689 WRITE(lunmon,'(A)') '! LFC Label Entries Median RMS(MAD) <error>'
8690 lfirst=.false.
8691 END IF
8692
8693 !$POMP INST BEGIN(monres)
8694#ifdef SCOREP_USER_ENABLE
8695 scorep_user_region_by_name_begin("UR_monres", scorep_user_region_type_common)
8696#endif
8697 ! analyze histograms
8698 ioff=0
8699 DO i=1,ntgb
8700 IF (measindex(i) > 0) THEN
8701 isuml=0
8702 ! sum up content
8703 isuml(1)=meashists(ioff+1)
8704 DO j=2,measbins
8705 isuml(j)=isuml(j-1)+meashists(ioff+j)
8706 END DO
8707 nent=isuml(measbins)
8708 IF (nent > 0) THEN
8709 ! get median (for location)
8710 DO j=2,measbins
8711 IF (2*isuml(j) > nent) EXIT
8712 END DO
8713 imed=j
8714 amed=real(j,mps)
8715 IF (isuml(j) > isuml(j-1)) amed=amed+real(nent-2*isuml(j-1),mps)/real(2*isuml(j)-2*isuml(j-1),mps)
8716 amed=real(measbinsize,mps)*(amed-real(measbins/2,mps))
8717 ! sum up differences
8718 isums = 0
8719 DO j=imed,measbins
8720 k=j-imed+1
8721 isums(k)=isums(k)+meashists(ioff+j)
8722 END DO
8723 DO j=imed-1,1,-1
8724 k=imed-j
8725 isums(k)=isums(k)+meashists(ioff+j)
8726 END DO
8727 DO j=2, measbins
8728 isums(j)=isums(j)+isums(j-1)
8729 END DO
8730 ! get median (for scale)
8731 DO j=2,measbins
8732 IF (2*isums(j) > nent) EXIT
8733 END DO
8734 amad=real(j-1,mps)
8735 IF (isums(j) > isums(j-1)) amad=amad+real(nent-2*isums(j-1),mps)/real(2*isums(j)-2*isums(j-1),mps)
8736 amad=real(measbinsize,mps)*amad
8737 ELSE
8738 amed=0.0
8739 amad=0.0
8740 END IF
8741 ij=globalparlabelindex(1,i)
8742 WRITE(lunmon,110) nloopn, ij, nent, amed, amad*1.4826, real(measres(i),mps)
8743 !
8744 ioff=ioff+measbins
8745 END IF
8746 END DO
8747#ifdef SCOREP_USER_ENABLE
8748 scorep_user_region_by_name_end("UR_monres")
8749#endif
8750 !$POMP INST END(monres)
8751
8752110 FORMAT(i5,2i10,3g14.5)
8753END SUBROUTINE monres
8754
8755
8759
8760SUBROUTINE vmprep(msize)
8761 USE mpmod
8762 USE mpdalc
8763
8764 IMPLICIT NONE
8765 INTEGER(mpi) :: i
8766 INTEGER(mpi) :: ib
8767 INTEGER(mpi) :: ioff
8768 INTEGER(mpi) :: ipar0
8769 INTEGER(mpi) :: ncon
8770 INTEGER(mpi) :: npar
8771 INTEGER(mpi) :: nextra
8772#ifdef LAPACK64
8773 INTEGER :: nbopt, nboptx, ILAENV
8774#endif
8775 !
8776 INTEGER(mpl), INTENT(IN) :: msize(2)
8777
8778 INTEGER(mpl) :: length
8779 INTEGER(mpl) :: nwrdpc
8780 INTEGER(mpl), PARAMETER :: three = 3
8781
8782 SAVE
8783 ! ...
8784 ! Vector/matrix storage
8785 length=nagb*mthrd
8786 CALL mpalloc(globalvector,length,'rhs vector') ! double precision vector
8787 CALL mpalloc(globalcounter,length,'rhs counter') ! integer vector
8789 length=naeqn*mthrd
8790 CALL mpalloc(localcorrections,length,'residual vector of one record')
8791 CALL mpalloc(localequations,three,length,'mesurements indices (ISJAJB) of one record')
8792 length=nalcn*nalcn
8793 CALL mpalloc(aux,length,' local fit scratch array: aux')
8794 CALL mpalloc(vbnd,length,' local fit scratch array: vbnd')
8795 CALL mpalloc(vbdr,length,' local fit scratch array: vbdr')
8796 length=((nalcn+1)*nalcn)/2
8797 CALL mpalloc(clmat,length,' local fit matrix: clmat')
8798 CALL mpalloc(vbk,length,' local fit scratch array: vbk')
8799 length=nalcn
8800 CALL mpalloc(blvec,length,' local fit vector: blvec')
8801 CALL mpalloc(vzru,length,' local fit scratch array: vzru')
8802 CALL mpalloc(scdiag,length,' local fit scratch array: scdiag')
8803 CALL mpalloc(scflag,length,' local fit scratch array: scflag')
8804 CALL mpalloc(ibandh,2*length,' local fit band width hist.: ibandh')
8805
8806 CALL mpalloc(globalmatd,msize(1),'global matrix (D)' )
8807 CALL mpalloc(globalmatf,msize(2),'global matrix (F)')
8808
8809 mszpcc=0
8810 IF(metsol >= 4.AND.metsol < 7.AND. mbandw >= 0) THEN ! GMRES/MINRES algorithms
8811 ! array space is:
8812 ! variable-width band matrix or diagonal matrix for parameters
8813 ! followed by symmetric matrix for constraints
8814 ! followed by rectangular matrix for constraints
8815 nwrdpc=0
8816 ncon=nagb-nvgb ! number of Lagrange multipliers
8817 ! constraint block info
8818 length=4*ncblck; IF(ncon == 0) length=0
8819 CALL mpalloc(blockprecond,length,'preconditioner: constraint blocks')
8820 length=ncon
8821 CALL mpalloc(offprecond,length,'preconditioner: constraint offsets')
8822 !END IF
8823 ! variable-width band matrix ?
8824 IF(mbandw > 0) THEN
8825 length=nagb
8826 CALL mpalloc(indprecond,length,'pointer-array variable-band matrix')
8827 nwrdpc=nwrdpc+length
8828 DO i=1,min(mbandw,nvgb)
8829 indprecond(i)=(i*i+i)/2 ! increasing number
8830 END DO
8831 DO i=min(mbandw,nvgb)+1,nvgb
8832 indprecond(i)=indprecond(i-1)+mbandw ! fixed band width
8833 END DO
8834 DO i=nvgb+1,nagb ! reset
8835 indprecond(i)=0
8836 END DO
8837 END IF
8838 ! symmetric part
8839 length=(ncon*ncon+ncon)/2
8840 ! add 'band' part
8841 IF(mbandw > 0) THEN ! variable-width band matrix
8842 length=length+indprecond(nvgb)
8843 ELSE ! default preconditioner (diagonal)
8844 length=length+nvgb
8845 END IF
8846 ! add rectangular part (compressed, constraint blocks)
8847 IF(ncon > 0) THEN
8848 ioff=0
8849 ! extra space (for forward solution in EQUDEC)
8850 nextra=max(0,mbandw-1)
8851 DO ib=1,ncblck
8852 ! first constraint in block
8853 blockprecond(ioff+1)=matconsblocks(1,ib)
8854 ! last constraint in block
8855 blockprecond(ioff+2)=matconsblocks(1,ib+1)-1
8856 ! parameter offset
8857 ipar0=matconsblocks(2,ib)-1
8858 blockprecond(ioff+3)=ipar0
8859 ! number of parameters (-> columns)
8860 npar=matconsblocks(3,ib)-ipar0
8861 blockprecond(ioff+4)=npar+nextra
8862 DO i=blockprecond(ioff+1),blockprecond(ioff+2)
8863 offprecond(i)=length-ipar0
8864 length=length+npar+nextra
8865 mszpcc=mszpcc+npar+nextra
8866 END DO
8867 ioff=ioff+4
8868 END DO
8869 ELSE
8870 IF(mbandw == 0) length=length+1 ! for valid precons argument matPreCond((ncon*ncon+ncon)/2+nvgb+1)
8871 END IF
8872 ! allocate
8873 IF(mbandw > 0) THEN
8874 CALL mpalloc(matprecond,length,'variable-band preconditioner matrix')
8875 ELSE
8876 CALL mpalloc(matprecond,length,'default preconditioner matrix')
8877 END IF
8878 nwrdpc=nwrdpc+2*length
8879 IF (nwrdpc > 250000) THEN
8880 WRITE(*,*)
8881 WRITE(*,*) 'Size of preconditioner matrix:',int(real(nwrdpc,mps)*4.0e-6,mpi),' MB'
8882 END IF
8883
8884 END IF
8885
8886
8887 length=nagb
8888 CALL mpalloc(globalcorrections,length,'corrections') ! double prec corrections
8889
8890 length=nagb
8891 CALL mpalloc(workspaced,length,'auxiliary array (D1)') ! double aux 1
8892 CALL mpalloc(workspacelinesearch,length,'auxiliary array (D2)') ! double aux 2
8893 CALL mpalloc(workspacei, length,'auxiliary array (I)') ! int aux 1
8894
8895 IF(metsol == 1) THEN
8896 CALL mpalloc(workspacediag,length,'diagonal of global matrix)') ! double aux 1
8897 CALL mpalloc(workspacerow,length,'(pivot) row of global matrix)')
8898 ! CALL MEGARR('t D',2*NAGB,'auxiliary array') ! double aux 8
8899 END IF
8900
8901 IF(metsol == 2) THEN
8902 IF(nagb>46300) THEN
8903 CALL peend(23,'Aborted, bad matrix index (will exceed 32bit)')
8904 stop 'vmprep: bad index (matrix to large for diagonalization)'
8905 END IF
8906 CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8907 CALL mpalloc(workspacediagonalization,length,'auxiliary array (D3)') ! double aux 3
8908 CALL mpalloc(workspaceeigenvalues,length,'auxiliary array (D6)') ! double aux 6
8909 length=nagb*nagb
8910 CALL mpalloc(workspaceeigenvectors,length,'(rotation) matrix U') ! rotation matrix
8911 END IF
8912
8913 IF(metsol >= 4.AND.metsol < 7) THEN
8914 CALL mpalloc(vecxav,length,'vector X (AVPROD)') ! double aux 1
8915 CALL mpalloc(vecbav,length,'vector B (AVPROD)') ! double aux 1
8916 END IF
8917
8918#ifdef LAPACK64
8919 IF(metsol == 7) THEN
8920 IF(nagb > nvgb) CALL mpalloc(lapackipiv, length,'IPIV for DSPTRG (L)') ! pivot indices for DSPTRF
8921 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8922 END IF
8923 IF(metsol == 8) THEN
8924 IF(nagb > nvgb) THEN
8925 CALL mpalloc(lapackipiv, length,'LAPACK IPIV (L)')
8926 nbopt = ilaenv( 1_mpl, 'DSYTRF', 'U', int(nagb,mpl), int(nagb,mpl), -1_mpl, -1_mpl ) ! optimal block size
8927 print *
8928 print *, 'LAPACK optimal block size for DSYTRF:', nbopt
8929 lplwrk=length*int(nbopt,mpl)
8930 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8931 ELSE IF(nfgb < nvgb.AND.icelim > 1) THEN
8932 ! elimination of constraints with LAPACK
8933 lplwrk=1
8934 DO i=1,npblck
8935 npar=matparblockoffsets(1,i+1)-matparblockoffsets(1,i) ! number of parameters in block
8936 ncon=vecparblockconoffsets(i+1)-vecparblockconoffsets(i) ! number of constraints in block
8937 nbopt = ilaenv( 1_mpl, 'DORMQL', 'RN', int(npar,mpl), int(npar,mpl), int(ncon,mpl), int(npar,mpl) ) ! optimal buffer size
8938 IF (int(npar,mpl)*int(nbopt,mpl) > lplwrk) THEN
8939 lplwrk=int(npar,mpl)*int(nbopt,mpl)
8940 nboptx=nbopt
8941 END IF
8942 END DO
8943 print *
8944 print *, 'LAPACK optimal block size for DORMQL:', nboptx
8945 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8946 END IF
8947 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8948 END IF
8949#endif
8950
8951END SUBROUTINE vmprep
8952
8956
8957SUBROUTINE minver
8958 USE mpmod
8959
8960 IMPLICIT NONE
8961 INTEGER(mpi) :: i
8962 INTEGER(mpi) :: ib
8963 INTEGER(mpi) :: icoff
8964 INTEGER(mpi) :: ipoff
8965 INTEGER(mpi) :: j
8966 INTEGER(mpi) :: lun
8967 INTEGER(mpi) :: ncon
8968 INTEGER(mpi) :: nfit
8969 INTEGER(mpi) :: npar
8970 INTEGER(mpi) :: nrank
8971 INTEGER(mpl) :: imoff
8972 INTEGER(mpl) :: ioff1
8973 REAL(mpd) :: matij
8974
8975 EXTERNAL avprds
8976
8977 SAVE
8978 ! ...
8979 lun=lunlog ! log file
8980
8981 IF(icalcm == 1) THEN
8982 ! save diagonal (for global correlation)
8983 DO i=1,nagb
8984 workspacediag(i)=matij(i,i)
8985 END DO
8986 ! use elimination for constraints ?
8987 IF(nfgb < nvgb) THEN
8988 ! monitor progress
8989 IF(monpg1 > 0) THEN
8990 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
8992 END IF
8993 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
8994 IF(monpg1 > 0) CALL monend()
8995 END IF
8996 END IF
8997
8998 ! loop over blocks (multiple blocks only with elimination !)
8999 DO ib=1,npblck
9000 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9001 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9002 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9003 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9004 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9005 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9006 ! use elimination for constraints ?
9007 IF(nfit < npar) THEN
9008 CALL qlsetb(ib)
9009 ! solve L^t*y=d by backward substitution
9011 ! transform, reduce rhs
9012 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9013 ! correction from eliminated part
9014 DO i=1,nfit
9015 DO j=1,ncon
9016 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9018 END DO
9019 END DO
9020 END IF
9021
9022 IF(icalcm == 1) THEN
9023 ! monitor progress
9024 IF(monpg1 > 0) THEN
9025 WRITE(lunlog,*) 'Inversion of global matrix (A->A^-1)'
9027 END IF
9028 ! invert and solve
9029 CALL sqminl(globalmatd(imoff+1:), globalcorrections(ipoff+1:),nfit,nrank, &
9031 IF(monpg1 > 0) CALL monend()
9032 IF(nfit /= nrank) THEN
9033 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
9034 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9035 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
9036 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9037 IF (iforce == 0 .AND. isubit == 0) THEN
9038 isubit=1
9039 WRITE(*,*) ' --> enforcing SUBITO mode'
9040 WRITE(lun,*) ' --> enforcing SUBITO mode'
9041 END IF
9042 ELSE IF(ndefec == 0) THEN
9043 IF(npblck == 1) THEN
9044 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9045 ELSE
9046 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9047 END IF
9048 END IF
9049 ndefec=ndefec+nfit-nrank ! rank defect
9050
9051 ELSE ! multiply gradient by inverse matrix
9052 workspaced(:nfit)=globalcorrections(ipoff+1:ipoff+nfit)
9053 CALL dbsvxl(globalmatd(imoff+1:),workspaced,globalcorrections(ipoff+1:),nfit)
9054 END IF
9055
9056 !use elimination for constraints ?
9057 IF(nfit < npar) THEN
9058 ! extend, transform back solution
9059 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9060 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9061 END IF
9062 END DO
9063
9064END SUBROUTINE minver
9065
9069
9070SUBROUTINE mchdec
9071 USE mpmod
9072
9073 IMPLICIT NONE
9074 INTEGER(mpi) :: i
9075 INTEGER(mpi) :: ib
9076 INTEGER(mpi) :: icoff
9077 INTEGER(mpi) :: ipoff
9078 INTEGER(mpi) :: j
9079 INTEGER(mpi) :: lun
9080 INTEGER(mpi) :: ncon
9081 INTEGER(mpi) :: nfit
9082 INTEGER(mpi) :: npar
9083 INTEGER(mpi) :: nrank
9084 INTEGER(mpl) :: imoff
9085 INTEGER(mpl) :: ioff1
9086
9087 REAL(mpd) :: evmax
9088 REAL(mpd) :: evmin
9089
9090 EXTERNAL avprds
9091
9092 SAVE
9093 ! ...
9094 lun=lunlog ! log file
9095
9096 IF(icalcm == 1) THEN
9097 ! use elimination for constraints ?
9098 ! monitor progress
9099 IF(monpg1 > 0) THEN
9100 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9102 END IF
9103 IF(nfgb < nvgb) CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9104 IF(monpg1 > 0) CALL monend()
9105 END IF
9106
9107 ! loop over blocks (multiple blocks only with elimination !)
9108 DO ib=1,npblck
9109 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9110 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9111 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9112 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9113 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9114 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9115 ! use elimination for constraints ?
9116 IF(nfit < npar) THEN
9117 CALL qlsetb(ib)
9118 ! solve L^t*y=d by backward substitution
9120 ! transform, reduce rhs
9121 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9122 ! correction from eliminated part
9123 DO i=1,nfit
9124 DO j=1,ncon
9125 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9127 END DO
9128 END DO
9129 END IF
9130
9131 IF(icalcm == 1) THEN
9132 ! monitor progress
9133 IF(monpg1 > 0) THEN
9134 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9136 END IF
9137 ! decompose and solve
9138 CALL chdec2(globalmatd(imoff+1:),nfit,nrank,evmax,evmin,monpg1)
9139 IF(monpg1 > 0) CALL monend()
9140 IF(nfit /= nrank) THEN
9141 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
9142 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9143 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
9144 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9145 IF (iforce == 0 .AND. isubit == 0) THEN
9146 isubit=1
9147 WRITE(*,*) ' --> enforcing SUBITO mode'
9148 WRITE(lun,*) ' --> enforcing SUBITO mode'
9149 END IF
9150 ELSE IF(ndefec == 0) THEN
9151 IF(npblck == 1) THEN
9152 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9153 ELSE
9154 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9155 END IF
9156 WRITE(lun,*) ' largest diagonal element (LDLt)', evmax
9157 WRITE(lun,*) ' smallest diagonal element (LDLt)', evmin
9158 END IF
9159 ndefec=ndefec+nfit-nrank ! rank defect
9160
9161 END IF
9162 ! backward/forward substitution
9163 CALL chslv2(globalmatd(imoff+1:),globalcorrections(ipoff+1:),nfit)
9164
9165 !use elimination for constraints ?
9166 IF(nfit < npar) THEN
9167 ! extend, transform back solution
9168 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9169 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9170 END IF
9171 END DO
9172
9173END SUBROUTINE mchdec
9174
9175#ifdef LAPACK64
9176
9181
9182SUBROUTINE mdptrf
9183 USE mpmod
9184
9185 IMPLICIT NONE
9186 INTEGER(mpi) :: i
9187 INTEGER(mpi) :: ib
9188 INTEGER(mpi) :: icoff
9189 INTEGER(mpi) :: ipoff
9190 INTEGER(mpi) :: j
9191 INTEGER(mpi) :: lun
9192 INTEGER(mpi) :: ncon
9193 INTEGER(mpi) :: nfit
9194 INTEGER(mpi) :: npar
9195 INTEGER(mpl) :: imoff
9196 INTEGER(mpl) :: ioff1
9197 INTEGER(mpi) :: infolp
9198 REAL(mpd) :: matij
9199
9200 EXTERNAL avprds
9201
9202 SAVE
9203 ! ...
9204 lun=lunlog ! log file
9205
9206 IF(icalcm == 1) THEN
9207 IF(ilperr == 1) THEN
9208 ! save diagonal (for global correlation)
9209 DO i=1,nagb
9210 workspacediag(i)=matij(i,i)
9211 END DO
9212 END IF
9213 ! use elimination for constraints ?
9214 IF(nfgb < nvgb) THEN
9215 ! monitor progress
9216 IF(monpg1 > 0) THEN
9217 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9219 END IF
9220 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9221 IF(monpg1 > 0) CALL monend()
9222 END IF
9223 END IF
9224
9225 ! loop over blocks (multiple blocks only with elimination !)
9226 DO ib=1,npblck
9227 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9228 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9229 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9230 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9231 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9232 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9233 ! use elimination for constraints ?
9234 IF(nfit < npar) THEN
9235 CALL qlsetb(ib)
9236 ! solve L^t*y=d by backward substitution
9238 ! transform, reduce rhs
9239 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9240 ! correction from eliminated part
9241 DO i=1,nfit
9242 DO j=1,ncon
9243 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9245 END DO
9246 END DO
9247 END IF
9248
9249 IF(icalcm == 1) THEN
9250 ! multipliers?
9251 IF (nfit > npar) THEN
9252 ! monitor progress
9253 IF(monpg1 > 0) THEN
9254 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9256 END IF
9257 !$POMP INST BEGIN(dsptrf)
9258#ifdef SCOREP_USER_ENABLE
9259 scorep_user_region_by_name_begin("UR_dsptrf", scorep_user_region_type_common)
9260#endif
9261 CALL dsptrf('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),infolp)
9262#ifdef SCOREP_USER_ENABLE
9263 scorep_user_region_by_name_end("UR_dsptrf")
9264#endif
9265 !$POMP INST END(dsptrf)
9266 IF(monpg1 > 0) CALL monend()
9267 ELSE
9268 ! monitor progress
9269 IF(monpg1 > 0) THEN
9270 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9272 END IF
9273 !$POMP INST BEGIN(dpptrf)
9274#ifdef SCOREP_USER_ENABLE
9275 scorep_user_region_by_name_begin("UR_dpptrf", scorep_user_region_type_common)
9276#endif
9277 CALL dpptrf('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
9278#ifdef SCOREP_USER_ENABLE
9279 scorep_user_region_by_name_end("UR_dpptrf")
9280#endif
9281 !$POMP INST END(dpptrf)
9282 IF(monpg1 > 0) CALL monend()
9283 ENDIF
9284 ! check result
9285 IF(infolp==0) THEN
9286 IF(npblck == 1) THEN
9287 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9288 ELSE
9289 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9290 END IF
9291 ELSE
9292 ndefec=ndefec+1 ! (lower limit of) rank defect
9293 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9294 '-by-',nfit,' failed at index ', infolp
9295 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9296 '-by-',nfit,' failed at index ', infolp
9297 CALL peend(29,'Aborted, factorization of global matrix failed')
9298 stop 'mdptrf: bad matrix'
9299 END IF
9300 END IF
9301 ! backward/forward substitution
9302 ! multipliers?
9303 IF (nfit > npar) THEN
9304 CALL dsptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),lapackipiv(ipoff+1:),&
9305 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9306 IF(infolp /= 0) print *, ' DSPTRS failed: ', infolp
9307 ELSE
9308 CALL dpptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),&
9309 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9310 IF(infolp /= 0) print *, ' DPPTRS failed: ', infolp
9311 ENDIF
9312
9313 !use elimination for constraints ?
9314 IF(nfit < npar) THEN
9315 ! extend, transform back solution
9316 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9317 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9318 END IF
9319 END DO
9320
9321END SUBROUTINE mdptrf
9322
9328
9329SUBROUTINE mdutrf
9330 USE mpmod
9331
9332 IMPLICIT NONE
9333 INTEGER(mpi) :: i
9334 INTEGER(mpi) :: ib
9335 INTEGER(mpi) :: icoff
9336 INTEGER(mpi) :: ipoff
9337 INTEGER(mpi) :: j
9338 INTEGER(mpi) :: lun
9339 INTEGER(mpi) :: ncon
9340 INTEGER(mpi) :: nfit
9341 INTEGER(mpi) :: npar
9342 INTEGER(mpl) :: imoff
9343 INTEGER(mpl) :: ioff1
9344 INTEGER(mpl) :: iloff
9345 INTEGER(mpi) :: infolp
9346
9347 REAL(mpd) :: matij
9348
9349 EXTERNAL avprds
9350
9351 SAVE
9352 ! ...
9353 lun=lunlog ! log file
9354
9355 IF(icalcm == 1) THEN
9356 IF(ilperr == 1) THEN
9357 ! save diagonal (for global correlation)
9358 DO i=1,nagb
9359 workspacediag(i)=matij(i,i)
9360 END DO
9361 END IF
9362 ! use elimination for constraints ?
9363 IF(nfgb < nvgb) THEN
9364 ! monitor progress
9365 IF(monpg1 > 0) THEN
9366 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9368 END IF
9369 IF (icelim > 1) THEN
9370 CALL lpavat(.true.)
9371 ELSE
9372 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9373 END IF
9374 IF(monpg1 > 0) CALL monend()
9375 END IF
9376 END IF
9377
9378 ! loop over blocks (multiple blocks only with elimination !)
9379 iloff=0 ! offset of L in lapackQL
9380 DO ib=1,npblck
9381 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9382 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9383 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9384 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9385 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9386 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9387 ! use elimination for constraints ?
9388 IF(nfit < npar) THEN
9389 IF (icelim > 1) THEN
9390 ! solve L^t*y=d by backward substitution
9391 vecconssolution(1:ncon)=vecconsresiduals(icoff+1:icoff+ncon)
9392 CALL dtrtrs('L','T','N',int(ncon,mpl),1_mpl,lapackql(iloff+npar-ncon+1:),int(npar,mpl),&
9393 vecconssolution,int(ncon,mpl),infolp)
9394 IF(infolp /= 0) print *, ' DTRTRS failed: ', infolp
9395 ! transform, reduce rhs, Q^t*b
9396 CALL dormql('L','T',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9397 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9398 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9399 ELSE
9400 CALL qlsetb(ib)
9401 ! solve L^t*y=d by backward substitution
9403 ! transform, reduce rhs
9404 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9405 END IF
9406 ! correction from eliminated part
9407 DO i=1,nfit
9408 DO j=1,ncon
9409 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9411 END DO
9412 END DO
9413 END IF
9414
9415 IF(icalcm == 1) THEN
9416 ! multipliers?
9417 IF (nfit > npar) THEN
9418 ! monitor progress
9419 IF(monpg1 > 0) THEN
9420 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9422 END IF
9423 !$POMP INST BEGIN(dsytrf)
9424#ifdef SCOREP_USER_ENABLE
9425 scorep_user_region_by_name_begin("UR_dsytrf", scorep_user_region_type_common)
9426#endif
9427 CALL dsytrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
9428 lapackipiv(ipoff+1:),lapackwork,lplwrk,infolp)
9429#ifdef SCOREP_USER_ENABLE
9430 scorep_user_region_by_name_end("UR_dsytrf")
9431#endif
9432 !$POMP INST END(dsytrf)
9433 IF(monpg1 > 0) CALL monend()
9434 ELSE
9435 ! monitor progress
9436 IF(monpg1 > 0) THEN
9437 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9439 END IF
9440 !$POMP INST BEGIN(dpotrf)
9441#ifdef SCOREP_USER_ENABLE
9442 scorep_user_region_by_name_begin("UR_dpotrf", scorep_user_region_type_common)
9443#endif
9444 CALL dpotrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
9445#ifdef SCOREP_USER_ENABLE
9446 scorep_user_region_by_name_end("UR_dpotrf")
9447#endif
9448 !$POMP INST END(dpotrf)
9449 IF(monpg1 > 0) CALL monend()
9450 ENDIF
9451 ! check result
9452 IF(infolp==0) THEN
9453 IF(npblck == 1) THEN
9454 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9455 ELSE
9456 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9457 END IF
9458 ELSE
9459 ndefec=ndefec+1 ! (lower limit of) rank defect
9460 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9461 '-by-',nfit,' failed at index ', infolp
9462 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9463 '-by-',nfit,' failed at index ', infolp
9464 CALL peend(29,'Aborted, factorization of global matrix failed')
9465 stop 'mdutrf: bad matrix'
9466 END IF
9467 END IF
9468 ! backward/forward substitution
9469 ! multipliers?
9470 IF (nfit > npar) THEN
9471 CALL dsytrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(nfit,mpl),&
9472 lapackipiv(ipoff+1:),globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9473 IF(infolp /= 0) print *, ' DSYTRS failed: ', infolp
9474 ELSE
9475 CALL dpotrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(npar,mpl),&
9476 globalcorrections(ipoff+1:),int(npar,mpl),infolp)
9477 IF(infolp /= 0) print *, ' DPOTRS failed: ', infolp
9478 ENDIF
9479
9480 !use elimination for constraints ?
9481 IF(nfit < npar) THEN
9482 IF (icelim > 1) THEN
9483 ! correction from eliminated part
9484 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9485 ! extend, transform back solution, Q*x
9486 CALL dormql('L','N',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9487 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9488 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9489 ELSE
9490 ! extend, transform back solution
9491 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9492 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9493 END IF
9494 END IF
9495 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9496 END DO
9497
9498END SUBROUTINE mdutrf
9499
9510SUBROUTINE lpqldec(a,emin,emax)
9511 USE mpmod
9512 USE mpdalc
9513
9514 IMPLICIT NONE
9515 INTEGER(mpi) :: ib
9516 INTEGER(mpi) :: icb
9517 INTEGER(mpi) :: icboff
9518 INTEGER(mpi) :: icblst
9519 INTEGER(mpi) :: icoff
9520 INTEGER(mpi) :: icfrst
9521 INTEGER(mpi) :: iclast
9522 INTEGER(mpi) :: ipfrst
9523 INTEGER(mpi) :: iplast
9524 INTEGER(mpi) :: ipoff
9525 INTEGER(mpi) :: i
9526 INTEGER(mpi) :: j
9527 INTEGER(mpi) :: ncon
9528 INTEGER(mpi) :: npar
9529 INTEGER(mpi) :: npb
9530 INTEGER(mpl) :: imoff
9531 INTEGER(mpl) :: iloff
9532 INTEGER(mpi) :: infolp
9533 INTEGER :: nbopt, ILAENV
9534
9535 REAL(mpd), INTENT(IN) :: a(mszcon)
9536 REAL(mpd), INTENT(OUT) :: emin
9537 REAL(mpd), INTENT(OUT) :: emax
9538 SAVE
9539
9540 print *
9541 ! loop over blocks (multiple blocks only with elimination !)
9542 iloff=0 ! size of unpacked constraint matrix
9543 DO ib=1,npblck
9544 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9545 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9546 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9547 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9548 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9549 END DO
9550 ! allocate
9551 CALL mpalloc(lapackql, iloff, 'LAPACK QL (QL decomp.) ')
9552 lapackql=0.
9553 iloff=ncgb
9554 CALL mpalloc(lapacktau, iloff, 'LAPACK TAU (QL decomp.) ')
9555 ! fill
9556 iloff=0 ! offset of unpacked constraint matrix block
9557 imoff=0 ! offset of packed constraint matrix block
9558 DO ib=1,npblck
9559 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9560 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9561 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9562 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9563 IF(ncon <= 0) cycle
9564 ! block with constraints
9565 icboff=matparblockoffsets(2,ib) ! constraint block offset
9566 icblst=matparblockoffsets(2,ib+1) ! constraint block offset
9567 DO icb=icboff+1,icboff+icblst
9568 icfrst=matconsblocks(1,icb) ! first constraint in block
9569 iclast=matconsblocks(1,icb+1)-1 ! last constraint in block
9570 DO j=icfrst,iclast
9571 ipfrst=matconsranges(3,j)-ipoff ! first (rel.) parameter
9572 iplast=matconsranges(4,j)-ipoff ! last (rel.) parameters
9573 npb=iplast-ipfrst+1
9574 lapackql(iloff+ipfrst:iloff+iplast)=a(imoff+1:imoff+npb)
9575 imoff=imoff+npb
9576 iloff=iloff+npar
9577 END DO
9578 END DO
9579 END DO
9580 ! decompose
9581 iloff=0 ! offset of unpacked constraint matrix block
9582 emax=-1.
9583 emin=1.
9584 DO ib=1,npblck
9585 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9586 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9587 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9588 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9589 IF(ncon <= 0) cycle
9590 ! block with constraints
9591 nbopt = ilaenv( 1_mpl, 'DGEQLF', '', int(npar,mpl), int(ncon,mpl), int(npar,mpl), -1_mpl ) ! optimal block size
9592 print *, 'LAPACK optimal block size for DGEQLF:', nbopt
9593 lplwrk=int(ncon,mpl)*int(nbopt,mpl)
9594 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (d)')
9595 !$POMP INST BEGIN(dgeqlf)
9596#ifdef SCOREP_USER_ENABLE
9597 scorep_user_region_by_name_begin("UR_dgeqlf", scorep_user_region_type_common)
9598#endif
9599 CALL dgeqlf(int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9600 lapacktau(icoff+1:),lapackwork,lplwrk,infolp)
9601 IF(infolp /= 0) print *, ' DGEQLF failed: ', infolp
9602#ifdef SCOREP_USER_ENABLE
9603 scorep_user_region_by_name_end("UR_dgeqlf")
9604#endif
9605 !$POMP INST END(dgeqlf)
9606 CALL mpdealloc(lapackwork)
9607 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9608 ! get min/max diaginal element of L
9609 imoff=iloff
9610 IF(emax < emin) THEN
9611 emax=lapackql(imoff)
9612 emin=emax
9613 END IF
9614 DO i=1,ncon
9615 IF (abs(emax) < abs(lapackql(imoff))) emax=lapackql(imoff)
9616 IF (abs(emin) > abs(lapackql(imoff))) emin=lapackql(imoff)
9617 imoff=imoff-npar-1
9618 END DO
9619 END DO
9620 print *
9621END SUBROUTINE lpqldec
9622
9632SUBROUTINE lpavat(t)
9633 USE mpmod
9634
9635 IMPLICIT NONE
9636 INTEGER(mpi) :: i
9637 INTEGER(mpi) :: ib
9638 INTEGER(mpi) :: icoff
9639 INTEGER(mpi) :: ipoff
9640 INTEGER(mpi) :: j
9641 INTEGER(mpi) :: ncon
9642 INTEGER(mpi) :: npar
9643 INTEGER(mpl) :: imoff
9644 INTEGER(mpl) :: iloff
9645 INTEGER(mpi) :: infolp
9646 CHARACTER (LEN=1) :: transr, transl
9647
9648 LOGICAL, INTENT(IN) :: t
9649 SAVE
9650
9651 IF (t) THEN ! Q^t*A*Q
9652 transr='N'
9653 transl='T'
9654 ELSE ! Q*A*Q^t
9655 transr='T'
9656 transl='N'
9657 ENDIF
9658
9659 ! loop over blocks (multiple blocks only with elimination !)
9660 iloff=0 ! offset of L in lapackQL
9661 DO ib=1,npblck
9662 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9663 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9664 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9665 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9666 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9667 IF(ncon <= 0 ) cycle
9668
9669 !$POMP INST BEGIN(dormql)
9670#ifdef SCOREP_USER_ENABLE
9671 scorep_user_region_by_name_begin("UR_dormql", scorep_user_region_type_common)
9672#endif
9673 ! expand matrix (copy lower to upper triangle)
9674 ! parallelize row loop
9675 ! slot of 32 'I' for next idle thread
9676 !$OMP PARALLEL DO &
9677 !$OMP PRIVATE(J) &
9678 !$OMP SCHEDULE(DYNAMIC,32)
9679 DO i=ipoff+1,ipoff+npar
9680 DO j=ipoff+1,i-1
9682 ENDDO
9683 ENDDO
9684 ! A*Q
9685 CALL dormql('R',transr,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9686 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9687 lapackwork,lplwrk,infolp)
9688 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9689 ! Q^t*(A*Q)
9690 CALL dormql('L',transl,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9691 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9692 lapackwork,lplwrk,infolp)
9693 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9694#ifdef SCOREP_USER_ENABLE
9695 scorep_user_region_by_name_end("UR_dormql")
9696#endif
9697 !$POMP INST END(dormql)
9698
9699 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9700 END DO
9701
9702END SUBROUTINE lpavat
9703
9704#ifdef PARDISO
9705include 'mkl_pardiso.f90'
9706!===============================================================================
9707! Copyright 2004-2022 Intel Corporation.
9708!
9709! This software and the related documents are Intel copyrighted materials, and
9710! your use of them is governed by the express license under which they were
9711! provided to you (License). Unless the License provides otherwise, you may not
9712! use, modify, copy, publish, distribute, disclose or transmit this software or
9713! the related documents without Intel's prior written permission.
9714!
9715! This software and the related documents are provided as is, with no express
9716! or implied warranties, other than those that are expressly stated in the
9717! License.
9718!===============================================================================
9719!
9720! Content : Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO Fortran-90
9721! use case
9722!
9723!*******************************************************************************
9724
9729SUBROUTINE mspardiso
9730 USE mkl_pardiso
9731 USE mpmod
9732 USE mpdalc
9733 IMPLICIT NONE
9734
9735 !.. Internal solver memory pointer
9736 TYPE(mkl_pardiso_handle) :: pt(64) ! Handle to internal data structure
9737 !.. All other variables
9738 INTEGER(mpl), PARAMETER :: maxfct =1 ! Max. number of factors with identical sparsity structure kept in memory
9739 INTEGER(mpl), PARAMETER :: mnum = 1 ! Actual factor to use
9740 INTEGER(mpl), PARAMETER :: nrhs = 1 ! Number of right hand sides
9741
9742 INTEGER(mpl) :: mtype ! Matrix type (symmetric, pos. def.: 2, indef.: -2)
9743 INTEGER(mpl) :: phase ! Solver phase(s) to be executed
9744 INTEGER(mpl) :: error ! Error code
9745 INTEGER(mpl) :: msglvl ! Message level
9746
9747 INTEGER(mpi) :: i
9748 INTEGER(mpl) :: ij
9749 INTEGER(mpl) :: idum(1)
9750 INTEGER(mpi) :: lun
9751 INTEGER(mpl) :: length
9752 INTEGER(mpi) :: nfill
9753 INTEGER(mpi) :: npdblk
9754 REAL(mpd) :: adum(1)
9755 REAL(mpd) :: ddum(1)
9756
9757 INTEGER(mpl) :: iparm(64)
9758 REAL(mpd), ALLOCATABLE :: b( : ) ! Right hand side (of equations system)
9759 REAL(mpd), ALLOCATABLE :: x( : ) ! Solution (of equations system)
9760 SAVE
9761
9762 lun=lunlog ! log file
9763
9764 error = 0 ! initialize error flag
9765 msglvl = ipddbg ! print statistical information
9766 npdblk=(nfgb-1)/matbsz+1 ! number of row blocks
9767
9768 IF(icalcm == 1) THEN
9769 mtype = 2 ! positive definite symmetric matrix
9770 IF (nfgb > nvgb) mtype = -2 ! indefinte symmetric matrix (Lagrange multipliers)
9771
9772 !$POMP INST BEGIN(mspd00)
9773#ifdef SCOREP_USER_ENABLE
9774 scorep_user_region_by_name_begin("UR_mspd00", scorep_user_region_type_common)
9775#endif
9776 WRITE(*,*)
9777 WRITE(*,*) 'MSPARDISO: number of non-zero elements = ', csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
9778 ! fill up last block?
9779 nfill = npdblk*matbsz-nfgb
9780 IF (nfill > 0) THEN
9781 WRITE(*,*) 'MSPARDISO: number of rows to fill up = ', nfill
9782 ! end of last block
9783 ij = (csr3rowoffsets(npdblk+1)-csr3rowoffsets(1))*int(matbsz,mpl)*int(matbsz,mpl)
9784 DO i=1,nfill
9785 globalmatd(ij) = 1.0_mpd
9786 ij = ij-matbsz-1 ! back one row and one column in last block
9787 END DO
9788 END IF
9789
9790 ! close previous PARADISO run
9791 IF (ipdmem > 0) THEN
9792 !.. Termination and release of memory
9793 phase = -1 ! release internal memory
9794 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), adum, idum, idum, &
9795 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9796 IF (error /= 0) THEN
9797 WRITE(lun,*) 'The following ERROR was detected: ', error
9798 WRITE(*,'(A,2I10)') ' PARDISO release failed (phase, error): ', phase, error
9799 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9800 CALL peend(40,'Aborted, other error: PARDISO release')
9801 stop 'MSPARDISO: stopping due to error in PARDISO release'
9802 END IF
9803 ipdmem=0
9804 END IF
9805
9806 !..
9807 !.. Set up PARDISO control parameter
9808 !..
9809 iparm=0 ! using defaults
9810 iparm(2) = 2 ! fill-in reordering from METIS
9811 iparm(10) = 8 ! perturb the pivot elements with 1E-8
9812 iparm(18) = -1 ! Output: number of nonzeros in the factor LU
9813 iparm(19) = -1 ! Output: Mflops for LU factorization
9814 iparm(21) = 1 ! pivoting for symmetric indefinite matrices
9815 DO i=1, lenpardiso
9816 iparm(listpardiso(i)%label)=listpardiso(i)%ivalue
9817 END DO
9818 IF (iparm(1) == 0) WRITE(lun,*) 'PARDISO using defaults '
9819 IF (iparm(43) /= 0) THEN
9820 WRITE(lun,*) 'PARDISO: computation of the diagonal of inverse matrix not implemented !'
9821 iparm(43) = 0 ! no computation of the diagonal of inverse matrix
9822 END IF
9823
9824 ! necessary for the FIRST call of the PARDISO solver.
9825 DO i = 1, 64
9826 pt(i)%DUMMY = 0
9827 END DO
9828#ifdef SCOREP_USER_ENABLE
9829 scorep_user_region_by_name_end("UR_mspd00")
9830#endif
9831 !$POMP INST END(mspd00)
9832 END IF
9833
9834 IF(icalcm == 1) THEN
9835 ! monitor progress
9836 IF(monpg1 > 0) THEN
9837 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9839 END IF
9840 ! decompose and solve
9841 !.. Reordering and Symbolic Factorization, This step also allocates
9842 ! all memory that is necessary for the factorization
9843 !$POMP INST BEGIN(mspd11)
9844#ifdef SCOREP_USER_ENABLE
9845 scorep_user_region_by_name_begin("UR_mspd11", scorep_user_region_type_common)
9846#endif
9847 phase = 11 ! only reordering and symbolic factorization
9848 IF (matbsz > 1) THEN
9849 iparm(1) = 1 ! non default setting
9850 iparm(37) = matbsz ! using BSR3 instead of CSR3
9851 END IF
9852 IF (ipddbg > 0) THEN
9853 DO i=1,64
9854 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9855 END DO
9856 END IF
9857 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9858 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9859#ifdef SCOREP_USER_ENABLE
9860 scorep_user_region_by_name_end("UR_mspd11")
9861#endif
9862 !$POMP INST END(mspd11)
9863 WRITE(lun,*) 'PARDISO reordering completed ... '
9864 WRITE(lun,*) 'PARDISO peak memory required (KB)', iparm(15)
9865 IF (ipddbg > 0) THEN
9866 DO i=1,64
9867 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9868 END DO
9869 END IF
9870 IF (error /= 0) THEN
9871 WRITE(lun,*) 'The following ERROR was detected: ', error
9872 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9873 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9874 CALL peend(40,'Aborted, other error: PARDISO reordering')
9875 stop 'MSPARDISO: stopping due to error in PARDISO reordering'
9876 END IF
9877 IF (iparm(60) == 0) THEN
9878 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(17) ! in core
9879 ELSE
9880 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(63) ! out of core
9881 END IF
9882 WRITE(lun,*) 'Size (KB) of allocated memory = ',ipdmem
9883 WRITE(lun,*) 'Number of nonzeros in factors = ',iparm(18)
9884 WRITE(lun,*) 'Number of factorization MFLOPS = ',iparm(19)
9885
9886 !.. Factorization.
9887 !$POMP INST BEGIN(mspd22)
9888#ifdef SCOREP_USER_ENABLE
9889 scorep_user_region_by_name_begin("UR_mspd22", scorep_user_region_type_common)
9890#endif
9891 phase = 22 ! only factorization
9892 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9893 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9894#ifdef SCOREP_USER_ENABLE
9895 scorep_user_region_by_name_end("UR_mspd22")
9896#endif
9897 !$POMP INST END(mspd22)
9898 WRITE(lun,*) 'PARDISO factorization completed ... '
9899 IF (ipddbg > 0) THEN
9900 DO i=1,64
9901 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9902 END DO
9903 END IF
9904 IF (error /= 0) THEN
9905 WRITE(lun,*) 'The following ERROR was detected: ', error
9906 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9907 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9908 CALL peend(40,'Aborted, other error: PARDISO factorization')
9909 stop 'MSPARDISO: stopping due to error in PARDISO factorization'
9910 ENDIF
9911 IF (mtype < 0) THEN
9912 IF (iparm(14) > 0) &
9913 WRITE(lun,*) 'Number of perturbed pivots = ',iparm(14)
9914 WRITE(lun,*) 'Number of positive eigenvalues = ',iparm(22)-nfill
9915 WRITE(lun,*) 'Number of negative eigenvalues = ',iparm(23)
9916 ELSE IF (iparm(30) > 0) THEN
9917 WRITE(lun,*) 'Equation with bad pivot (<=0.) = ',iparm(30)
9918 END IF
9919
9920 IF (monpg1 > 0) CALL monend()
9921 END IF
9922
9923 ! backward/forward substitution
9924 !.. Back substitution and iterative refinement
9925 length=nfgb+nfill
9926 CALL mpalloc(b,length,' PARDISO r.h.s')
9927 CALL mpalloc(x,length,' PARDISO solution')
9929 !$POMP INST BEGIN(mspd33)
9930#ifdef SCOREP_USER_ENABLE
9931 scorep_user_region_by_name_begin("UR_mspd33", scorep_user_region_type_common)
9932#endif
9933 iparm(6) = 0 ! don't update r.h.s. with solution
9934 phase = 33 ! only solving
9935 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9936 idum, nrhs, iparm, msglvl, b, x, error)
9937#ifdef SCOREP_USER_ENABLE
9938 scorep_user_region_by_name_end("UR_mspd33")
9939#endif
9940 !$POMP INST END(mspd33)
9942 CALL mpdealloc(x)
9943 CALL mpdealloc(b)
9944 WRITE(lun,*) 'PARDISO solve completed ... '
9945 IF (error /= 0) THEN
9946 WRITE(lun,*) 'The following ERROR was detected: ', error
9947 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9948 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9949 CALL peend(40,'Aborted, other error: PARDISO solve')
9950 stop 'MSPARDISO: stopping due to error in PARDISO solve'
9951 ENDIF
9952
9953END SUBROUTINE mspardiso
9954#endif
9955#endif
9956
9958SUBROUTINE mdiags
9959 USE mpmod
9960
9961 IMPLICIT NONE
9962 REAL(mps) :: evalue
9963 INTEGER(mpi) :: i
9964 INTEGER(mpi) :: iast
9965 INTEGER(mpi) :: idia
9966 INTEGER(mpi) :: imin
9967 INTEGER(mpl) :: ioff1
9968 INTEGER(mpi) :: j
9969 INTEGER(mpi) :: last
9970 INTEGER(mpi) :: lun
9971 INTEGER(mpi) :: nmax
9972 INTEGER(mpi) :: nmin
9973 INTEGER(mpi) :: ntop
9974 REAL(mpd) :: matij
9975 !
9976 EXTERNAL avprds
9977
9978 SAVE
9979 ! ...
9980
9981 lun=lunlog ! log file
9982
9983 ! save diagonal (for global correlation)
9984 IF(icalcm == 1) THEN
9985 DO i=1,nagb
9986 workspacediag(i)=matij(i,i)
9987 END DO
9988 ENDIF
9989
9990 !use elimination for constraints ?
9991 IF(nfgb < nvgb) THEN
9992 IF(icalcm == 1) THEN
9993 ! monitor progress
9994 IF(monpg1 > 0) THEN
9995 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9997 END IF
9998 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9999 IF(monpg1 > 0) CALL monend()
10000 ENDIF
10001 ! solve L^t*y=d by backward substitution
10003 ! transform, reduce rhs
10004 CALL qlmlq(globalcorrections,1,.true.) ! Q^t*b
10005 ! correction from eliminated part
10006 DO i=1,nfgb
10007 DO j=1,ncgb
10008 ioff1=globalrowoffsets(nfgb+j)+i ! global (nfit+j,i)
10010 END DO
10011 END DO
10012 END IF
10013
10014 IF(icalcm == 1) THEN
10015 ! eigenvalues eigenvectors symm_input
10016 workspaceeigenvalues=0.0_mpd
10019
10020 ! histogram of positive eigenvalues
10021
10022 nmax=int(1.0+log10(real(workspaceeigenvalues(1),mps)),mpi) ! > log of largest eigenvalue
10023 imin=1
10024 DO i=nfgb,1,-1
10025 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
10026 imin=i ! index of smallest pos. eigenvalue
10027 EXIT
10028 END IF
10029 END DO
10030 nmin=int(log10(real(workspaceeigenvalues(imin),mps)),mpi) ! log of smallest pos. eigenvalue
10031 ntop=nmin+6
10032 DO WHILE(ntop < nmax)
10033 ntop=ntop+3
10034 END DO
10035
10036 CALL hmpdef(7,real(nmin,mps),real(ntop,mps), 'log10 of positive eigenvalues')
10037 DO idia=1,nfgb
10038 IF(workspaceeigenvalues(idia) > 0.0_mpd) THEN ! positive
10039 evalue=log10(real(workspaceeigenvalues(idia),mps))
10040 CALL hmpent(7,evalue)
10041 END IF
10042 END DO
10043 IF(nhistp /= 0) CALL hmprnt(7)
10044 CALL hmpwrt(7)
10045
10046 iast=max(1,imin-60)
10047 CALL gmpdef(3,2,'low-value end of eigenvalues')
10048 DO i=iast,nfgb
10049 evalue=real(workspaceeigenvalues(i),mps)
10050 CALL gmpxy(3,real(i,mps),evalue)
10051 END DO
10052 IF(nhistp /= 0) CALL gmprnt(3)
10053 CALL gmpwrt(3)
10054
10055 DO i=1,nfgb
10056 workspacediagonalization(i)=0.0_mpd
10057 IF(workspaceeigenvalues(i) /= 0.0_mpd) THEN
10058 workspacediagonalization(i)=max(0.0_mpd,log10(abs(workspaceeigenvalues(i)))+3.0_mpd)
10060 END IF
10061 END DO
10062 last=min(nfgb,nvgb)
10063 WRITE(lun,*) ' '
10064 WRITE(lun,*) 'The first (largest) eigenvalues ...'
10065 WRITE(lun,102) (workspaceeigenvalues(i),i=1,min(20,nagb))
10066 WRITE(lun,*) ' '
10067 WRITE(lun,*) 'The last eigenvalues ... up to',last
10068 WRITE(lun,102) (workspaceeigenvalues(i),i=max(1,last-19),last)
10069 WRITE(lun,*) ' '
10070 IF(nagb > nvgb) THEN
10071 WRITE(lun,*) 'The eigenvalues from',nvgb+1,' to',nagb
10072 WRITE(lun,102) (workspaceeigenvalues(i),i=nvgb+1,nagb)
10073 WRITE(lun,*) ' '
10074 ENDIF
10075 WRITE(lun,*) 'Log10 + 3 of ',nfgb,' eigenvalues in decreasing', ' order'
10076 WRITE(lun,*) '(for Eigenvalue < 0.001 the value 0.0 is shown)'
10077 WRITE(lun,101) (workspacediagonalization(i),i=1,nfgb)
10078 IF(workspacediagonalization(nfgb) < 0) WRITE(lun,*) 'Negative values are ', &
10079 'printed for negative eigenvalues'
10081 WRITE(lun,*) ' '
10082 WRITE(lun,*) last,' significances: insignificant if ', &
10083 'compatible with N(0,1)'
10084 WRITE(lun,101) (workspacediagonalization(i),i=1,last)
10085
10086
10087101 FORMAT(10f7.1)
10088102 FORMAT(5e14.6)
10089
10090 END IF
10091
10092 ! solution ---------------------------------------------------------
10094 ! eigenvalues eigenvectors
10096
10097 !use elimination for constraints ?
10098 IF(nfgb < nvgb) THEN
10099 ! extend, transform back solution
10101 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10102 END IF
10103
10104END SUBROUTINE mdiags
10105
10107SUBROUTINE zdiags
10108 USE mpmod
10109
10110 IMPLICIT NONE
10111 INTEGER(mpi) :: i
10112 INTEGER(mpl) :: ioff1
10113 INTEGER(mpl) :: ioff2
10114 INTEGER(mpi) :: j
10115
10116 ! eigenvalue eigenvectors cov.matrix
10118
10119 !use elimination for constraints ?
10120 IF(nfgb < nvgb) THEN
10121 ! extend, transform eigenvectors
10122 ioff1=nfgb*nfgb
10123 ioff2=nfgb*nvgb
10124 workspaceeigenvectors(ioff2+1:)=0.0_mpd
10125 DO i=nfgb,1,-1
10126 ioff1=ioff1-nfgb
10127 ioff2=ioff2-nvgb
10128 DO j=nfgb,1,-1
10130 END DO
10131 workspaceeigenvectors(ioff2+nfgb+1:ioff2+nvgb)=0.0_mpd
10132 END DO
10133 CALL qlmlq(workspaceeigenvectors,nvgb,.false.) ! Q*U
10134 END IF
10135
10136END SUBROUTINE zdiags
10137
10143
10144SUBROUTINE mminrs
10145 USE mpmod
10146 USE minresmodule, ONLY: minres
10147
10148 IMPLICIT NONE
10149 INTEGER(mpi) :: istop
10150 INTEGER(mpi) :: itn
10151 INTEGER(mpi) :: itnlim
10152 INTEGER(mpi) :: lun
10153 INTEGER(mpi) :: nout
10154 INTEGER(mpi) :: nrkd
10155 INTEGER(mpi) :: nrkd2
10156
10157 REAL(mpd) :: shift
10158 REAL(mpd) :: rtol
10159 REAL(mpd) :: anorm
10160 REAL(mpd) :: acond
10161 REAL(mpd) :: arnorm
10162 REAL(mpd) :: rnorm
10163 REAL(mpd) :: ynorm
10164 LOGICAL :: checka
10165 EXTERNAL avprds, avprod, mvsolv, mcsolv
10166 SAVE
10167 ! ...
10168 lun=lunlog ! log file
10169
10170 nout=lun
10171 itnlim=2000 ! iteration limit
10172 shift =0.0_mpd ! not used
10173 rtol = mrestl ! from steering
10174 checka=.false.
10175
10177 !use elimination for constraints ?
10178 IF(nfgb < nvgb) THEN
10179 ! solve L^t*y=d by backward substitution
10181 ! input to AVPRD0
10182 vecxav(1:nfgb)=0.0_mpd
10184 CALL qlmlq(vecxav,1,.false.) ! Q*x
10185 ! calclulate vecBav=globalMat*vecXav
10186 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10187 ! correction from eliminated part
10189 ! transform, reduce rhs
10190 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10191 END IF
10192
10193 IF(mbandw == 0) THEN ! default preconditioner
10194 IF(icalcm == 1) THEN
10195 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10196 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10197 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10199 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10200 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10201 IF(monpg1 > 0) CALL monend()
10202 END IF
10203 CALL minres(nfgb, avprod, mcsolv, workspaced, shift, checka ,.true. , &
10204 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10205 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10206 IF(icalcm == 1) THEN
10207 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10208 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10209 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10211 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10212 IF(monpg1 > 0) CALL monend()
10213 END IF
10214 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.true. , &
10215 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10216 ELSE
10217 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.false. , &
10218 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10219 END IF
10220
10221 !use elimination for constraints ?
10222 IF(nfgb < nvgb) THEN
10223 ! extend, transform back solution
10225 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10226 END IF
10227
10228 iitera=itn
10229 istopa=istop
10230 mnrsit=mnrsit+itn
10231
10232 IF (istopa == 0) print *, 'MINRES: istop=0, exact solution x=0.'
10233
10234END SUBROUTINE mminrs
10235
10241
10242SUBROUTINE mminrsqlp
10243 USE mpmod
10244 USE minresqlpmodule, ONLY: minresqlp
10245
10246 IMPLICIT NONE
10247 INTEGER(mpi) :: istop
10248 INTEGER(mpi) :: itn
10249 INTEGER(mpi) :: itnlim
10250 INTEGER(mpi) :: lun
10251 INTEGER(mpi) :: nout
10252 INTEGER(mpi) :: nrkd
10253 INTEGER(mpi) :: nrkd2
10254
10255 REAL(mpd) :: rtol
10256 REAL(mpd) :: mxxnrm
10257 REAL(mpd) :: trcond
10258
10259 EXTERNAL avprds, avprod, mvsolv, mcsolv
10260 SAVE
10261 ! ...
10262 lun=lunlog ! log file
10263
10264 nout=lun
10265 itnlim=2000 ! iteration limit
10266 rtol = mrestl ! from steering
10267 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
10268 IF(mrmode == 1) THEN
10269 trcond = 1.0_mpd/epsilon(trcond) ! only QR
10270 ELSE IF(mrmode == 2) THEN
10271 trcond = 1.0_mpd ! only QLP
10272 ELSE
10273 trcond = mrtcnd ! QR followed by QLP
10274 END IF
10275
10277 !use elimination for constraints ?
10278 IF(nfgb < nvgb) THEN
10279 ! solve L^t*y=d by backward substitution
10281 ! input to AVPRD0
10282 vecxav(1:nfgb)=0.0_mpd
10284 CALL qlmlq(vecxav,1,.false.) ! Q*x
10285 ! calclulate vecBav=globalMat*vecXav
10286 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10287 ! correction from eliminated part
10289 ! transform, reduce rhs
10290 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10291 END IF
10292
10293 IF(mbandw == 0) THEN ! default preconditioner
10294 IF(icalcm == 1) THEN
10295 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10296 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10297 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10299 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10300 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10301 IF(monpg1 > 0) CALL monend()
10302 END IF
10303 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mcsolv, nout=nout, &
10304 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10305 x=globalcorrections, istop=istop, itn=itn)
10306 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10307 IF(icalcm == 1) THEN
10308 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10309 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10310 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10312 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10313 IF(monpg1 > 0) CALL monend()
10314 END IF
10315
10316 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mvsolv, nout=nout, &
10317 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10318 x=globalcorrections, istop=istop, itn=itn)
10319 ELSE
10320 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, nout=nout, &
10321 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10322 x=globalcorrections, istop=istop, itn=itn)
10323 END IF
10324
10325 !use elimination for constraints ?
10326 IF(nfgb < nvgb) THEN
10327 ! extend, transform back solution
10329 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10330 END IF
10331
10332 iitera=itn
10333 istopa=istop
10334 mnrsit=mnrsit+itn
10335
10336 IF (istopa == 3) print *, 'MINRES: istop=0, exact solution x=0.'
10337
10338END SUBROUTINE mminrsqlp
10339
10347
10348SUBROUTINE mcsolv(n,x,y) ! solve M*y = x
10349 USE mpmod
10350
10351 IMPLICIT NONE
10352 INTEGER(mpi),INTENT(IN) :: n
10353 REAL(mpd), INTENT(IN) :: x(n)
10354 REAL(mpd), INTENT(OUT) :: y(n)
10355 SAVE
10356 ! ...
10358 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),y,x)
10359END SUBROUTINE mcsolv
10360
10368
10369SUBROUTINE mvsolv(n,x,y) ! solve M*y = x
10370 USE mpmod
10371
10372 IMPLICIT NONE
10373
10374 INTEGER(mpi), INTENT(IN) :: n
10375 REAL(mpd), INTENT(IN) :: x(n)
10376 REAL(mpd), INTENT(OUT) :: y(n)
10377
10378 SAVE
10379 ! ...
10380 y=x ! copy to output vector
10381
10383END SUBROUTINE mvsolv
10384
10385
10386
10387!***********************************************************************
10388
10401
10402SUBROUTINE xloopn !
10403 USE mpmod
10404
10405 IMPLICIT NONE
10406 REAL(mps) :: catio
10407 REAL(mps) :: concu2
10408 REAL(mps) :: concut
10409 REAL, DIMENSION(2) :: ta
10410 REAL etime
10411 INTEGER(mpi) :: i
10412 INTEGER(mpi) :: iact
10413 INTEGER(mpi) :: iagain
10414 INTEGER(mpi) :: idx
10415 INTEGER(mpi) :: info
10416 INTEGER(mpi) :: ib
10417 INTEGER(mpi) :: ipoff
10418 INTEGER(mpi) :: icoff
10419 INTEGER(mpl) :: ioff
10420 INTEGER(mpi) :: itgbi
10421 INTEGER(mpi) :: ivgbi
10422 INTEGER(mpi) :: jcalcm
10423 INTEGER(mpi) :: k
10424 INTEGER(mpi) :: labelg
10425 INTEGER(mpi) :: litera
10426 INTEGER(mpl) :: lrej
10427 INTEGER(mpi) :: lun
10428 INTEGER(mpi) :: lunp
10429 INTEGER(mpi) :: minf
10430 INTEGER(mpi) :: mrati
10431 INTEGER(mpi) :: nan
10432 INTEGER(mpi) :: ncon
10433 INTEGER(mpi) :: nfaci
10434 INTEGER(mpi) :: nloopsol
10435 INTEGER(mpi) :: npar
10436 INTEGER(mpi) :: nrati
10437 INTEGER(mpl) :: nrej
10438 INTEGER(mpi) :: nsol
10439 INTEGER(mpi) :: inone
10440#ifdef LAPACK64
10441 INTEGER(mpi) :: infolp
10442 INTEGER(mpi) :: nfit
10443 INTEGER(mpl) :: imoff
10444#endif
10445
10446 REAL(mpd) :: stp
10447 REAL(mpd) :: dratio
10448 REAL(mpd) :: dwmean
10449 REAL(mpd) :: db
10450 REAL(mpd) :: db1
10451 REAL(mpd) :: db2
10452 REAL(mpd) :: dbdot
10453 REAL(mpd) :: dbsig
10454 LOGICAL :: btest
10455 LOGICAL :: warner
10456 LOGICAL :: warners
10457 LOGICAL :: warnerss
10458 LOGICAL :: warners3
10459 LOGICAL :: lsflag
10460 CHARACTER (LEN=7) :: cratio
10461 CHARACTER (LEN=7) :: cfacin
10462 CHARACTER (LEN=7) :: crjrat
10463 EXTERNAL avprds
10464 SAVE
10465 ! ...
10466
10467 ! Printout of algorithm for solution and important parameters ------
10468
10469 lun=lunlog ! log file
10470
10471 DO lunp=6,lunlog,lunlog-6
10472 WRITE(lunp,*) ' '
10473 WRITE(lunp,*) 'Solution algorithm: '
10474 WRITE(lunp,121) '=================================================== '
10475
10476 IF(metsol == 1) THEN
10477 WRITE(lunp,121) 'solution method:','matrix inversion'
10478 ELSE IF(metsol == 2) THEN
10479 WRITE(lunp,121) 'solution method:','diagonalization'
10480 ELSE IF(metsol == 3) THEN
10481 WRITE(lunp,121) 'solution method:','decomposition'
10482 ELSE IF(metsol == 4) THEN
10483 WRITE(lunp,121) 'solution method:', 'minres (Paige/Saunders)'
10484 ELSE IF(metsol == 5) THEN
10485 WRITE(lunp,121) 'solution method:', 'minres-qlp (Choi/Paige/Saunders)'
10486 IF(mrmode == 1) THEN
10487 WRITE(lunp,121) ' ', ' using QR factorization' ! only QR
10488 ELSE IF(mrmode == 2) THEN
10489 WRITE(lunp,121) ' ', ' using QLP factorization' ! only QLP
10490 ELSE
10491 WRITE(lunp,121) ' ', ' using QR and QLP factorization' ! QR followed by QLP
10492 WRITE(lunp,123) 'transition condition', mrtcnd
10493 END IF
10494 ELSE IF(metsol == 6) THEN
10495 WRITE(lunp,121) 'solution method:', &
10496 'gmres (generalized minimzation of residuals)'
10497#ifdef LAPACK64
10498 ELSE IF(metsol == 7) THEN
10499 IF (nagb > nvgb) THEN
10500 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSPTRF)'
10501 ELSE
10502 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPPTRF)'
10503 ENDIF
10504 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10505 ELSE IF(metsol == 8) THEN
10506 IF (nagb > nvgb) THEN
10507 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSYTRF)'
10508 ELSE
10509 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPOTRF)'
10510 ENDIF
10511 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10512#ifdef PARDISO
10513 ELSE IF(metsol == 9) THEN
10514 IF (matbsz < 2) THEN
10515 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (CSR3))'
10516 ELSE
10517 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (BSR3))'
10518 ENDIF
10519#endif
10520#endif
10521 END IF
10522 WRITE(lunp,123) 'convergence limit at Delta F=',dflim
10523 WRITE(lunp,122) 'maximum number of iterations=',mitera
10524 matrit=min(matrit,mitera)
10525 IF(matrit > 1) THEN
10526 WRITE(lunp,122) 'matrix recalculation up to ',matrit, '. iteration'
10527 END IF
10528 IF(metsol >= 4.AND.metsol < 7) THEN
10529 IF(matsto == 1) THEN
10530 WRITE(lunp,121) 'matrix storage:','full'
10531 ELSE IF(matsto == 2) THEN
10532 WRITE(lunp,121) 'matrix storage:','sparse'
10533 END IF
10534 WRITE(lunp,122) 'pre-con band-width parameter=',mbandw
10535 IF(mbandw == 0) THEN
10536 WRITE(lunp,121) 'pre-conditioning:','default'
10537 ELSE IF(mbandw < 0) THEN
10538 WRITE(lunp,121) 'pre-conditioning:','none!'
10539 ELSE IF(mbandw > 0) THEN
10540 IF(lprecm > 0) THEN
10541 WRITE(lunp,121) 'pre-conditioning=','skyline-matrix (rank preserving)'
10542 ELSE
10543 WRITE(lunp,121) 'pre-conditioning=','band-matrix'
10544 ENDIF
10545 END IF
10546 END IF
10547 IF(regpre == 0.0_mpd.AND.npresg == 0) THEN
10548 WRITE(lunp,121) 'using pre-sigmas:','no'
10549 ELSE
10550 ! FIXME: NPRESG contains parameters that failed the 'entries' cut...
10551 WRITE(lunp,124) 'pre-sigmas defined for', &
10552 REAL(100*npresg,mps)/REAL(nvgb,mps),' % of variable parameters'
10553 WRITE(lunp,123) 'default pre-sigma=',regpre
10554 END IF
10555 IF(nregul == 0) THEN
10556 WRITE(lunp,121) 'regularization:','no'
10557 ELSE
10558 WRITE(lunp,121) 'regularization:','yes'
10559 WRITE(lunp,123) 'regularization factor=',regula
10560 END IF
10561
10562 IF(chicut /= 0.0) THEN
10563 WRITE(lunp,121) 'Chi square cut equiv 3 st.dev applied'
10564 WRITE(lunp,123) '... in first iteration with factor',chicut
10565 WRITE(lunp,123) '... in second iteration with factor',chirem
10566 WRITE(lunp,121) ' (reduced by sqrt in next iterations)'
10567 END IF
10568 IF(iscerr > 0) THEN
10569 WRITE(lunp,121) 'Scaling of measurement errors applied'
10570 WRITE(lunp,123) '... factor for "global" measuements',dscerr(1)
10571 WRITE(lunp,123) '... factor for "local" measuements',dscerr(2)
10572 END IF
10573 IF(lhuber /= 0) THEN
10574 WRITE(lunp,122) 'Down-weighting of outliers in', lhuber,' iterations'
10575 WRITE(lunp,123) 'Cut on downweight fraction',dwcut
10576 END IF
10577
10578
10579121 FORMAT(1x,a40,3x,a)
10580122 FORMAT(1x,a40,3x,i0,a)
10581123 FORMAT(1x,a40,2x,e9.2)
10582124 FORMAT(1x,a40,3x,f5.1,a)
10583 END DO
10584
10585 ! initialization of iterations -------------------------------------
10586
10587 iitera=0
10588 nsol =0 ! counter for solutions
10589 info =0
10590 lsinfo=0
10591 stp =0.0_mpd
10592 stepl =real(stp,mps)
10593 concut=1.0e-12 ! initial constraint accuracy
10594 concu2=1.0e-06 ! constraint accuracy
10595 icalcm=1 ! require matrix calculation
10596 iterat=0 ! iteration counter
10597 iterat=-1
10598 litera=-2
10599 nloopsol=0 ! (new) solution from this nloopn
10600 nrej=0 ! reset number of rejects
10601 IF(metsol == 1) THEN
10602 wolfc2=0.5 ! not accurate
10603 minf=1
10604 ELSE IF(metsol == 2) THEN
10605 wolfc2=0.5 ! not acurate
10606 minf=2
10607 ELSE IF(metsol == 3) THEN
10608 wolfc2=0.5 ! not acurate
10609 minf=1
10610 ELSE IF(metsol == 4) THEN
10611 wolfc2=0.1 ! accurate
10612 minf=3
10613 ELSE IF(metsol == 5) THEN
10614 wolfc2=0.1 ! accurate
10615 minf=3
10616 ELSE IF(metsol == 6) THEN
10617 wolfc2=0.1 ! accurate
10618 minf=3
10619 ELSE
10620 wolfc2=0.5 ! not accurate
10621 minf=1
10622 END IF
10623
10624 ! check initial feasibility of constraint equations ----------------
10625
10626 WRITE(*,*) ' '
10627 IF(nofeas == 0) THEN ! make parameter feasible
10628 WRITE(lunlog,*) 'Checking feasibility of parameters:'
10629 WRITE(*,*) 'Checking feasibility of parameters:'
10630 CALL feasib(concut,iact) ! check feasibility
10631 IF(iact /= 0) THEN ! done ...
10632 WRITE(*,102) concut
10633 WRITE(*,*) ' parameters are made feasible'
10634 WRITE(lunlog,102) concut
10635 WRITE(lunlog,*) ' parameters are made feasible'
10636 ELSE ! ... was OK
10637 WRITE(*,*) ' parameters are feasible (i.e. satisfy constraints)'
10638 WRITE(lunlog,*) ' parameters are feasible (i.e. satisfy constraints)'
10639 END IF
10640 concut=concu2 ! cut for constraint check
10641 END IF
10642 iact=1 ! set flag for new data loop
10643 nofeas=0 ! set check-feasibility flag
10644
10645 WRITE(*,*) ' '
10646 WRITE(*,*)'Reading files and accumulating vectors/matrices ...'
10647 WRITE(*,*) ' '
10648 IF(monpg1>0) THEN
10649 WRITE(lunlog,*)
10650 WRITE(lunlog,*)'Reading files and accumulating vectors/matrices ...'
10651 WRITE(lunlog,*)
10652 END IF
10653
10654 rstart=etime(ta)
10655 iterat=-1
10656 litera= 0
10657 jcalcm=-1
10658 iagain= 0
10659
10660 icalcm=1
10661
10662 ! Block 1: data loop with vector (and matrix) calculation ----------
10663
10664 DO
10665 IF(iterat >= 0) THEN
10666 lcalcm=jcalcm+3 ! mode (1..4) of last loop
10667 IF(jcalcm+1 /= 0) THEN
10668 IF(iterat == 0) THEN
10669 CALL ploopa(6) ! header
10670 CALL ploopb(6)
10671 CALL ploopa(lunlog) ! iteration line
10672 CALL ploopb(lunlog)
10673 iterat=1
10674 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10675 ELSE
10676 IF(iterat /= litera) THEN
10677 CALL ploopb(6)
10678 ! CALL PLOOPA(LUNLOG)
10679 CALL ploopb(lunlog)
10680 litera=iterat
10681 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,delfun) ! fcn-value (with expected)
10682 IF(metsol == 4 .OR. metsol == 5) THEN ! extend to 6, i.e. GMRES?
10683 CALL gmpxy(2,real(iterat,mps),real(iitera,mps)) ! MINRES iterations
10684 END IF
10685 ELSE
10686 CALL ploopc(6) ! sub-iteration line
10687 CALL ploopc(lunlog)
10688 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10689 END IF
10690 END IF
10691 ELSE
10692 CALL ploopd(6) ! solution line
10693 CALL ploopd(lunlog)
10694 END IF
10695 rstart=etime(ta)
10696 ! CHK
10697 IF (iabs(jcalcm) <= 1) THEN
10698 idx=jcalcm+4
10699 times(idx )=(times(idx )*times(idx+3)+deltim) /(times(idx+3)+1.0)
10700 times(idx+3)= times(idx+3)+1.0
10701 END IF
10702 END IF
10703 jcalcm=icalcm
10704
10705 IF(icalcm >= 0) THEN ! ICALCM = +1 & 0
10706 CALL loopn ! data loop
10707 CALL addcst ! constraints
10708 lrej=nrej
10709 nrej=sum(nrejec) ! total number of rejects
10710 IF(3*nrej > nrecal) THEN
10711 WRITE(*,*) ' '
10712 WRITE(*,*) 'Data records rejected in previous loop: '
10713 CALL prtrej(6)
10714 WRITE(*,*) 'Too many rejects (>33.3%) - stop'
10715 CALL peend(26,'Aborted, too many rejects')
10716 stop
10717 END IF
10718 ! fill second half (j>i) of global matrix for extended storage, experimental
10719 IF (icalcm == 1.AND.mextnd > 0) CALL mhalf2()
10720 END IF
10721 ! Block 2: new iteration with calculation of solution --------------
10722 IF(abs(icalcm) == 1) THEN ! ICALCM = +1 & -1
10723 DO i=1,nagb
10724 globalcorrections(i)=globalvector(i) ! copy rhs
10725 END DO
10726 DO i=1,nvgb
10727 itgbi=globalparvartototal(i)
10728 workspacelinesearch(i)=globalparameter(itgbi) ! copy X for line search
10729 END DO
10730
10731 iterat=iterat+1 ! increase iteration count
10732 IF(metsol == 1) THEN
10733 CALL minver ! inversion
10734 ELSE IF(metsol == 2) THEN
10735 CALL mdiags ! diagonalization
10736 ELSE IF(metsol == 3) THEN
10737 CALL mchdec ! decomposition
10738 ELSE IF(metsol == 4) THEN
10739 CALL mminrs ! MINRES
10740 ELSE IF(metsol == 5) THEN
10741 CALL mminrsqlp ! MINRES-QLP
10742 ELSE IF(metsol == 6) THEN
10743 WRITE(*,*) '... reserved for GMRES (not yet!)'
10744 CALL mminrs ! GMRES not yet
10745#ifdef LAPACK64
10746 ELSE IF(metsol == 7) THEN
10747 CALL mdptrf ! LAPACK (packed storage)
10748 ELSE IF(metsol == 8) THEN
10749 CALL mdutrf ! LAPACK (unpacked storage)
10750#ifdef PARDISO
10751 ELSE IF(metsol == 9) THEN
10752 CALL mspardiso ! Intel oneMKL PARDISO (sparse matrix (CSR3, upper triangle))
10753#endif
10754#endif
10755 END IF
10756 nloopsol=nloopn ! (new) solution for this nloopn
10757
10758 ! check feasibility and evtl. make step vector feasible
10759
10760 DO i=1,nvgb
10761 itgbi=globalparvartototal(i)
10762 globalparcopy(itgbi)=globalparameter(itgbi) ! save
10763 globalparameter(itgbi)=globalparameter(itgbi)+globalcorrections(i) ! update
10764 END DO
10765 CALL feasib(concut,iact) ! improve constraints
10766 concut=concu2 ! new cut for constraint check
10767 DO i=1,nvgb
10768 itgbi=globalparvartototal(i)
10769 globalcorrections(i)=globalparameter(itgbi)-globalparcopy(itgbi) ! feasible stp
10770 globalparameter(itgbi)=globalparcopy(itgbi) ! restore
10771 END DO
10772
10775 db2=dbdot(nvgb,globalvector,globalvector)
10776 delfun=real(db,mps)
10777 angras=real(db/sqrt(db1*db2),mps)
10778 dbsig=16.0_mpd*sqrt(max(db1,db2))*epsilon(db) ! significant change
10779
10780 ! do line search for this iteration/solution ?
10781 ! lsearch >2: all, =2: all with (next) chicut =1., =1: last, <1: none
10782 lsflag=(lsearch > 2 .OR. (lsearch == 2 .AND. chicut < 2.25) .OR. &
10783 (lsearch == 1 .AND. chicut < 2.25 .AND. (delfun <= dflim .OR. iterat >= mitera)))
10784 lsflag=lsflag .AND. (db > dbsig) ! require significant change
10785 IF (lsflag) THEN
10786 ! initialize line search based on slopes and prepare next
10787 CALL ptldef(wolfc2, 10.0, minf,10)
10788 IF(metsol == 1) THEN
10789 wolfc2=0.5 ! not accurate
10790 minf=3
10791 ELSE IF(metsol == 2) THEN
10792 wolfc2=0.5 ! not acurate
10793 minf=3
10794 ELSE IF(metsol == 3) THEN
10795 wolfc2=0.5 ! not acurate
10796 minf=3
10797 ELSE IF(metsol == 4) THEN
10798 wolfc2=0.1 ! accurate
10799 minf=4
10800 ELSE IF(metsol == 5) THEN
10801 wolfc2=0.1 ! accurate
10802 minf=4
10803 ELSE IF(metsol == 6) THEN
10804 wolfc2=0.1 ! accurate
10805 minf=4
10806 ELSE
10807 wolfc2=0.5 ! not accurate
10808 minf=3
10809 END IF
10810 ENDIF
10811
10812 ! change significantly negative ?
10813 IF(db <= -dbsig) THEN
10814 WRITE(*,*) 'Function not decreasing:',db
10815 IF(db > -1.0e-3_mpd) THEN ! 100311, VB/CK: allow some margin for numerics
10816 iagain=iagain+1
10817 IF (iagain <= 1) THEN
10818 WRITE(*,*) '... again matrix calculation'
10819 icalcm=1
10820 cycle
10821 ELSE
10822 WRITE(*,*) '... aborting iterations'
10823 GO TO 90
10824 END IF
10825 ELSE
10826 WRITE(*,*) '... stopping iterations'
10827 iagain=-1
10828 GO TO 90
10829 END IF
10830 ELSE
10831 iagain=0
10832 END IF
10833 icalcm=0 ! switch
10834 ENDIF
10835 ! Block 3: line searching ------------------------------------------
10836
10837 IF(icalcm+2 == 0) EXIT
10838 IF (lsflag) THEN
10839 CALL ptline(nvgb,workspacelinesearch, & ! current parameter values
10840 flines, & ! chi^2 function value
10841 globalvector, & ! gradient
10842 globalcorrections, & ! step vector stp
10843 stp, & ! returned step factor
10844 info) ! returned information
10845 ! WRITE(*,*) 'PTLINE returns INFO, STP=',INFO, STP
10846 ELSE ! skip line search
10847 info=10
10848 stepl=1.0
10849 IF (nloopn == nloopsol) THEN ! new solution: update corrections
10851 ENDIF
10852 ENDIF
10853 lsinfo=info
10854
10855 stepl=real(stp,mps)
10856 nan=0
10857 DO i=1,nvgb
10858 itgbi=globalparvartototal(i)
10859 IF ((.NOT.(workspacelinesearch(i) <= 0.0_mpd)).AND. &
10860 (.NOT.(workspacelinesearch(i) > 0.0_mpd))) nan=nan+1
10861 globalparameter(itgbi)=workspacelinesearch(i) ! current parameter values
10862 END DO
10863
10864 IF (nan > 0) THEN
10865 WRITE(*,*) 'Result vector containes ', nan,' NaNs - stop'
10866 CALL peend(25,'Aborted, result vector contains NaNs')
10867 stop
10868 END IF
10869
10870 ! subito exit, if required -----------------------------------------
10871
10872 IF(isubit /= 0) THEN ! subito
10873 WRITE(*,*) 'Subito! Exit after first step.'
10874 GO TO 90
10875 END IF
10876
10877 IF(info == 0) THEN
10878 WRITE(*,*) 'INFO=0 should not happen (line search input err)'
10879 IF (iagain <= 0) THEN
10880 icalcm=1
10881 cycle
10882 ENDIF
10883 END IF
10884 IF(info < 0 .OR. nloopn == nloopsol) cycle
10885 ! Block 4: line search convergence ---------------------------------
10886
10887 CALL ptlprt(lunlog)
10888 CALL feasib(concut,iact) ! check constraints
10889 IF(iact /= 0.OR.chicut > 1.0) THEN
10890 icalcm=-1
10891 IF(iterat < matrit) icalcm=+1
10892 cycle ! iterate
10893 END IF
10894 IF(delfun <= dflim) GO TO 90 ! convergence
10895 IF(iterat >= mitera) GO TO 90 ! ending
10896 icalcm=-1
10897 IF(iterat < matrit) icalcm=+1
10898 cycle ! next iteration
10899
10900 ! Block 5: iteration ending ----------------------------------------
10901
1090290 icalcm=-2
10903 END DO
10904 IF(sum(nrejec) /= 0) THEN
10905 WRITE(*,*) ' '
10906 WRITE(*,*) 'Data records rejected in last loop: '
10907 CALL prtrej(6)
10908 END IF
10909
10910 ! monitoring of residuals
10911 IF (imonit > 0 .AND. btest(imonit,1)) CALL monres
10912 IF (lunmon > 0) CLOSE(unit=lunmon)
10913
10914 ! construct inverse from diagonalization
10915 IF(metsol == 2) CALL zdiags
10916
10917 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
10918#ifdef LAPACK64
10919 IF (metsol == 7.OR.metsol == 8) THEN
10920 ! inverse from factorization
10921 ! loop over blocks (multiple blocks only with elimination !)
10922 DO ib=1,npblck
10923 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10924 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10925 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10926 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10927 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
10928 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
10929 IF (nfit > npar) THEN
10930 ! monitor progress
10931 IF(monpg1 > 0) THEN
10932 WRITE(lunlog,*) 'Inverse of global matrix from LDLt factorization'
10934 END IF
10935 IF (matsto == 1) THEN
10936 !$POMP INST BEGIN(dsptri)
10937#ifdef SCOREP_USER_ENABLE
10938 scorep_user_region_by_name_begin("UR_dsptri", scorep_user_region_type_common)
10939#endif
10940 CALL dsptri('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),workspaced,infolp)
10941 IF(infolp /= 0) print *, ' DSPTRI failed: ', infolp
10942#ifdef SCOREP_USER_ENABLE
10943 scorep_user_region_by_name_end("UR_dsptri")
10944#endif
10945 !$POMP INST END(dsptri)
10946 IF(monpg1 > 0) CALL monend()
10947 ELSE
10948 !$POMP INST BEGIN(dsytri)
10949#ifdef SCOREP_USER_ENABLE
10950 scorep_user_region_by_name_begin("UR_dsytri", scorep_user_region_type_common)
10951#endif
10952 CALL dsytri('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
10953 lapackipiv(ipoff+1:),workspaced,infolp)
10954 IF(infolp /= 0) print *, ' DSYTRI failed: ', infolp
10955#ifdef SCOREP_USER_ENABLE
10956 scorep_user_region_by_name_end("UR_dsytri")
10957#endif
10958 !$POMP INST END(dsytri)
10959 IF(monpg1 > 0) CALL monend()
10960 END IF
10961 ELSE
10962 IF(monpg1 > 0) THEN
10963 WRITE(lunlog,*) 'Inverse of global matrix from LLt factorization'
10965 END IF
10966 IF (matsto == 1) THEN
10967 !$POMP INST BEGIN(dpptri)
10968#ifdef SCOREP_USER_ENABLE
10969 scorep_user_region_by_name_begin("UR_dpptri", scorep_user_region_type_common)
10970#endif
10971 CALL dpptri('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
10972 IF(infolp /= 0) print *, ' DPPTRI failed: ', infolp
10973#ifdef SCOREP_USER_ENABLE
10974 scorep_user_region_by_name_end("UR_dpptri")
10975#endif
10976 !$POMP INST END(dpptri)
10977 ELSE
10978 !$POMP INST BEGIN(dpotri)
10979#ifdef SCOREP_USER_ENABLE
10980 scorep_user_region_by_name_begin("UR_dpotri", scorep_user_region_type_common)
10981#endif
10982 CALL dpotri('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
10983 IF(infolp /= 0) print *, ' DPOTRI failed: ', infolp
10984#ifdef SCOREP_USER_ENABLE
10985 scorep_user_region_by_name_end("UR_dpotri")
10986#endif
10987 !$POMP INST END(dpotri)
10988 END IF
10989 IF(monpg1 > 0) CALL monend()
10990 END IF
10991 END DO
10992 END IF
10993#endif
10994 !use elimination for constraints ?
10995 IF(nfgb < nvgb) THEN
10996 ! extend, transform matrix
10997 ! loop over blocks
10998 DO ib=1,npblck
10999 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
11000 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
11001 icoff=vecparblockconoffsets(ib) ! constraint offset for block
11002 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
11003 DO i=npar-ncon+1,npar
11004 ioff=globalrowoffsets(i+ipoff)+ipoff
11005 globalmatd(ioff+1:ioff+i)=0.0_mpd
11006 END DO
11007 END DO
11008 ! monitor progress
11009 IF(monpg1 > 0) THEN
11010 WRITE(lunlog,*) 'Expansion of global matrix (A->Q*A*Q^t)'
11012 END IF
11013 IF(icelim < 2) THEN
11014 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.false.) ! Q*A*Q^t
11015#ifdef LAPACK64
11016 ELSE ! unpack storage, use LAPACK
11017 CALL lpavat(.false.)
11018#endif
11019 END IF
11020 IF(monpg1 > 0) CALL monend()
11021 END IF
11022 END IF
11023
11024 dwmean=sumndf/real(ndfsum,mpd)
11025 dratio=fvalue/dwmean/real(ndfsum-nfgb,mpd)
11026 catio=real(dratio,mps)
11027 IF(nloopn /= 1.AND.lhuber /= 0) THEN
11028 catio=catio/0.9326 ! correction Huber downweighting (in global chi2)
11029 END IF
11030 mrati=nint(100.0*catio,mpi)
11031
11032 DO lunp=6,lunlog,lunlog-6
11033 WRITE(lunp,*) ' '
11034 IF (nfilw <= 0) THEN
11035 WRITE(lunp,*) 'Sum(Chi^2)/Sum(Ndf) =',fvalue
11036 WRITE(lunp,*) ' / (',ndfsum,'-',nfgb,')'
11037 WRITE(lunp,*) ' =',dratio
11038 ELSE
11039 WRITE(lunp,*) 'Sum(W*Chi^2)/Sum(Ndf)/<W> =',fvalue
11040 WRITE(lunp,*) ' / (',ndfsum,'-', nfgb,')'
11041 WRITE(lunp,*) ' /',dwmean
11042 WRITE(lunp,*) ' =',dratio
11043 END IF
11044 WRITE(lunp,*) ' '
11045 IF(nloopn /= 1.AND.lhuber /= 0) WRITE(lunp,*) &
11046 ' with correction for down-weighting ',catio
11047 END DO
11048 nrej=sum(nrejec) ! total number of rejects
11049
11050 ! ... the end with exit code ???????????????????????????????????????
11051
11052 ! WRITE(*,199) ! write exit code
11053 ! + '-----------------------------------------------------------'
11054 ! IF(ITEXIT.EQ.0) WRITE(*,199)
11055 ! + 'Exit code = 0: Convergence reached'
11056 ! IF(ITEXIT.EQ.1) WRITE(*,199)
11057 ! + 'Exit code = 1: No improvement in last iteration'
11058 ! IF(ITEXIT.EQ.2) WRITE(*,199)
11059 ! + 'Exit code = 2: Maximum number of iterations reached'
11060 ! IF(ITEXIT.EQ.3) WRITE(*,199)
11061 ! + 'Exit code = 3: Failure'
11062 ! WRITE(*,199)
11063 ! + '-----------------------------------------------------------'
11064 ! WRITE(*,199) ' '
11065
11066
11067 nrati=nint(10000.0*real(nrej,mps)/real(nrecal,mps),mpi)
11068 WRITE(crjrat,197) 0.01_mpd*real(nrati,mpd)
11069 nfaci=nint(100.0*sqrt(catio),mpi)
11070
11071 WRITE(cratio,197) 0.01_mpd*real(mrati,mpd)
11072 WRITE(cfacin,197) 0.01_mpd*real(nfaci,mpd)
11073
11074 warner=.false. ! warnings
11075 IF(mrati < 90.OR.mrati > 110) warner=.true.
11076 IF(nrati > 100) warner=.true.
11077 IF(ncgbe /= 0) warner=.true.
11078 warners = .false. ! severe warnings
11079 IF(nalow /= 0) warners=.true.
11080 warnerss = .false. ! more severe warnings
11081 IF(nmiss1 /= 0) warnerss=.true.
11082 IF(iagain /= 0) warnerss=.true.
11083 IF(ndefec /= 0) warnerss=.true.
11084 IF(ndefpg /= 0) warnerss=.true.
11085 warners3 = .false. ! more severe warnings
11086 IF(nrderr /= 0) warners3=.true.
11087
11088 IF(warner.OR.warners.OR.warnerss.Or.warners3) THEN
11089 WRITE(*,199) ' '
11090 WRITE(*,199) ' '
11091 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
11092 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
11093 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
11094 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
11095 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
11096 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
11097 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
11098
11099 IF(mrati < 90.OR.mrati > 110) THEN
11100 WRITE(*,199) ' '
11101 WRITE(*,*) ' Chi^2/Ndf = ',cratio, ' (should be close to 1)'
11102 WRITE(*,*) ' => multiply all input standard ', &
11103 'deviations by factor',cfacin
11104 END IF
11105
11106 IF(nrati > 100) THEN
11107 WRITE(*,199) ' '
11108 WRITE(*,*) ' Fraction of rejects =',crjrat,' %', &
11109 ' (should be far below 1 %)'
11110 WRITE(*,*) ' => please provide correct mille data'
11111 CALL chkrej ! check (and print) rejection details
11112 END IF
11113
11114 IF(iagain /= 0) THEN
11115 WRITE(*,199) ' '
11116 WRITE(*,*) ' Matrix not positiv definite '// &
11117 '(function not decreasing)'
11118 WRITE(*,*) ' => please provide correct mille data'
11119 END IF
11120
11121 IF(ndefec /= 0) THEN
11122 WRITE(*,199) ' '
11123 WRITE(*,*) ' Rank defect =',ndefec, &
11124 ' for global matrix, should be 0'
11125 WRITE(*,*) ' => please provide correct mille data'
11126 END IF
11127
11128 IF(ndefpg /= 0) THEN
11129 WRITE(*,199) ' '
11130 WRITE(*,*) ' Rank defect for',ndefpg, &
11131 ' parameter groups, should be 0'
11132 WRITE(*,*) ' => please provide correct mille data'
11133 END IF
11134
11135 IF(nmiss1 /= 0) THEN
11136 WRITE(*,199) ' '
11137 WRITE(*,*) ' Rank defect =',nmiss1, &
11138 ' for constraint equations, should be 0'
11139 WRITE(*,*) ' => please correct constraint definition'
11140 END IF
11141
11142 IF(ncgbe /= 0) THEN
11143 WRITE(*,199) ' '
11144 WRITE(*,*) ' Number of empty constraints =',ncgbe, ', should be 0'
11145 WRITE(*,*) ' => please check constraint definition, mille data'
11146 END IF
11147
11148 IF(nxlow /= 0) THEN
11149 WRITE(*,199) ' '
11150 WRITE(*,*) ' Possible rank defects =',nxlow, ' for global matrix'
11151 WRITE(*,*) ' (too few accepted entries)'
11152 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11153 END IF
11154
11155 IF(nalow /= 0) THEN
11156 WRITE(*,199) ' '
11157 WRITE(*,*) ' Possible bad elements =',nalow, ' in global vector'
11158 WRITE(*,*) ' (toos few accepted entries)'
11159 IF(ipcntr > 0) WRITE(*,*) ' (indicated in millepede.res by counts<0)'
11160 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11161 END IF
11162
11163 IF(nrderr /= 0) THEN
11164 WRITE(*,199) ' '
11165 WRITE(*,*) ' Binary file(s) with read errors =',nrderr, ' (treated as EOF)'
11166 WRITE(*,*) ' => please check mille data'
11167 END IF
11168
11169 WRITE(*,199) ' '
11170 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
11171 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
11172 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
11173 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
11174 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
11175 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
11176 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
11177 WRITE(*,199) ' '
11178
11179 ENDIF
11180
11181 CALL mend ! modul ending
11182
11183 ! ------------------------------------------------------------------
11184
11185 IF(metsol == 1) THEN
11186
11187 ELSE IF(metsol == 2) THEN
11188 ! CALL zdiags moved up (before qlssq)
11189 ELSE IF(metsol == 3) THEN
11190 ! decomposition - nothing foreseen yet
11191 ELSE IF(metsol == 4 .OR. metsol == 5) THEN
11192 ! errors and correlations from MINRES
11193 DO k=1,mnrsel
11194 labelg=lbmnrs(k)
11195 IF(labelg == 0) cycle
11196 itgbi=inone(labelg)
11197 ivgbi=0
11198 IF(itgbi /= 0) ivgbi=globalparlabelindex(2,itgbi)
11199 IF(ivgbi < 0) ivgbi=0
11200 IF(ivgbi == 0) cycle
11201 ! determine error and global correlation for parameter IVGBI
11202 IF (metsol == 4) THEN
11203 CALL solglo(ivgbi)
11204 ELSE
11205 CALL solgloqlp(ivgbi)
11206 ENDIF
11207 END DO
11208
11209 ELSE IF(metsol == 6) THEN
11210
11211#ifdef LAPACK64
11212 ELSE IF(metsol == 7) THEN
11213 ! LAPACK - nothing foreseen yet
11214#endif
11215 END IF
11216
11217 CALL prtglo ! print result
11218
11219 IF (warners3) THEN
11220 CALL peend(4,'Ended with severe warnings (bad binary file(s))')
11221 ELSE IF (warnerss) THEN
11222 CALL peend(3,'Ended with severe warnings (bad global matrix)')
11223 ELSE IF (warners) THEN
11224 CALL peend(2,'Ended with severe warnings (insufficient measurements)')
11225 ELSE IF (warner) THEN
11226 CALL peend(1,'Ended with warnings (bad measurements)')
11227 ELSE
11228 CALL peend(0,'Ended normally')
11229 END IF
11230
11231102 FORMAT(' Call FEASIB with cut=',g10.3)
11232 ! 103 FORMAT(1X,A,G12.4)
11233197 FORMAT(f7.2)
11234199 FORMAT(7x,a)
11235END SUBROUTINE xloopn ! standard solution
11236
11237
11242
11243SUBROUTINE chkrej
11244 USE mpmod
11245 USE mpdalc
11246
11247 IMPLICIT NONE
11248 INTEGER(mpi) :: i
11249 INTEGER(mpi) :: kfl
11250 INTEGER(mpi) :: kmin
11251 INTEGER(mpi) :: kmax
11252 INTEGER(mpi) :: nrc
11253 INTEGER(mpl) :: nrej
11254
11255 REAL(mps) :: fmax
11256 REAL(mps) :: fmin
11257 REAL(mps) :: frac
11258
11259 REAL(mpd) :: sumallw
11260 REAL(mpd) :: sumrejw
11261
11262 sumallw=0.; sumrejw=0.;
11263 kmin=0; kmax=0;
11264 fmax=-1.; fmin=2;
11265
11266 DO i=1,nfilb
11267 kfl=kfd(2,i)
11268 nrc=-kfd(1,i)
11269 IF (nrc > 0) THEN
11270 nrej=nrc-jfd(kfl)
11271 sumallw=sumallw+real(nrc,mpd)*wfd(kfl)
11272 sumrejw=sumrejw+real(nrej,mpd)*wfd(kfl)
11273 frac=real(nrej,mps)/real(nrc,mps)
11274 IF (frac > fmax) THEN
11275 kmax=kfl
11276 fmax=frac
11277 END IF
11278 IF (frac < fmin) THEN
11279 kmin=kfl
11280 fmin=frac
11281 END IF
11282 END IF
11283 END DO
11284 IF (nfilw > 0) &
11285 WRITE(*,"(' Weighted fraction =',F8.2,' %')") 100.*sumrejw/sumallw
11286 IF (nfilb > 1) THEN
11287 WRITE(*,"(' File with max. fraction ',I6,' :',F8.2,' %')") kmax, 100.*fmax
11288 WRITE(*,"(' File with min. fraction ',I6,' :',F8.2,' %')") kmin, 100.*fmin
11289 END IF
11290
11291END SUBROUTINE chkrej
11292
11306
11307SUBROUTINE filetc
11308 USE mpmod
11309 USE mpdalc
11310
11311 IMPLICIT NONE
11312 INTEGER(mpi) :: i
11313 INTEGER(mpi) :: ia
11314 INTEGER(mpi) :: iargc
11315 INTEGER(mpi) :: ib
11316 INTEGER(mpi) :: ie
11317 INTEGER(mpi) :: ierrf
11318 INTEGER(mpi) :: ieq
11319 INTEGER(mpi) :: ifilb
11320 INTEGER(mpi) :: ioff
11321 INTEGER(mpi) :: iopt
11322 INTEGER(mpi) :: ios
11323 INTEGER(mpi) :: iosum
11324 INTEGER(mpi) :: it
11325 INTEGER(mpi) :: k
11326 INTEGER(mpi) :: mat
11327 INTEGER(mpi) :: nab
11328 INTEGER(mpi) :: nline
11329 INTEGER(mpi) :: npat
11330 INTEGER(mpi) :: ntext
11331 INTEGER(mpi) :: nu
11332 INTEGER(mpi) :: nuf
11333 INTEGER(mpi) :: nums
11334 INTEGER(mpi) :: nufile
11335 INTEGER(mpi) :: lenfileInfo
11336 INTEGER(mpi) :: lenFileNames
11337 INTEGER(mpi) :: matint
11338 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: vecfileInfo
11339 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArray
11340 INTEGER(mpl) :: rows
11341 INTEGER(mpl) :: cols
11342 INTEGER(mpl) :: newcols
11343 INTEGER(mpl) :: length
11344
11345 CHARACTER (LEN=1024) :: text
11346 CHARACTER (LEN=1024) :: fname
11347 CHARACTER (LEN=14) :: bite(3)
11348 CHARACTER (LEN=32) :: keystx
11349 INTEGER(mpi), PARAMETER :: mnum=100
11350 REAL(mpd) :: dnum(mnum)
11351
11352#ifdef READ_C_FILES
11353 INTERFACE
11354 SUBROUTINE initc(nfiles) BIND(c)
11355 USE iso_c_binding
11356 INTEGER(c_int), INTENT(IN), VALUE :: nfiles
11357 END SUBROUTINE initc
11358 END INTERFACE
11359#endif
11360
11361 SAVE
11362 DATA bite/'C_binary','text ','Fortran_binary'/
11363 ! ...
11364 CALL mstart('FILETC/X')
11365
11366 nuf=1 ! C binary is default
11367 DO i=1,8
11368 times(i)=0.0
11369 END DO
11370
11371 ! read command line options ----------------------------------------
11372
11373 filnam=' ' ! print command line options and find steering file
11374 DO i=1,iargc()
11375 IF(i == 1) THEN
11376 WRITE(*,*) ' '
11377 WRITE(*,*) 'Command line options: '
11378 WRITE(*,*) '--------------------- '
11379 END IF
11380 CALL getarg(i,text) ! get I.th text from command line
11381 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11382 WRITE(*,101) i,text(1:nab) ! echo print
11383 IF(text(ia:ia) /= '-') THEN
11384 nu=nufile(text(ia:ib)) ! inquire on file existence
11385 IF(nu == 2) THEN ! existing text file
11386 IF(filnam /= ' ') THEN
11387 WRITE(*,*) 'Second text file in command line - stop'
11388 CALL peend(12,'Aborted, second text file in command line')
11389 stop
11390 ELSE
11391 filnam=text
11392 END IF
11393 ELSE
11394 WRITE(*,*) 'Open error for file:',text(ia:ib),' - stop'
11395 CALL peend(16,'Aborted, open error for file')
11396 IF(text(ia:ia) /= '/') THEN
11397 CALL getenv('PWD',text)
11398 CALL rltext(text,ia,ib,nab)
11399 WRITE(*,*) 'PWD:',text(ia:ib)
11400 END IF
11401 stop
11402 END IF
11403 ELSE
11404 IF(index(text(ia:ib),'b') /= 0) THEN
11405 mdebug=3 ! debug flag
11406 WRITE(*,*) 'Debugging requested'
11407 END IF
11408 it=index(text(ia:ib),'t')
11409 IF(it /= 0) THEN
11410 ictest=1 ! internal test files
11411 ieq=index(text(ia+it:ib),'=')+it
11412 IF (it /= ieq) THEN
11413 IF (index(text(ia+ieq:ib),'SL0' ) /= 0) ictest=2
11414 IF (index(text(ia+ieq:ib),'SLE' ) /= 0) ictest=3
11415 IF (index(text(ia+ieq:ib),'BP' ) /= 0) ictest=4
11416 IF (index(text(ia+ieq:ib),'BRLF') /= 0) ictest=5
11417 IF (index(text(ia+ieq:ib),'BRLC') /= 0) ictest=6
11418 END IF
11419 END IF
11420 IF(index(text(ia:ib),'s') /= 0) isubit=1 ! like "subito"
11421 IF(index(text(ia:ib),'f') /= 0) iforce=1 ! like "force"
11422 IF(index(text(ia:ib),'c') /= 0) icheck=1 ! like "checkinput"
11423 IF(index(text(ia:ib),'C') /= 0) icheck=2 ! like "checkinput 2"
11424 END IF
11425 IF(i == iargc()) WRITE(*,*) '--------------------- '
11426 END DO
11427
11428
11429 ! create test files for option -t ----------------------------------
11430
11431 IF(ictest >= 1) THEN
11432 WRITE(*,*) ' '
11433 IF (ictest == 1) THEN
11434 CALL mptest ! 'wire chamber'
11435 ELSE
11436 CALL mptst2(ictest-2) ! 'silicon tracker'
11437 END IF
11438 IF(filnam == ' ') filnam='mp2str.txt'
11439 WRITE(*,*) ' '
11440 END IF
11441
11442 ! check default steering file with file-name "steerfile" -----------
11443
11444 IF(filnam == ' ') THEN ! check default steering file
11445 text='steerfile'
11446 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11447 nu=nufile(text(ia:ib)) ! inquire on file existence and type
11448 IF(nu > 0) THEN
11449 filnam=text
11450 ELSE
11451 CALL peend(10,'Aborted, no steering file')
11452 stop 'in FILETC: no steering file. .'
11453 END IF
11454 END IF
11455
11456
11457 ! open, read steering file:
11458 ! end
11459 ! fortranfiles
11460 ! cfiles
11461
11462
11463 CALL rltext(filnam,ia,ib,nfnam) ! return indices for non-blank area
11464 WRITE(*,*) ' '
11465 WRITE(*,*) 'Listing of steering file: ',filnam(1:nfnam)
11466 WRITE(*,*) '-------------------------'
11467 OPEN(10,file=filnam(1:nfnam),iostat=ios)
11468 IF(ios /= 0) THEN
11469 WRITE(*,*) 'Open error for steering file - stop'
11470 CALL peend(11,'Aborted, open error for steering file')
11471 IF(filnam(1:1) /= '/') THEN
11472 CALL getenv('PWD',text)
11473 CALL rltext(text,ia,ib,nab)
11474 WRITE(*,*) 'PWD:',text(ia:ib)
11475 END IF
11476 stop
11477 END IF
11478 ifile =0
11479 nfiles=0
11480
11481 lenfileinfo=2
11482 lenfilenames=0
11483 rows=6; cols=lenfileinfo
11484 CALL mpalloc(vecfileinfo,rows,cols,'file info from steering')
11485 nline=0
11486 DO
11487 READ(10,102,iostat=ierrf) text ! read steering file
11488 IF (ierrf < 0) EXIT ! eof
11489 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11490 nline=nline+1
11491 IF(nline <= 50) THEN ! print up to 50 lines
11492 WRITE(*,101) nline,text(1:nab)
11493 IF(nline == 50) WRITE(*,*) ' ...'
11494 END IF
11495 IF(ia == 0) cycle ! skip empty lines
11496
11497 CALL rltext(text,ia,ib,nab) ! test content 'end'
11498 IF(ib == ia+2) THEN
11499 mat=matint(text(ia:ib),'end',npat,ntext)
11500 IF(mat == max(npat,ntext)) THEN ! exact matching
11501 text=' '
11502 CALL intext(text,nline)
11503 WRITE(*,*) ' end-statement after',nline,' text lines'
11504 EXIT
11505 END IF
11506 END IF
11507
11508 keystx='fortranfiles'
11509 mat=matint(text(ia:ib),keystx,npat,ntext)
11510 IF(mat == max(npat,ntext)) THEN ! exact matching
11511 nuf=3
11512 ! WRITE(*,*) 'Fortran files'
11513 cycle
11514 END IF
11515
11516 keystx='Cfiles'
11517 mat=matint(text(ia:ib),keystx,npat,ntext)
11518 IF(mat == max(npat,ntext)) THEN ! exact matching
11519 nuf=1
11520 ! WRITE(*,*) 'Cfiles'
11521 cycle
11522 END IF
11523
11524 keystx='closeandreopen' ! don't keep binary files open
11525 mat=matint(text(ia:ib),keystx,npat,ntext)
11526 IF(mat == max(npat,ntext)) THEN ! exact matching
11527 keepopen=0
11528 cycle
11529 END IF
11530
11531 ! file names
11532 ! check for file options (' -- ')
11533 ie=ib
11534 iopt=index(text(ia:ib),' -- ')
11535 IF (iopt > 0) ie=iopt-1
11536
11537 IF(nab == 0) cycle
11538 nu=nufile(text(ia:ie)) ! inquire on file existence
11539 IF(nu > 0) THEN ! existing file
11540 IF (nfiles == lenfileinfo) THEN ! increase length
11541 CALL mpalloc(temparray,rows,cols,'temp file info from steering')
11542 temparray=vecfileinfo
11543 CALL mpdealloc(vecfileinfo)
11544 lenfileinfo=lenfileinfo*2
11545 newcols=lenfileinfo
11546 CALL mpalloc(vecfileinfo,rows,newcols,'file info from steering')
11547 vecfileinfo(:,1:cols)=temparray(:,1:cols)
11548 CALL mpdealloc(temparray)
11549 cols=newcols
11550 ENDIF
11551 nfiles=nfiles+1 ! count number of files
11552 IF(nu == 1) nu=nuf !
11553 lenfilenames=lenfilenames+ie-ia+1 ! total length of file names
11554 vecfileinfo(1,nfiles)=nline ! line number
11555 vecfileinfo(2,nfiles)=nu ! cbinary =1, text =2, fbinary=3
11556 vecfileinfo(3,nfiles)=ia ! file name start
11557 vecfileinfo(4,nfiles)=ie ! file name end
11558 vecfileinfo(5,nfiles)=iopt ! option start
11559 vecfileinfo(6,nfiles)=ib ! option end
11560 ELSE
11561 ! WRITE(*,*) 'Open error for file ',TEXT(IA:IB)
11562 ! STOP
11563 END IF
11564 END DO
11565 rewind 10
11566 ! read again to fill dynamic arrays with file info
11567 length=nfiles
11568 CALL mpalloc(mfd,length,'file type')
11569 CALL mpalloc(nfd,length,'file line (in steering)')
11570 CALL mpalloc(lfd,length,'file name length')
11571 CALL mpalloc(ofd,length,'file option')
11572 length=lenfilenames
11573 CALL mpalloc(tfd,length,'file name')
11574 nline=0
11575 i=1
11576 ioff=0
11577 DO
11578 READ(10,102,iostat=ierrf) text ! read steering file
11579 IF (ierrf < 0) EXIT ! eof
11580 nline=nline+1
11581 IF (nline == vecfileinfo(1,i)) THEN
11582 nfd(i)=vecfileinfo(1,i)
11583 mfd(i)=vecfileinfo(2,i)
11584 ia=vecfileinfo(3,i)-1
11585 lfd(i)=vecfileinfo(4,i)-ia ! length file name
11586 DO k=1,lfd(i)
11587 tfd(ioff+k)=text(ia+k:ia+k)
11588 END DO
11589 ! tfd(i)=text(vecFileInfo(3,i):vecFileInfo(4,i)) ! file name
11590 ioff=ioff+lfd(i)
11591 ofd(i)=1.0 ! option for file
11592 IF (vecfileinfo(5,i) > 0) THEN
11593 CALL ratext(text(vecfileinfo(5,i)+4:vecfileinfo(6,i)),nums,dnum,mnum) ! translate text to DP numbers
11594 IF (nums > 0) ofd(i)=real(dnum(1),mps)
11595 END IF
11596 i=i+1
11597 IF (i > nfiles) EXIT
11598 ENDIF
11599 ENDDO
11600 CALL mpdealloc(vecfileinfo)
11601 rewind 10
11602 ! additional info for binary files
11603 length=nfiles; rows=2
11604 CALL mpalloc(ifd,length,'integrated record numbers (=offset)')
11605 CALL mpalloc(jfd,length,'number of accepted records')
11606 CALL mpalloc(kfd,rows,length,'number of records in file, file order')
11607 CALL mpalloc(dfd,length,'ndf sum')
11608 CALL mpalloc(xfd,length,'max. record size')
11609 CALL mpalloc(wfd,length,'file weight')
11610 CALL mpalloc(cfd,length,'chi2 sum')
11611 CALL mpalloc(sfd,rows,length,'start, end of file name in TFD')
11612 CALL mpalloc(yfd,length,'modification date')
11613 yfd=0
11614 !
11615 WRITE(*,*) '-------------------------'
11616 WRITE(*,*) ' '
11617
11618 ! print table of files ---------------------------------------------
11619
11620 IF (mprint > 1) THEN
11621 WRITE(*,*) 'Table of files:'
11622 WRITE(*,*) '---------------'
11623 END IF
11624 WRITE(8,*) ' '
11625 WRITE(8,*) 'Text and data files:'
11626 ioff=0
11627 DO i=1,nfiles
11628 DO k=1,lfd(i)
11629 fname(k:k)=tfd(ioff+k)
11630 END DO
11631 ! fname=tfd(i)(1:lfd(i))
11632 IF (mprint > 1) WRITE(*,103) i,bite(mfd(i)),fname(1:lfd(i))
11633 WRITE(8,103) i,bite(mfd(i)),fname(1:lfd(i))
11634 ioff=ioff+lfd(i)
11635 END DO
11636 IF (mprint > 1) THEN
11637 WRITE(*,*) '---------------'
11638 WRITE(*,*) ' '
11639 END IF
11640
11641 ! open the binary Fortran (data) files on unit 11, 12, ...
11642
11643 iosum=0
11644 nfilf=0
11645 nfilb=0
11646 nfilw=0
11647 ioff=0
11648 ifilb=0
11649 IF (keepopen < 1) ifilb=1
11650 DO i=1,nfiles
11651 IF(mfd(i) == 3) THEN
11652 nfilf=nfilf+1
11653 nfilb=nfilb+1
11654 ! next file name
11655 sfd(1,nfilb)=ioff
11656 sfd(2,nfilb)=lfd(i)
11657 CALL binopn(nfilb,ifilb,ios)
11658 IF(ios == 0) THEN
11659 wfd(nfilb)=ofd(i)
11660 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11661 ELSE ! failure
11662 iosum=iosum+1
11663 nfilf=nfilf-1
11664 nfilb=nfilb-1
11665 END IF
11666 END IF
11667 ioff=ioff+lfd(i)
11668 END DO
11669
11670 ! open the binary C files
11671
11672 nfilc=-1
11673 ioff=0
11674 DO i=1,nfiles ! Cfiles
11675 IF(mfd(i) == 1) THEN
11676#ifdef READ_C_FILES
11677 IF(nfilc < 0) THEN ! initialize
11678 CALL initc(max(nfiles,mthrdr)) ! uncommented by GF
11679 nfilc=0
11680 END IF
11681 nfilc=nfilc+1
11682 nfilb=nfilb+1
11683 ! next file name
11684 sfd(1,nfilb)=ioff
11685 sfd(2,nfilb)=lfd(i)
11686 CALL binopn(nfilb,ifilb,ios)
11687 IF(ios == 0) THEN
11688 wfd(nfilb)=ofd(i)
11689 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11690 ELSE ! failure
11691 iosum=iosum+1
11692 nfilc=nfilc-1
11693 nfilb=nfilb-1
11694 END IF
11695#else
11696 WRITE(*,*) 'Opening of C-files not supported.'
11697 ! GF add
11698 iosum=iosum+1
11699 ! GF add end
11700#endif
11701 END IF
11702 ioff=ioff+lfd(i)
11703 END DO
11704
11705 DO k=1,nfilb
11706 kfd(1,k)=1 ! reset (negated) record counters
11707 kfd(2,k)=k ! set file number
11708 ifd(k)=0 ! reset integrated record numbers
11709 xfd(k)=0 ! reset max record size
11710 END DO
11711
11712 IF(iosum /= 0) THEN
11713 CALL peend(15,'Aborted, open error(s) for binary files')
11714 stop 'FILETC: open error '
11715 END IF
11716 IF(nfilb == 0) THEN
11717 CALL peend(14,'Aborted, no binary files')
11718 stop 'FILETC: no binary files '
11719 END IF
11720 IF (keepopen > 0) THEN
11721 WRITE(*,*) nfilb,' binary files opened' ! corrected by GF
11722 ELSE
11723 WRITE(*,*) nfilb,' binary files opened and closed' ! corrected by GF
11724 END IF
11725101 FORMAT(i3,2x,a)
11726102 FORMAT(a)
11727103 FORMAT(i3,2x,a14,3x,a)
11728 ! CALL mend
11729 RETURN
11730END SUBROUTINE filetc
11731
11782
11783SUBROUTINE filetx ! ---------------------------------------------------
11784 USE mpmod
11785
11786 IMPLICIT NONE
11787 INTEGER(mpi) :: i
11788 INTEGER(mpi) :: ia
11789 INTEGER(mpi) :: ib
11790 INTEGER(mpi) :: ierrf
11791 INTEGER(mpi) :: ioff
11792 INTEGER(mpi) :: ios
11793 INTEGER(mpi) :: iosum
11794 INTEGER(mpi) :: k
11795 INTEGER(mpi) :: mat
11796 INTEGER(mpi) :: nab
11797 INTEGER(mpi) :: nfiln
11798 INTEGER(mpi) :: nline
11799 INTEGER(mpi) :: nlinmx
11800 INTEGER(mpi) :: npat
11801 INTEGER(mpi) :: ntext
11802 INTEGER(mpi) :: matint
11803
11804 ! CALL MSTART('FILETX')
11805
11806 CHARACTER (LEN=1024) :: text
11807 CHARACTER (LEN=1024) :: fname
11808
11809 WRITE(*,*) ' '
11810 WRITE(*,*) 'Processing text files ...'
11811 WRITE(*,*) ' '
11812
11813 iosum=0
11814 ioff=0
11815 DO i=0,nfiles
11816 IF(i == 0) THEN
11817 WRITE(*,*) 'File ',filnam(1:nfnam)
11818 nlinmx=100
11819 ELSE
11820 nlinmx=10
11821 ia=ioff
11822 ioff=ioff+lfd(i)
11823 IF(mfd(i) /= 2) cycle ! exclude binary files
11824 DO k=1,lfd(i)
11825 fname(k:k)=tfd(ia+k)
11826 END DO
11827 WRITE(*,*) 'File ',fname(1:lfd(i))
11828 IF (mprint > 1) WRITE(*,*) ' '
11829 OPEN(10,file=fname(1:lfd(i)),iostat=ios,form='FORMATTED')
11830 IF(ios /= 0) THEN
11831 WRITE(*,*) 'Open error for file ',fname(1:lfd(i))
11832 iosum=iosum+1
11833 cycle
11834 END IF
11835 END IF
11836
11837 nline=0
11838 nfiln=1
11839 ! read text file
11840 DO
11841 READ(10,102,iostat=ierrf) text
11842 IF (ierrf < 0) THEN
11843 text=' '
11844 CALL intext(text,nline)
11845 WRITE(*,*) ' end-of-file after',nline,' text lines'
11846 EXIT ! eof
11847 ENDIF
11848 nline=nline+1
11849 IF(nline <= nlinmx.AND.mprint > 1) THEN ! print first 10 lines of every text fiLE
11850 CALL rltext(text,ia,ib,nab)
11851 nab=max(1,nab)
11852 WRITE(*,101) nline,text(1:nab)
11853 IF(nline == nlinmx) WRITE(*,*) ' ...'
11854 END IF
11855
11856 CALL rltext(text,ia,ib,nab) ! test content 'end'
11857 IF(ib == ia+2) THEN
11858 mat=matint(text(ia:ib),'end',npat,ntext)
11859 IF(mat == max(npat,ntext)) THEN ! exact matching
11860 text=' '
11861 CALL intext(text,nline)
11862 WRITE(*,*) ' end-statement after',nline,' text lines'
11863 EXIT
11864 END IF
11865 END IF
11866
11867 IF(i == 0) THEN ! first text file - exclude lines with file names
11868 IF(nfiln <= nfiles) THEN
11869 IF(nline == nfd(nfiln)) THEN
11870 nfiln=nfiln+1
11871 text=' '
11872 ! WRITE(*,*) 'line is excluded ',TEXT(1:10)
11873 END IF
11874 END IF
11875 END IF
11876 ! WRITE(*,*) TEXT(1:40),' < interprete text'
11877 CALL intext(text,nline) ! interprete text
11878 END DO
11879 WRITE(*,*) ' '
11880 rewind 10
11881 CLOSE(unit=10)
11882 END DO
11883
11884 IF(iosum /= 0) THEN
11885 CALL peend(16,'Aborted, open error(s) for text files')
11886 stop 'FILETX: open error(s) in text files '
11887 END IF
11888
11889 WRITE(*,*) '... end of text file processing.'
11890 WRITE(*,*) ' '
11891
11892 IF(lunkno /= 0) THEN
11893 WRITE(*,*) ' '
11894 WRITE(*,*) lunkno,' unknown keywords in steering files, ', &
11895 'or file non-existing,'
11896 WRITE(*,*) ' see above!'
11897 WRITE(*,*) '------------> stop'
11898 WRITE(*,*) ' '
11899 CALL peend(13,'Aborted, unknown keywords in steering file')
11900 stop
11901 END IF
11902
11903 ! check methods
11904
11905 IF(metsol == 0) THEN ! if undefined
11906 IF(matsto == 0) THEN ! if unpacked symmetric
11907 metsol=8 ! LAPACK
11908 ELSE IF(matsto == 1) THEN ! if full symmetric
11909 metsol=4 ! MINRES
11910 ELSE IF(matsto == 2) THEN ! if sparse
11911 metsol=4 ! MINRES
11912 END IF
11913 ELSE IF(metsol == 1) THEN ! if inversion
11914 matsto=1
11915 ELSE IF(metsol == 2) THEN ! if diagonalization
11916 matsto=1
11917 ELSE IF(metsol == 3) THEN ! if decomposition
11918 matsto=1
11919 ELSE IF(metsol == 4) THEN ! if MINRES
11920 ! MATSTO=2 or 1
11921 ELSE IF(metsol == 5) THEN ! if MINRES-QLP
11922 ! MATSTO=2 or 1
11923 ELSE IF(metsol == 6) THEN ! if GMRES
11924 ! MATSTO=2 or 1
11925#ifdef LAPACK64
11926 ELSE IF(metsol == 7) THEN ! if LAPACK
11927 matsto=1
11928 ELSE IF(metsol == 8) THEN ! if LAPACK
11929 matsto=0
11930#ifdef PARDISO
11931 ELSE IF(metsol == 9) THEN ! if Intel oneMKL PARDISO
11932 matsto=3
11933#endif
11934#endif
11935 ELSE
11936 WRITE(*,*) 'MINRES forced with sparse matrix!'
11937 WRITE(*,*) ' '
11938 WRITE(*,*) 'MINRES forced with sparse matrix!'
11939 WRITE(*,*) ' '
11940 WRITE(*,*) 'MINRES forced with sparse matrix!'
11941 metsol=4 ! forced
11942 matsto=2 ! forced
11943 END IF
11944 IF(matsto > 4) THEN
11945 WRITE(*,*) 'MINRES forced with sparse matrix!'
11946 WRITE(*,*) ' '
11947 WRITE(*,*) 'MINRES forced with sparse matrix!'
11948 WRITE(*,*) ' '
11949 WRITE(*,*) 'MINRES forced with sparse matrix!'
11950 metsol=4 ! forced
11951 matsto=2 ! forced
11952 END IF
11953
11954 ! print information about methods and matrix storage modes
11955
11956 WRITE(*,*) ' '
11957 WRITE(*,*) 'Solution method and matrix-storage mode:'
11958 IF(metsol == 1) THEN
11959 WRITE(*,*) ' METSOL = 1: matrix inversion'
11960 ELSE IF(metsol == 2) THEN
11961 WRITE(*,*) ' METSOL = 2: diagonalization'
11962 ELSE IF(metsol == 3) THEN
11963 WRITE(*,*) ' METSOL = 3: decomposition'
11964 ELSE IF(metsol == 4) THEN
11965 WRITE(*,*) ' METSOL = 4: MINRES'
11966 ELSE IF(metsol == 5) THEN
11967 WRITE(*,*) ' METSOL = 5: MINRES-QLP'
11968 ELSE IF(metsol == 6) THEN
11969 WRITE(*,*) ' METSOL = 6: GMRES (-> MINRES)'
11970#ifdef LAPACK64
11971 ELSE IF(metsol == 7) THEN
11972 WRITE(*,*) ' METSOL = 7: LAPACK factorization'
11973 ELSE IF(metsol == 8) THEN
11974 WRITE(*,*) ' METSOL = 8: LAPACK factorization'
11975#ifdef PARDISO
11976 ELSE IF(metsol == 9) THEN
11977 WRITE(*,*) ' METSOL = 9: Intel oneMKL PARDISO'
11978#endif
11979#endif
11980 END IF
11981
11982 WRITE(*,*) ' with',mitera,' iterations'
11983
11984 IF(matsto == 0) THEN
11985 WRITE(*,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
11986 ELSEIF(matsto == 1) THEN
11987 WRITE(*,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
11988 ELSE IF(matsto == 2) THEN
11989 WRITE(*,*) ' MATSTO = 2: sparse matrix (custom)'
11990 ELSE IF(matsto == 3) THEN
11991 IF (mpdbsz == 0) THEN
11992 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
11993 ELSE
11994 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
11995 END IF
11996 END IF
11997 IF(mbandw /= 0.AND.(metsol >= 4.AND. metsol <7)) THEN ! band matrix as MINRES preconditioner
11998 WRITE(*,*) ' and band matrix, width',mbandw
11999 END IF
12000
12001 IF(chicut /= 0.0) THEN
12002 WRITE(*,*) 'Chi square cut equiv 3 st.dev applied ...'
12003 WRITE(*,*) ' in first iteration with factor',chicut
12004 WRITE(*,*) ' in second iteration with factor',chirem
12005 WRITE(*,*) ' (reduced by sqrt in next iterations)'
12006 END IF
12007
12008 IF(lhuber /= 0) THEN
12009 WRITE(*,*) ' Down-weighting of outliers in', lhuber,' iterations'
12010 WRITE(*,*) ' Cut on downweight fraction',dwcut
12011 END IF
12012
12013 WRITE(*,*) 'Iterations (solutions) with line search:'
12014 IF(lsearch > 2) THEN
12015 WRITE(*,*) ' All'
12016 ELSEIF (lsearch == 1) THEN
12017 WRITE(*,*) ' Last'
12018 ELSEIF (lsearch < 1) THEN
12019 WRITE(*,*) ' None'
12020 ELSE
12021 IF (chicut /= 0.0) THEN
12022 WRITE(*,*) ' All with Chi square cut scaling factor <= 1.'
12023 ELSE
12024 WRITE(*,*) ' All'
12025 ENDIF
12026 ENDIF
12027
12028 IF(nummeasurements>0) THEN
12029 WRITE(*,*)
12030 WRITE(*,*) ' Number of external measurements ', nummeasurements
12031 ENDIF
12032
12033 CALL mend
12034
12035101 FORMAT(i3,2x,a)
12036102 FORMAT(a)
12037END SUBROUTINE filetx
12038
12048
12049INTEGER(mpi) FUNCTION nufile(fname)
12050 USE mpdef
12051
12052 IMPLICIT NONE
12053 INTEGER(mpi) :: ios
12054 INTEGER(mpi) :: l1
12055 INTEGER(mpi) :: ll
12056 INTEGER(mpi) :: nm
12057 INTEGER(mpi) :: npat
12058 INTEGER(mpi) :: ntext
12059 INTEGER(mpi) :: nuprae
12060 INTEGER(mpi) :: matint
12061
12062 CHARACTER (LEN=*), INTENT(INOUT) :: fname
12063 LOGICAL :: ex
12064 SAVE
12065 ! ...
12066 nufile=0
12067 nuprae=0
12068 IF(len(fname) > 5) THEN
12069 IF(fname(1:5) == 'rfio:') nuprae=1
12070 IF(fname(1:5) == 'dcap:') nuprae=2
12071 IF(fname(1:5) == 'root:') nuprae=3
12072 END IF
12073 IF(nuprae == 0) THEN
12074 INQUIRE(file=fname,iostat=ios,exist=ex)
12075 IF(ios /= 0) nufile=-abs(ios)
12076 IF(ios /= 0) RETURN
12077 ELSE IF(nuprae == 1) THEN ! rfio:
12078 ll=len(fname)
12079 fname=fname(6:ll)
12080 ex=.true.
12081 nufile=1
12082 RETURN
12083 ELSE
12084 ex=.true. ! assume file existence
12085 END IF
12086 IF(ex) THEN
12087 nufile=1 ! binary
12088 ll=len(fname)
12089 l1=max(1,ll-3)
12090 nm=matint('xt',fname(l1:ll),npat,ntext)
12091 IF(nm == 2) nufile=2 ! text
12092 IF(nm < 2) THEN
12093 nm=matint('tx',fname(l1:ll),npat,ntext)
12094 IF(nm == 2) nufile=2 ! text
12095 END IF
12096 END IF
12097END FUNCTION nufile
12098
12106SUBROUTINE intext(text,nline)
12107 USE mpmod
12108 USE mptext
12109
12110 IMPLICIT NONE
12111 INTEGER(mpi) :: i
12112 INTEGER(mpi) :: ia
12113 INTEGER(mpi) :: ib
12114 INTEGER(mpi) :: ier
12115 INTEGER(mpi) :: iomp
12116 INTEGER(mpi) :: j
12117 INTEGER(mpi) :: k
12118 INTEGER(mpi) :: kkey
12119 INTEGER(mpi) :: label
12120 INTEGER(mpi) :: lkey
12121 INTEGER(mpi) :: mat
12122 INTEGER(mpi) :: miter
12123 INTEGER(mpi) :: nab
12124 INTEGER(mpi) :: nkey
12125 INTEGER(mpi) :: nkeys
12126 INTEGER(mpi) :: nl
12127 INTEGER(mpi) :: nmeth
12128 INTEGER(mpi) :: npat
12129 INTEGER(mpi) :: ntext
12130 INTEGER(mpi) :: nums
12131 INTEGER(mpi) :: matint
12132
12133 CHARACTER (LEN=*), INTENT(IN) :: text
12134 INTEGER(mpi), INTENT(IN) :: nline
12135
12136#ifdef LAPACK64
12137#ifdef PARDISO
12138 parameter(nkeys=7,nmeth=10)
12139#else
12140 parameter(nkeys=6,nmeth=9)
12141#endif
12142#else
12143 parameter(nkeys=6,nmeth=7)
12144#endif
12145 CHARACTER (LEN=16) :: methxt(nmeth)
12146 CHARACTER (LEN=16) :: keylst(nkeys)
12147 CHARACTER (LEN=32) :: keywrd
12148 CHARACTER (LEN=32) :: keystx
12149 CHARACTER (LEN=itemCLen) :: ctext
12150 INTEGER(mpi), PARAMETER :: mnum=100
12151 REAL(mpd) :: dnum(mnum)
12152#ifdef LAPACK64
12153#ifdef PARDISO
12154 INTEGER(mpi) :: ipvs ! ... integer value
12155#endif
12156#endif
12157 INTEGER(mpi) :: lpvs ! ... integer label
12158 REAL(mpd) :: plvs ! ... float value
12159
12160 INTERFACE
12161 SUBROUTINE additem(length,list,label,value)
12162 USE mpmod
12163 INTEGER(mpi), INTENT(IN OUT) :: length
12164 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12165 INTEGER(mpi), INTENT(IN) :: label
12166 REAL(mpd), INTENT(IN) :: value
12167 END SUBROUTINE additem
12168 SUBROUTINE additemc(length,list,label,text)
12169 USE mpmod
12170 INTEGER(mpi), INTENT(IN OUT) :: length
12171 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12172 INTEGER(mpi), INTENT(IN) :: label
12173 CHARACTER(LEN = itemCLen), INTENT(IN) :: text
12174 END SUBROUTINE additemc
12175 SUBROUTINE additemi(length,list,label,ivalue)
12176 USE mpmod
12177 INTEGER(mpi), INTENT(IN OUT) :: length
12178 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12179 INTEGER(mpi), INTENT(IN) :: label
12180 INTEGER(mpi), INTENT(IN) :: ivalue
12181 END SUBROUTINE additemi
12182 END INTERFACE
12183
12184 SAVE
12185#ifdef LAPACK64
12186#ifdef PARDISO
12187 DATA keylst/'unknown','parameter','constraint','measurement','method','comment','pardiso'/
12188 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12189 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK', &
12190 'sparsePARDISO'/
12191#else
12192 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12193 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12194 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK'/
12195#endif
12196#else
12197 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12198 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12199 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition'/
12200#endif
12201 DATA lkey/-1/ ! last keyword
12202
12203 ! ...
12204 nkey=-1 ! new keyword
12205 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
12206 IF(nab == 0) GOTO 10
12207 CALL ratext(text(1:nab),nums,dnum,mnum) ! translate text to DP numbers
12208
12209 IF(nums /= 0) nkey=0
12210 IF(keyb /= 0) THEN
12211 keywrd=text(keya:keyb) ! text is TEXT(KEYA)...TEXT(KEYB)
12212 ! WRITE(*,*) 'Keyword is ',KEYWRD
12213
12214 ! compare keywords
12215
12216 DO nkey=2,nkeys ! loop over all pede keywords
12217 keystx=keylst(nkey) ! copy NKEY.th pede keyword
12218 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12219 IF(100*mat >= 80*max(npat,ntext)) GO TO 10 ! 80% (symmetric) matching
12220 END DO
12221
12222 ! more comparisons
12223
12224 keystx='print'
12225 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12226 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12227 mprint=1
12228 IF(nums > 0) mprint=nint(dnum(1),mpi)
12229 RETURN
12230 END IF
12231
12232 keystx='debug'
12233 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12234 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12235 mdebug=3
12236 ! GF IF(NUMS.GT.0) MPRINT=DNUM(1)
12237 IF(nums > 0) mdebug=nint(dnum(1),mpi)
12238 IF(nums > 1) mdebg2=nint(dnum(2),mpi)
12239 RETURN
12240 END IF
12241
12242 keystx='entries'
12243 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12244 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12245 IF(nums > 0 .AND. dnum(1) > 0.5) mreqenf=nint(dnum(1),mpi)
12246 IF(nums > 1 .AND. dnum(2) > 0.5) mreqena=nint(dnum(2),mpi)
12247 IF(nums > 2 .AND. dnum(3) > 0.5) iteren=nint(dnum(1)*dnum(3),mpi)
12248 RETURN
12249 END IF
12250
12251 keystx='printrecord'
12252 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12253 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12254 IF(nums > 0) nrecpr=nint(dnum(1),mpi)
12255 IF(nums > 1) nrecp2=nint(dnum(2),mpi)
12256 RETURN
12257 END IF
12258
12259 keystx='maxrecord'
12260 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12261 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12262 IF (nums > 0.AND.dnum(1) > 0.) mxrec=nint(dnum(1),mpi)
12263 RETURN
12264 END IF
12265
12266 keystx='cache'
12267 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12268 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12269 IF (nums > 0.AND.dnum(1) >= 0.) ncache=nint(dnum(1),mpi) ! cache size, <0 keeps default
12270 IF (nums == 2.AND.dnum(2) > 0..AND.dnum(2) <= 1.0) & ! read cache fill level
12271 fcache(1)=real(dnum(2),mps)
12272 IF (nums >= 4) THEN ! explicit cache splitting
12273 DO k=1,3
12274 fcache(k)=real(dnum(k+1),mps)
12275 END DO
12276 END IF
12277 RETURN
12278 END IF
12279
12280 keystx='chisqcut'
12281 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12282 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12283 IF(nums == 0) THEN ! always 3-sigma cut
12284 chicut=1.0
12285 chirem=1.0
12286 ELSE
12287 chicut=real(dnum(1),mps)
12288 IF(chicut < 1.0) chicut=-1.0
12289 IF(nums == 1) THEN
12290 chirem=1.0 ! 3-sigma cut, if not specified
12291 ELSE
12292 chirem=real(dnum(2),mps)
12293 IF(chirem < 1.0) chirem=1.0
12294 IF(chicut >= 1.0) chirem=min(chirem,chicut)
12295 END IF
12296 END IF
12297 RETURN
12298 END IF
12299
12300 ! GF added:
12301 keystx='hugecut'
12302 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12303 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12304 IF(nums > 0) chhuge=real(dnum(1),mps)
12305 IF(chhuge < 1.0) chhuge=1.0 ! at least (!!) 3-sigma
12306 RETURN
12307 END IF
12308 ! GF added end
12309
12310 keystx='linesearch'
12311 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12312 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12313 IF(nums > 0) lsearch=nint(dnum(1),mpi)
12314 RETURN
12315 END IF
12316
12317 keystx='localfit'
12318 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12319 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12320 IF(nums > 0) lfitnp=nint(dnum(1),mpi)
12321 IF(nums > 1) lfitbb=nint(dnum(2),mpi)
12322 RETURN
12323 END IF
12324
12325 keystx='regularization'
12326 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12327 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12328 nregul=1
12329 regula=real(dnum(1),mps)
12330 IF(nums >= 2) regpre=real(dnum(2),mps)
12331 RETURN
12332 END IF
12333
12334 keystx='regularisation'
12335 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12336 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12337 nregul=1
12338 regula=real(dnum(1),mps)
12339 IF(nums >= 2) regpre=real(dnum(2),mps)
12340 RETURN
12341 END IF
12342
12343 keystx='presigma'
12344 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12345 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12346 regpre=real(dnum(1),mps)
12347 RETURN
12348 END IF
12349
12350 keystx='matiter'
12351 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12352 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12353 matrit=nint(dnum(1),mpi)
12354 RETURN
12355 END IF
12356
12357 keystx='matmoni'
12358 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12359 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12360 matmon=-1
12361 IF (nums > 0.AND.dnum(1) > 0.) matmon=nint(dnum(1),mpi)
12362 RETURN
12363 END IF
12364
12365 keystx='bandwidth'
12366 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12367 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12368 IF(nums > 0) mbandw=nint(dnum(1),mpi)
12369 IF(mbandw < 0) mbandw=-1
12370 IF(nums > 1) lprecm=nint(dnum(2),mpi)
12371 RETURN
12372 END IF
12373
12374 ! KEYSTX='outlierrejection'
12375 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12376 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12377 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12378 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12379 ! CHDFRJ=DNUM(1)
12380 ! IF(CHDFRJ.LT.3.0) CHDFRJ=100.0
12381 ! RETURN
12382 ! END IF
12383
12384 ! KEYSTX='outliersuppression'
12385 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12386 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12387 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12388 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12389 ! LHUBER=DNUM(1)
12390 ! IF(LHUBER.LE.2) LHUBER=2 ! at least 2 Huber iterations
12391 ! RETURN
12392 ! END IF
12393
12394 keystx='outlierdownweighting'
12395 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12396 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12397 lhuber=nint(dnum(1),mpi)
12398 IF(lhuber > 0.AND.lhuber <= 2) lhuber=2 ! at least 2 Huber iterations (if any)
12399 RETURN
12400 END IF
12401
12402 keystx='dwfractioncut'
12403 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12404 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12405 dwcut=real(dnum(1),mps)
12406 IF(dwcut > 0.5) dwcut=0.5
12407 RETURN
12408 END IF
12409
12410 keystx='maxlocalcond'
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.AND.dnum(1) > 0.0) cndlmx=real(dnum(1),mps)
12414 RETURN
12415 END IF
12416
12417 keystx='pullrange'
12418 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12419 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12420 prange=abs(real(dnum(1),mps))
12421 RETURN
12422 END IF
12423
12424 keystx='subito'
12425 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12426 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12427 isubit=1
12428 RETURN
12429 END IF
12430
12431 keystx='force'
12432 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12433 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12434 iforce=1
12435 RETURN
12436 END IF
12437
12438 keystx='memorydebug'
12439 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12440 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12441 memdbg=1
12442 IF (nums > 0.AND.dnum(1) > 0.0) memdbg=nint(dnum(1),mpi)
12443 RETURN
12444 END IF
12445
12446 keystx='globalcorr'
12447 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12448 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12449 igcorr=1
12450 RETURN
12451 END IF
12452
12453 keystx='printcounts'
12454 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12455 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12456 ipcntr=1
12457 IF (nums > 0) ipcntr=nint(dnum(1),mpi)
12458 RETURN
12459 END IF
12460
12461 keystx='weightedcons'
12462 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12463 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12464 iwcons=1
12465 IF (nums > 0) iwcons=nint(dnum(1),mpi)
12466 RETURN
12467 END IF
12468
12469 keystx='skipemptycons'
12470 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12471 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12472 iskpec=1
12473 RETURN
12474 END IF
12475
12476 keystx='resolveredundancycons'
12477 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12478 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12479 irslvrc=1
12480 RETURN
12481 END IF
12482
12483 keystx='withelimination'
12484 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12485 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12486 icelim=1
12487 RETURN
12488 END IF
12489
12490 keystx='postprocessing'
12491 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12492 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12493 lenpostproc=ib-keyb-1
12494 cpostproc(1:lenpostproc)=text(keyb+2:ib)
12495 RETURN
12496 END IF
12497
12498#ifdef LAPACK64
12499 keystx='withLAPACKelimination'
12500 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12501 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12502 icelim=2
12503 RETURN
12504 END IF
12505#endif
12506
12507 keystx='withmultipliers'
12508 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12509 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12510 icelim=0
12511 RETURN
12512 END IF
12513
12514 keystx='checkinput'
12515 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12516 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12517 icheck=1
12518 IF (nums > 0) icheck=nint(dnum(1),mpi)
12519 RETURN
12520 END IF
12521
12522 keystx='checkparametergroups'
12523 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12524 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12525 ichkpg=1
12526 RETURN
12527 END IF
12528
12529 keystx='monitorresiduals'
12530 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12531 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12532 imonit=3
12533 IF (nums > 0) imonit=nint(dnum(1),mpi)
12534 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12535 RETURN
12536 END IF
12537
12538 keystx='monitorpulls'
12539 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12540 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12541 imonit=3
12542 imonmd=1
12543 IF (nums > 0) imonit=nint(dnum(1),mpi)
12544 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12545 RETURN
12546 END IF
12547
12548 keystx='monitorprogress'
12549 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12550 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12551 monpg1=1
12552 monpg2=1024
12553 IF (nums > 0) monpg1=max(1,nint(dnum(1),mpi))
12554 IF (nums > 1) monpg2=max(1,nint(dnum(2),mpi))
12555 RETURN
12556 END IF
12557
12558 keystx='scaleerrors'
12559 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12560 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12561 iscerr=1
12562 IF (nums > 0) dscerr(1:2)=dnum(1)
12563 IF (nums > 1) dscerr(2)=dnum(2)
12564 RETURN
12565 END IF
12566
12567 keystx='iterateentries'
12568 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12569 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12570 iteren=huge(iteren)
12571 IF (nums > 0) iteren=nint(dnum(1),mpi)
12572 RETURN
12573 END IF
12574
12575 keystx='threads'
12576 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12577 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12578 iomp=0
12579 !$ IOMP=1
12580 !$ IF (IOMP.GT.0) THEN
12581 !$ IF (NUMS.GE.1.AND.DNUM(1).GT.0.) MTHRD =NINT(dnum(1),mpi)
12582 !$ MTHRDR=MTHRD
12583 !$ IF (NUMS.GE.2.AND.DNUM(2).GT.0.) MTHRDR=NINT(dnum(2),mpi)
12584 !$ ELSE
12585 WRITE(*,*) 'WARNING: multithreading not available'
12586 !$ ENDIF
12587 RETURN
12588 END IF
12589
12590 keystx='compress'
12591 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12592 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12593 WRITE(*,*) 'WARNING: keyword COMPRESS is obsolete (compression is default)'
12594 RETURN
12595 END IF
12596
12597 ! still experimental
12598 !keystx='extendedStorage'
12599 !mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12600 !IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12601 ! mextnd=1
12602 ! RETURN
12603 !END IF
12604
12605 keystx='countrecords'
12606 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12607 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12608 mcount=1
12609 RETURN
12610 END IF
12611
12612 keystx='errlabels'
12613 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12614 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12615 nl=min(nums,100-mnrsel)
12616 DO k=1,nl
12617 lbmnrs(mnrsel+k)=nint(dnum(k),mpi)
12618 END DO
12619 mnrsel=mnrsel+nl
12620 RETURN
12621 END IF
12622
12623 keystx='pairentries'
12624 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12625 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12626 ! This option could be implemented to get rid of parameter pairs
12627 ! that have very few entries - to save matrix memory size.
12628 IF (nums > 0.AND.dnum(1) > 0.0) THEN
12629 mreqpe=nint(dnum(1),mpi)
12630 IF (nums >= 2.AND.dnum(2) >= dnum(1)) mhispe=nint(dnum(2),mpi)
12631 IF (nums >= 3.AND.dnum(3) >= dnum(1)) msngpe=nint(dnum(3),mpi)
12632 END IF
12633 RETURN
12634 END IF
12635
12636 keystx='wolfe'
12637 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12638 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12639 wolfc1=real(dnum(1),mps)
12640 wolfc2=real(dnum(2),mps)
12641 RETURN
12642 END IF
12643
12644 ! GF added:
12645 ! convergence tolerance for minres:
12646 keystx='mrestol'
12647 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12648 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12649 IF(nums > 0) THEN
12650 IF (dnum(1) < 1.0e-10_mpd.OR.dnum(1) > 1.0e-04_mpd) THEN
12651 WRITE(*,*) 'ERROR: need 1.0D-10 <= MRESTL ', &
12652 '<= 1.0D-04, but get ', dnum(1)
12653 ELSE
12654 mrestl=dnum(1)
12655 END IF
12656 END IF
12657 RETURN
12658 END IF
12659 ! GF added end
12660
12661 keystx='mrestranscond'
12662 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12663 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12664 IF(nums > 0) THEN
12665 mrtcnd = dnum(1)
12666 END IF
12667 RETURN
12668 END IF
12669
12670 keystx='mresmode'
12671 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12672 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12673 IF(nums > 0) THEN
12674 mrmode = int(dnum(1),mpi)
12675 END IF
12676 RETURN
12677 END IF
12678
12679 keystx='nofeasiblestart'
12680 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12681 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12682 nofeas=1 ! do not make parameters feasible at start
12683 RETURN
12684 END IF
12685
12686 keystx='histprint'
12687 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12688 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12689 nhistp=1 ! print histograms
12690 RETURN
12691 END IF
12692
12693 keystx='readerroraseof' ! treat (C) read errors as eof
12694 mat=matint(text(ia:ib),keystx,npat,ntext)
12695 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12696 ireeof=1
12697 RETURN
12698 END IF
12699
12700#ifdef LAPACK64
12701 keystx='LAPACKwitherrors' ! calculate parameter errors with LAPACK
12702 mat=matint(text(ia:ib),keystx,npat,ntext)
12703 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12704 ilperr=1
12705 RETURN
12706 END IF
12707#ifdef PARDISO
12708 keystx='debugPARDISO' ! enable debug for Intel oneMKL PARDISO
12709 mat=matint(text(ia:ib),keystx,npat,ntext)
12710 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12711 ipddbg=1
12712 RETURN
12713 END IF
12714
12715 keystx='blocksizePARDISO' ! use BSR3 for Intel oneMKL PARDISO, list of (increasing) block sizes to be tried
12716 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12717 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12718 nl=min(nums,10-mpdbsz)
12719 DO k=1,nl
12720 IF (nint(dnum(k),mpi) > 0) THEN
12721 IF (mpdbsz == 0) THEN
12722 mpdbsz=mpdbsz+1
12723 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12724 ELSE IF (nint(dnum(k),mpi) > ipdbsz(mpdbsz)) THEN
12725 mpdbsz=mpdbsz+1
12726 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12727 END IF
12728 END IF
12729 END DO
12730 RETURN
12731 END IF
12732#endif
12733#endif
12734 keystx='fortranfiles'
12735 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12736 IF(mat == max(npat,ntext)) RETURN
12737
12738 keystx='Cfiles'
12739 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12740 IF(mat == max(npat,ntext)) RETURN
12741
12742 keystx='closeandreopen'
12743 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12744 IF(mat == max(npat,ntext)) RETURN
12745
12746 keystx=keylst(1)
12747 nkey=1 ! unknown keyword
12748 IF(nums /= 0) nkey=0
12749
12750 WRITE(*,*) ' '
12751 WRITE(*,*) '**************************************************'
12752 WRITE(*,*) ' '
12753 WRITE(*,*) 'Unknown keyword(s): ',text(1:min(nab,50))
12754 WRITE(*,*) ' '
12755 WRITE(*,*) '**************************************************'
12756 WRITE(*,*) ' '
12757 lunkno=lunkno+1
12758
12759 END IF
12760 ! result: NKEY = -1 blank
12761 ! NKEY = 0 numerical data, no text keyword or unknown
12762 ! NKEY > 0 keyword NKEY from list, keyword = KEYSTX
12763
12764
12765 ! content/lastcontent
12766 ! -------------------
12767 ! blank -1
12768 ! data 0
12769 ! keyword
12770 ! unknown 1
12771 ! parameter 2
12772 ! constraint 3
12773 ! measurement 4
12774 ! method 5
12775
12776
1277710 IF(nkey > 0) THEN ! new keyword
12778 lkey=nkey
12779 IF(lkey == 2) THEN ! parameter
12780 IF(nums == 3) THEN
12781 lpvs=nint(dnum(1),mpi) ! label
12782 IF(lpvs /= 0) THEN
12783 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12784 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12785 ELSE
12786 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12787 END IF
12788 ELSE IF(nums /= 0) THEN
12789 kkey=1 ! switch to "unknown" ?
12790 WRITE(*,*) 'Wrong text in line',nline
12791 WRITE(*,*) 'Status: new parameter'
12792 WRITE(*,*) '> ',text(1:nab)
12793 END IF
12794 ELSE IF(lkey == 3) THEN ! constraint
12795 ! WRITE(*,*) 'Keyword is constraint!',NUMS,' numerical data'
12796 IF(nums >= 1.AND.nums <= 2) THEN ! start constraint
12797 lpvs=-nline ! r = r.h.s. value
12798 CALL additem(lenconstraints,listconstraints,lpvs,dnum(1))
12799 lpvs=-1 ! constraint
12800 IF(iwcons > 0) lpvs=-2 ! weighted constraint
12801 plvs=0.0
12802 IF(nums == 2) plvs=dnum(2) ! sigma
12803 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12804 ELSE
12805 kkey=1 ! switch to "unknown"
12806 WRITE(*,*) 'Wrong text in line',nline
12807 WRITE(*,*) 'Status: new keyword constraint'
12808 WRITE(*,*) '> ',text(1:nab)
12809 END IF
12810 ELSE IF(lkey == 4) THEN ! measurement
12811 IF(nums == 2) THEN ! start measurement
12812 nummeasurements=nummeasurements+1
12813 lpvs=-nline ! r = r.h.s. value
12814 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(1))
12815 lpvs=-1 ! sigma
12816 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(2))
12817 ELSE
12818 kkey=1 ! switch to "unknown"
12819 WRITE(*,*) 'Wrong text in line',nline
12820 WRITE(*,*) 'Status: new keyword measurement'
12821 WRITE(*,*) '> ',text(1:nab)
12822 END IF
12823 ELSE IF(lkey == 5.AND.keyb < keyc) THEN ! method with text argument
12824 miter=mitera
12825 IF(nums >= 1) miter=nint(dnum(1),mpi)
12826 IF(miter >= 1) mitera=miter
12827 dflim=real(dnum(2),mps)
12828 lkey=0
12829 DO i=1,nmeth
12830 keystx=methxt(i)
12831 mat=matint(text(keyb+1:keyc),keystx,npat,ntext) ! comparison
12832 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12833 IF(i == 1) THEN ! diagonalization
12834 metsol=2
12835 matsto=1
12836 ELSE IF(i == 2) THEN ! inversion
12837 metsol=1
12838 matsto=1
12839 ELSE IF(i == 3) THEN ! fullMINRES
12840 metsol=4
12841 matsto=1
12842 ELSE IF(i == 4) THEN ! sparseMINRES
12843 metsol=4
12844 matsto=2
12845 ELSE IF(i == 5) THEN ! fullMINRES-QLP
12846 metsol=5
12847 matsto=1
12848 ELSE IF(i == 6) THEN ! sparseMINRES-QLP
12849 metsol=5
12850 matsto=2
12851 ELSE IF(i == 7) THEN ! decomposition
12852 metsol=3
12853 matsto=1
12854#ifdef LAPACK64
12855 ELSE IF(i == 8) THEN ! fullLAPACK factorization
12856 metsol=7
12857 matsto=1
12858 ELSE IF(i == 9) THEN ! unpackedLAPACK factorization
12859 metsol=8
12860 matsto=0
12861#ifdef PARDISO
12862 ELSE IF(i == 10) THEN ! Intel oneMKL PARDISO (sparse matrix (CSR3 or BSR3, upper triangle))
12863 metsol=9
12864 matsto=3
12865#endif
12866#endif
12867 END IF
12868 END IF
12869 END DO
12870 END IF
12871 ELSE IF(nkey == 0) THEN ! data for continuation
12872 IF(lkey == 2) THEN ! parameter
12873 IF(nums >= 3) THEN ! store data from this line
12874 lpvs=nint(dnum(1),mpi) ! label
12875 IF(lpvs /= 0) THEN
12876 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12877 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12878 ELSE
12879 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12880 END IF
12881 ELSE IF(nums > 1.AND.nums < 3) THEN
12882 kkey=1 ! switch to "unknown" ?
12883 WRITE(*,*) 'Wrong text in line',nline
12884 WRITE(*,*) 'Status continuation parameter'
12885 WRITE(*,*) '> ',text(1:nab)
12886 END IF
12887
12888 ELSE IF(lkey == 3) THEN ! constraint
12889 ier=0
12890 DO i=1,nums,2
12891 label=nint(dnum(i),mpi)
12892 IF(label <= 0) ier=1
12893 END DO
12894 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12895 IF(ier == 0) THEN
12896 DO i=1,nums,2
12897 lpvs=nint(dnum(i),mpi) ! label
12898 plvs=dnum(i+1) ! factor
12899 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12900 END DO
12901 ELSE
12902 kkey=0
12903 WRITE(*,*) 'Wrong text in line',nline
12904 WRITE(*,*) 'Status continuation constraint'
12905 WRITE(*,*) '> ',text(1:nab)
12906 END IF
12907
12908 ELSE IF(lkey == 4) THEN ! measurement
12909 ! WRITE(*,*) 'continuation < ',NUMS
12910 ier=0
12911 DO i=1,nums,2
12912 label=nint(dnum(i),mpi)
12913 IF(label <= 0) ier=1
12914 END DO
12915 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12916 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12917 IF(ier == 0) THEN
12918 DO i=1,nums,2
12919 lpvs=nint(dnum(i),mpi) ! label
12920 plvs=dnum(i+1) ! factor
12921 CALL additem(lenmeasurements,listmeasurements,lpvs,plvs)
12922 END DO
12923 ELSE
12924 kkey=0
12925 WRITE(*,*) 'Wrong text in line',nline
12926 WRITE(*,*) 'Status continuation measurement'
12927 WRITE(*,*) '> ',text(1:nab)
12928 END IF
12929 ELSE IF(lkey == 6) THEN ! comment
12930 IF(nums == 1) THEN
12931 lpvs=nint(dnum(1),mpi) ! label
12932 IF(lpvs /= 0) THEN
12933 ! skip label
12934 DO j=ia,ib
12935 IF (text(j:j) == ' ') EXIT
12936 END DO
12937 ctext=text(j:ib)
12938 CALL additemc(lencomments,listcomments,lpvs,ctext)
12939 ELSE
12940 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12941 END IF
12942 ELSE IF(nums /= 0) THEN
12943 kkey=1 ! switch to "unknown"
12944 WRITE(*,*) 'Wrong text in line',nline
12945 WRITE(*,*) 'Status: continuation comment'
12946 WRITE(*,*) '> ',text(1:nab)
12947 END IF
12948#ifdef LAPACK64
12949#ifdef PARDISO
12950 ELSE IF(lkey == 7) THEN ! Intel oneMKL PARDISO parameters
12951 ier=0
12952 DO i=1,nums,2
12953 label=nint(dnum(i),mpi)
12954 IF(label <= 0.OR.label > 64) ier=1
12955 END DO
12956 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12957 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12958 IF(ier == 0) THEN
12959 DO i=1,nums,2
12960 lpvs=nint(dnum(i),mpi) ! label
12961 ipvs=nint(dnum(i+1),mpi) ! parameter
12962 CALL additemi(lenpardiso,listpardiso,lpvs,ipvs)
12963 END DO
12964 ELSE
12965 kkey=0
12966 WRITE(*,*) 'Wrong text in line',nline
12967 WRITE(*,*) 'Status continuation measurement'
12968 WRITE(*,*) '> ',text(1:nab)
12969 END IF
12970#endif
12971#endif
12972 END IF
12973 END IF
12974END SUBROUTINE intext
12975
12983SUBROUTINE additem(length,list,label,value)
12984 USE mpdef
12985 USE mpdalc
12986
12987 INTEGER(mpi), INTENT(IN OUT) :: length
12988 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12989 INTEGER(mpi), INTENT(IN) :: label
12990 REAL(mpd), INTENT(IN) :: value
12991
12992 INTEGER(mpl) :: newSize
12993 INTEGER(mpl) :: oldSize
12994 TYPE(listitem), DIMENSION(:), ALLOCATABLE :: tempList
12995
12996 IF (label > 0.AND.value == 0.) RETURN ! skip zero for valid labels
12997 IF (length == 0 ) THEN ! initial list with size = 100
12998 newsize = 100
12999 CALL mpalloc(list,newsize,' list ')
13000 ENDIF
13001 oldsize=size(list,kind=mpl)
13002 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
13003 newsize = oldsize + oldsize/5 + 100
13004 CALL mpalloc(templist,oldsize,' temp. list ')
13005 templist=list
13006 CALL mpdealloc(list)
13007 CALL mpalloc(list,newsize,' list ')
13008 list(1:oldsize)=templist(1:oldsize)
13009 CALL mpdealloc(templist)
13010 ENDIF
13011 ! add to end of list
13012 length=length+1
13013 list(length)%label=label
13014 list(length)%value=value
13015
13016END SUBROUTINE additem
13017
13025SUBROUTINE additemc(length,list,label,text)
13026 USE mpdef
13027 USE mpdalc
13028
13029 INTEGER(mpi), INTENT(IN OUT) :: length
13030 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
13031 INTEGER(mpi), INTENT(IN) :: label
13032 CHARACTER(len = itemCLen), INTENT(IN) :: text
13033
13034 INTEGER(mpl) :: newSize
13035 INTEGER(mpl) :: oldSize
13036 TYPE(listitemc), DIMENSION(:), ALLOCATABLE :: tempList
13037
13038 IF (label > 0.AND.text == '') RETURN ! skip empty text for valid labels
13039 IF (length == 0 ) THEN ! initial list with size = 100
13040 newsize = 100
13041 CALL mpalloc(list,newsize,' list ')
13042 ENDIF
13043 oldsize=size(list,kind=mpl)
13044 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
13045 newsize = oldsize + oldsize/5 + 100
13046 CALL mpalloc(templist,oldsize,' temp. list ')
13047 templist=list
13048 CALL mpdealloc(list)
13049 CALL mpalloc(list,newsize,' list ')
13050 list(1:oldsize)=templist(1:oldsize)
13051 CALL mpdealloc(templist)
13052 ENDIF
13053 ! add to end of list
13054 length=length+1
13055 list(length)%label=label
13056 list(length)%text=text
13057
13058END SUBROUTINE additemc
13059
13067SUBROUTINE additemi(length,list,label,ivalue)
13068 USE mpdef
13069 USE mpdalc
13070
13071 INTEGER(mpi), INTENT(IN OUT) :: length
13072 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
13073 INTEGER(mpi), INTENT(IN) :: label
13074 INTEGER(mpi), INTENT(IN) :: ivalue
13075
13076 INTEGER(mpl) :: newSize
13077 INTEGER(mpl) :: oldSize
13078 TYPE(listitemi), DIMENSION(:), ALLOCATABLE :: tempList
13079
13080 IF (length == 0 ) THEN ! initial list with size = 100
13081 newsize = 100
13082 CALL mpalloc(list,newsize,' list ')
13083 ENDIF
13084 oldsize=size(list,kind=mpl)
13085 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
13086 newsize = oldsize + oldsize/5 + 100
13087 CALL mpalloc(templist,oldsize,' temp. list ')
13088 templist=list
13089 CALL mpdealloc(list)
13090 CALL mpalloc(list,newsize,' list ')
13091 list(1:oldsize)=templist(1:oldsize)
13092 CALL mpdealloc(templist)
13093 ENDIF
13094 ! add to end of list
13095 length=length+1
13096 list(length)%label=label
13097 list(length)%ivalue=ivalue
13098
13099END SUBROUTINE additemi
13100
13102SUBROUTINE mstart(text)
13103 USE mpdef
13104 USE mpmod, ONLY: textl
13105
13106 IMPLICIT NONE
13107 INTEGER(mpi) :: i
13108 INTEGER(mpi) :: ka
13109 INTEGER(mpi) :: kb
13110 INTEGER(mpi) :: l
13111 CHARACTER (LEN=*), INTENT(IN) :: text
13112 CHARACTER (LEN=16) :: textc
13113 SAVE
13114 ! ...
13115 DO i=1,74
13116 textl(i:i)='_'
13117 END DO
13118 l=len(text)
13119 ka=(74-l)/2
13120 kb=ka+l-1
13121 textl(ka:kb)=text(1:l)
13122 WRITE(*,*) ' '
13123 WRITE(*,*) textl
13124 WRITE(*,*) ' '
13125 textc=text(1:l)//'-end'
13126
13127 DO i=1,74
13128 textl(i:i)='_'
13129 END DO
13130 l=l+4
13131 ka=(74-l)/2
13132 kb=ka+l-1
13133 textl(ka:kb)=textc(1:l)
13134 RETURN
13135END SUBROUTINE mstart
13136
13138SUBROUTINE mend
13139 USE mpmod, ONLY: textl
13140
13141 IMPLICIT NONE
13142 WRITE(*,*) ' '
13143 WRITE(*,*) textl
13144 CALL petime
13145 WRITE(*,*) ' '
13146END SUBROUTINE mend
13147
13154
13155SUBROUTINE mvopen(lun,fname)
13156 USE mpdef
13157
13158 IMPLICIT NONE
13159 INTEGER(mpi) :: l
13160 INTEGER(mpi), INTENT(IN) :: lun
13161 CHARACTER (LEN=*), INTENT(IN) :: fname
13162 CHARACTER (LEN=33) :: nafile
13163 CHARACTER (LEN=33) :: nbfile
13164 LOGICAL :: ex
13165 SAVE
13166 ! ...
13167 l=len(fname)
13168 IF(l > 32) THEN
13169 CALL peend(17,'Aborted, file name too long')
13170 stop 'File name too long '
13171 END IF
13172 nafile=fname
13173 nafile(l+1:l+1)='~'
13174
13175 INQUIRE(file=nafile(1:l),exist=ex)
13176 IF(ex) THEN
13177 INQUIRE(file=nafile(1:l+1),exist=ex)
13178 IF(ex) THEN
13179 CALL system('rm '//nafile)
13180 END IF
13181 nbfile=nafile
13182 nafile(l+1:l+1)=' '
13183 CALL system('mv '//nafile//nbfile)
13184 END IF
13185 OPEN(unit=lun,file=fname)
13186END SUBROUTINE mvopen
13187
13191
13192SUBROUTINE petime
13193 USE mpdef
13194
13195 IMPLICIT NONE
13196 REAL, DIMENSION(2) :: ta
13197 REAL etime
13198 REAL :: rst
13199 REAL :: delta
13200 REAL :: rstp
13201 REAL :: secnd1
13202 REAL :: secnd2
13203 INTEGER :: ncount
13204 INTEGER :: nhour1
13205 INTEGER :: minut1
13206 INTEGER :: nsecd1
13207 INTEGER :: nhour2
13208 INTEGER :: minut2
13209 INTEGER :: nsecd2
13210
13211 SAVE
13212 DATA ncount/0/
13213 ! ...
13214 ncount=ncount+1
13215 rst=etime(ta)
13216 IF(ncount > 1) THEN
13217 delta=rst
13218 nsecd1=int(delta,mpi) ! -> integer
13219 nhour1=nsecd1/3600
13220 minut1=nsecd1/60-60*nhour1
13221 secnd1=delta-60*(minut1+60*nhour1)
13222 delta=rst-rstp
13223 nsecd2=int(delta,mpi) ! -> integer
13224 nhour2=nsecd2/3600
13225 minut2=nsecd2/60-60*nhour2
13226 secnd2=delta-60*(minut2+60*nhour2)
13227 WRITE(*,101) nhour1,minut1,secnd1, nhour2,minut2,secnd2
13228 END IF
13229
13230 rstp=rst
13231 RETURN
13232101 FORMAT(i4,' h',i3,' min',f5.1,' sec total',18x,'elapsed', &
13233 i4,' h',i3,' min',f5.1,' sec')
13234END SUBROUTINE petime ! print
13235
13242
13243SUBROUTINE peend(icode, cmessage)
13244 USE mpdef
13245
13246 IMPLICIT NONE
13247 INTEGER(mpi), INTENT(IN) :: icode
13248 CHARACTER (LEN=*), INTENT(IN) :: cmessage
13249
13250 CALL mvopen(9,'millepede.end')
13251 WRITE(9,101) icode, cmessage
13252101 FORMAT(1x,i4,3x,a)
13253 CLOSE(9)
13254 RETURN
13255
13256END SUBROUTINE peend
13257
13264SUBROUTINE binopn(kfile, ithr, ierr)
13265 USE mpmod
13266
13267 IMPLICIT NONE
13268 INTEGER(mpi), INTENT(IN) :: kfile
13269 INTEGER(mpi), INTENT(IN) :: ithr
13270 INTEGER(mpi), INTENT(OUT) :: ierr
13271
13272 INTEGER(mpi), DIMENSION(13) :: ibuff
13273 INTEGER(mpi) :: ioff
13274 INTEGER(mpi) :: ios
13275 INTEGER(mpi) :: k
13276 INTEGER(mpi) :: lfn
13277 INTEGER(mpi) :: lun
13278 INTEGER(mpi) :: moddate
13279 CHARACTER (LEN=1024) :: fname
13280 CHARACTER (LEN=7) :: cfile
13281 INTEGER stat
13282
13283#ifdef READ_C_FILES
13284 INTERFACE
13285 SUBROUTINE openc(filename, lfn, lun, ios) BIND(c)
13286 USE iso_c_binding
13287 CHARACTER(kind=c_char), DIMENSION(*), INTENT(IN) :: filename
13288 INTEGER(c_int), INTENT(IN), VALUE :: lfn
13289 INTEGER(c_int), INTENT(IN), VALUE :: lun
13290 INTEGER(c_int), INTENT(INOUT) :: ios
13291 END SUBROUTINE openc
13292 END INTERFACE
13293#endif
13294
13295 ierr=0
13296 lun=ithr
13297 ! modification date (=0: open for first time, >0: reopen, <0: unknown )
13298 moddate=yfd(kfile)
13299 ! file name
13300 ioff=sfd(1,kfile)
13301 lfn=sfd(2,kfile)
13302 DO k=1,lfn
13303 fname(k:k)=tfd(ioff+k)
13304 END DO
13305 !print *, " opening binary ", kfile, ithr, moddate, " : ", fname(1:lfn)
13306 ! open
13307 ios=0
13308 IF(kfile <= nfilf) THEN
13309 ! Fortran file
13310 lun=kfile+10
13311 OPEN(lun,file=fname(1:lfn),iostat=ios, form='UNFORMATTED')
13312 print *, ' lun ', lun, ios
13313#ifdef READ_C_FILES
13314 ELSE
13315 ! C file
13316 CALL openc(fname(1:lfn),lfn,lun,ios)
13317#else
13318 WRITE(*,*) 'Opening of C-files not supported.'
13319 ierr=1
13320 RETURN
13321#endif
13322 END IF
13323 IF(ios /= 0) THEN
13324 ierr=1
13325 WRITE(*,*) 'Open error for file ',fname(1:lfn), ios
13326 IF (moddate /= 0) THEN
13327 WRITE(cfile,'(I7)') kfile
13328 CALL peend(15,'Aborted, open error(s) for binary file ' // cfile)
13329 stop 'PEREAD: open error'
13330 ENDIF
13331 RETURN
13332 END IF
13333 ! get status
13334 ios=stat(fname(1:lfn),ibuff)
13335 !print *, ' STAT ', ios, ibuff(10), moddate
13336 IF(ios /= 0) THEN
13337 ierr=1
13338 WRITE(*,*) 'STAT error for file ',fname(1:lfn), ios
13339 ibuff(10)=-1
13340 END IF
13341 ! check/store modification date
13342 IF (moddate /= 0) THEN
13343 IF (ibuff(10) /= moddate) THEN
13344 WRITE(cfile,'(I7)') kfile
13345 CALL peend(19,'Aborted, binary file modified (date) ' // cfile)
13346 stop 'PEREAD: file modified'
13347 END IF
13348 ELSE
13349 yfd(kfile)=ibuff(10)
13350 END IF
13351 RETURN
13352
13353END SUBROUTINE binopn
13354
13360SUBROUTINE bincls(kfile, ithr)
13361 USE mpmod
13362
13363 IMPLICIT NONE
13364 INTEGER(mpi), INTENT(IN) :: kfile
13365 INTEGER(mpi), INTENT(IN) :: ithr
13366
13367 INTEGER(mpi) :: lun
13368
13369#ifdef READ_C_FILES
13370 INTERFACE
13371 SUBROUTINE closec(lun) BIND(c)
13372 USE iso_c_binding
13373 INTEGER(c_int), INTENT(IN), VALUE :: lun
13374 END SUBROUTINE closec
13375 END INTERFACE
13376#endif
13377
13378 lun=ithr
13379 !print *, " closing binary ", kfile, ithr
13380 IF(kfile <= nfilf) THEN ! Fortran file
13381 lun=kfile+10
13382 CLOSE(lun)
13383#ifdef READ_C_FILES
13384 ELSE ! C file
13385 CALL closec(lun)
13386#endif
13387 END IF
13388
13389END SUBROUTINE bincls
13390
13395SUBROUTINE binrwd(kfile)
13396 USE mpmod
13397
13398 IMPLICIT NONE
13399 INTEGER(mpi), INTENT(IN) :: kfile
13400
13401 INTEGER(mpi) :: lun
13402
13403#ifdef READ_C_FILES
13404 INTERFACE
13405 SUBROUTINE resetc(lun) BIND(c)
13406 USE iso_c_binding
13407 INTEGER(c_int), INTENT(IN), VALUE :: lun
13408 END SUBROUTINE resetc
13409 END INTERFACE
13410#endif
13411
13412 !print *, " rewinding binary ", kfile
13413 IF (kfile <= nfilf) THEN
13414 lun=kfile+10
13415 rewind lun
13416#ifdef READ_C_FILES
13417 ELSE
13418 lun=kfile-nfilf
13419 CALL resetc(lun)
13420#endif
13421 END IF
13422
13423END SUBROUTINE binrwd
13424
13426SUBROUTINE ckpgrp
13427 USE mpmod
13428 USE mpdalc
13429
13430 IMPLICIT NONE
13431 INTEGER(mpi) :: i
13432 INTEGER(mpi) :: ipgrp
13433 INTEGER(mpi) :: irank
13434 INTEGER(mpi) :: isize
13435 INTEGER(mpi) :: ivoff
13436 INTEGER(mpi) :: itgbi
13437 INTEGER(mpi) :: j
13438 INTEGER(mpi) :: msize
13439 INTEGER(mpi), PARAMETER :: mxsize = 1000
13440 INTEGER(mpl):: ij
13441 INTEGER(mpl):: length
13442
13443 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
13444 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
13445 REAL(mpd), DIMENSION(:), ALLOCATABLE :: resParGroup
13446 REAL(mpd), DIMENSION(:), ALLOCATABLE :: blockParGroup
13447 REAL(mpd) :: matij
13448 SAVE
13449
13450 ! maximal group size
13451 msize=0
13452 DO ipgrp=1,nvpgrp
13453 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13454 IF (isize <= mxsize) THEN
13455 msize=max(msize,isize)
13456 ELSE
13457 print *, ' CKPGRP: par. group', ipgrp, ' not checked -- too large: ', isize
13458 END IF
13459 END DO
13460 IF (msize == 0) RETURN
13461
13462 ! (matrix) block for parameter groups
13463 length=int(msize,mpl)*(int(msize,mpl)+1)/2
13464 CALL mpalloc(blockpargroup,length,'(matrix) block for parameter groups (D)')
13465 length=msize
13466 CALL mpalloc(respargroup,length,'residuals for parameter groups (D)') ! double aux 1
13467 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
13468 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
13469
13470 respargroup=0
13471 print *
13472 print *,' CKPGRP par. group first label size rank'
13473 DO ipgrp=1,nvpgrp
13474 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13475 IF (isize > mxsize) cycle
13476 ! copy matrix block
13477 ivoff=globalallindexgroups(ipgrp)-1
13478 ij=0
13479 DO i=1,isize
13480 DO j=1,i
13481 ij=ij+1
13482 blockpargroup(ij)=matij(ivoff+i,ivoff+j)
13483 END DO
13484 END DO
13485 ! inversion of matrix block
13486 CALL sqminv(blockpargroup,respargroup,isize,irank, auxvectord, auxvectori)
13487 !
13489 IF (isize == irank) THEN
13490 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank
13491 ELSE
13492 ndefpg=ndefpg+1
13493 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank, ' rank deficit !!!'
13494 END IF
13495 END DO
13496
13497 ! clean up
13498 CALL mpdealloc(auxvectord)
13499 CALL mpdealloc(auxvectori)
13500 CALL mpdealloc(respargroup)
13501 CALL mpdealloc(blockpargroup)
13502
13503END SUBROUTINE ckpgrp
13504
13506SUBROUTINE chkmat
13507 USE mpmod
13508
13509 IMPLICIT NONE
13510 INTEGER(mpl) :: i
13511 INTEGER(mpl) :: nan
13512 INTEGER(mpl) :: neg
13513
13514 print *, ' Checking global matrix(D) for NANs ', size(globalmatd,kind=mpl)
13515 nan=0
13516 DO i=1,size(globalmatd,kind=mpl)
13517 IF(.NOT.(globalmatd(i) <= 0.0_mpd).AND..NOT.(globalmatd(i) > 0.0_mpd)) THEN
13518 nan=nan+1
13519 print *, ' i, nan ', i, nan
13520 END IF
13521 END DO
13522
13523 IF (matsto > 1) RETURN
13524 print *
13525 print *, ' Checking diagonal elements ', nagb
13526 neg=0
13527 DO i=1,nagb
13528 IF(.NOT.(globalmatd(globalrowoffsets(i)+i) > 0.0_mpd)) THEN
13529 neg=neg+1
13530 print *, ' i, neg ', i, neg
13531 END IF
13532 END DO
13533 print *
13534 print *, ' CHKMAT summary ', nan, neg
13535 print *
13536
13537END SUBROUTINE chkmat
13538
13539
13540! ----- accurate summation ----(from mpnum) ---------------------------------
13541
13551
13552SUBROUTINE addsums(ithrd, chi2, ndf, dw)
13553 USE mpmod
13554
13555 IMPLICIT NONE
13556 REAL(mpd), INTENT(IN) :: chi2
13557 INTEGER(mpi), INTENT(IN) :: ithrd
13558 INTEGER(mpi), INTENT(IN) :: ndf
13559 REAL(mpd), INTENT(IN) :: dw
13560
13561 INTEGER(mpl) ::nadd
13562 REAL(mpd) ::add
13563 ! ...
13564 add=chi2*dw ! apply (file) weight
13565 nadd=int(add,mpl) ! convert to integer
13566 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+nadd ! sum integer
13567 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)+(add-real(nadd,mpd)) ! sum remainder
13568 IF(globalchi2sumd(ithrd) > 16.0_mpd) THEN ! + - 16
13569 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)-16.0_mpd
13570 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+16_mpl
13571 END IF
13572 globalndfsum(ithrd)=globalndfsum(ithrd)+int(ndf,mpl)
13573 globalndfsumw(ithrd)=globalndfsumw(ithrd)+real(ndf,mpd)*dw
13574 RETURN
13575END SUBROUTINE addsums
13576
13584
13585SUBROUTINE getsums(chi2, ndf, wndf)
13586 USE mpmod
13587
13588 IMPLICIT NONE
13589 REAL(mpd), INTENT(OUT) ::chi2
13590 INTEGER(mpl), INTENT(OUT) ::ndf
13591 REAL(mpd), INTENT(OUT) ::wndf
13592 ! ...
13593 chi2=sum(globalchi2sumd)+real(sum(globalchi2sumi),mpd)
13594 ndf=sum(globalndfsum)
13595 wndf=sum(globalndfsumw)
13596 globalchi2sumd=0.0_mpd
13597 globalchi2sumi=0_mpl
13598 globalndfsum=0_mpl
13599 globalndfsumw=0.0_mpd
13600 RETURN
13601END 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:1034
subroutine ndbits(npgrp, ndims, nsparr, ihst)
Analyze bit fields.
Definition: mpbits.f90:306
subroutine clbits(in, jreqpe, jhispe, jsngpe, jextnd, idimb, ispc)
Calculate bit (field) array size, encoding.
Definition: mpbits.f90:183
subroutine plbits(in, inar, inac, idimb)
Calculate bit field array size (PARDISO).
Definition: mpbits.f90:256
subroutine spbits(npgrp, nsparr, nsparc)
Create sparsity information.
Definition: mpbits.f90:1221
subroutine irbits(i, j)
Fill bit fields (counters, rectangular part).
Definition: mpbits.f90:150
subroutine clbmap(in)
Clear (additional) bit map.
Definition: mpbits.f90:1358
subroutine inbmap(im, jm)
Fill bit map.
Definition: mpbits.f90:1390
subroutine ckbits(npgrp, ndims)
Check sparsity of matrix.
Definition: mpbits.f90:1128
subroutine ggbmap(ipgrp, npair, npgrp)
Get paired (parameter) groups from map.
Definition: mpbits.f90:1470
subroutine prbits(npgrp, nsparr)
Analyze bit fields.
Definition: mpbits.f90:935
subroutine gpbmap(ngroup, npgrp, npair)
Get pairs (statistic) from map.
Definition: mpbits.f90:1424
subroutine pblbits(npgrp, ibsize, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:762
subroutine pbsbits(npgrp, ibsize, nnzero, nblock, nbkrow)
Analyze bit fields.
Definition: mpbits.f90:579
subroutine inbits(im, jm, inc)
Fill bit fields (counters, triangular part).
Definition: mpbits.f90:74
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 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 sqmibb(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag, evdmin, evdmax)
Bordered band matrix.
Definition: mpnum.f90:3119
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 devinv(n, diag, u, v)
Inversion by diagonalization.
Definition: mpnum.f90:697
subroutine sqmibb2(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag, evdmin, evdmax)
Band bordered matrix.
Definition: mpnum.f90:3391
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:712
subroutine qldecb(a, bpar, bcon, rcon)
QL decomposition (for disjoint block matrix).
Definition: mpqldec.f90:220
subroutine qlmlq(x, m, t)
Multiply left by Q(t) (per block).
Definition: mpqldec.f90:405
subroutine qlsetb(ib)
Set block.
Definition: mpqldec.f90:1019
subroutine qlbsub(d, y)
Backward substitution (per block).
Definition: mpqldec.f90:992
subroutine qlini(n, m, l, s, k)
Initialize QL decomposition.
Definition: mpqldec.f90:62
subroutine qlgete(emin, emax)
Get eigenvalues.
Definition: mpqldec.f90:956
subroutine qlssq(aprod, A, s, roff, t)
Similarity transformation by Q(t).
Definition: mpqldec.f90:574
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:284
integer(mpl) mszpcc
(integrated block) matrix size for constraint matrix for preconditioner
Definition: mpmod.f90:145
real(mpd), dimension(:), allocatable workspaceeigenvectors
workspace eigen vectors
Definition: mpmod.f90:232
real(mpd), dimension(:), allocatable globalparameter
global parameters (start values + sum(x_i))
Definition: mpmod.f90:198
integer(mpl) nrecal
number of records
Definition: mpmod.f90:168
integer(mpi), dimension(:), allocatable localglobalmap
matrix correlating local and global par, map (counts)
Definition: mpmod.f90:315
type(listitem), dimension(:), allocatable listparameters
list of parameters from steering file
Definition: mpmod.f90:332
integer(mpi), dimension(:), allocatable vecparblockconoffsets
global par block (constraint) offsets
Definition: mpmod.f90:299
real(mpd), dimension(:), allocatable lapacktau
LAPACK TAU (QL decomp.)
Definition: mpmod.f90:238
integer(mpl) mszprd
(integrated block) matrix size for (constraint) product matrix
Definition: mpmod.f90:143
integer(mpi) lunmon
unit for monitoring output file
Definition: mpmod.f90:127
real(mpd), dimension(:), allocatable vecconsresiduals
residuals of constraints
Definition: mpmod.f90:244
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:292
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:185
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:146
character(len=74) textl
name of current MP 'module' (step)
Definition: mpmod.f90:159
integer(mpi) nloopn
number of data reading, fitting loops
Definition: mpmod.f90:43
integer(mpl) sumrecords
sum of records
Definition: mpmod.f90:190
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:179
integer(mpi) ncgrp
number of (disjoint) constraint groups
Definition: mpmod.f90:140
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:308
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:249
character(len=1024) cpostproc
post processing string
Definition: mpmod.f90:350
real(mpd), dimension(:), allocatable lapackwork
LAPACK work array.
Definition: mpmod.f90:239
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:286
integer(mpi) nhistp
flag for histogram printout
Definition: mpmod.f90:65
integer(mpl), dimension(:), allocatable csr3rowoffsets
row offsets for column list
Definition: mpmod.f90:283
real(mpd), dimension(:), allocatable globalparcopy
copy of global parameters
Definition: mpmod.f90:199
real(mpd), dimension(:), allocatable lapackql
LAPACK QL (QL decomp.)
Definition: mpmod.f90:237
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:280
integer(mpl), dimension(:,:), allocatable sparsematrixoffsets
row offsets for column list, sparse matrix elements
Definition: mpmod.f90:281
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:248
integer(mpi) lunkno
flag for unkown keywords
Definition: mpmod.f90:46
integer(mpi), dimension(:), allocatable scflag
local fit workspace (I)
Definition: mpmod.f90:311
real(mpd), parameter measbinsize
bins size for monitoring
Definition: mpmod.f90:178
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:139
real(mpd), dimension(:), allocatable matconsproduct
product matrix of constraints
Definition: mpmod.f90:243
integer(mpi), dimension(:), allocatable yfd
binary file: modification date
Definition: mpmod.f90:365
integer(mpi) nxlow
(max of) global parameters with too few accepted entries for icalcm=1
Definition: mpmod.f90:173
integer(mpl) ndgb
number of global derivatives read
Definition: mpmod.f90:153
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:313
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:314
integer(mpi) mhispe
upper bound for pair entry histogrammimg
Definition: mpmod.f90:81
integer(mpi) nfgb
number of fit parameters
Definition: mpmod.f90:133
integer(mpi), dimension(:,:), allocatable kfd
(1,.)= number of records in file, (2,..)= file order
Definition: mpmod.f90:356
real(mpd), dimension(:), allocatable globalchi2sumd
fractional part of Chi2 sum
Definition: mpmod.f90:221
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:358
integer(mpl) nzgb
number of zero global derivatives read
Definition: mpmod.f90:154
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:336
real(mpd), dimension(:), allocatable globalmatd
global matrix 'A' (double, full or sparse)
Definition: mpmod.f90:207
real(mpr8), dimension(:), allocatable readbufferdatad
double data
Definition: mpmod.f90:290
type(listitem), dimension(:), allocatable listmeasurements
list of (external) measurements from steering file
Definition: mpmod.f90:339
integer(mpi) lsinfo
line search: returned information
Definition: mpmod.f90:164
integer(mpi) nregul
regularization flag
Definition: mpmod.f90:70
integer(mpi) nfilw
number of weighted binary files
Definition: mpmod.f90:374
integer(mpi) ndefpg
number of parameter groups with rank deficit (from inversion)
Definition: mpmod.f90:170
integer(mpi), dimension(:), allocatable paircounter
number of paired parameters (in equations)
Definition: mpmod.f90:295
integer(mpi) nummeasurements
number of (external) measurements from steering file
Definition: mpmod.f90:337
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:375
real(mpd) fvalue
function value (chi2 sum) solution
Definition: mpmod.f90:180
real(mpd), dimension(:), allocatable globalcorrections
correction x_i (from A*x_i=b_i in iteration i)
Definition: mpmod.f90:200
real(mps), dimension(:), allocatable cfd
file: chi2 sum
Definition: mpmod.f90:361
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:175
integer(mpi) nfilc
number of C binary files
Definition: mpmod.f90:373
integer(mpi) nagb
number of all parameters (var.
Definition: mpmod.f90:132
integer(mpi) nmiss1
rank deficit for constraints
Definition: mpmod.f90:171
integer(mpi), dimension(:), allocatable globalparhashtable
global parameters hash table
Definition: mpmod.f90:262
integer(mpi) nalow
(sum of) global parameters with too few accepted entries
Definition: mpmod.f90:172
integer(mpi) iscerr
flag for scaling of errors
Definition: mpmod.f90:111
real(mpd) sumndf
weighted sum(ndf)
Definition: mpmod.f90:182
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:240
integer(mpi) iterat
iterations in solution
Definition: mpmod.f90:69
real(mpd) flines
function value line search
Definition: mpmod.f90:181
integer(mpi), dimension(:), allocatable meashists
measurement histograms (100 bins per thread)
Definition: mpmod.f90:256
integer(mpi), dimension(:), allocatable globalindexranges
global par ranges
Definition: mpmod.f90:297
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:236
real(mps) dwcut
down-weight fraction cut
Definition: mpmod.f90:57
integer(mpl), dimension(:), allocatable globalcounter
global counter (entries in 'x')
Definition: mpmod.f90:211
real(mps), dimension(:), allocatable globalmatf
global matrix 'A' (float part for compressed sparse)
Definition: mpmod.f90:208
integer(mpi), dimension(:,:), allocatable matconsgroups
start of constraint groups, parameter range
Definition: mpmod.f90:250
real(mps), dimension(0:8) times
cpu time counters
Definition: mpmod.f90:157
integer(mpi) minrecordsinblock
min.
Definition: mpmod.f90:192
integer(mpi), dimension(:), allocatable localglobalstructure
matrix correlating local and global par, (sparsity) structure
Definition: mpmod.f90:316
real(mpd), dimension(:), allocatable globalndfsumw
weighted NDF sum
Definition: mpmod.f90:224
integer(mpi) naeqn
max number of equations (measurements) per record
Definition: mpmod.f90:148
integer(mpi) nfilb
number of binary files
Definition: mpmod.f90:371
real(mpd), dimension(:), allocatable vzru
local fit 'border solution'
Definition: mpmod.f90:309
real(mpd), dimension(:), allocatable globalparpreweight
weight from pre-sigma
Definition: mpmod.f90:203
integer(mpi) ictest
test mode '-t'
Definition: mpmod.f90:33
real(mpd), dimension(:), allocatable vbdr
local fit border part of 'A'
Definition: mpmod.f90:306
integer(mpi) mdebg2
number of measurements for record debug printout
Definition: mpmod.f90:39
integer(mpi), dimension(:,:), allocatable globaltotindexgroups
Definition: mpmod.f90:276
integer(mpi), dimension(:), allocatable vecconsgroupcounts
counter for constraint groups
Definition: mpmod.f90:251
real(mps) deltim
cpu time difference
Definition: mpmod.f90:166
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:265
integer(mpi) lencomments
length of list of (global parameter) comments from steering file
Definition: mpmod.f90:340
integer(mpl), dimension(:), allocatable offprecond
preconditioner (block matrix) offsets
Definition: mpmod.f90:219
real(mpd), dimension(:), allocatable vecconssolution
solution for constraint elimination
Definition: mpmod.f90:245
integer(mpi) nfiles
number of files
Definition: mpmod.f90:370
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:152
integer(mpi) keepopen
flag for keeping binary files open
Definition: mpmod.f90:113
real(mpd), dimension(:), allocatable workspacediagonalization
workspace diag.
Definition: mpmod.f90:230
real(mps), dimension(:), allocatable wfd
binary file: weight
Definition: mpmod.f90:363
real(mpd), dimension(:), allocatable matprecond
preconditioner matrix (band and other parts)
Definition: mpmod.f90:216
integer(mpi) ntgb
total number of global parameters
Definition: mpmod.f90:130
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:341
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:188
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:366
integer(mpi) lunlog
unit for logfile
Definition: mpmod.f90:128
integer(mpi) ncblck
number of (non overlapping) constraint blocks
Definition: mpmod.f90:141
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:228
integer(mpi) maxrecordsinblock
max.
Definition: mpmod.f90:193
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:202
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:344
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:259
real(mpd), dimension(:), allocatable scdiag
local fit workspace (D)
Definition: mpmod.f90:310
integer(mpi), dimension(:), allocatable readbufferdatai
integer data
Definition: mpmod.f90:288
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:364
integer(mpi) lenconstraints
length of list of constraints from steering file
Definition: mpmod.f90:335
integer(mpi), dimension(:), allocatable blockprecond
preconditioner (constraint) blocks
Definition: mpmod.f90:218
integer(mpi) lenparameters
list items from steering file
Definition: mpmod.f90:331
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:169
integer(mpi) lenpostproc
length of post processing string
Definition: mpmod.f90:349
integer(mpl) nrecp2
record number with printout
Definition: mpmod.f90:52
integer(mpl) nrec
number of records read
Definition: mpmod.f90:149
integer(mpi), dimension(:,:), allocatable matparblockoffsets
global par block offsets (parameter, constraint blocks)
Definition: mpmod.f90:298
integer(mpl) nrecpr
record number with printout
Definition: mpmod.f90:51
integer(mpl), dimension(:), allocatable ifd
file: integrated record numbers (=offset)
Definition: mpmod.f90:357
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:367
real rstart
cpu start time for solution iterations
Definition: mpmod.f90:165
integer(mpi), dimension(:), allocatable writebufferindices
write buffer for indices
Definition: mpmod.f90:320
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:229
integer(mpi), dimension(:), allocatable globalparvartototal
global parameters variable -> total index
Definition: mpmod.f90:263
real(mpd), dimension(:), allocatable clmat
local fit matrix 'A' (in A*x=b)
Definition: mpmod.f90:302
integer(mpi), dimension(:), allocatable lfd
length of file name
Definition: mpmod.f90:354
integer(mpi) ntpgrp
number of parameter groups
Definition: mpmod.f90:136
character, dimension(:), allocatable tfd
file names (concatenation)
Definition: mpmod.f90:368
integer(mpi) ncgbe
number of empty constraints (no variable parameters)
Definition: mpmod.f90:135
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:247
integer(mpi) nummeas
number of measurement groups for monitoring
Definition: mpmod.f90:177
integer(mpi) lvllog
log level
Definition: mpmod.f90:129
integer(mpi), dimension(3) nprecond
number of constraints (blocks), matrix size for preconditioner
Definition: mpmod.f90:144
integer(mpi) nalcn
max number of local paramters per record
Definition: mpmod.f90:147
integer(mpi), dimension(:), allocatable globalparcomments
global parameters comments
Definition: mpmod.f90:205
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:362
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:369
real(mps) delfun
expected function change
Definition: mpmod.f90:66
integer(mpi) iitera
MINRES iterations.
Definition: mpmod.f90:162
integer(mpl) skippedrecords
number of skipped records (buffer too small)
Definition: mpmod.f90:191
integer(mpi) lenmeasurements
length of list of (external) measurements from steering file
Definition: mpmod.f90:338
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:307
integer(mpi) napgrp
number of all parameter groups (variable + Lagrange mult.)
Definition: mpmod.f90:138
integer(mpl) nrecd
number of records read containing doubles
Definition: mpmod.f90:150
integer(mpi), dimension(:,:), allocatable localequations
indices (ISJAJB) for local equations (measurements)
Definition: mpmod.f90:312
integer(mpi), dimension(:), allocatable globalallpartogroup
all parameters variable -> group index
Definition: mpmod.f90:264
integer(mpi), dimension(:), allocatable backindexusage
list of global par in record
Definition: mpmod.f90:293
integer(mpi), dimension(:), allocatable ibandh
local fit 'band width histogram' (band size autodetection)
Definition: mpmod.f90:303
integer(mpi) isubit
subito flag '-s'
Definition: mpmod.f90:58
integer(mpi), dimension(:), allocatable indprecond
preconditioner pointer array
Definition: mpmod.f90:217
real(mps) dflim
convergence limit
Definition: mpmod.f90:155
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:184
integer(mpi) lfitnp
local fit: number of iteration to calculate pulls
Definition: mpmod.f90:87
integer(mpl), dimension(6) nrejec
rejected records
Definition: mpmod.f90:156
integer(mpl), dimension(:), allocatable globalparlabelcounter
global parameters label counters
Definition: mpmod.f90:260
integer(mpi) lcalcm
last calclation mode
Definition: mpmod.f90:174
real(mpd), dimension(:), allocatable globalvector
global vector 'x' (in A*x=b)
Definition: mpmod.f90:209
real(mpd), dimension(:), allocatable writebufferupdates
write buffer for update matrices
Definition: mpmod.f90:321
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:226
integer(mpl) neqn
number of equations (measurements) read
Definition: mpmod.f90:151
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:142
integer(mpi), dimension(:), allocatable nfd
index (line) in (steering) file
Definition: mpmod.f90:355
integer(mpi) ilperr
flag to calculate parameter errors with LAPACK
Definition: mpmod.f90:119
integer(mpl), dimension(:), allocatable globalparlabelzeros
global parameters label with zero derivative counters
Definition: mpmod.f90:261
integer(mpi) numblocks
number of (read) blocks
Definition: mpmod.f90:189
integer(mpi) ncgb
number of constraints
Definition: mpmod.f90:134
integer(mpi), dimension(:,:), allocatable matconsblocks
start of constraint blocks, parameter range
Definition: mpmod.f90:253
real(mpd), dimension(:), allocatable workspaceeigenvalues
workspace eigen values
Definition: mpmod.f90:231
integer(mpi) lhuber
Huber down-weighting flag.
Definition: mpmod.f90:47
integer(mpi) nvgb
number of variable global parameters
Definition: mpmod.f90:131
integer(mpi) nfilf
number of Fortran binary files
Definition: mpmod.f90:372
integer(mpi), dimension(:), allocatable measindex
mapping of 1.
Definition: mpmod.f90:255
integer(mpi) istopa
MINRES istop (convergence)
Definition: mpmod.f90:163
integer(mpi), dimension(:), allocatable mfd
file mode: cbinary =1, text =2, fbinary=3
Definition: mpmod.f90:353
real(mpd), dimension(:), allocatable blvec
local fit vector 'b' (in A*x=b), replaced by 'x'
Definition: mpmod.f90:301
logical newite
flag for new iteration
Definition: mpmod.f90:160
integer(mpi) nrderr
number of binary files with read errors
Definition: mpmod.f90:183
real(mpd), dimension(:), allocatable measres
average measurement error
Definition: mpmod.f90:257
real(mpd), dimension(:), allocatable vecxav
vector x for AVPROD (A*x=b)
Definition: mpmod.f90:213
real(mpd), dimension(:), allocatable globalparstart
start value for global parameters
Definition: mpmod.f90:201
integer(mpi), dimension(-6:6) writebufferheader
write buffer header (-6..-1: updates, 1..6: indices)
Definition: mpmod.f90:322
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:210
integer(mpi) lenpresigmas
length of list of pre-sigmas from steering file
Definition: mpmod.f90:333
integer(mpi) npresg
number of pre-sigmas
Definition: mpmod.f90:167
integer(mpi), dimension(:), allocatable appearancecounter
appearance statistics for global par (first/last file,record)
Definition: mpmod.f90:294
integer(mpi) nvpgrp
number of variable parameter groups
Definition: mpmod.f90:137
integer(mpi), dimension(:), allocatable xfd
file: max.
Definition: mpmod.f90:360
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:319
real(mpd), dimension(:), allocatable workspacediag
diagonal of global matrix (for global corr.)
Definition: mpmod.f90:227
integer(mpl) ndfsum
sum(ndf)
Definition: mpmod.f90:161
integer(mpi) lenglobalvec
length of global vector 'b' (A*x=b)
Definition: mpmod.f90:194
real(mps) stepl
step length (line search)
Definition: mpmod.f90:158
integer(mpi) msngpe
upper bound for pair entry single precision storage
Definition: mpmod.f90:82
real(mps) cndlmx
cut on log10(condition of band part) of local (bordered-band matrix) fit
Definition: mpmod.f90:124
real(mpd), dimension(:), allocatable vecbav
vector b for AVPROD (A*x=b)
Definition: mpmod.f90:214
integer(mpl), dimension(:), allocatable globalchi2sumi
integer part of Chi2 sum
Definition: mpmod.f90:222
integer(mpl) ipdmem
memory (kB) used by Intel oneMKL PARDISO
Definition: mpmod.f90:346
integer(mpi), dimension(:), allocatable readbufferpointer
pointer to used buffers
Definition: mpmod.f90:287
integer(mpi), dimension(:), allocatable workspacei
(general) workspace (I)
Definition: mpmod.f90:233
integer(mpi), dimension(:), allocatable globalparcons
global parameters (number of) constraints
Definition: mpmod.f90:204
integer(mpi), dimension(:,:), allocatable writebufferinfo
write buffer management (per thread)
Definition: mpmod.f90:318
integer(mpl), dimension(:), allocatable globalndfsum
NDF sum.
Definition: mpmod.f90:223
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:305
real(mpr4), dimension(:), allocatable readbufferdataf
float data
Definition: mpmod.f90:289
type(listitemi), dimension(:), allocatable listpardiso
list of Intel oneMKL PARDISO parameters
Definition: mpmod.f90:345
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:359
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:334
integer(mpi), dimension(:), allocatable globalallindexgroups
Definition: mpmod.f90:277
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:3880
subroutine mchdec
Solution by Cholesky decomposition.
Definition: pede.f90:9071
subroutine bincls(kfile, ithr)
Close binary file.
Definition: pede.f90:13361
subroutine prpcon
Prepare constraints.
Definition: pede.f90:1962
subroutine mminrs
Solution with MINRES.
Definition: pede.f90:10145
subroutine prtrej(lun)
Print rejection statistics.
Definition: pede.f90:5398
subroutine mcsolv(n, x, y)
Solution for zero band width preconditioner.
Definition: pede.f90:10349
subroutine mupdat(i, j, add)
Update element of global matrix.
Definition: pede.f90:4102
subroutine peend(icode, cmessage)
Print exit code.
Definition: pede.f90:13244
subroutine loopn
Loop with fits and sums.
Definition: pede.f90:3445
subroutine loop1
First data loop (get global labels).
Definition: pede.f90:6949
subroutine feasma
Matrix for feasible solution.
Definition: pede.f90:2262
subroutine xloopn
Standard solution algorithm.
Definition: pede.f90:10403
subroutine ploopa(lunp)
Print title for iteration.
Definition: pede.f90:3859
subroutine isjajb(nst, is, ja, jb, jsp)
Decode Millepede record.
Definition: pede.f90:3394
subroutine additem(length, list, label, value)
add item to list
Definition: pede.f90:12984
subroutine mgupdt(i, j1, j2, il, jl, n, sub)
Update global matrix for parameter group.
Definition: pede.f90:4187
subroutine lpavat(t)
Similarity transformation by Q(t).
Definition: pede.f90:9633
subroutine binrwd(kfile)
Rewind binary file.
Definition: pede.f90:13396
subroutine zdiags
Covariance matrix for diagonalization (,correction of eigenvectors).
Definition: pede.f90:10108
subroutine solglo(ivgbi)
Error for single global parameter from MINRES.
Definition: pede.f90:1423
subroutine upone
Update, redefine hash indices.
Definition: pede.f90:6815
subroutine pargrp(inds, inde)
Parameter group info update for block of parameters.
Definition: pede.f90:3277
subroutine prtglo
Print final log file.
Definition: pede.f90:5427
subroutine monres
Monitor input residuals.
Definition: pede.f90:8654
subroutine intext(text, nline)
Interprete text.
Definition: pede.f90:12107
integer(mpl) function ijadd(itema, itemb)
Index for sparse storage (custom).
Definition: pede.f90:6448
subroutine mdiags
Solution by diagonalization.
Definition: pede.f90:9959
program mptwo
Millepede II main program Pede.
Definition: pede.f90:918
subroutine prtstat
Print input statistic.
Definition: pede.f90:5614
real(mpd) function matij(itema, itemb)
Get matrix element at (i,j).
Definition: pede.f90:6555
subroutine grpcon
Group constraints.
Definition: pede.f90:1664
subroutine loopbf(nrej, numfil, naccf, chi2f, ndff)
Loop over records in read buffer (block), fits and sums.
Definition: pede.f90:4355
subroutine peread(more)
Read (block of) records from binary files.
Definition: pede.f90:2598
subroutine filetx
Interprete text files.
Definition: pede.f90:11784
integer(mpi) function iprime(n)
largest prime number < N.
Definition: pede.f90:6917
subroutine ploopc(lunp)
Print sub-iteration line.
Definition: pede.f90:3937
integer(mpl) function ijcsr3(itema, itemb)
Index for sparse storage (CSR3).
Definition: pede.f90:6497
subroutine useone
Make usable (sort items and redefine hash indices).
Definition: pede.f90:6885
subroutine mvopen(lun, fname)
Open file.
Definition: pede.f90:13156
subroutine chkrej
Check rejection details.
Definition: pede.f90:11244
subroutine avprd0(n, l, x, b)
Product symmetric (sub block) matrix times vector.
Definition: pede.f90:6019
subroutine addsums(ithrd, chi2, ndf, dw)
Accurate summation.
Definition: pede.f90:13553
subroutine solgloqlp(ivgbi)
Error for single global parameter from MINRES-QLP.
Definition: pede.f90:1507
subroutine lpqldec(a, emin, emax)
QL decomposition.
Definition: pede.f90:9511
subroutine addcst
Add constraint information to matrix and vector.
Definition: pede.f90:1590
subroutine petime
Print times.
Definition: pede.f90:13193
subroutine mstart(text)
Start of 'module' printout.
Definition: pede.f90:13103
subroutine mend
End of 'module' printout.
Definition: pede.f90:13139
subroutine anasps
Analyse sparsity structure.
Definition: pede.f90:6187
subroutine minver
Solution by matrix inversion.
Definition: pede.f90:8958
subroutine peprep(mode)
Prepare records.
Definition: pede.f90:2950
integer(mpi) function ijprec(itema, itemb)
Precision for storage of parameter groups.
Definition: pede.f90:6419
subroutine explfc(lunit)
Print explanation of iteration table.
Definition: pede.f90:4011
subroutine getsums(chi2, ndf, wndf)
Get accurate sums.
Definition: pede.f90:13586
subroutine chkmat
Check global matrix.
Definition: pede.f90:13507
subroutine binopn(kfile, ithr, ierr)
Open binary file.
Definition: pede.f90:13265
subroutine pepgrp
Parameter group info update.
Definition: pede.f90:3123
subroutine sechms(deltat, nhour, minut, secnd)
Time conversion.
Definition: pede.f90:6700
integer(mpi) function inone(item)
Translate labels to indices (for global parameters).
Definition: pede.f90:6745
subroutine avprds(n, l, x, is, ie, b)
Product symmetric (sub block) matrix times sparse vector.
Definition: pede.f90:5805
subroutine avprod(n, x, b)
Product symmetric matrix times vector.
Definition: pede.f90:6281
subroutine ijpgrp(itema, itemb, ij, lr, iprc)
Index (region length and precision) for sparse storage of parameter groups.
Definition: pede.f90:6321
subroutine loop1i
Iteration of first data loop.
Definition: pede.f90:7320
subroutine mhalf2
Fill 2nd half of matrix for extended storage.
Definition: pede.f90:6613
subroutine ckpgrp
Check (rank of) parameter groups.
Definition: pede.f90:13427
subroutine additemi(length, list, label, ivalue)
add item to list
Definition: pede.f90:13068
subroutine mminrsqlp
Solution with MINRES-QLP.
Definition: pede.f90:10243
subroutine filetc
Interprete command line option, steering file.
Definition: pede.f90:11308
subroutine feasib(concut, iact)
Make parameters feasible.
Definition: pede.f90:2437
subroutine mspardiso
Solution with Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO.
Definition: pede.f90:9730
subroutine mdutrf
Solution by factorization.
Definition: pede.f90:9330
subroutine mdptrf
Solution by factorization.
Definition: pede.f90:9183
subroutine mvsolv(n, x, y)
Solution for finite band width preconditioner.
Definition: pede.f90:10370
subroutine vmprep(msize)
Prepare storage for vectors and matrices.
Definition: pede.f90:8761
subroutine ploopd(lunp)
Print solution line.
Definition: pede.f90:3985
subroutine pechk(ibuf, nerr)
Check Millepede record.
Definition: pede.f90:3051
subroutine loop2
Second data loop (number of derivatives, global label pairs).
Definition: pede.f90:7432
integer(mpi) function nufile(fname)
Inquire on file.
Definition: pede.f90:12050
subroutine additemc(length, list, label, text)
add character item to list
Definition: pede.f90:13026
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