Millepede-II V04-17-00
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
271
558
559
817
855
898
900PROGRAM mptwo
901 USE mpmod
902 USE mpdalc
903 USE mptest1, ONLY: nplan,del,dvd
904 USE mptest2, ONLY: nlyr,nmx,nmy,sdevx,sdevy,ntot
905
906 IMPLICIT NONE
907 REAL(mps) :: andf
908 REAL(mps) :: c2ndf
909 REAL(mps) :: deltat
910 REAL(mps) :: diff
911 REAL(mps) :: err
912 REAL(mps) :: gbu
913 REAL(mps) :: gmati
914 REAL(mps) :: rej
915 REAL :: rloop1
916 REAL :: rloop2
917 REAL :: rstext
918 REAL(mps) :: secnd
919 REAL :: rst
920 REAL :: rstp
921 REAL, DIMENSION(2) :: ta
922 INTEGER(mpi) :: i
923 INTEGER(mpi) :: ii
924 INTEGER(mpi) :: iopnmp
925 INTEGER(mpi) :: ix
926 INTEGER(mpi) :: ixv
927 INTEGER(mpi) :: iy
928 INTEGER(mpi) :: k
929 INTEGER(mpi) :: kfl
930 INTEGER(mpi) :: lun
931 INTEGER :: minut
932 INTEGER :: nhour
933 INTEGER(mpi) :: nmxy
934 INTEGER(mpi) :: nrc
935 INTEGER(mpi) :: nsecnd
936 INTEGER(mpi) :: ntsec
937
938 CHARACTER (LEN=24) :: chdate
939 CHARACTER (LEN=24) :: chost
940#ifdef LAPACK64
941 CHARACTER (LEN=6) :: c6
942 INTEGER major, minor, patch
943#endif
944
945 INTEGER(mpl) :: rows
946 INTEGER(mpl) :: cols
947
948 REAL(mpd) :: sums(9)
949 !$ INTEGER(mpi) :: OMP_GET_NUM_PROCS,OMP_GET_MAX_THREADS
950 !$ INTEGER(mpi) :: MXTHRD
951 !$ INTEGER(mpi) :: NPROC
952
953 REAL etime
954
955 SAVE
956 ! ...
957 rstp=etime(ta)
958 CALL fdate(chdate)
959
960 ! millepede monitoring file
961 lunmon=0
962 ! millepede.log file
963 lunlog=8
964 lvllog=1
965 CALL mvopen(lunlog,'millepede.log')
966 CALL getenv('HOSTNAME',chost)
967 IF (chost(1:1) == ' ') CALL getenv('HOST',chost)
968 WRITE(*,*) '($Id: c5a7342b3793f36f30ad6658bc1f72bc74250cf7 $)'
969 iopnmp=0
970 !$ iopnmp=1
971 !$ WRITE(*,*) 'using OpenMP (TM)'
972#ifdef LAPACK64
973 CALL ilaver( major,minor, patch )
974 WRITE(*,110) lapack64, major,minor, patch
975110 FORMAT(' using LAPACK64 with ',(a),', version ',i0,'.',i0,'.',i0)
976#ifdef PARDISO
977 WRITE(*,*) 'using Intel oneMKL PARDISO'
978#endif
979#endif
980#ifdef __GFORTRAN__
981 WRITE(*,111) __gnuc__ , __gnuc_minor__ , __gnuc_patchlevel__
982111 FORMAT(' compiled with gcc ',i0,'.',i0,'.',i0)
983#endif
984#ifdef __PGIC__
985 WRITE(*,111) __pgic__ , __pgic_minor__ , __pgic_patchlevel__
986111 FORMAT(' compiled with pgi ',i0,'.',i0,'.',i0)
987#endif
988 WRITE(*,*) ' '
989 WRITE(*,*) ' < Millepede II-P starting ... ',chdate
990 WRITE(*,*) ' ',chost
991 WRITE(*,*) ' '
992
993 WRITE(8,*) '($Id: c5a7342b3793f36f30ad6658bc1f72bc74250cf7 $)'
994 WRITE(8,*) ' '
995 WRITE(8,*) 'Log-file Millepede II-P ', chdate
996 WRITE(8,*) ' ', chost
997
998 CALL peend(-1,'Still running or crashed')
999 ! read command line and text files
1000
1001 CALL filetc ! command line and steering file analysis
1002 CALL filetx ! read text files
1003 ! dummy call for dynamic memory allocation
1004 CALL gmpdef(0,nfilb,'dummy call')
1005
1006 IF (icheck > 0) THEN
1007 WRITE(*,*) '!!! Checking input only, no calculation of a solution !!!'
1008 WRITE(8,*) '!!! Checking input only, no calculation of a solution !!!'
1009 END IF
1010 lvllog=mprint ! export print level
1011 IF (memdbg > 0) printflagalloc=1 ! debug memory management
1012 !$ WRITE(*,*)
1013 !$ NPROC=1
1014 !$ MXTHRD=1
1015 !$ NPROC=OMP_GET_NUM_PROCS() ! number of processors available
1016 !$ CALL OMP_SET_NUM_THREADS(MTHRD) ! set max number of threads to MTHRD
1017 !$ MXTHRD=OMP_GET_MAX_THREADS() ! get max number of threads back
1018 !$ WRITE(*,*) 'Number of processors available: ', NPROC
1019 !$ WRITE(*,*) 'Maximum number of OpenMP threads: ', MXTHRD
1020 !$ WRITE(*,*) 'Number of threads for processing: ', MTHRD
1021 !$ IF (MXREC.GT.0) MTHRDR=1 ! to get allways the same MXREC records
1022 !$ IF (ICHECK.GT.1) MTHRDR=1 ! to get allways the same order of records
1023 !$ WRITE(*,*) 'Number of threads for reading: ', MTHRDR
1024 !$POMP INST INIT ! start profiling with ompP
1025#ifdef LAPACK64
1026 IF(iopnmp > 0) THEN
1027 CALL getenv('OMP_NUM_THREADS',c6)
1028 ELSE
1029 CALL getenv(lapack64//'_NUM_THREADS',c6)
1030 END IF
1031 IF (c6(1:1) == ' ') THEN
1032 IF(iopnmp > 0) THEN
1033 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty OMP_NUM_THREADS)'
1034 ELSE
1035 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty ',lapack64//'_NUM_THREADS)'
1036 END IF
1037 ELSE
1038 WRITE(*,*) 'Number of threads for LAPACK: ', c6
1039 END IF
1040#endif
1041 cols=mthrd
1042 CALL mpalloc(globalchi2sumd,cols,'fractional part of Chi2 sum')
1043 globalchi2sumd=0.0_mpd
1044 CALL mpalloc(globalchi2sumi,cols,'integer part of Chi2 sum')
1045 globalchi2sumi=0_mpl
1046 CALL mpalloc(globalndfsum,cols,'NDF sum')
1047 globalndfsum=0_mpl
1048 CALL mpalloc(globalndfsumw,cols,'weighted NDF sum')
1049 globalndfsumw=0.0_mpd
1050
1051 IF (ncache < 0) THEN
1052 ncache=25000000*mthrd ! default cache size (100 MB per thread)
1053 ENDIF
1054 rows=6; cols=mthrdr
1055 CALL mpalloc(readbufferinfo,rows,cols,'read buffer header')
1056 ! histogram file
1057 lun=7
1058 CALL mvopen(lun,'millepede.his')
1059 CALL hmplun(lun) ! unit for histograms
1060 CALL gmplun(lun) ! unit for xy data
1061
1062 ! debugging
1063 IF(nrecpr /= 0.OR.nrecp2 /= 0) THEN
1064 CALL mvopen(1,'mpdebug.txt')
1065 END IF
1066
1067 rstext=etime(ta)
1068 times(0)=rstext-rstp ! time for text processing
1069
1070 ! preparation of data sub-arrays
1071
1072 CALL loop1
1073 rloop1=etime(ta)
1074 times(1)=rloop1-rstext ! time for LOOP1
1075
1076 CALL loop2
1077 IF(chicut /= 0.0) THEN
1078 WRITE(8,*) 'Chi square cut equiv 3 st.dev applied ...'
1079 WRITE(8,*) ' in first iteration with factor',chicut
1080 WRITE(8,*) ' in second iteration with factor',chirem
1081 WRITE(8,*) ' (reduced by sqrt in next iterations)'
1082 END IF
1083
1084 IF(lhuber /= 0) THEN
1085 WRITE(8,*) 'Down-weighting of outliers in', lhuber,' iterations'
1086 WRITE(8,*) 'Cut on downweight fraction',dwcut
1087 END IF
1088
1089 rloop2=etime(ta)
1090 times(2)=rloop2-rloop1 ! time for LOOP2
1091
1092 IF(icheck > 0) THEN
1093 CALL prtstat
1094 IF (ncgbe < 0) THEN
1095 CALL peend(5,'Ended without solution (empty constraints)')
1096 ELSE
1097 CALL peend(0,'Ended normally')
1098 END IF
1099 GOTO 99 ! only checking input
1100 END IF
1101
1102 ! use different solution methods
1103
1104 CALL mstart('Iteration') ! Solution module starting
1105
1106 CALL xloopn ! all methods
1107
1108 ! ------------------------------------------------------------------
1109
1110 IF(nloopn > 2.AND.nhistp /= 0) THEN ! last iteration
1111 CALL hmprnt(3) ! scaled residual of single measurement (with global deriv.)
1112 CALL hmprnt(12) ! scaled residual of single measurement (no global deriv.)
1113 CALL hmprnt(4) ! chi^2/Ndf
1114 END IF
1115 IF(nloopn > 2) THEN
1116 CALL hmpwrt(3)
1117 CALL hmpwrt(12)
1118 CALL hmpwrt(4)
1119 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
1120 IF (nloopn <= lfitnp) THEN
1121 CALL hmpwrt(13)
1122 CALL hmpwrt(14)
1123 CALL gmpwrt(5)
1124 END IF
1125 END IF
1126 IF(nhistp /= 0) THEN
1127 CALL gmprnt(1)
1128 CALL gmprnt(2)
1129 END IF
1130 CALL gmpwrt(1) ! output of xy data
1131 CALL gmpwrt(2) ! output of xy data
1132 ! 'track quality' per binary file
1133 IF (nfilb > 1) THEN
1134 CALL gmpdef(6,1,'log10(#records) vs file number')
1135 CALL gmpdef(7,1,'final rejection fraction vs file number')
1136 CALL gmpdef(8,1, &
1137 'final <Chi^2/Ndf> from accepted local fits vs file number')
1138 CALL gmpdef(9,1, '<Ndf> from accepted local fits vs file number')
1139
1140 DO i=1,nfilb
1141 kfl=kfd(2,i)
1142 nrc=-kfd(1,i)
1143 IF (nrc > 0) THEN
1144 rej=real(nrc-jfd(kfl),mps)/real(nrc,mps)
1145 CALL gmpxy(6,real(kfl,mps),log10(real(nrc,mps))) ! log10(#records) vs file
1146 CALL gmpxy(7,real(kfl,mps),rej) ! rejection fraction vs file
1147 END IF
1148 IF (jfd(kfl) > 0) THEN
1149 c2ndf=cfd(kfl)/real(jfd(kfl),mps)
1150 CALL gmpxy(8,real(kfl,mps),c2ndf) ! <Chi2/NDF> vs file
1151 andf=real(dfd(kfl),mps)/real(jfd(kfl),mps)
1152 CALL gmpxy(9,real(kfl,mps),andf) ! <NDF> vs file
1153 END IF
1154 END DO
1155 IF(nhistp /= 0) THEN
1156 CALL gmprnt(6)
1157 CALL gmprnt(7)
1158 CALL gmprnt(8)
1159 CALL gmprnt(9)
1160 END IF
1161 CALL gmpwrt(6) ! output of xy data
1162 CALL gmpwrt(7) ! output of xy data
1163 CALL gmpwrt(8) ! output of xy data
1164 CALL gmpwrt(9) ! output of xy data
1165 END IF
1166
1167 IF(ictest == 1) THEN
1168 WRITE(*,*) ' '
1169 WRITE(*,*) 'Misalignment test wire chamber'
1170 WRITE(*,*) ' '
1171
1172 CALL hmpdef( 9,-0.0015,+0.0015,'True - fitted displacement')
1173 CALL hmpdef(10,-0.0015,+0.0015,'True - fitted Vdrift')
1174 DO i=1,4
1175 sums(i)=0.0_mpd
1176 END DO
1177 DO i=1,nplan
1178 diff=real(-del(i)-globalparameter(i),mps)
1179 sums(1)=sums(1)+diff
1180 sums(2)=sums(2)+diff*diff
1181 diff=real(-dvd(i)-globalparameter(100+i),mps)
1182 sums(3)=sums(3)+diff
1183 sums(4)=sums(4)+diff*diff
1184 END DO
1185 sums(1)=0.01_mpd*sums(1)
1186 sums(2)=sqrt(0.01_mpd*sums(2))
1187 sums(3)=0.01_mpd*sums(3)
1188 sums(4)=sqrt(0.01_mpd*sums(4))
1189 WRITE(*,143) 'Parameters 1 - 100: mean =',sums(1), 'rms =',sums(2)
1190 WRITE(*,143) 'Parameters 101 - 200: mean =',sums(3), 'rms =',sums(4)
1191143 FORMAT(6x,a28,f9.6,3x,a5,f9.6)
1192 WRITE(*,*) ' '
1193 WRITE(*,*) ' '
1194 WRITE(*,*) ' I label simulated fitted diff'
1195 WRITE(*,*) ' -------------------------------------------- '
1196 DO i=1,100
1197 WRITE(*,102) i,globalparlabelindex(1,i),-del(i),globalparameter(i),-del(i)-globalparameter(i)
1198 diff=real(-del(i)-globalparameter(i),mps)
1199 CALL hmpent( 9,diff)
1200 END DO
1201 DO i=101,200
1202 WRITE(*,102) i,globalparlabelindex(1,i),-dvd(i-100),globalparameter(i),-dvd(i-100)-globalparameter(i)
1203 diff=real(-dvd(i-100)-globalparameter(i),mps)
1204 CALL hmpent(10,diff)
1205 END DO
1206 IF(nhistp /= 0) THEN
1207 CALL hmprnt( 9)
1208 CALL hmprnt(10)
1209 END IF
1210 CALL hmpwrt( 9)
1211 CALL hmpwrt(10)
1212 END IF
1213 IF(ictest > 1) THEN
1214 WRITE(*,*) ' '
1215 WRITE(*,*) 'Misalignment test Si tracker'
1216 WRITE(*,*) ' '
1217
1218 CALL hmpdef( 9,-0.0025,+0.0025,'True - fitted displacement X')
1219 CALL hmpdef(10,-0.025,+0.025,'True - fitted displacement Y')
1220 DO i=1,9
1221 sums(i)=0.0_mpd
1222 END DO
1223 nmxy=nmx*nmy
1224 ix=0
1225 iy=ntot
1226 DO i=1,nlyr
1227 DO k=1,nmxy
1228 ix=ix+1
1229 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1230 sums(1)=sums(1)+1.0_mpd
1231 sums(2)=sums(2)+diff
1232 sums(3)=sums(3)+diff*diff
1233 ixv=globalparlabelindex(2,ix)
1234 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1235 ii=(ixv*ixv+ixv)/2
1236 gmati=real(globalmatd(ii),mps)
1237 err=sqrt(abs(gmati))
1238 diff=diff/err
1239 sums(7)=sums(7)+1.0_mpd
1240 sums(8)=sums(8)+diff
1241 sums(9)=sums(9)+diff*diff
1242 END IF
1243 END DO
1244 IF (mod(i,3) == 1) THEN
1245 DO k=1,nmxy
1246 iy=iy+1
1247 diff=-real(sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1248 sums(4)=sums(4)+1.0_mpd
1249 sums(5)=sums(5)+diff
1250 sums(6)=sums(6)+diff*diff
1251 ixv=globalparlabelindex(2,iy)
1252 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1253 ii=(ixv*ixv+ixv)/2
1254 gmati=real(globalmatd(ii),mps)
1255 err=sqrt(abs(gmati))
1256 diff=diff/err
1257 sums(7)=sums(7)+1.0_mpd
1258 sums(8)=sums(8)+diff
1259 sums(9)=sums(9)+diff*diff
1260 END IF
1261 END DO
1262 END IF
1263 END DO
1264 sums(2)=sums(2)/sums(1)
1265 sums(3)=sqrt(sums(3)/sums(1))
1266 sums(5)=sums(5)/sums(4)
1267 sums(6)=sqrt(sums(6)/sums(4))
1268 WRITE(*,143) 'Parameters 1 - 500: mean =',sums(2), 'rms =',sums(3)
1269 WRITE(*,143) 'Parameters 501 - 700: mean =',sums(5), 'rms =',sums(6)
1270 IF (sums(7) > 0.5_mpd) THEN
1271 sums(8)=sums(8)/sums(7)
1272 sums(9)=sqrt(sums(9)/sums(7))
1273 WRITE(*,143) 'Parameter pulls, all: mean =',sums(8), 'rms =',sums(9)
1274 END IF
1275 WRITE(*,*) ' '
1276 WRITE(*,*) ' '
1277 WRITE(*,*) ' I label simulated fitted diff'
1278 WRITE(*,*) ' -------------------------------------------- '
1279 ix=0
1280 iy=ntot
1281 DO i=1,nlyr
1282 DO k=1,nmxy
1283 ix=ix+1
1284 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1285 CALL hmpent( 9,diff)
1286 WRITE(*,102) ix,globalparlabelindex(1,ix),-sdevx((i-1)*nmxy+k),globalparameter(ix),-diff
1287 END DO
1288 END DO
1289 DO i=1,nlyr
1290 IF (mod(i,3) == 1) THEN
1291 DO k=1,nmxy
1292 iy=iy+1
1293 diff=real(-sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1294 CALL hmpent(10,diff)
1295 WRITE(*,102) iy,globalparlabelindex(1,iy),-sdevy((i-1)*nmxy+k),globalparameter(iy),-diff
1296 END DO
1297 END IF
1298 END DO
1299 IF(nhistp /= 0) THEN
1300 CALL hmprnt( 9)
1301 CALL hmprnt(10)
1302 END IF
1303 CALL hmpwrt( 9)
1304 CALL hmpwrt(10)
1305 END IF
1306
1307 IF(nrec1+nrec2 > 0) THEN
1308 WRITE(8,*) ' '
1309 IF(nrec1 > 0) THEN
1310 WRITE(8,*) 'Record',nrec1,' has largest residual:',value1
1311 END IF
1312 IF(nrec2 > 0) THEN
1313 WRITE(8,*) 'Record',nrec2,' has largest Chi^2/Ndf:',value2
1314 END IF
1315 END IF
1316 IF(nrec3 < huge(nrec3)) THEN
1317 WRITE(8,*) 'Record',nrec3, ' is first with error (rank deficit/NaN)'
1318 END IF
131999 WRITE(8,*) ' '
1320 IF (iteren > mreqenf) THEN
1321 WRITE(8,*) 'In total 3 +',nloopn,' loops through the data files'
1322 ELSE
1323 WRITE(8,*) 'In total 2 +',nloopn,' loops through the data files'
1324 ENDIF
1325 IF (mnrsit > 0) THEN
1326 WRITE(8,*) ' '
1327 WRITE(8,*) 'In total ',mnrsit,' internal MINRES iterations'
1328 END IF
1329
1330 WRITE(8,103) times(0),times(1),times(2),times(4),times(7), &
1331 times(5),times(8),times(3),times(6)
1332
1333 rst=etime(ta)
1334 deltat=rst-rstp
1335 ntsec=nint(deltat,mpi)
1336 CALL sechms(deltat,nhour,minut,secnd)
1337 nsecnd=nint(secnd,mpi) ! round
1338 WRITE(8,*) 'Total time =',ntsec,' seconds =',nhour,' h',minut, &
1339 ' m',nsecnd,' seconds'
1340 CALL fdate(chdate)
1341 WRITE(8,*) 'end ', chdate
1342 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1343 WRITE(8,*) ' '
1344 WRITE(8,105) gbu
1345
1346 ! Rejects ----------------------------------------------------------
1347
1348 IF(sum(nrejec) /= 0) THEN
1349 WRITE(8,*) ' '
1350 WRITE(8,*) 'Data records rejected in last iteration: '
1351 CALL prtrej(8)
1352 WRITE(8,*) ' '
1353 END IF
1354 IF (icheck <= 0) CALL explfc(8)
1355
1356 WRITE(*,*) ' '
1357 WRITE(*,*) ' < Millepede II-P ending ... ', chdate ! with exit code',ITEXIT,' >'
1358 WRITE(*,*) ' '
1359 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1360 WRITE(*,105) gbu
1361#ifdef LAPACK64
1362#ifdef PARDISO
1363 IF(ipdmem > 0) WRITE(*,106) real(ipdmem,mps)*1.e-6
1364106 FORMAT(' PARDISO dyn. memory allocation: ',f11.6,' GB')
1365#endif
1366#endif
1367 WRITE(*,*) ' '
1368
1369102 FORMAT(2x,i4,i10,2x,3f10.5)
1370103 FORMAT(' Times [in sec] for text processing',f12.3/ &
1371 ' LOOP1',f12.3/ &
1372 ' LOOP2',f12.3/ &
1373 ' func. value ',f12.3,' *',f4.0/ &
1374 ' func. value, global matrix, solution',f12.3,' *',f4.0/ &
1375 ' new solution',f12.3,' *',f4.0/)
1376105 FORMAT(' Peak dynamic memory allocation: ',f11.6,' GB')
1377END PROGRAM mptwo ! Mille
1378
1385
1386SUBROUTINE solglo(ivgbi)
1387 USE mpmod
1388 USE minresmodule, ONLY: minres
1389
1390 IMPLICIT NONE
1391 REAL(mps) :: par
1392 REAL(mps) :: dpa
1393 REAL(mps) :: err
1394 REAL(mps) :: gcor2
1395 INTEGER(mpi) :: iph
1396 INTEGER(mpi) :: istop
1397 INTEGER(mpi) :: itgbi
1398 INTEGER(mpi) :: itgbl
1399 INTEGER(mpi) :: itn
1400 INTEGER(mpi) :: itnlim
1401 INTEGER(mpi) :: nout
1402
1403 INTEGER(mpi), INTENT(IN) :: ivgbi
1404
1405 REAL(mpd) :: shift
1406 REAL(mpd) :: rtol
1407 REAL(mpd) :: anorm
1408 REAL(mpd) :: acond
1409 REAL(mpd) :: arnorm
1410 REAL(mpd) :: rnorm
1411 REAL(mpd) :: ynorm
1412 REAL(mpd) :: gmati
1413 REAL(mpd) :: diag
1414 REAL(mpd) :: matij
1415 LOGICAL :: checka
1416 EXTERNAL avprod, mcsolv, mvsolv
1417 SAVE
1418 DATA iph/0/
1419 ! ...
1420 IF(iph == 0) THEN
1421 iph=1
1422 WRITE(*,101)
1423 END IF
1424 itgbi=globalparvartototal(ivgbi)
1425 itgbl=globalparlabelindex(1,itgbi)
1426
1427 globalvector=0.0_mpd ! reset rhs vector IGVEC
1428 globalvector(ivgbi)=1.0_mpd
1429
1430 ! NOUT =6
1431 nout =0
1432 itnlim=200
1433 shift =0.0_mpd
1434 rtol = mrestl ! from steering
1435 checka=.false.
1436
1437
1438 IF(mbandw == 0) THEN ! default preconditioner
1439 CALL minres(nagb, avprod, mcsolv, globalvector, shift, checka ,.true. , &
1440 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1441
1442 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1443 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.true. , &
1444 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1445 ELSE
1446 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.false. , &
1447 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1448 END IF
1449
1450 par=real(globalparameter(itgbi),mps)
1451 dpa=real(par-globalparstart(itgbi),mps)
1452 gmati=globalcorrections(ivgbi)
1453 err=sqrt(abs(real(gmati,mps)))
1454 IF(gmati < 0.0_mpd) err=-err
1455 diag=matij(ivgbi,ivgbi)
1456 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1457 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1458101 FORMAT(1x,' label parameter presigma differ', &
1459 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1460102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1461END SUBROUTINE solglo
1462
1469
1470SUBROUTINE solgloqlp(ivgbi)
1471 USE mpmod
1472 USE minresqlpmodule, ONLY: minresqlp
1473
1474 IMPLICIT NONE
1475 REAL(mps) :: par
1476 REAL(mps) :: dpa
1477 REAL(mps) :: err
1478 REAL(mps) :: gcor2
1479 INTEGER(mpi) :: iph
1480 INTEGER(mpi) :: istop
1481 INTEGER(mpi) :: itgbi
1482 INTEGER(mpi) :: itgbl
1483 INTEGER(mpi) :: itn
1484 INTEGER(mpi) :: itnlim
1485 INTEGER(mpi) :: nout
1486
1487 INTEGER(mpi), INTENT(IN) :: ivgbi
1488
1489 REAL(mpd) :: shift
1490 REAL(mpd) :: rtol
1491 REAL(mpd) :: mxxnrm
1492 REAL(mpd) :: trcond
1493 REAL(mpd) :: gmati
1494 REAL(mpd) :: diag
1495 REAL(mpd) :: matij
1496
1497 EXTERNAL avprod, mcsolv, mvsolv
1498 SAVE
1499 DATA iph/0/
1500 ! ...
1501 IF(iph == 0) THEN
1502 iph=1
1503 WRITE(*,101)
1504 END IF
1505 itgbi=globalparvartototal(ivgbi)
1506 itgbl=globalparlabelindex(1,itgbi)
1507
1508 globalvector=0.0_mpd ! reset rhs vector IGVEC
1509 globalvector(ivgbi)=1.0_mpd
1510
1511 ! NOUT =6
1512 nout =0
1513 itnlim=200
1514 shift =0.0_mpd
1515 rtol = mrestl ! from steering
1516 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
1517 IF(mrmode == 1) THEN
1518 trcond = 1.0_mpd/epsilon(trcond) ! only QR
1519 ELSE IF(mrmode == 2) THEN
1520 trcond = 1.0_mpd ! only QLP
1521 ELSE
1522 trcond = mrtcnd ! QR followed by QLP
1523 END IF
1524
1525 IF(mbandw == 0) THEN ! default preconditioner
1526 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mcsolv, nout=nout, &
1527 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1528 x=globalcorrections, istop=istop, itn=itn)
1529 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1530 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mvsolv, nout=nout, &
1531 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1532 x=globalcorrections, istop=istop, itn=itn)
1533 ELSE
1534 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, nout=nout, &
1535 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1536 x=globalcorrections, istop=istop, itn=itn)
1537 END IF
1538
1539 par=real(globalparameter(itgbi),mps)
1540 dpa=real(par-globalparstart(itgbi),mps)
1541 gmati=globalcorrections(ivgbi)
1542 err=sqrt(abs(real(gmati,mps)))
1543 IF(gmati < 0.0_mpd) err=-err
1544 diag=matij(ivgbi,ivgbi)
1545 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1546 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1547101 FORMAT(1x,' label parameter presigma differ', &
1548 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1549102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1550END SUBROUTINE solgloqlp
1551
1553SUBROUTINE addcst
1554 USE mpmod
1555
1556 IMPLICIT NONE
1557 REAL(mpd) :: climit
1558 REAL(mpd) :: factr
1559 REAL(mpd) :: sgm
1560
1561 INTEGER(mpi) :: i
1562 INTEGER(mpi) :: icgb
1563 INTEGER(mpi) :: irhs
1564 INTEGER(mpi) :: itgbi
1565 INTEGER(mpi) :: ivgb
1566 INTEGER(mpi) :: j
1567 INTEGER(mpi) :: jcgb
1568 INTEGER(mpi) :: l
1569 INTEGER(mpi) :: label
1570 INTEGER(mpi) :: nop
1571 INTEGER(mpi) :: inone
1572
1573 REAL(mpd) :: rhs
1574 REAL(mpd) :: drhs(4)
1575 INTEGER(mpi) :: idrh (4)
1576 SAVE
1577 ! ...
1578 nop=0
1579 IF(lenconstraints == 0) RETURN ! no constraints
1580 climit=1.0e-5 ! limit for printout
1581 irhs=0 ! number of values in DRHS(.), to be printed
1582
1583 DO jcgb=1,ncgb
1584 icgb=matconssort(3,jcgb) ! unsorted constraint index
1585 i=vecconsstart(icgb)
1586 rhs=listconstraints(i )%value ! right hand side
1587 sgm=listconstraints(i+1)%value ! sigma parameter
1588 DO j=i+2,vecconsstart(icgb+1)-1
1589 label=listconstraints(j)%label
1590 factr=listconstraints(j)%value
1591 itgbi=inone(label) ! -> ITGBI= index of parameter label
1592 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1593
1594 IF(icalcm == 1.AND.nagb > nvgb.AND.ivgb > 0) THEN
1595 CALL mupdat(nvgb+jcgb,ivgb,factr) ! add to matrix
1596 END IF
1597
1598 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
1599 END DO
1600 IF(abs(rhs) > climit) THEN
1601 irhs=irhs+1
1602 idrh(irhs)=jcgb
1603 drhs(irhs)=rhs
1604 nop=1
1605 IF(irhs == 4) THEN
1606 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1607 irhs=0
1608 END IF
1609 END IF
1610 vecconsresiduals(jcgb)=rhs
1611 IF (nagb > nvgb) globalvector(nvgb+jcgb)=rhs
1612 END DO
1613
1614 IF(irhs /= 0) THEN
1615 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1616 END IF
1617 IF(nop == 0) RETURN
1618 WRITE(*,102) ' Constraints: only equation values >', climit,' are printed'
1619101 FORMAT(' ',4(i6,g11.3))
1620102 FORMAT(a,g11.2,a)
1621END SUBROUTINE addcst
1622
1627SUBROUTINE grpcon
1628 USE mpmod
1629 USE mpdalc
1630
1631 IMPLICIT NONE
1632 INTEGER(mpi) :: i
1633 INTEGER(mpi) :: icgb
1634 INTEGER(mpi) :: icgrp
1635 INTEGER(mpi) :: ioff
1636 INTEGER(mpi) :: itgbi
1637 INTEGER(mpi) :: j
1638 INTEGER(mpi) :: jcgb
1639 INTEGER(mpi) :: label
1640 INTEGER(mpi) :: labelf
1641 INTEGER(mpi) :: labell
1642 INTEGER(mpi) :: last
1643 INTEGER(mpi) :: line1
1644 INTEGER(mpi) :: ncon
1645 INTEGER(mpi) :: ndiff
1646 INTEGER(mpi) :: npar
1647 INTEGER(mpi) :: inone
1648 INTEGER(mpi) :: itype
1649 INTEGER(mpi) :: ncgbd
1650 INTEGER(mpi) :: ncgbr
1651 INTEGER(mpi) :: ncgbw
1652 INTEGER(mpi) :: ncgrpd
1653 INTEGER(mpi) :: ncgrpr
1654 INTEGER(mpi) :: next
1655
1656 INTEGER(mpl):: length
1657 INTEGER(mpl) :: rows
1658
1659 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsOffsets
1660 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsList
1661 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParOffsets
1662 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParList
1663 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1664
1665 ncgb=0
1666 ncgbw=0
1667 IF(lenconstraints == 0) RETURN ! no constraints
1668
1669 i=0
1670 last=0
1671 itype=0
1672 ! find next constraint header and count nr of constraints
1673 DO WHILE(i < lenconstraints)
1674 i=i+1
1675 label=listconstraints(i)%label
1676 IF(last < 0.AND.label < 0) THEN
1677 ncgb=ncgb+1
1678 itype=-label
1679 IF(itype == 2) ncgbw=ncgbw+1
1680 END IF
1681 last=label
1682 IF(label > 0) THEN
1683 itgbi=inone(label) ! -> ITGBI= index of parameter label
1684 globalparcons(itgbi)=globalparcons(itgbi)+1
1685 END IF
1686 IF(label > 0.AND.itype == 2) THEN ! weighted constraints
1687 itgbi=inone(label) ! -> ITGBI= index of parameter label
1689 END IF
1690 END DO
1691
1692 WRITE(*,*)
1693 IF (ncgbw == 0) THEN
1694 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files'
1695 ELSE
1696 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files,',ncgbw, 'weighted'
1697 END IF
1698 WRITE(*,*)
1699
1700 ! keys and index for sorting of constraints
1701 length=ncgb+1; rows=3
1702 CALL mpalloc(matconssort,rows,length,'keys and index for sorting (I)')
1703 matconssort(1,ncgb+1)=ntgb+1
1704 ! start of constraint in list
1705 CALL mpalloc(vecconsstart,length,'start of constraint in list (I)')
1707 ! start and parameter range of constraint groups
1708 CALL mpalloc(matconsgroups,rows,length,'start of constraint groups, par. range (I)')
1709 ! parameter ranges (all, variable) of constraints
1710 length=ncgb; rows=4
1711 CALL mpalloc(matconsranges,rows,length,'parameter ranges for constraint (I)')
1712
1713 length=ncgb; rows=3
1714 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1715 matconsgroupindex=0
1716 length=ncgb+1
1717 CALL mpalloc(vecconsparoffsets,length,'offsets for global par list for cons. (I)')
1718 length=ntgb+1
1719 CALL mpalloc(vecparconsoffsets,length,'offsets for cons. list for global par. (I)')
1720 vecparconsoffsets(1)=0
1721 DO i=1,ntgb
1722 vecparconsoffsets(i+1)=vecparconsoffsets(i)+globalparcons(i)
1723 END DO
1725
1726 length=vecparconsoffsets(ntgb+1)
1727 CALL mpalloc(vecconsparlist,length,'global par. list for constraint (I)')
1728 CALL mpalloc(vecparconslist,length,'constraint list for global par. (I)')
1729
1730 ! prepare
1731 i=1
1732 ioff=0
1733 vecconsparoffsets(1)=ioff
1734 DO icgb=1,ncgb
1735 ! new constraint
1736 vecconsstart(icgb)=i
1737 line1=-listconstraints(i)%label
1738 npar=0
1739 i=i+2
1740 DO
1741 label=listconstraints(i)%label
1742 itgbi=inone(label) ! -> ITGBI= index of parameter label
1743 ! list of constraints for 'itgbi'
1744 globalparcons(itgbi)=globalparcons(itgbi)+1
1745 vecparconslist(vecparconsoffsets(itgbi)+globalparcons(itgbi))=icgb
1746 npar=npar+1
1747 vecconsparlist(ioff+npar)=itgbi
1748 i=i+1
1749 IF(i > lenconstraints) EXIT
1750 IF(listconstraints(i)%label < 0) EXIT
1751 END DO
1752 ! sort to find duplicates
1753 CALL sort1k(vecconsparlist(ioff+1),npar)
1754 last=-1
1755 ndiff=0
1756 DO j=1,npar
1757 next=vecconsparlist(ioff+j)
1758 IF (next /= last) THEN
1759 ndiff=ndiff+1
1760 vecconsparlist(ioff+ndiff) = next
1761 END IF
1762 last=next
1763 END DO
1764 matconsranges(1,icgb)=vecconsparlist(ioff+1) ! min parameter
1765 matconsranges(3,icgb)=vecconsparlist(ioff+1) ! min parameter
1766 ioff=ioff+ndiff
1767 matconsranges(2,icgb)=vecconsparlist(ioff) ! max parameter
1768 matconsranges(4,icgb)=vecconsparlist(ioff) ! max parameter
1769 vecconsparoffsets(icgb+1)=ioff
1770 END DO
1772
1773 ! sort (by first, last parameter)
1774 DO icgb=1,ncgb
1775 matconssort(1,icgb)=matconsranges(1,icgb) ! first par.
1776 matconssort(2,icgb)=matconsranges(2,icgb) ! last par.
1777 matconssort(3,icgb)=icgb ! index
1778 END DO
1779 CALL sort2i(matconssort,ncgb)
1780
1781 IF (icheck>1) THEN
1782 print *, ' Constraint #parameters first par. last par. first line'
1783 END IF
1784 ! split into disjoint groups
1785 ncgrp=0
1787 DO jcgb=1,ncgb
1788 icgb=matconssort(3,jcgb)
1789 IF (icheck>0) THEN
1790 npar=vecconsparoffsets(icgb+1)-vecconsparoffsets(icgb)
1791 line1=-listconstraints(vecconsstart(icgb))%label
1792 labelf=globalparlabelindex(1,matconsranges(1,icgb))
1793 labell=globalparlabelindex(1,matconsranges(2,icgb))
1794 print *, jcgb, npar, labelf, labell, line1
1795 END IF
1796 ! already part of group?
1797 icgrp=matconsgroupindex(1,icgb)
1798 IF (icgrp == 0) THEN
1799 ! check all parameters
1800 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1801 itgbi=vecconsparlist(i)
1802 ! check all related constraints
1803 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1804 icgrp=matconsgroupindex(1,vecparconslist(j))
1805 ! already part of group?
1806 IF (icgrp > 0) EXIT
1807 END DO
1808 IF (icgrp > 0) EXIT
1809 END DO
1810 IF (icgrp == 0) THEN
1811 ! new group
1812 ncgrp=ncgrp+1
1813 icgrp=ncgrp
1814 END IF
1815 END IF
1816 ! add to group
1817 matconsgroupindex(2,icgb)=jcgb
1818 matconsgroupindex(3,icgb)=icgb
1819 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1820 itgbi=vecconsparlist(i)
1821 globalparcons(itgbi)=icgrp
1822 ! mark all related constraints
1823 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1824 matconsgroupindex(1,vecparconslist(j))=icgrp
1825 END DO
1826 END DO
1827 END DO
1828 WRITE(*,*) 'GRPCON:',ncgrp,' disjoint constraints groups built'
1829
1830 ! sort by group number
1831 CALL sort2i(matconsgroupindex,ncgb)
1832
1833 matconsgroups(1,1:ncgrp)=0
1834 DO jcgb=1,ncgb
1835 ! set up matConsSort
1836 icgb=matconsgroupindex(3,jcgb)
1837 matconssort(1,jcgb)=matconsranges(1,icgb)
1838 matconssort(2,jcgb)=matconsranges(2,icgb)
1839 matconssort(3,jcgb)=icgb
1840 ! set up matConsGroups
1841 icgrp=matconsgroupindex(1,jcgb)
1842 IF (matconsgroups(1,icgrp) == 0) THEN
1843 matconsgroups(1,icgrp)=jcgb
1844 matconsgroups(2,icgrp)=matconsranges(1,icgb)
1845 matconsgroups(3,icgrp)=matconsranges(2,icgb)
1846 ELSE
1847 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
1848 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
1849 END IF
1850 END DO
1851 matconsgroups(1,ncgrp+1)=ncgb+1
1852 matconsgroups(2,ncgrp+1)=ntgb+1
1853
1854 ! check for redundancy constraint groups
1855 ncgbr=0
1856 ncgrpr=0
1857 ncgbd=0
1858 ncgrpd=0
1859 IF (icheck>0) THEN
1860 print *
1861 print *, ' cons.group first con. first par. last par. #cons #par'
1862 ENDIF
1863 DO icgrp=1,ncgrp
1864 npar=0
1865 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1866 IF (globalparcons(i) == icgrp) npar=npar+1
1867 END DO
1868 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
1869 IF (icheck>0) THEN
1870 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1871 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1872 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ncon, npar
1873 END IF
1874 ! redundancy constraints?
1875 IF (ncon == npar) THEN
1876 IF (irslvrc > 0) THEN
1877 ncgrpr=ncgrpr+1
1878 ncgbr=ncgbr+ncon
1879 IF (icheck > 0) THEN
1880 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1881 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1882 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group resolved'
1883 END IF
1884 ! flag redundant parameters
1885 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1886 IF (globalparcons(i) == icgrp) globalparcons(i)=-icgrp
1887 END DO
1888 ! flag constraint group
1889 matconsgroups(2,icgrp)=ntgb+1
1890 matconsgroups(3,icgrp)=ntgb
1891 ELSE
1892 ncgrpd=ncgrpd+1
1893 ncgbd=ncgbd+ncon
1894 IF (icheck > 0) THEN
1895 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1896 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1897 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group redundant'
1898 END IF
1899 END IF
1900 END IF
1901 END DO
1902 IF (ncgrpr > 0) THEN
1903 WRITE(*,*) 'GRPCON:',ncgbr,' redundancy constraints in ', ncgrpr, ' groups resolved'
1904 ! all constraint groups resolved ?
1905 IF (ncgrpr == ncgrp) ncgrp=0
1906 ENDIF
1907 IF (ncgrpd > 0) THEN
1908 WRITE(*,*) 'GRPCON:',ncgbd,' redundancy constraints in ', ncgrpd, ' groups detected'
1909 ENDIF
1910 WRITE(*,*)
1911
1912 ! clean up
1913 CALL mpdealloc(vecparconslist)
1914 CALL mpdealloc(vecconsparlist)
1915 CALL mpdealloc(vecparconsoffsets)
1916 CALL mpdealloc(vecconsparoffsets)
1917 CALL mpdealloc(matconsgroupindex)
1918
1919END SUBROUTINE grpcon
1920
1924
1925SUBROUTINE prpcon
1926 USE mpmod
1927 USE mpdalc
1928
1929 IMPLICIT NONE
1930 INTEGER(mpi) :: i
1931 INTEGER(mpi) :: icgb
1932 INTEGER(mpi) :: icgrp
1933 INTEGER(mpi) :: ifrst
1934 INTEGER(mpi) :: ilast
1935 INTEGER(mpi) :: isblck
1936 INTEGER(mpi) :: itgbi
1937 INTEGER(mpi) :: ivgb
1938 INTEGER(mpi) :: j
1939 INTEGER(mpi) :: jcgb
1940 INTEGER(mpi) :: jfrst
1941 INTEGER(mpi) :: label
1942 INTEGER(mpi) :: labelf
1943 INTEGER(mpi) :: labell
1944 INTEGER(mpi) :: ncon
1945 INTEGER(mpi) :: ngrp
1946 INTEGER(mpi) :: npar
1947 INTEGER(mpi) :: ncnmxb
1948 INTEGER(mpi) :: ncnmxg
1949 INTEGER(mpi) :: nprmxb
1950 INTEGER(mpi) :: nprmxg
1951 INTEGER(mpi) :: inone
1952 INTEGER(mpi) :: nvar
1953
1954 INTEGER(mpl):: length
1955 INTEGER(mpl) :: rows
1956
1957 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1958
1959 ncgbe=0
1960 !
1961 ! constraint groups already built in GRPCON based on steering,
1962 ! now care about fixed parameters
1963 !
1964 IF(ncgrp == 0) THEN ! no constraints groups
1965 ncgb=0
1966 ncblck=0
1967 RETURN
1968 END IF
1969
1970 length=ncgrp+1; rows=3
1971 ! start and parameter range of constraint blocks
1972 CALL mpalloc(matconsblocks,rows,length,'start of constraint blocks, par. range (I)')
1973
1974 length=ncgb; rows=3
1975 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1976 matconsgroupindex=0
1977
1978 ! check for empty constraints, redefine (accepted/active) constraints and groups
1979 ngrp=0
1980 ncgb=0
1981 DO icgrp=1,ncgrp
1982 ncon=ncgb
1983 ! resolved group ?
1984 IF (matconsgroups(2,icgrp) > matconsgroups(3,icgrp)) cycle
1985 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
1986 icgb=matconssort(3,jcgb)
1987 i=vecconsstart(icgb)+2
1988 npar=0
1989 nvar=0
1990 matconsranges(1,icgb)=ntgb
1991 matconsranges(2,icgb)=1
1992 DO
1993 label=listconstraints(i)%label
1994 itgbi=inone(label) ! -> ITGBI= index of parameter label
1995 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1996 npar=npar+1
1997 IF(ivgb > 0) THEN
1998 nvar=nvar+1
1999 matconsranges(1,icgb)=min(matconsranges(1,icgb),itgbi)
2000 matconsranges(2,icgb)=max(matconsranges(2,icgb),itgbi)
2001 ENDIF
2002 i=i+1
2003 IF(i > lenconstraints) EXIT
2004 IF(listconstraints(i)%label < 0) EXIT
2005 END DO
2006 IF (nvar == 0) THEN
2007 ncgbe=ncgbe+1
2008 ! reset range
2009 matconsranges(1,icgb)=matconsranges(3,icgb)
2010 matconsranges(2,icgb)=matconsranges(4,icgb)
2011 END IF
2012 IF (nvar > 0 .OR. iskpec == 0) THEN
2013 ! constraint accepted (or kept)
2014 ncgb=ncgb+1
2015 matconsgroupindex(1,ncgb)=ngrp+1
2016 matconsgroupindex(2,ncgb)=icgb
2017 matconsgroupindex(3,ncgb)=nvar
2018 END IF
2019 END DO
2020 IF (ncgb > ncon) ngrp=ngrp+1
2021 END DO
2022 ncgrp=ngrp
2023
2024 IF (ncgbe > 0) THEN
2025 IF (iskpec > 0) THEN
2026 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints skipped'
2027 ELSE
2028 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints detected, to be fixed !!!'
2029 WRITE(*,*) ' (use option "skipemptycons" to skip those)'
2030 IF (icheck == 0) THEN
2031 icheck=2 ! switch to '-C'
2032 ncgbe=-ncgbe ! indicate that
2033 WRITE(*,*)
2034 WRITE(*,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2035 WRITE(8,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2036 WRITE(*,*)
2037 END IF
2038 END IF
2039 END IF
2040 WRITE(*,*) 'PRPCON:',ncgb,' constraints accepted'
2041 WRITE(*,*)
2042
2043 IF(ncgb == 0) RETURN ! no constraints left
2044
2045 ! already sorted by group number
2046
2047 matconsgroups(1,1:ncgrp)=0
2048 DO jcgb=1,ncgb
2049 ! set up matConsSort
2050 icgb=matconsgroupindex(2,jcgb)
2051 matconssort(1,jcgb)=matconsranges(1,icgb)
2052 matconssort(2,jcgb)=matconsranges(2,icgb)
2053 matconssort(3,jcgb)=icgb
2054 ! set up matConsGroups
2055 icgrp=matconsgroupindex(1,jcgb)
2056 IF (matconsgroups(1,icgrp) == 0) THEN
2057 matconsgroups(1,icgrp)=jcgb
2058 matconsgroups(2,icgrp)=matconsranges(1,icgb)
2059 matconsgroups(3,icgrp)=matconsranges(2,icgb)
2060 ELSE
2061 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
2062 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
2063 END IF
2064 END DO
2065 matconsgroups(1,ncgrp+1)=ncgb+1
2066 matconsgroups(2,ncgrp+1)=ntgb+1
2067
2068 ! loop over constraints groups, combine into non overlapping blocks
2069 ncblck=0
2070 ncnmxg=0
2071 nprmxg=0
2072 ncnmxb=0
2073 nprmxb=0
2074 mszcon=0
2075 mszprd=0
2076 isblck=1
2077 ilast=0
2078 IF (icheck > 0) THEN
2079 WRITE(*,*)
2080 IF (icheck > 1) &
2081 WRITE(*,*) ' Cons. sorted index #var.par. first line first label last label'
2082 WRITE(*,*) ' Cons. group index first cons. last cons. first label last label'
2083 WRITE(*,*) ' Cons. block index first group last group first label last label'
2084 END IF
2085 DO icgrp=1,ncgrp
2086 IF (icheck > 1) THEN
2087 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2088 icgb=matconssort(3,jcgb)
2089 nvar=matconsgroupindex(3,jcgb)
2090 labelf=globalparlabelindex(1,matconssort(1,jcgb))
2091 labell=globalparlabelindex(1,matconssort(2,jcgb))
2092 IF (nvar > 0) THEN
2093 WRITE(*,*) ' Cons. sorted', jcgb, nvar, &
2094 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2095 ELSE
2096 WRITE(*,*) ' Cons. sorted', jcgb, ' empty (0)', &
2097 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2098 END IF
2099 END DO
2100 END IF
2101 IF (icheck > 0) THEN
2102 !ivgb=globalParLabelIndex(2,matConsGroups(2,icgrp)) ! -> index of variable global parameter
2103 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
2104 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
2105 WRITE(*,*) ' Cons. group ', icgrp, matconsgroups(1,icgrp), &
2106 matconsgroups(1,icgrp+1)-1, labelf, labell
2107 ENDIF
2108 ! combine into non overlapping blocks
2109 ilast=max(ilast, matconsgroups(3,icgrp))
2110 IF (matconsgroups(2,icgrp+1) > ilast) THEN
2111 ncblck=ncblck+1
2112 ifrst=matconsgroups(2,isblck)
2114 matconsblocks(2,ncblck)=ifrst ! save first parameter in block
2115 matconsblocks(3,ncblck)=ilast ! save last parameter in block
2116 ! update matConsSort
2117 jfrst=matconsgroups(2,icgrp)
2118 DO i=icgrp,isblck,-1
2119 DO j=matconsgroups(1,i),matconsgroups(1,i+1)-1
2120 ! non zero range (from group)
2121 matconsranges(1,j)=matconsgroups(2,i)
2123 ! storage range (from max group, ilast)
2124 jfrst=min(jfrst,matconsgroups(2,i))
2125 matconsranges(3,j)=jfrst
2126 matconsranges(4,j)=ilast
2127 END DO
2128 END DO
2129 IF (icheck > 0) THEN
2130 labelf=globalparlabelindex(1,ifrst)
2131 labell=globalparlabelindex(1,ilast)
2132 WRITE(*,*) ' Cons. block ', ncblck, isblck, icgrp, labelf, labell
2133 ENDIF
2134 ! reset for new block
2135 isblck=icgrp+1
2136 END IF
2137 END DO
2139
2140 ! convert from total parameter index to index of variable global parameter
2141 DO i=1,ncblck
2142 ifrst=globalparlabelindex(2,matconsblocks(2,i)) ! -> index of variable global parameter
2143 ilast=globalparlabelindex(2,matconsblocks(3,i)) ! -> index of variable global parameter
2144 IF (ifrst > 0) THEN
2145 matconsblocks(2,i)=ifrst
2146 matconsblocks(3,i)=ilast
2147 ! statistics
2148 ncon=matconsblocks(1,i+1)-matconsblocks(1,i)
2149 npar=ilast+1-ifrst
2150 ncnmxb=max(ncnmxb,ncon)
2151 nprmxb=max(nprmxb,npar)
2152 ! update index ranges
2153 globalindexranges(ifrst)=max(globalindexranges(ifrst),ilast)
2154 ELSE
2155 ! empty
2156 matconsblocks(2,i)=1
2157 matconsblocks(3,i)=0
2158 END IF
2159 END DO
2160 DO icgrp=1,ncgrp
2161 ifrst=globalparlabelindex(2,matconsgroups(2,icgrp)) ! -> index of variable global parameter
2162 ilast=globalparlabelindex(2,matconsgroups(3,icgrp)) ! -> index of variable global parameter
2163 IF (ifrst > 0) THEN
2164 matconsgroups(2,icgrp)=ifrst
2165 matconsgroups(3,icgrp)=ilast
2166 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2167 DO i=1,4
2168 ivgb=globalparlabelindex(2,matconsranges(i,jcgb)) ! -> index of variable global parameter
2169 matconsranges(i,jcgb)=ivgb
2170 END DO
2171 END DO
2172 ! storage sizes, statistics
2173 jcgb=matconsgroups(1,icgrp) ! first cons.
2174 ncon=matconsgroups(1,icgrp+1)-jcgb
2175 npar=matconsranges(4,jcgb)+1-matconsranges(3,jcgb)
2176 ncnmxg=max(ncnmxg,ncon)
2177 nprmxg=max(nprmxg,npar)
2178 mszcon=mszcon+int(ncon,mpl)*int(npar,mpl) ! (sum of) block size for constraint matrix
2179 mszprd=mszprd+int(ncon,mpl)*int(ncon+1,mpl)/2 ! (sum of) block size for product matrix
2180 ELSE
2181 ! empty
2182 matconsgroups(2,icgrp)=1
2183 matconsgroups(3,icgrp)=0
2184 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2185 matconsranges(1,jcgb)=1
2186 matconsranges(2,jcgb)=0
2187 matconsranges(3,jcgb)=1
2188 matconsranges(4,jcgb)=0
2189 END DO
2190 END IF
2191 END DO
2192
2193 ! clean up
2194 CALL mpdealloc(matconsgroupindex)
2195
2196 ! save constraint group for global parameters
2198 DO icgrp=1,ncgrp
2199 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2200 ! index in list
2201 icgb=matconssort(3,jcgb)
2202 DO j=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
2203 label=listconstraints(j)%label
2204 itgbi=inone(label) ! -> ITGBI= index of parameter label
2205 globalparcons(itgbi)=icgrp ! save constraint group
2206 END DO
2207 END DO
2208 END DO
2209
2210 IF (ncgrp+icheck > 1) THEN
2211 WRITE(*,*)
2212 WRITE(*,*) 'PRPCON: constraints split into ', ncgrp, '(disjoint) groups,'
2213 WRITE(*,*) ' groups combined into ', ncblck, '(non overlapping) blocks'
2214 WRITE(*,*) ' max group size (cons., par.) ', ncnmxg, nprmxg
2215 WRITE(*,*) ' max block size (cons., par.) ', ncnmxb, nprmxb
2216 IF (icheck > 0) WRITE(*,*) ' total block matrix sizes ', mszcon, mszprd
2217 END IF
2218
2219END SUBROUTINE prpcon
2220
2224
2225SUBROUTINE feasma
2226 USE mpmod
2227 USE mpdalc
2228
2229 IMPLICIT NONE
2230 REAL(mpd) :: factr
2231 REAL(mpd) :: sgm
2232 INTEGER(mpi) :: i
2233 INTEGER(mpi) :: icgb
2234 INTEGER(mpi) :: icgrp
2235 INTEGER(mpl) :: ij
2236 INTEGER(mpi) :: ifirst
2237 INTEGER(mpi) :: ilast
2238 INTEGER(mpl) :: ioffc
2239 INTEGER(mpl) :: ioffp
2240 INTEGER(mpi) :: irank
2241 INTEGER(mpi) :: ipar0
2242 INTEGER(mpi) :: itgbi
2243 INTEGER(mpi) :: ivgb
2244 INTEGER(mpi) :: j
2245 INTEGER(mpi) :: jcgb
2246 INTEGER(mpl) :: ll
2247 INTEGER(mpi) :: label
2248 INTEGER(mpi) :: ncon
2249 INTEGER(mpi) :: npar
2250 INTEGER(mpi) :: nrank
2251 INTEGER(mpi) :: inone
2252
2253 REAL(mpd):: rhs
2254 REAL(mpd):: evmax
2255 REAL(mpd):: evmin
2256 INTEGER(mpl):: length
2257 REAL(mpd), DIMENSION(:), ALLOCATABLE :: matConstraintsT
2258 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
2259 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
2260 SAVE
2261 ! ...
2262
2263 IF(ncgb == 0) RETURN ! no constraints
2264
2265 ! product matrix A A^T (A is stored as transposed)
2266 length=mszprd
2267 CALL mpalloc(matconsproduct, length, 'product matrix of constraints (blocks)')
2268 matconsproduct=0.0_mpd
2269 length=ncgb
2270 CALL mpalloc(vecconsresiduals, length, 'residuals of constraints')
2271 CALL mpalloc(vecconssolution, length, 'solution for constraints')
2272 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
2273 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
2274 ! constraint matrix A (A is stored as transposed)
2275 length = mszcon
2276 CALL mpalloc(matconstraintst,length,'transposed matrix of constraints (blocks)')
2277 matconstraintst=0.0_mpd
2278
2279 ! loop over sorted constraints, fill matrices, get rank, inverted product matrix (in groups)
2280 ioffc=0 ! group offset in constraint matrix
2281 ioffp=0 ! group offset in product matrix
2282 nrank=0
2283 DO icgrp=1,ncgrp
2284 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2285 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2286 ncon=ilast+1-ifirst
2287 ipar0=matconsranges(3,ifirst)-1 ! parameter offset
2288 npar=matconsranges(4,ifirst)-ipar0 ! number of parameters
2289 IF (npar <= 0) THEN
2290 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, 0, ' (empty)'
2291 cycle ! skip empty groups/cons.
2292 END IF
2293 DO jcgb=ifirst,ilast
2294 ! index in list
2295 icgb=matconssort(3,jcgb)
2296 ! fill constraint matrix
2297 i=vecconsstart(icgb)
2298 rhs=listconstraints(i )%value ! right hand side
2299 sgm=listconstraints(i+1)%value ! sigma parameter
2300 DO j=i+2,vecconsstart(icgb+1)-1
2301 label=listconstraints(j)%label
2302 factr=listconstraints(j)%value
2303 itgbi=inone(label) ! -> ITGBI= index of parameter label
2304 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2305 IF(ivgb > 0) matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)= &
2306 matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)+factr ! matrix element
2307 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2308 END DO
2309 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2310 END DO
2311
2312 ! get rank of groups
2313 DO ll=ioffc+1,ioffc+npar
2314 ij=ioffp
2315 DO i=1,ncon
2316 DO j=1,i
2317 ij=ij+1
2318 matconsproduct(ij)=matconsproduct(ij)+ &
2319 matconstraintst(int(i-1,mpl)*int(npar,mpl)+ll)* &
2320 matconstraintst(int(j-1,mpl)*int(npar,mpl)+ll)
2321 END DO
2322 END DO
2323 END DO
2324 ! inversion of product matrix of constraints
2325 CALL sqminv(matconsproduct(ioffp+1:ij),vecconsresiduals(ifirst:ilast),ncon,irank, auxvectord, auxvectori)
2326 IF (icheck > 1 .OR. irank < ncon) THEN
2327 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, irank
2328 IF (irank < ncon) THEN
2329 WRITE(*,*) ' .. rank deficit !! '
2330 WRITE(*,*) ' E.g. fix all parameters and remove all constraints related to label ', &
2332 END IF
2333 END IF
2334 nrank=nrank+irank
2335 ioffc=ioffc+int(npar,mpl)*int(ncon,mpl)
2336 ioffp=ij
2337 END DO
2338
2339 nmiss1=ncgb-nrank
2340
2341 WRITE(*,*) ' '
2342 WRITE(*,*) 'Rank of product matrix of constraints is',nrank, &
2343 ' for',ncgb,' constraint equations'
2344 WRITE(8,*) 'Rank of product matrix of constraints is',nrank, &
2345 ' for',ncgb,' constraint equations'
2346 IF(nrank < ncgb) THEN
2347 WRITE(*,*) 'Warning: insufficient constraint equations!'
2348 WRITE(8,*) 'Warning: insufficient constraint equations!'
2349 IF (iforce == 0) THEN
2350 isubit=1
2351 WRITE(*,*) ' --> enforcing SUBITO mode'
2352 WRITE(8,*) ' --> enforcing SUBITO mode'
2353 END IF
2354 END IF
2355
2356 ! QL decomposition
2357 IF (nfgb < nvgb) THEN
2358 print *
2359 print *, 'QL decomposition of constraints matrix'
2360 ! monitor progress
2361 IF(monpg1 > 0) THEN
2362 WRITE(lunlog,*) 'QL decomposition of constraints matrix'
2364 END IF
2365 IF(icelim < 2) THEN ! True unless unpacked LAPACK
2366 ! QL decomposition
2368 ! loop over parameter blocks
2370 ! check eignevalues of L
2371 CALL qlgete(evmin,evmax)
2372#ifdef LAPACK64
2373 ELSE
2374 CALL lpqldec(matconstraintst,evmin,evmax)
2375#endif
2376 END IF
2377 IF(monpg1 > 0) CALL monend()
2378 print *, ' largest |eigenvalue| of L: ', evmax
2379 print *, ' smallest |eigenvalue| of L: ', evmin
2380 IF (evmin == 0.0_mpd.AND.icheck == 0) THEN
2381 CALL peend(27,'Aborted, singular QL decomposition of constraints matrix')
2382 stop 'FEASMA: stopping due to singular QL decomposition of constraints matrix'
2383 END IF
2384 END IF
2385
2386 CALL mpdealloc(matconstraintst)
2387 CALL mpdealloc(auxvectord)
2388 CALL mpdealloc(auxvectori)
2389
2390 RETURN
2391END SUBROUTINE feasma ! matrix for feasible solution
2392
2400SUBROUTINE feasib(concut,iact)
2401 USE mpmod
2402 USE mpdalc
2403
2404 IMPLICIT NONE
2405 REAL(mpd) :: factr
2406 REAL(mpd) :: sgm
2407 INTEGER(mpi) :: i
2408 INTEGER(mpi) :: icgb
2409 INTEGER(mpi) :: icgrp
2410 INTEGER(mpi) :: iter
2411 INTEGER(mpi) :: itgbi
2412 INTEGER(mpi) :: ivgb
2413 INTEGER(mpi) :: ieblck
2414 INTEGER(mpi) :: isblck
2415 INTEGER(mpi) :: ifirst
2416 INTEGER(mpi) :: ilast
2417 INTEGER(mpi) :: j
2418 INTEGER(mpi) :: jcgb
2419 INTEGER(mpi) :: label
2420 INTEGER(mpi) :: inone
2421 INTEGER(mpi) :: ncon
2422
2423 REAL(mps), INTENT(IN) :: concut
2424 INTEGER(mpi), INTENT(OUT) :: iact
2425
2426 REAL(mpd) :: rhs
2427 REAL(mpd) ::sum1
2428 REAL(mpd) ::sum2
2429 REAL(mpd) ::sum3
2430
2431 REAL(mpd), DIMENSION(:), ALLOCATABLE :: vecCorrections
2432 SAVE
2433
2434 iact=0
2435 IF(ncgb == 0) RETURN ! no constraints
2436
2437 DO iter=1,2
2438 vecconsresiduals=0.0_mpd
2439
2440 ! calculate right constraint equation discrepancies
2441 DO jcgb=1,ncgb
2442 icgb=matconssort(3,jcgb) ! unsorted constraint index
2443 i=vecconsstart(icgb)
2444 rhs=listconstraints(i )%value ! right hand side
2445 sgm=listconstraints(i+1)%value ! sigma parameter
2446 DO j=i+2,vecconsstart(icgb+1)-1
2447 label=listconstraints(j)%label
2448 factr=listconstraints(j)%value
2449 itgbi=inone(label) ! -> ITGBI= index of parameter label
2450 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2451 ENDDO
2452 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2453 END DO
2454
2455 ! constraint equation discrepancies -------------------------------
2456
2457 sum1=0.0_mpd
2458 sum2=0.0_mpd
2459 sum3=0.0_mpd
2460 DO icgb=1,ncgb
2461 sum1=sum1+vecconsresiduals(icgb)**2
2462 sum2=sum2+abs(vecconsresiduals(icgb))
2463 sum3=max(sum3,abs(vecconsresiduals(icgb)))
2464 END DO
2465 sum1=sqrt(sum1/real(ncgb,mpd))
2466 sum2=sum2/real(ncgb,mpd)
2467
2468 IF(iter == 1.AND.sum1 < concut) RETURN ! do nothing if correction small
2469
2470 IF(iter == 1.AND.ncgb <= 12) THEN
2471 WRITE(*,*) ' '
2472 WRITE(*,*) 'Constraint equation discrepancies:'
2473 WRITE(*,101) (icgb,vecconsresiduals(icgb),icgb=1,ncgb)
2474101 FORMAT(4x,4(i5,g12.4))
2475 WRITE(*,103) concut
2476103 FORMAT(10x,' Cut on rms value is',g8.1)
2477 END IF
2478
2479 IF(iact == 0) THEN
2480 WRITE(*,*) ' '
2481 WRITE(*,*) 'Improve constraints'
2482 END IF
2483 iact=1
2484
2485 WRITE(*,102) iter,sum1,sum2,sum3
2486102 FORMAT(i6,' rms',g12.4,' avrg_abs',g12.4,' max_abs',g12.4)
2487
2488 CALL mpalloc(veccorrections,int(nvgb,mpl),'constraint corrections')
2489 veccorrections=0.0_mpd
2490
2491 ! multiply (group-wise) inverse matrix and constraint vector
2492 isblck=0
2493 DO icgrp=1,ncgrp
2494 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2495 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2496 ncon=ilast+1-ifirst
2497 ieblck=isblck+(ncon*(ncon+1))/2
2498 CALL dbsvx(matconsproduct(isblck+1:ieblck),vecconsresiduals(ifirst:ilast),vecconssolution(ifirst:ilast),ncon)
2499 isblck=ieblck
2500 END DO
2501
2502 DO jcgb=1,ncgb
2503 icgb=matconssort(3,jcgb) ! unsorted constraint index
2504 i=vecconsstart(icgb)
2505 rhs=listconstraints(i )%value ! right hand side
2506 sgm=listconstraints(i+1)%value ! sigma parameter
2507 DO j=i+2,vecconsstart(icgb+1)-1
2508 label=listconstraints(j)%label
2509 factr=listconstraints(j)%value
2510 itgbi=inone(label) ! -> ITGBI= index of parameter label
2511 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2512 IF(ivgb > 0) THEN
2513 veccorrections(ivgb)=veccorrections(ivgb)+vecconssolution(jcgb)*factr
2514 END IF
2515 ENDDO
2516 END DO
2517
2518 DO i=1,nvgb ! add corrections
2519 itgbi=globalparvartototal(i)
2520 globalparameter(itgbi)=globalparameter(itgbi)+veccorrections(i)
2521 END DO
2522
2523 CALL mpdealloc(veccorrections)
2524
2525 END DO ! iteration 1 and 2
2526
2527END SUBROUTINE feasib ! make parameters feasible
2528
2561SUBROUTINE peread(more)
2562 USE mpmod
2563
2564 IMPLICIT NONE
2565 INTEGER(mpi) :: i
2566 INTEGER(mpi) :: iact
2567 INTEGER(mpi) :: ierrc
2568 INTEGER(mpi) :: ierrf
2569 INTEGER(mpi) :: ioffp
2570 INTEGER(mpi) :: ios
2571 INTEGER(mpi) :: ithr
2572 INTEGER(mpi) :: jfile
2573 INTEGER(mpi) :: jrec
2574 INTEGER(mpi) :: k
2575 INTEGER(mpi) :: kfile
2576 INTEGER(mpi) :: l
2577 INTEGER(mpi) :: lun
2578 INTEGER(mpi) :: mpri
2579 INTEGER(mpi) :: n
2580 INTEGER(mpi) :: nact
2581 INTEGER(mpi) :: nbuf
2582 INTEGER(mpi) :: ndata
2583 INTEGER(mpi) :: noff
2584 INTEGER(mpi) :: noffs
2585 INTEGER(mpi) :: npointer
2586 INTEGER(mpi) :: npri
2587 INTEGER(mpi) :: nr
2588 INTEGER(mpi) :: nrc
2589 INTEGER(mpi) :: nrd
2590 INTEGER(mpi) :: nrpr
2591 INTEGER(mpi) :: nthr
2592 INTEGER(mpi) :: ntot
2593 INTEGER(mpi) :: maxRecordSize
2594 INTEGER(mpi) :: maxRecordFile
2595
2596 INTEGER(mpi), INTENT(OUT) :: more
2597
2598 LOGICAL :: lprint
2599 LOGICAL :: floop
2600 LOGICAL :: eof
2601 REAL(mpd) :: ds0
2602 REAL(mpd) :: ds1
2603 REAL(mpd) :: ds2
2604 REAL(mpd) :: dw
2605 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
2606 CHARACTER (LEN=7) :: cfile
2607 SAVE
2608
2609#ifdef READ_C_FILES
2610 INTERFACE
2611 SUBROUTINE readc(bufferD, bufferF, bufferI, bufferLength, lun, err) BIND(c)
2612 USE iso_c_binding
2613 REAL(c_double), DIMENSION(*), INTENT(OUT) :: bufferD
2614 REAL(c_float), DIMENSION(*), INTENT(OUT) :: bufferF
2615 INTEGER(c_int), DIMENSION(*), INTENT(OUT) :: bufferI
2616 INTEGER(c_int), INTENT(INOUT) :: bufferLength
2617 INTEGER(c_int), INTENT(IN), VALUE :: lun
2618 INTEGER(c_int), INTENT(OUT) :: err
2619 END SUBROUTINE readc
2620 END INTERFACE
2621#endif
2622
2623 DATA lprint/.true./
2624 DATA floop/.true./
2625 DATA npri / 0 /, mpri / 1000 /
2626 ! ...
2627 IF(ifile == 0) THEN ! start/restart
2628 nrec=0
2629 nrecd=0
2630 ntot=0
2631 sumrecords=0
2633 numblocks=0
2636 readbufferinfo=0 ! reset management info
2637 nrpr=1
2638 nthr=mthrdr
2639 nact=0 ! active threads (have something still to read)
2640 DO k=1,nthr
2641 IF (ifile < nfilb) THEN
2642 ifile=ifile+1
2644 readbufferinfo(2,k)=nact
2645 nact=nact+1
2646 END IF
2647 END DO
2648 END IF
2649 npointer=size(readbufferpointer)/nact
2650 ndata=size(readbufferdatai)/nact
2651 more=-1
2652 DO k=1,nthr
2653 iact=readbufferinfo(2,k)
2654 readbufferinfo(4,k)=0 ! reset counter
2655 readbufferinfo(5,k)=iact*ndata ! reset offset
2656 END DO
2657 numblocks=numblocks+1 ! new block
2658
2659 !$OMP PARALLEL &
2660 !$OMP DEFAULT(PRIVATE) &
2661 !$OMP SHARED(readBufferInfo,readBufferPointer,readBufferDataI,readBufferDataD, &
2662 !$OMP readBufferDataF,nPointer,nData,skippedRecords,ndimbuf,NTHR,NFILF,FLOOP, &
2663 !$OMP IFD,KFD,IFILE,NFILB,WFD,XFD,icheck,keepOpen,ireeof,nrderr) &
2664 !$OMP NUM_THREADS(NTHR)
2665
2666 ithr=1
2667 !$ ITHR=OMP_GET_THREAD_NUM()+1 ! thread number
2668 jfile=readbufferinfo(1,ithr) ! file index
2669 iact =readbufferinfo(2,ithr) ! active thread number
2670 jrec =readbufferinfo(3,ithr) ! records read
2671 ioffp=iact*npointer
2672 noffs=(ithr-1)*ndimbuf ! offset for intermediate float buffer
2673
2674 files: DO WHILE (jfile > 0)
2675 kfile=kfd(2,jfile)
2676 ! open again
2677 IF (keepopen < 1 .AND. readbufferinfo(3,ithr) == 0) THEN
2678 CALL binopn(kfile,ithr,ios)
2679 END IF
2680 records: DO
2681 nbuf=readbufferinfo(4,ithr)+1
2682 noff=readbufferinfo(5,ithr)+2 ! 2 header words per record
2683 nr=ndimbuf
2684 IF(kfile <= nfilf) THEN ! Fortran file
2685 lun=kfile+10
2686 READ(lun,iostat=ierrf) n,(readbufferdataf(noffs+i),i=1,min(n/2,nr)),&
2687 (readbufferdatai(noff+i),i=1,min(n/2,nr))
2688 nr=n/2
2689 ! convert to double
2690 DO i=1,nr
2691 readbufferdatad(noff+i)=real(readbufferdataf(noffs+i),mpr8)
2692 END DO
2693 ! IF (ierrf < 0) REWIND lun ! end-of-file ! CHK use binrwd()
2694 eof=(ierrf /= 0)
2695 ELSE ! C file
2696 lun=kfile-nfilf
2697 IF (keepopen < 1) lun=ithr
2698#ifdef READ_C_FILES
2699 CALL readc(readbufferdatad(noff+1),readbufferdataf(noffs+1),readbufferdatai(noff+1),nr,lun,ierrc)
2700 n=nr+nr
2701 IF (ierrc > 4) readbufferinfo(6,ithr)=readbufferinfo(6,ithr)+1
2702#else
2703 ierrc=0
2704#endif
2705 eof=(ierrc <= 0.AND.ierrc /= -4) ! allow buffer overruns -> skip record
2706 IF(eof.AND.ierrc < 0) THEN
2707 WRITE(*,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2708 WRITE(8,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2709 IF (icheck <= 0 .AND. ireeof <=0) THEN ! stop unless 'checkinput' mode or 'readerroraseof'
2710 WRITE(cfile,'(I7)') kfile
2711 CALL peend(18,'Aborted, read error(s) for binary file ' // cfile)
2712 stop 'PEREAD: stopping due to read errors'
2713 END IF
2714 IF (kfd(1,jfile) == 1) THEN ! count files with read errors in first loop
2715 !$OMP ATOMIC
2716 nrderr=nrderr+1
2717 END IF
2718 END IF
2719 END IF
2720 IF(eof) EXIT records ! end-of-files or error
2721
2722 jrec=jrec+1
2723 readbufferinfo(3,ithr)=jrec
2724 IF(floop) THEN
2725 xfd(jfile)=max(xfd(jfile),n)
2726 IF(ithr == 1) THEN
2727 CALL hmplnt(1,n)
2728 IF(readbufferdatai(noff+1) /= 0) CALL hmpent(8,real(readbufferdatai(noff+1),mps))
2729 END IF
2730 END IF
2731
2732 IF (nr <= ndimbuf) THEN
2733 readbufferinfo(4,ithr)=nbuf
2734 readbufferinfo(5,ithr)=noff+nr
2735
2736 readbufferpointer(ioffp+nbuf)=noff ! pointer to start of buffer
2737 readbufferdatai(noff )=noff+nr ! pointer to end of buffer
2738 readbufferdatai(noff-1)=jrec ! local record number
2739 readbufferdatad(noff )=real(kfile,mpr8) ! file number
2740 readbufferdatad(noff-1)=real(wfd(kfile),mpr8) ! weight
2741
2742 IF ((noff+nr+2+ndimbuf >= ndata*(iact+1)).OR.(nbuf >= npointer)) EXIT files ! buffer full
2743 ELSE
2744 !$OMP ATOMIC
2746 cycle records
2747 END IF
2748
2749 END DO records
2750
2751 readbufferinfo(1,ithr)=-jfile ! flag eof
2752 IF (keepopen < 1) THEN ! close again
2753 CALL bincls(kfile,ithr)
2754 ELSE ! rewind
2755 CALL binrwd(kfile)
2756 END IF
2757 IF (kfd(1,jfile) == 1) THEN
2758 print *, 'PEREAD: file ', kfile, 'read the first time, found',jrec,' records'
2759 kfd(1,jfile)=-jrec
2760 ELSE
2761 !PRINT *, 'PEREAD: file ', kfile, 'records', jrec, -kfd(1,jfile)
2762 IF (-kfd(1,jfile) /= jrec) THEN
2763 WRITE(cfile,'(I7)') kfile
2764 CALL peend(19,'Aborted, binary file modified (length) ' // cfile)
2765 stop 'PEREAD: file modified (length)'
2766 END IF
2767 END IF
2768 ! take next file
2769 !$OMP CRITICAL
2770 IF (ifile < nfilb) THEN
2771 ifile=ifile+1
2772 jrec=0
2773 readbufferinfo(1,ithr)=ifile
2774 readbufferinfo(3,ithr)=jrec
2775 END IF
2776 !$OMP END CRITICAL
2777 jfile=readbufferinfo(1,ithr)
2778
2779 END DO files
2780 !$OMP END PARALLEL
2781 ! compress pointers
2782 nrd=readbufferinfo(4,1) ! buffers from 1 .thread
2783 DO k=2,nthr
2784 iact =readbufferinfo(2,k)
2785 ioffp=iact*npointer
2786 nbuf=readbufferinfo(4,k)
2787 DO l=1,nbuf
2788 readbufferpointer(nrd+l)=readbufferpointer(ioffp+l)
2789 END DO
2790 nrd=nrd+nbuf
2791 END DO
2792
2793 more=0
2794 DO k=1,nthr
2795 jfile=readbufferinfo(1,k)
2796 IF (jfile > 0) THEN ! no eof yet
2797 readbufferinfo(2,k)=more
2798 more=more+1
2799 ELSE
2800 ! no more files, thread retires
2801 readbufferinfo(1,k)=0
2802 readbufferinfo(2,k)=-1
2803 readbufferinfo(3,k)=0
2805 readbufferinfo(6,k)=0
2806 END IF
2807 END DO
2808 ! record limit ?
2809 IF (mxrec > 0.AND.(ntot+nrd) >= mxrec) THEN
2810 nrd=mxrec-ntot
2811 more=-1
2812 DO k=1,nthr
2813 jfile=readbufferinfo(1,k)
2814 IF (jfile > 0) THEN ! rewind or close files
2815 nrc=readbufferinfo(3,k)
2816 IF (kfd(1,jfile) == 1) kfd(1,jfile)=-nrc
2817 kfile=kfd(2,jfile)
2818 IF (keepopen < 1) THEN ! close again
2819 CALL bincls(kfile,k)
2820 ELSE ! rewind
2821 CALL binrwd(kfile)
2822 END IF
2823 END IF
2824 END DO
2825 END IF
2826
2827 ntot=ntot+nrd
2828 nrec=ntot
2829 numreadbuffer=nrd
2830
2834
2835 DO WHILE (nloopn == 0.AND.ntot >= nrpr)
2836 WRITE(*,*) ' Record ',nrpr
2837 IF (nrpr < 100000) THEN
2838 nrpr=nrpr*10
2839 ELSE
2840 nrpr=nrpr+100000
2841 END IF
2842 END DO
2843
2844 IF (ncache > 0.AND.nloopn <= 1.AND. npri < mpri.AND.mprint > 1) THEN
2845 npri=npri+1
2846 IF (npri == 1) WRITE(*,100)
2847 WRITE(*,101) nrec, nrd, more ,ifile
2848100 FORMAT(/' PeRead records active file' &
2849 /' total block threads number')
2850101 FORMAT(' PeRead',4i10)
2851 END IF
2852
2853 IF (more <= 0) THEN
2854 ifile=0
2855 IF (floop) THEN
2856 ! check for file weights
2857 ds0=0.0_mpd
2858 ds1=0.0_mpd
2859 ds2=0.0_mpd
2860 maxrecordsize=0
2861 maxrecordfile=0
2862 DO k=1,nfilb
2863 IF (xfd(k) > maxrecordsize) THEN
2864 maxrecordsize=xfd(k)
2865 maxrecordfile=k
2866 END IF
2867 dw=real(-kfd(1,k),mpd)
2868 IF (wfd(k) /= 1.0) nfilw=nfilw+1
2869 ds0=ds0+dw
2870 ds1=ds1+dw*real(wfd(k),mpd)
2871 ds2=ds2+dw*real(wfd(k)**2,mpd)
2872 END DO
2873 print *, 'PEREAD: file ', maxrecordfile, 'with max record size ', maxrecordsize
2874 IF (nfilw > 0.AND.ds0 > 0.0_mpd) THEN
2875 ds1=ds1/ds0
2876 ds2=ds2/ds0-ds1*ds1
2877 DO lun=6,lunlog,2
2878 WRITE(lun,177) nfilw,real(ds1,mps),real(ds2,mps)
2879177 FORMAT(/' !!!!!',i4,' weighted binary files', &
2880 /' !!!!! mean, variance of weights =',2g12.4)
2881 END DO
2882 END IF
2883 ! integrate record numbers
2884 DO k=2,nfilb
2885 ifd(k)=ifd(k-1)-kfd(1,k-1)
2886 END DO
2887 ! sort
2888 IF (nthr > 1) CALL sort2k(kfd,nfilb)
2889 IF (skippedrecords > 0) THEN
2890 print *, 'PEREAD skipped records: ', skippedrecords
2891 ndimbuf=maxrecordsize/2 ! adjust buffer size
2892 END IF
2893 END IF
2894 lprint=.false.
2895 floop=.false.
2896 IF (ncache > 0.AND.nloopn <= 1.AND.mprint > 0) &
2898179 FORMAT(/' Read cache usage (#blocks, #records, ', &
2899 'min,max records/block'/17x,i10,i12,2i10)
2900 END IF
2901 RETURN
2902
2903END SUBROUTINE peread
2904
2912SUBROUTINE peprep(mode)
2913 USE mpmod
2914
2915 IMPLICIT NONE
2916
2917 INTEGER(mpi), INTENT(IN) :: mode
2918
2919 INTEGER(mpi) :: ibuf
2920 INTEGER(mpi) :: ichunk
2921 INTEGER(mpi) :: ist
2922 INTEGER(mpi) :: itgbi
2923 INTEGER(mpi) :: j
2924 INTEGER(mpi) :: ja
2925 INTEGER(mpi) :: jb
2926 INTEGER(mpi) :: jsp
2927 INTEGER(mpi) :: nst
2928 INTEGER(mpi), PARAMETER :: maxbad = 100 ! max number of bad records with print out
2929 INTEGER(mpi) :: nbad
2930 INTEGER(mpi) :: nerr
2931 INTEGER(mpi) :: inone
2932
2933 IF (mode > 0) THEN
2934#ifdef __PGIC__
2935 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
2936 ichunk=256
2937#else
2938 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
2939#endif
2940 ! parallelize record loop
2941 !$OMP PARALLEL DO &
2942 !$OMP DEFAULT(PRIVATE) &
2943 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,ICHUNK,iscerr,dscerr) &
2944 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
2945 DO ibuf=1,numreadbuffer ! buffer for current record
2946 ist=readbufferpointer(ibuf)+1
2948 DO ! loop over measurements
2949 CALL isjajb(nst,ist,ja,jb,jsp)
2950 IF(jb == 0) EXIT
2951 DO j=1,ist-jb
2952 readbufferdatai(jb+j)=inone( readbufferdatai(jb+j) ) ! translate to index
2953 END DO
2954 ! scale error ?
2955 IF (iscerr > 0) THEN
2956 IF (jb < ist) THEN
2957 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(1) ! 'global' measurement
2958 ELSE
2959 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(2) ! 'local' measurement
2960 END IF
2961 END IF
2962 END DO
2963 END DO
2964 !$OMP END PARALLEL DO
2965 END IF
2966
2967 !$POMP INST BEGIN(peprep)
2968 IF (mode <= 0) THEN
2969 nbad=0
2970 DO ibuf=1,numreadbuffer ! buffer for current record
2971 CALL pechk(ibuf,nerr)
2972 IF(nerr > 0) THEN
2973 nbad=nbad+1
2974 IF(nbad >= maxbad) EXIT
2975 ELSE
2976 ist=readbufferpointer(ibuf)+1
2978 DO ! loop over measurements
2979 CALL isjajb(nst,ist,ja,jb,jsp)
2980 IF(jb == 0) EXIT
2981 neqn=neqn+1
2982 IF(jb == ist) cycle
2983 negb=negb+1
2984 ndgb=ndgb+(ist-jb)
2985 DO j=1,ist-jb
2986 itgbi=inone( readbufferdatai(jb+j) ) ! generate index
2987 END DO
2988 END DO
2989 END IF
2990 END DO
2991 IF(nbad > 0) THEN
2992 CALL peend(20,'Aborted, bad binary records')
2993 stop 'PEREAD: stopping due to bad records'
2994 END IF
2995 END IF
2996 !$POMP INST END(peprep)
2997
2998END SUBROUTINE peprep
2999
3007SUBROUTINE pechk(ibuf, nerr)
3008 USE mpmod
3009
3010 IMPLICIT NONE
3011 INTEGER(mpi) :: i
3012 INTEGER(mpi) :: is
3013 INTEGER(mpi) :: ist
3014 INTEGER(mpi) :: ioff
3015 INTEGER(mpi) :: ja
3016 INTEGER(mpi) :: jb
3017 INTEGER(mpi) :: jsp
3018 INTEGER(mpi) :: nan
3019 INTEGER(mpi) :: nst
3020
3021 INTEGER(mpi), INTENT(IN) :: ibuf
3022 INTEGER(mpi), INTENT(OUT) :: nerr
3023 SAVE
3024 ! ...
3025
3026 ist=readbufferpointer(ibuf)+1
3028 nerr=0
3029 is=ist
3030 jsp=0
3031 outer: DO WHILE(is < nst)
3032 ja=0
3033 jb=0
3034 inner1: DO
3035 is=is+1
3036 IF(is > nst) EXIT outer
3037 IF(readbufferdatai(is) == 0) EXIT inner1 ! found 1. marker
3038 END DO inner1
3039 ja=is
3040 inner2: DO
3041 is=is+1
3042 IF(is > nst) EXIT outer
3043 IF(readbufferdatai(is) == 0) EXIT inner2 ! found 2. marker
3044 END DO inner2
3045 jb=is
3046 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3047 ! special data
3048 jsp=jb ! pointer to special data
3049 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3050 cycle outer
3051 END IF
3052 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3053 is=is+1
3054 END DO
3055 END DO outer
3056 IF(is > nst) THEN
3057 ioff = readbufferpointer(ibuf)
3058 WRITE(*,100) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi)
3059100 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' is broken !!!')
3060 nerr=nerr+1
3061 ENDIF
3062 nan=0
3063 DO i=ist, nst
3064 IF(.NOT.(readbufferdatad(i) <= 0.0_mpr8).AND..NOT.(readbufferdatad(i) > 0.0_mpr8)) nan=nan+1
3065 END DO
3066 IF(nan > 0) THEN
3067 ioff = readbufferpointer(ibuf)
3068 WRITE(*,101) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi), nan
3069101 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' contains ', i6, ' NaNs !!!')
3070 nerr= nerr+2
3071 ENDIF
3072
3073END SUBROUTINE pechk
3074
3079SUBROUTINE pepgrp
3080 USE mpmod
3081 USE mpdalc
3082
3083 IMPLICIT NONE
3084
3085 INTEGER(mpi) :: ibuf
3086 INTEGER(mpi) :: ichunk
3087 INTEGER(mpi) :: iproc
3088 INTEGER(mpi) :: ioff
3089 INTEGER(mpi) :: ioffbi
3090 INTEGER(mpi) :: ist
3091 INTEGER(mpi) :: itgbi
3092 INTEGER(mpi) :: j
3093 INTEGER(mpi) :: ja
3094 INTEGER(mpi) :: jb
3095 INTEGER(mpi) :: jsp
3096 INTEGER(mpi) :: nalg
3097 INTEGER(mpi) :: neqna
3098 INTEGER(mpi) :: nnz
3099 INTEGER(mpi) :: nst
3100 INTEGER(mpi) :: nzero
3101 INTEGER(mpi) :: inone
3102 INTEGER(mpl) :: length
3103 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
3104
3105 CALL useone ! make (INONE) usable
3106 globalparheader(-2)=-1 ! set flag to inhibit further updates
3107 ! need back index
3108 IF (mcount > 0) THEN
3109 length=globalparheader(-1)*mthrd
3110 CALL mpalloc(backindexusage,length,'global variable-index array')
3112 END IF
3113 nzero=0
3114#ifdef __PGIC__
3115 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
3116 ichunk=256
3117#else
3118 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
3119#endif
3120 ! parallelize record loop
3121 !$OMP PARALLEL DO &
3122 !$OMP DEFAULT(PRIVATE) &
3123 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,backIndexUsage,globalParHeader,ICHUNK,MCOUNT) &
3124 !$OMP REDUCTION(+:NZERO) &
3125 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
3126 DO ibuf=1,numreadbuffer ! buffer for current record
3127 ist=readbufferpointer(ibuf)+1
3129 IF (mcount > 0) THEN
3130 ! count per record
3131 iproc=0
3132 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
3133 ioffbi=globalparheader(-1)*iproc
3134 nalg=0
3135 ioff=readbufferpointer(ibuf)
3136 DO ! loop over measurements
3137 CALL isjajb(nst,ist,ja,jb,jsp)
3138 IF(jb == 0) EXIT
3139 IF (ist > jb) THEN
3140 DO j=1,ist-jb
3141 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3142 nzero=nzero+1
3143 cycle ! skip 'zero global derivatives' for counting and grouping
3144 END IF
3145 itgbi=inone( readbufferdatai(jb+j) ) ! translate to index
3146 IF (backindexusage(ioffbi+itgbi) == 0) THEN
3147 nalg=nalg+1
3148 readbufferdatai(ioff+nalg)=itgbi
3149 backindexusage(ioffbi+itgbi)=nalg
3150 END IF
3151 END DO
3152 END IF
3153 END DO
3154 ! reset back index
3155 DO j=1,nalg
3156 itgbi=readbufferdatai(ioff+j)
3157 backindexusage(ioffbi+itgbi)=0
3158 END DO
3159 ! sort (record)
3160 CALL sort1k(readbufferdatai(ioff+1),nalg)
3161 readbufferdatai(ioff)=ioff+nalg
3162 ELSE
3163 ! count per equation
3164 nalg=1 ! reserve space for counter 'nnz'
3165 ioff=readbufferpointer(ibuf)
3166 neqna=0 ! number of accepted equations
3167 DO ! loop over measurements
3168 CALL isjajb(nst,ist,ja,jb,jsp)
3169 IF(jb == 0) EXIT
3170 IF (ist > jb) THEN
3171 nnz=0 ! number of non-zero derivatives
3172 DO j=1,ist-jb
3173 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3174 nzero=nzero+1
3175 cycle ! skip 'zero global derivatives' for counting and grouping
3176 END IF
3177 nnz=nnz+1
3178 readbufferdatai(ioff+nalg+nnz)=inone( readbufferdatai(jb+j) ) ! translate to index
3179 END DO
3180 IF (nnz == 0) cycle ! nothing for this equation
3181 readbufferdatai(ioff+nalg)=nnz
3182 ! sort (equation)
3183 CALL sort1k(readbufferdatai(ioff+nalg+1),nnz)
3184 nalg=nalg+nnz+1
3185 ! count (accepted) equations
3186 neqna=neqna+1
3187 END IF
3188 END DO
3189 readbufferdatai(ioff)=neqna
3190 END IF
3191 END DO
3192 !$OMP END PARALLEL DO
3193 nzgb=nzgb+nzero
3194
3195 !$POMP INST BEGIN(pepgrp)
3196 DO ibuf=1,numreadbuffer ! buffer for current record
3197 ist=readbufferpointer(ibuf)+1
3199 IF (mcount == 0) THEN
3200 ! equation level
3201 DO j=1,nst! loop over measurements
3202 nnz=readbufferdatai(ist)
3203 CALL pargrp(ist+1,ist+nnz)
3204 ist=ist+nnz+1
3205 END DO
3206 ELSE
3207 ! record level, group
3208 CALL pargrp(ist,nst)
3209 ENDIF
3210 END DO
3211 ! free back index
3212 IF (mcount > 0) THEN
3214 END IF
3215 !$POMP INST END(pepgrp)
3216 globalparheader(-2)=0 ! reset flag to reenable further updates
3217
3218END SUBROUTINE pepgrp
3219
3227SUBROUTINE pargrp(inds,inde)
3228 USE mpmod
3229
3230 IMPLICIT NONE
3231
3232 INTEGER(mpi) :: istart
3233 INTEGER(mpi) :: itgbi
3234 INTEGER(mpi) :: j
3235 INTEGER(mpi) :: jstart
3236 INTEGER(mpi) :: jtgbi
3237 INTEGER(mpi) :: lstart
3238 INTEGER(mpi) :: ltgbi
3239
3240 INTEGER(mpi), INTENT(IN) :: inds
3241 INTEGER(mpi), INTENT(IN) :: inde
3242
3243 IF (inds > inde) RETURN
3244
3245 ltgbi=-1
3246 lstart=-1
3247 ! build up groups
3248 DO j=inds,inde
3249 itgbi=readbufferdatai(j)
3250 globalparlabelcounter(itgbi)=globalparlabelcounter(itgbi)+1 ! count entries
3251 istart=globalparlabelindex(3,itgbi) ! label of group start
3252 IF (istart == 0) THEN ! not yet in group
3253 IF (itgbi /= ltgbi+1) THEN ! start group
3255 ELSE
3256 IF (lstart == 0) THEN ! extend group
3258 ELSE ! start group
3259 globalparlabelindex(3,itgbi)=globalparlabelindex(1,itgbi)
3260 END IF
3261 END IF
3262 END IF
3263 ltgbi=itgbi
3264 lstart=istart
3265 END DO
3266 ! split groups:
3267 ! - start inside group?
3268 itgbi=readbufferdatai(inds)
3269 istart=globalparlabelindex(3,itgbi) ! label of group start
3270 jstart=globalparlabelindex(1,itgbi) ! label of first parameter
3271 IF (istart /= jstart) THEN ! start new group
3272 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3273 globalparlabelindex(3,itgbi) = jstart
3274 itgbi=itgbi+1
3275 IF (itgbi > globalparheader(-1)) EXIT
3276 END DO
3277 END IF
3278 ! - not neigbours anymore
3279 ltgbi=readbufferdatai(inds)
3280 DO j=inds+1,inde
3281 itgbi=readbufferdatai(j)
3282 IF (itgbi /= ltgbi+1) THEN
3283 ! split after ltgbi
3284 lstart=globalparlabelindex(3,ltgbi) ! label of last group start
3285 jtgbi=ltgbi+1 ! new group after ltgbi
3286 jstart=globalparlabelindex(1,jtgbi)
3287 DO WHILE (globalparlabelindex(3,jtgbi) == lstart)
3288 globalparlabelindex(3,jtgbi) = jstart
3289 jtgbi=jtgbi+1
3290 IF (jtgbi > globalparheader(-1)) EXIT
3291 IF (jtgbi == itgbi) jstart=globalparlabelindex(1,jtgbi)
3292 END DO
3293 ! split at itgbi
3294 jtgbi=itgbi
3295 istart=globalparlabelindex(3,jtgbi) ! label of group start
3296 jstart=globalparlabelindex(1,jtgbi) ! label of first parameter
3297 IF (istart /= jstart) THEN ! start new group
3298 DO WHILE (globalparlabelindex(3,jtgbi) == istart)
3299 globalparlabelindex(3,jtgbi) = jstart
3300 jtgbi=jtgbi+1
3301 IF (jtgbi > globalparheader(-1)) EXIT
3302 END DO
3303 END IF
3304 ENDIF
3305 ltgbi=itgbi
3306 END DO
3307 ! - end inside group?
3308 itgbi=readbufferdatai(inde)
3309 IF (itgbi < globalparheader(-1)) THEN
3310 istart=globalparlabelindex(3,itgbi) ! label of group start
3311 itgbi=itgbi+1
3312 jstart=globalparlabelindex(1,itgbi) ! label of new group start
3313 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3314 globalparlabelindex(3,itgbi) = jstart
3315 itgbi=itgbi+1
3316 IF (itgbi > globalparheader(-1)) EXIT
3317 END DO
3318 END IF
3319
3320END SUBROUTINE pargrp
3321
3344SUBROUTINE isjajb(nst,is,ja,jb,jsp)
3345 USE mpmod
3346
3347 IMPLICIT NONE
3348
3349 INTEGER(mpi), INTENT(IN) :: nst
3350 INTEGER(mpi), INTENT(IN OUT) :: is
3351 INTEGER(mpi), INTENT(OUT) :: ja
3352 INTEGER(mpi), INTENT(OUT) :: jb
3353 INTEGER(mpi), INTENT(OUT) :: jsp
3354 SAVE
3355 ! ...
3356
3357 jsp=0
3358 DO
3359 ja=0
3360 jb=0
3361 IF(is >= nst) RETURN
3362 DO
3363 is=is+1
3364 IF(readbufferdatai(is) == 0) EXIT
3365 END DO
3366 ja=is
3367 DO
3368 is=is+1
3369 IF(readbufferdatai(is) == 0) EXIT
3370 END DO
3371 jb=is
3372 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3373 ! special data
3374 jsp=jb ! pointer to special data
3375 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3376 cycle
3377 END IF
3378 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3379 is=is+1
3380 END DO
3381 EXIT
3382 END DO
3383
3384END SUBROUTINE isjajb
3385
3386
3387!***********************************************************************
3388! LOOPN ...
3394
3395SUBROUTINE loopn
3396 USE mpmod
3397
3398 IMPLICIT NONE
3399 REAL(mpd) :: dsum
3400 REAL(mps) :: elmt
3401 REAL(mpd) :: factrj
3402 REAL(mpd) :: factrk
3403 REAL(mps) :: peakd
3404 REAL(mps) :: peaki
3405 REAL(mps) :: ratae
3406 REAL(mpd) :: rhs
3407 REAL(mps) :: rloop
3408 REAL(mpd) :: sgm
3409 REAL(mps) :: used
3410 REAL(mps) :: usei
3411 REAL(mpd) :: weight
3412 INTEGER(mpi) :: i
3413 INTEGER(mpi) :: ia
3414 INTEGER(mpi) :: ib
3415 INTEGER(mpi) :: ioffb
3416 INTEGER(mpi) :: ipr
3417 INTEGER(mpi) :: itgbi
3418 INTEGER(mpi) :: itgbij
3419 INTEGER(mpi) :: itgbik
3420 INTEGER(mpi) :: ivgb
3421 INTEGER(mpi) :: ivgbij
3422 INTEGER(mpi) :: ivgbik
3423 INTEGER(mpi) :: j
3424 INTEGER(mpi) :: k
3425 INTEGER(mpi) :: lastit
3426 INTEGER(mpi) :: lun
3427 INTEGER(mpi) :: ncrit
3428 INTEGER(mpi) :: ngras
3429 INTEGER(mpi) :: nparl
3430 INTEGER(mpi) :: nr
3431 INTEGER(mpl) :: nrej
3432 INTEGER(mpi) :: inone
3433 INTEGER(mpi) :: ilow
3434 INTEGER(mpi) :: nlow
3435 INTEGER(mpi) :: nzero
3436 LOGICAL :: btest
3437
3438 REAL(mpd):: adder
3439 REAL(mpd)::funref
3440 REAL(mpd)::matij
3441
3442 SAVE
3443 ! ...
3444
3445 ! ----- book and reset ---------------------------------------------
3446 IF(nloopn == 0) THEN ! first call
3447 lastit=-1
3448 iitera=0
3449 END IF
3450
3451 nloopn=nloopn+1 ! increase loop counter
3452 funref=0.0_mpd
3453
3454 IF(nloopn == 1) THEN ! book histograms for 1. iteration
3455 CALL gmpdef(1,4,'Function value in iterations')
3456 IF (metsol == 4 .OR. metsol == 5) THEN ! extend to GMRES, i.e. 6?
3457 CALL gmpdef(2,3,'Number of MINRES steps vs iteration nr')
3458 END IF
3459 CALL hmpdef( 5,0.0,0.0,'Number of degrees of freedom')
3460 CALL hmpdef(11,0.0,0.0,'Number of local parameters')
3461 CALL hmpdef(16,0.0,24.0,'LOG10(cond(band part decomp.)) local fit ')
3462 CALL hmpdef(23,0.0,0.0, 'SQRT of diagonal elements without presigma')
3463 CALL hmpdef(24,0.0,0.0, 'Log10 of off-diagonal elements')
3464 CALL hmpdef(25,0.0,0.0, 'Relative individual pre-sigma')
3465 CALL hmpdef(26,0.0,0.0, 'Relative global pre-sigma')
3466 END IF
3467
3468
3469 CALL hmpdef(3,-prange,prange, & ! book
3470 'Normalized residuals of single (global) measurement')
3471 CALL hmpdef(12,-prange,prange, & ! book
3472 'Normalized residuals of single (local) measurement')
3473 CALL hmpdef(13,-prange,prange, & ! book
3474 'Pulls of single (global) measurement')
3475 CALL hmpdef(14,-prange,prange, & ! book
3476 'Pulls of single (local) measurement')
3477 CALL hmpdef(4,0.0,0.0,'Chi^2/Ndf after local fit')
3478 CALL gmpdef(4,5,'location, dispersion (res.) vs record nr')
3479 CALL gmpdef(5,5,'location, dispersion (pull) vs record nr')
3480
3481 ! WRITE(*,*) 'LOOPN ', NLOOPN, ' executing ICALCM=', ICALCM
3482
3483 ! reset
3484
3485 globalvector=0.0_mpd ! reset rhs vector IGVEC
3487 IF(icalcm == 1) THEN
3488 globalmatd=0.0_mpd
3489 globalmatf=0.
3490 IF (metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) matprecond=0.0_mpd
3491 END IF
3492
3493 IF(nloopn == 2) CALL hmpdef(6,0.0,0.0,'Down-weight fraction')
3494
3495 newite=.false.
3496 IF(iterat /= lastit) THEN ! new iteration
3497 newite=.true.
3498 funref=fvalue
3499 IF(nloopn > 1) THEN
3500 nrej=sum(nrejec)
3501 ! CALL MEND
3502 IF(iterat == 1) THEN
3504 ELSE IF(iterat >= 1) THEN
3505 chicut=sqrt(chicut)
3506 IF(chicut /= 0.0.AND.chicut < 1.5) chicut=1.0
3507 IF(chicut /= 0.0.AND.nrej == 0) chicut=1.0
3508 END IF
3509 END IF
3510 ! WRITE(*,111) ! header line
3511 END IF
3512
3513 nrejec=0 ! reset reject counter
3514 DO k=3,6
3515 writebufferheader(k)=0 ! cache usage
3516 writebufferheader(-k)=0
3517 END DO
3518 ! statistics per binary file
3519 DO i=1,nfilb
3520 jfd(i)=0
3521 cfd(i)=0.0
3522 dfd(i)=0
3523 END DO
3524
3525 IF (imonit /= 0) meashists=0 ! reset monitoring histograms
3526
3527 ! ----- read next data ----------------------------------------------
3528 DO
3529 CALL peread(nr) ! read records
3530 CALL peprep(1) ! prepare records
3532 IF (nr <= 0) EXIT ! next block of events ?
3533 END DO
3534 ! sum up RHS (over threads) once (reduction in LOOPBF: summation for each block)
3535 ioffb=0
3536 DO ipr=2,mthrd
3537 ioffb=ioffb+lenglobalvec
3538 DO k=1,lenglobalvec
3541 END DO
3542 END DO
3543
3544 IF (icalcm == 1) THEN
3545 ! PRINT *, ' cache/w ',(writeBufferHeader(-K),K=3,6),(writeBufferHeader(K),K=3,6)
3546 nparl=writebufferheader(3)
3547 ncrit=writebufferheader(4)
3548 used=real(writebufferheader(-5),mps)/real(writebufferheader(-3),mps)*0.1
3549 usei=real(writebufferheader(5),mps)/real(writebufferheader(3),mps)*0.1
3550 peakd=real(writebufferheader(-6),mps)*0.1
3551 peaki=real(writebufferheader(6),mps)*0.1
3552 WRITE(*,111) nparl,ncrit,usei,used,peaki,peakd
3553111 FORMAT(' Write cache usage (#flush,#overrun,<levels>,', &
3554 'peak(levels))'/2i7,',',4(f6.1,'%'))
3555 ! fill part of MINRES preconditioner matrix from binary files (formerly in mgupdt)
3556 IF (metsol >= 4.AND.metsol < 7) THEN
3557 IF (mbandw == 0) THEN
3558 ! default preconditioner (diagonal)
3559 DO i=1, nvgb
3560 matprecond(i)=matij(i,i)
3561 END DO
3562 ELSE IF (mbandw > 0) THEN
3563 ! band matrix
3564 DO i=1, nvgb
3565 ia=indprecond(i) ! index of diagonal element
3566 DO j=max(1,i-mbandw+1),i
3567 matprecond(ia-i+j)=matij(i,j)
3568 END DO
3569 END DO
3570 END IF
3571 END IF
3572 IF (ichkpg > 0) THEN
3573 ! check parameter groups
3574 CALL ckpgrp
3575 END IF
3576 END IF
3577
3578 ! check entries/counters
3579 nlow=0
3580 ilow=1
3581 nzero=0
3582 DO i=1,nvgb
3583 IF(globalcounter(i) == 0) nzero=nzero+1
3584 IF(globalcounter(i) < mreqena) THEN
3585 nlow=nlow+1
3586 IF(globalcounter(i) < globalcounter(ilow)) ilow=i
3587 END IF
3588 END DO
3589 IF(nlow > 0) THEN
3590 nalow=nalow+nlow
3591 IF(icalcm == 1) nxlow=max(nxlow,nlow) ! for matrix construction ?
3592 itgbi=globalparvartototal(ilow)
3593 print *
3594 print *, " ... warning ..."
3595 print *, " global parameters with too few (< MREQENA) accepted entries: ", nlow
3596 print *, " minimum entries: ", globalcounter(ilow), " for label ", globalparlabelindex(1,itgbi)
3597 print *
3598 END IF
3599 IF(icalcm == 1 .AND. nzero > 0) THEN
3600 ndefec = nzero ! rank defect
3601 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfgb, &
3602 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3603 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfgb, &
3604 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3605 IF (iforce == 0) THEN
3606 isubit=1
3607 WRITE(*,*) ' --> enforcing SUBITO mode'
3608 WRITE(lun,*) ' --> enforcing SUBITO mode'
3609 END IF
3610 END IF
3611
3612 ! ----- after end-of-data add contributions from pre-sigma ---------
3613
3614 IF(nloopn == 1) THEN
3615 ! plot diagonal elements
3616 elmt=0.0
3617 DO i=1,nvgb ! diagonal elements
3618 elmt=real(matij(i,i),mps)
3619 IF(elmt > 0.0) CALL hmpent(23,1.0/sqrt(elmt))
3620 END DO
3621 END IF
3622
3623
3624
3625 ! add pre-sigma contributions to matrix diagonal
3626
3627 ! WRITE(*,*) 'Adding to diagonal ICALCM IND6',ICALCM,IND6
3628
3629 IF(icalcm == 1) THEN
3630 DO ivgb=1,nvgb ! add evtl. pre-sigma
3631 ! WRITE(*,*) 'Index ',IVGB,IVGB,QM(IND6+IVGB)
3632 IF(globalparpreweight(ivgb) /= 0.0) THEN
3633 IF(ivgb > 0) CALL mupdat(ivgb,ivgb,globalparpreweight(ivgb))
3634 END IF
3635 END DO
3636 END IF
3637
3638 CALL hmpwrt(23)
3639 CALL hmpwrt(24)
3640 CALL hmpwrt(25)
3641 CALL hmpwrt(26)
3642
3643
3644 ! add regularization term to F and to rhs --------------------------
3645
3646 ! WRITE(*,*) 'NREGUL ',NREGUL,NLOOPN
3647
3648 IF(nregul /= 0) THEN ! add regularization term to F and to rhs
3649 DO ivgb=1,nvgb
3650 itgbi=globalparvartototal(ivgb) ! global parameter index
3652 adder=globalparpreweight(ivgb)*globalparameter(itgbi)**2
3653 CALL addsums(1, adder, 0, 1.0_mpl)
3654 END DO
3655 END IF
3656
3657
3658 ! ----- add contributions from "measurement" -----------------------
3659
3660
3661 i=1
3662 DO WHILE (i <= lenmeasurements)
3663 rhs=listmeasurements(i )%value ! right hand side
3664 sgm=listmeasurements(i+1)%value ! sigma parameter
3665 i=i+2
3666 weight=0.0
3667 IF(sgm > 0.0) weight=1.0/sgm**2
3668
3669 dsum=-rhs
3670
3671 ! loop over label/factor pairs
3672 ia=i
3673 DO
3674 i=i+1
3675 IF(i > lenmeasurements) EXIT
3676 IF(listmeasurements(i)%label < 0) EXIT
3677 END DO
3678 ib=i-1
3679
3680 DO j=ia,ib
3681 factrj=listmeasurements(j)%value
3682 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3683 IF(itgbij /= 0) THEN
3684 dsum=dsum+factrj*globalparameter(itgbij) ! update residuum
3685 END IF
3686 END DO
3687 DO j=ia,ib
3688 factrj=listmeasurements(j)%value
3689 IF (factrj == 0.0_mpd) cycle ! skip zero factors
3690 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3691 ! add to vector
3692 ivgbij=0
3693 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
3694 IF(ivgbij > 0) THEN
3695 globalvector(ivgbij)=globalvector(ivgbij) -weight*dsum*factrj ! vector
3696 globalcounter(ivgbij)=globalcounter(ivgbij)+1
3697 END IF
3698
3699 IF(icalcm == 1.AND.ivgbij > 0) THEN
3700 DO k=ia,j
3701 factrk=listmeasurements(k)%value
3702 itgbik=inone(listmeasurements(k)%label) ! total parameter index
3703 ! add to matrix
3704 ivgbik=0
3705 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
3706 IF(ivgbij > 0.AND.ivgbik > 0) THEN !
3707 CALL mupdat(ivgbij,ivgbik,weight*factrj*factrk)
3708 END IF
3709 END DO
3710 END IF
3711 END DO
3712
3713 adder=weight*dsum**2
3714 CALL addsums(1, adder, 1, 1.0_mpl)
3715
3716 END DO
3717
3718 ! ----- printout ---------------------------------------------------
3719
3720
3721 ! get accurate sum (Chi^2, (w)NDF)
3723
3724 flines=0.5_mpd*fvalue ! Likelihood function value
3725 rloop=iterat+0.01*nloopn
3726 actfun=real(funref-fvalue,mps)
3727 IF(nloopn == 1) actfun=0.0
3728 ngras=nint(angras,mpi)
3729 ratae=0.0 !!!
3730 IF(delfun /= 0.0) THEN
3731 ratae=min(99.9,actfun/delfun) !!!
3732 ratae=max(-99.9,ratae)
3733 END IF
3734
3735 ! rejects ...
3736
3737 nrej =sum(nrejec)
3738 IF(nloopn == 1) THEN
3739 IF(nrej /= 0) THEN
3740 WRITE(*,*) ' '
3741 WRITE(*,*) 'Data records rejected in initial loop:'
3742 CALL prtrej(6)
3743 END IF
3744 END IF
3745
3746 IF(newite.AND.iterat == 2) THEN
3747 IF(nrecpr /= 0.OR.nrecp2 /= 0) nrecer=nrec3
3748 IF(nrecpr < 0) THEN
3750 END IF
3751 IF(nrecp2 < 0) THEN
3753 END IF
3754 END IF
3755
3756 IF(nloopn <= 2) THEN
3757 IF(nhistp /= 0) THEN
3758 ! CALL HMPRNT(3) ! scaled residual of single measurement
3759 ! CALL HMPRNT(12) ! scaled residual of single measurement
3760 ! CALL HMPRNT(4) ! chi^2/Ndf
3761 END IF
3762 CALL hmpwrt(3)
3763 CALL hmpwrt(12)
3764 CALL hmpwrt(4)
3765 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
3766 IF (nloopn <= lfitnp) THEN
3767 CALL hmpwrt(13)
3768 CALL hmpwrt(14)
3769 CALL gmpwrt(5) ! location, dispersion (pull) as a function of record nr
3770 END IF
3771 END IF
3772 ! IF(NLOOPN.EQ.2.AND.NHISTP.NE.0) CALL HMPRNT(6)
3773 IF(nloopn == 2) CALL hmpwrt(6)
3774 IF(nloopn <= 1) THEN
3775 ! IF(NHISTP.NE.0) CALL HMPRNT(5) ! number of degrees of freedom
3776 ! IF(NHISTP.NE.0) CALL HMPRNT(11) ! Nlocal
3777 CALL hmpwrt(5)
3778 CALL hmpwrt(11)
3779 CALL hmpwrt(16)
3780 END IF
3781
3782 ! local fit: band matrix structure !?
3783 IF (nloopn == 1.AND.nbndr(1)+nbndr(2) > 0) THEN
3784 DO lun=6,8,2
3785 WRITE(lun,*) ' '
3786 WRITE(lun,*) ' === local fits have bordered band matrix structure ==='
3787 IF (nbndr(1) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(1),'number of records (upper/left border)'
3788 IF (nbndr(2) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(2),'number of records (lower/right border)'
3789 WRITE(lun,101) ' NBDRX',nbdrx,'max border size'
3790 WRITE(lun,101) ' NBNDX',nbndx,'max band width'
3791 END DO
3792 END IF
3793
3794 lastit=iterat
3795
3796 ! monitoring of residuals
3797 IF (imonit < 0 .OR. (nloopn == 1 .AND. btest(imonit,0))) CALL monres
3798
3799101 FORMAT(1x,a8,' =',i14,' = ',a)
3800! 101 FORMAT(' LOOPN',I6,' Function value',F22.8,10X,I6,' records')
3801! 102 FORMAT(' incl. constraint penalty',F22.8)
3802! 103 FORMAT(I13,3X,A,G12.4)
3803END SUBROUTINE loopn ! loop with fits
3804
3808
3809SUBROUTINE ploopa(lunp)
3810 USE mpmod
3811
3812 IMPLICIT NONE
3813
3814 INTEGER(mpi), INTENT(IN) :: lunp
3815 ! ..
3816 WRITE(lunp,*) ' '
3817 WRITE(lunp,101) ! header line
3818 WRITE(lunp,102) ! header line
3819101 FORMAT(' it fc',' fcn_value dfcn_exp slpr costh iit st', &
3820 ' ls step cutf',1x,'rejects hhmmss FMS')
3821102 FORMAT(' -- --',' ----------- -------- ---- ----- --- --', &
3822 ' -- ----- ----',1x,'------- ------ ---')
3823 RETURN
3824END SUBROUTINE ploopa ! title for iteration
3825
3829
3830SUBROUTINE ploopb(lunp)
3831 USE mpmod
3832
3833 IMPLICIT NONE
3834 INTEGER(mpi) :: ma
3835 INTEGER :: minut
3836 INTEGER(mpi) :: nfa
3837 INTEGER :: nhour
3838 INTEGER(mpl) :: nrej
3839 INTEGER(mpi) :: nsecnd
3840 REAL(mps) :: ratae
3841 REAL :: rstb
3842 REAL(mps) :: secnd
3843 REAL(mps) :: slopes(3)
3844 REAL(mps) :: steps(3)
3845 REAL, DIMENSION(2) :: ta
3846 REAl etime
3847
3848 INTEGER(mpi), INTENT(IN) :: lunp
3849
3850 CHARACTER (LEN=4):: ccalcm(4)
3851 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3852 SAVE
3853
3854 nrej=sum(nrejec) ! rejects
3855 IF(nrej > 9999999) nrej=9999999
3856 rstb=etime(ta)
3857 deltim=rstb-rstart
3858 CALL sechms(deltim,nhour,minut,secnd) ! time
3859 nsecnd=nint(secnd,mpi)
3860 IF(iterat == 0) THEN
3861 WRITE(lunp,103) iterat,nloopn,fvalue, &
3862 chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3863 ELSE
3864 IF (lsinfo == 10) THEN ! line search skipped
3865 WRITE(lunp,105) iterat,nloopn,fvalue,delfun, &
3866 iitera,istopa,chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3867 ELSE
3868 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3869 ratae=max(-99.9,min(99.9,slopes(2)/slopes(1)))
3870 stepl=steps(2)
3871 WRITE(lunp,104) iterat,nloopn,fvalue,delfun,ratae,angras, &
3872 iitera,istopa,lsinfo,stepl, chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3873 ENDIF
3874 END IF
3875103 FORMAT(i3,i3,e12.5,38x,f5.1, 1x,i7, i3,i2.2,i2.2,a4)
3876104 FORMAT(i3,i3,e12.5,1x,e8.2,f6.3,f6.3,i5,2i3,f6.3,f5.1, &
3877 1x,i7, i3,i2.2,i2.2,a4)
3878105 FORMAT(i3,i3,e12.5,1x,e8.2,12x,i5,i3,9x,f5.1, &
3879 1x,i7, i3,i2.2,i2.2,a4)
3880 RETURN
3881END SUBROUTINE ploopb ! iteration line
3882
3886
3887SUBROUTINE ploopc(lunp)
3888 USE mpmod
3889
3890 IMPLICIT NONE
3891 INTEGER(mpi) :: ma
3892 INTEGER(mpi) :: minut
3893 INTEGER(mpi) :: nfa
3894 INTEGER(mpi) :: nhour
3895 INTEGER(mpl) :: nrej
3896 INTEGER(mpi) :: nsecnd
3897 REAL(mps) :: ratae
3898 REAL :: rstb
3899 REAL(mps) :: secnd
3900 REAL(mps) :: slopes(3)
3901 REAL(mps) :: steps(3)
3902 REAL, DIMENSION(2) :: ta
3903 REAL etime
3904
3905 INTEGER(mpi), INTENT(IN) :: lunp
3906 CHARACTER (LEN=4):: ccalcm(4)
3907 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3908 SAVE
3909
3910 nrej=sum(nrejec) ! rejects
3911 IF(nrej > 9999999) nrej=9999999
3912 rstb=etime(ta)
3913 deltim=rstb-rstart
3914 CALL sechms(deltim,nhour,minut,secnd) ! time
3915 nsecnd=nint(secnd,mpi)
3916 IF (lsinfo == 10) THEN ! line search skipped
3917 WRITE(lunp,104) nloopn,fvalue,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3918 ELSE
3919 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3920 ratae=abs(slopes(2)/slopes(1))
3921 stepl=steps(2)
3922 WRITE(lunp,105) nloopn,fvalue, ratae,lsinfo, &
3923 stepl,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3924 END IF
3925104 FORMAT(3x,i3,e12.5,9x, 35x, i7, i3,i2.2,i2.2,a4)
3926105 FORMAT(3x,i3,e12.5,9x, f6.3,14x,i3,f6.3,6x, i7, i3,i2.2,i2.2,a4)
3927 RETURN
3928
3929END SUBROUTINE ploopc ! sub-iteration line
3930
3934
3935SUBROUTINE ploopd(lunp)
3936 USE mpmod
3937 IMPLICIT NONE
3938 INTEGER :: minut
3939 INTEGER :: nhour
3940 INTEGER(mpi) :: nsecnd
3941 REAL :: rstb
3942 REAL(mps) :: secnd
3943 REAL, DIMENSION(2) :: ta
3944 REAL etime
3945
3946 INTEGER(mpi), INTENT(IN) :: lunp
3947 CHARACTER (LEN=4):: ccalcm(4)
3948 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3949 SAVE
3950 rstb=etime(ta)
3951 deltim=rstb-rstart
3952 CALL sechms(deltim,nhour,minut,secnd) ! time
3953 nsecnd=nint(secnd,mpi)
3954
3955 WRITE(lunp,106) nhour,minut,nsecnd,ccalcm(lcalcm)
3956106 FORMAT(69x,i3,i2.2,i2.2,a4)
3957 RETURN
3958END SUBROUTINE ploopd
3959
3961SUBROUTINE explfc(lunit)
3962 USE mpdef
3963 USE mpmod, ONLY: metsol
3964
3965 IMPLICIT NONE
3966 INTEGER(mpi) :: lunit
3967 WRITE(lunit,*) ' '
3968 WRITE(lunit,102) 'Explanation of iteration table'
3969 WRITE(lunit,102) '=============================='
3970 WRITE(lunit,101) 'it', &
3971 'iteration number. Global parameters are improved for it > 0.'
3972 WRITE(lunit,102) 'First function evaluation is called iteraton 0.'
3973 WRITE(lunit,101) 'fc', 'number of function evaluations.'
3974 WRITE(lunit,101) 'fcn_value', 'value of 2 x Likelihood function (LF).'
3975 WRITE(lunit,102) 'The final value is the chi^2 value of the fit and should'
3976 WRITE(lunit,102) 'be about equal to the NDF (see below).'
3977 WRITE(lunit,101) 'dfcn_exp', &
3978 'expected reduction of the value of the Likelihood function (LF)'
3979 WRITE(lunit,101) 'slpr', 'ratio of the actual slope to inital slope.'
3980 WRITE(lunit,101) 'costh', &
3981 'cosine of angle between search direction and -gradient'
3982 IF (metsol == 4) THEN
3983 WRITE(lunit,101) 'iit', &
3984 'number of internal iterations in MINRES algorithm'
3985 WRITE(lunit,101) 'st', 'stop code of MINRES algorithm'
3986 WRITE(lunit,102) '< 0: rhs is very special, with beta2 = 0'
3987 WRITE(lunit,102) '= 0: rhs b = 0, i.e. the exact solution is x = 0'
3988 WRITE(lunit,102) '= 1 requested accuracy achieved, as determined by rtol'
3989 WRITE(lunit,102) '= 2 reasonable accuracy achieved, given eps'
3990 WRITE(lunit,102) '= 3 x has converged to an eigenvector'
3991 WRITE(lunit,102) '= 4 matrix ill-conditioned (Acond has exceeded 0.1/eps)'
3992 WRITE(lunit,102) '= 5 the iteration limit was reached'
3993 WRITE(lunit,102) '= 6 Matrix x vector does not define a symmetric matrix'
3994 WRITE(lunit,102) '= 7 Preconditioner does not define a symmetric matrix'
3995 ELSEIF (metsol == 5) THEN
3996 WRITE(lunit,101) 'iit', &
3997 'number of internal iterations in MINRES-QLP algorithm'
3998 WRITE(lunit,101) 'st', 'stop code of MINRES-QLP algorithm'
3999 WRITE(lunit,102) '= 1: beta_{k+1} < eps, iteration k is the final Lanczos step.'
4000 WRITE(lunit,102) '= 2: beta2 = 0. If M = I, b and x are eigenvectors of A.'
4001 WRITE(lunit,102) '= 3: beta1 = 0. The exact solution is x = 0.'
4002 WRITE(lunit,102) '= 4: A solution to (poss. singular) Ax = b found, given rtol.'
4003 WRITE(lunit,102) '= 5: A solution to (poss. singular) Ax = b found, given eps.'
4004 WRITE(lunit,102) '= 6: Pseudoinverse solution for singular LS problem, given rtol.'
4005 WRITE(lunit,102) '= 7: Pseudoinverse solution for singular LS problem, given eps.'
4006 WRITE(lunit,102) '= 8: The iteration limit was reached.'
4007 WRITE(lunit,102) '= 9: The operator defined by Aprod appears to be unsymmetric.'
4008 WRITE(lunit,102) '=10: The operator defined by Msolve appears to be unsymmetric.'
4009 WRITE(lunit,102) '=11: The operator defined by Msolve appears to be indefinite.'
4010 WRITE(lunit,102) '=12: xnorm has exceeded maxxnorm or will exceed it next iteration.'
4011 WRITE(lunit,102) '=13: Acond has exceeded Acondlim or 0.1/eps.'
4012 WRITE(lunit,102) '=14: Least-squares problem but no converged solution yet.'
4013 WRITE(lunit,102) '=15: A null vector obtained, given rtol.'
4014 ENDIF
4015 WRITE(lunit,101) 'ls', 'line search info'
4016 WRITE(lunit,102) '< 0 recalculate function'
4017 WRITE(lunit,102) '= 0: N or STP lt 0 or step not descending'
4018 WRITE(lunit,102) '= 1: Linesearch convergence conditions reached'
4019 WRITE(lunit,102) '= 2: interval of uncertainty at lower limit'
4020 WRITE(lunit,102) '= 3: max nr of line search calls reached'
4021 WRITE(lunit,102) '= 4: step at the lower bound'
4022 WRITE(lunit,102) '= 5: step at the upper bound'
4023 WRITE(lunit,102) '= 6: rounding error limitation'
4024 WRITE(lunit,101) 'step', &
4025 'the factor for the Newton step during the line search. Usually'
4026 WRITE(lunit,102) &
4027 'a value of 1 gives a sufficient reduction of the LF. Oherwise'
4028 WRITE(lunit,102) 'other step values are tried.'
4029 WRITE(lunit,101) 'cutf', &
4030 'cut factor. Local fits are rejected, if their chi^2 value'
4031 WRITE(lunit,102) &
4032 'is larger than the 3-sigma chi^2 value times the cut factor.'
4033 WRITE(lunit,102) 'A cut factor of 1 is used finally, but initially a larger'
4034 WRITE(lunit,102) 'factor may be used. A value of 0.0 means no cut.'
4035 WRITE(lunit,101) 'rejects', 'total number of rejected local fits.'
4036 WRITE(lunit,101) 'hmmsec', 'the time in hours (h), minutes (mm) and seconds.'
4037 WRITE(lunit,101) 'FMS', 'calculation of Function value, Matrix, Solution.'
4038 WRITE(lunit,*) ' '
4039
4040101 FORMAT(a9,' = ',a)
4041102 FORMAT(13x,a)
4042END SUBROUTINE explfc
4043
4051
4052SUBROUTINE mupdat(i,j,add) !
4053 USE mpmod
4054
4055 IMPLICIT NONE
4056
4057 INTEGER(mpi), INTENT(IN) :: i
4058 INTEGER(mpi), INTENT(IN) :: j
4059 REAL(mpd), INTENT(IN) :: add
4060
4061 INTEGER(mpl):: ijadd
4062 INTEGER(mpl):: ijcsr3
4063 INTEGER(mpl):: ia
4064 INTEGER(mpl):: ja
4065 INTEGER(mpl):: ij
4066 ! ...
4067 IF(i <= 0.OR.j <= 0.OR. add == 0.0_mpd) RETURN
4068 ia=max(i,j) ! larger
4069 ja=min(i,j) ! smaller
4070 ij=0
4071 IF(matsto == 3) THEN
4072 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
4073 ij=ijcsr3(i,j) ! inline code requires same time
4074 IF (ij > 0) globalmatd(ij)=globalmatd(ij)+add
4075 RETURN
4076 ELSE ! sparse symmetric matrix (BSR3)
4077 ! block index
4078 ij=ijcsr3((i-1)/matbsz+1,(j-1)/matbsz+1)
4079 IF (ij > 0) THEN
4080 ! index of first element in block
4081 ij=(ij-1)*matbsz*matbsz+1
4082 ! adjust index for position in block
4083 ij=ij+mod(int(ia-1,mpi),matbsz)*matbsz+mod(int(ja-1,mpi),matbsz)
4084 globalmatd(ij)=globalmatd(ij)+add
4085 ENDIF
4086 RETURN
4087 END IF
4088 ELSE IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4089 ij=ijadd(i,j) ! inline code requires same time
4090 IF (ij == 0) RETURN ! pair is suppressed
4091 IF (ij > 0) THEN
4092 globalmatd(ij)=globalmatd(ij)+add
4093 ELSE
4094 globalmatf(-ij)=globalmatf(-ij)+real(add,mps)
4095 END IF
4096 ELSE ! full or unpacked (block diagonal) symmetric matrix
4097 ! global (ia,ib) to local (row,col) in block
4098 ij=globalrowoffsets(ia)+ja
4099 globalmatd(ij)=globalmatd(ij)+add
4100 END IF
4101 ! MINRES preconditioner
4102 IF(metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) THEN
4103 ij=0 ! no update
4104 IF(ia <= nvgb) THEN ! variable global parameter
4105 IF(mbandw > 0) THEN ! band matrix for Cholesky decomposition
4106 ij=indprecond(ia)-ia+ja
4107 IF(ia > 1.AND.ij <= indprecond(ia-1)) ij=0
4108 ELSE ! default preconditioner (diagonal)
4109 IF(ja == ia) ij=ia
4110 END IF
4111 ELSE ! Lagrange multiplier
4112 ij=offprecond(ia-nvgb)+ja
4113 END IF
4114 ! bad index?
4115 IF(ij < 0.OR.ij > size(matprecond)) THEN
4116 CALL peend(23,'Aborted, bad matrix index')
4117 stop 'mupdat: bad index'
4118 END IF
4119 ! update?
4120 IF(ij /= 0) matprecond(ij)=matprecond(ij)+add
4121 END IF
4122END SUBROUTINE mupdat
4123
4124
4136
4137SUBROUTINE mgupdt(i,j1,j2,il,jl,n,sub)
4138 USE mpmod
4139
4140 IMPLICIT NONE
4141
4142 INTEGER(mpi), INTENT(IN) :: i
4143 INTEGER(mpi), INTENT(IN) :: j1
4144 INTEGER(mpi), INTENT(IN) :: j2
4145 INTEGER(mpi), INTENT(IN) :: il
4146 INTEGER(mpi), INTENT(IN) :: jl
4147 INTEGER(mpi), INTENT(IN) :: n
4148 REAL(mpd), INTENT(IN) :: sub((n*n+n)/2)
4149
4150 INTEGER(mpl):: ij
4151 INTEGER(mpl):: ioff
4152 INTEGER(mpi):: ia
4153 INTEGER(mpi):: ia1
4154 INTEGER(mpi):: ib
4155 INTEGER(mpi):: iblast
4156 INTEGER(mpi):: iblock
4157 INTEGER(mpi):: ijl
4158 INTEGER(mpi):: iprc
4159 INTEGER(mpi):: ir
4160 INTEGER(mpi):: ja
4161 INTEGER(mpi):: jb
4162 INTEGER(mpi):: jblast
4163 INTEGER(mpi):: jblock
4164 INTEGER(mpi):: jc
4165 INTEGER(mpi):: jc1
4166 INTEGER(mpi):: jpg
4167 INTEGER(mpi):: k
4168 INTEGER(mpi):: lr
4169 INTEGER(mpi):: nc
4170
4171 INTEGER(mpl) ijcsr3
4172 ! ...
4173 IF(i <= 0.OR.j1 <= 0.OR.j2 > i) RETURN
4174
4175 IF(matsto == 3) THEN ! sparse symmetric matrix (CSR3, upper triangle)
4176 ja=globalallindexgroups(i) ! first (global) column
4177 jb=globalallindexgroups(i+1)-1 ! last (global) column
4178 ia1=globalallindexgroups(j1) ! first (global) row
4179 ! loop over groups (now in same column)
4180 DO jpg=j1,j2
4181 ia=globalallindexgroups(jpg) ! first (global) row in group
4182 ib=globalallindexgroups(jpg+1)-1 ! last (global) row in group
4183 IF (matbsz < 2) THEN
4184 ! CSR3
4185 ij=ijcsr3(ia,ja)
4186 IF (ij == 0) THEN
4187 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc, matsto
4188 stop
4189 END IF
4190 ioff=ij-ja ! offset
4191 DO ir=ia,ib
4192 jc1=max(ir,ja)
4193 k=il+jc1-ja
4194 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4195 DO jc=jc1,jb
4196 globalmatd(ioff+jc)=globalmatd(ioff+jc)-sub(ijl)
4197 ijl=ijl+k
4198 k=k+1
4199 END DO
4200 ioff=ioff+csr3rowoffsets(ir+1)-csr3rowoffsets(ir)-1
4201 END DO
4202 ELSE
4203 ! BSR3
4204 iblast=-1
4205 jblast=-1
4206 ioff=0
4207 DO ir=ia,ib
4208 iblock=(ir-1)/matbsz+1
4209 jc1=max(ir,ja)
4210 k=il+jc1-ja
4211 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4212 DO jc=jc1,jb
4213 jblock=(jc-1)/matbsz+1
4214 ! index of first element in (new) block
4215 IF (jblock /= jblast.OR.iblock /= iblast) THEN
4216 ioff=(ijcsr3(iblock,jblock)-1)*matbsz*matbsz+1
4217 iblast=iblock
4218 jblast=jblock
4219 END IF
4220 ! adjust index for position in block
4221 ij=ioff+mod(int(ir-1,mpi),matbsz)+mod(int(jc-1,mpi),matbsz)*matbsz
4222 globalmatd(ij)=globalmatd(ij)-sub(ijl)
4223 ijl=ijl+k
4224 k=k+1
4225 END DO
4226 END DO
4227 END IF
4228 END DO
4229 RETURN
4230 END IF
4231
4232 ! lower triangle
4233 ia=globalallindexgroups(i) ! first (global) row
4234 ib=globalallindexgroups(i+1)-1 ! last (global) row
4235 ja=globalallindexgroups(j1) ! first (global) column
4236 jb=globalallindexgroups(j2+1)-1 ! last (global) column
4237
4238 IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4239 CALL ijpgrp(i,j1,ij,lr,iprc) ! index of first element of group 'j1'
4240 IF (ij == 0) THEN
4241 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc,matsto
4242 stop
4243 END IF
4244 k=il
4245 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4246 DO ir=ia,ib
4247 nc=min(ir,jb)-ja ! number of columns -1
4248 IF (jb >= ir) THEN ! diagonal element
4249 globalmatd(ir)=globalmatd(ir)-sub(ijl+jl+nc)
4250 nc=nc-1
4251 END IF
4252 ! off-diagonal elements
4253 IF (iprc == 1) THEN
4254 globalmatd(ij:ij+nc)=globalmatd(ij:ij+nc)-sub(ijl+jl:ijl+jl+nc)
4255 ELSE
4256 globalmatf(ij:ij+nc)=globalmatf(ij:ij+nc)-real(sub(ijl+jl:ijl+jl+nc),mps)
4257 END IF
4258 ij=ij+lr
4259 ijl=ijl+k
4260 k=k+1
4261 END DO
4262 ELSE ! full or unpacked (block diagonal) symmetric matrix
4263 k=il
4264 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4265 DO ir=ia,ib
4266 ! global (ir,0) to local (row,col) in block
4267 ij=globalrowoffsets(ir)
4268 nc=min(ir,jb)-ja ! number of columns -1
4269 globalmatd(ij+ja:ij+ja+nc)=globalmatd(ij+ja:ij+ja+nc)-sub(ijl+jl:ijl+jl+nc)
4270 ijl=ijl+k
4271 k=k+1
4272 END DO
4273 END IF
4274
4275END SUBROUTINE mgupdt
4276
4277
4304
4305SUBROUTINE loopbf(nrej,numfil,naccf,chi2f,ndff)
4306 USE mpmod
4307
4308 IMPLICIT NONE
4309 REAL(mpd) :: cauchy
4310 REAL(mps) :: chichi
4311 REAL(mps) :: chlimt
4312 REAL(mps) :: chndf
4313 REAL(mpd) :: chuber
4314 REAL(mpd) :: down
4315 REAL(mpd) :: pull
4316 REAL(mpd) :: r1
4317 REAL(mpd) :: r2
4318 REAL(mps) :: rec
4319 REAL(mpd) :: rerr
4320 REAL(mpd) :: resid
4321 REAL(mps) :: resing
4322 REAL(mpd) :: resmax
4323 REAL(mpd) :: rmeas
4324 REAL(mpd) :: rmloc
4325 REAL(mpd) :: suwt
4326 REAL(mps) :: used
4327 REAL(mpd) :: wght
4328 REAL(mps) :: chindl
4329 INTEGER(mpi) :: i
4330 INTEGER(mpi) :: ia
4331 INTEGER(mpi) :: ib
4332 INTEGER(mpi) :: ibuf
4333 INTEGER(mpi) :: ichunk
4334 INTEGER(mpl) :: icmn
4335 INTEGER(mpl) :: icost
4336 INTEGER(mpi) :: id
4337 INTEGER(mpi) :: idiag
4338 INTEGER(mpi) :: ieq
4339 INTEGER(mpi) :: iext
4340 INTEGER(mpi) :: ij
4341 INTEGER(mpi) :: ije
4342 INTEGER(mpi) :: ijn
4343 INTEGER(mpi) :: ik
4344 INTEGER(mpi) :: ike
4345 INTEGER(mpi) :: il
4346 INTEGER(mpi) :: im
4347 INTEGER(mpi) :: imeas
4348 INTEGER(mpi) :: in
4349 INTEGER(mpi) :: inv
4350 INTEGER(mpi) :: ioffb
4351 INTEGER(mpi) :: ioffc
4352 INTEGER(mpi) :: ioffd
4353 INTEGER(mpi) :: ioffe
4354 INTEGER(mpi) :: ioffi
4355 INTEGER(mpi) :: ioffq
4356 INTEGER(mpi) :: iprc
4357 INTEGER(mpi) :: iprcnx
4358 INTEGER(mpi) :: iprdbg
4359 INTEGER(mpi) :: iproc
4360 INTEGER(mpi) :: irbin
4361 INTEGER(mpi) :: isize
4362 INTEGER(mpi) :: ist
4363 INTEGER(mpi) :: iter
4364 INTEGER(mpi) :: itgbi
4365 INTEGER(mpi) :: ivgbj
4366 INTEGER(mpi) :: ivgbk
4367 INTEGER(mpi) :: ivpgrp
4368 INTEGER(mpi) :: j
4369 INTEGER(mpi) :: j1
4370 INTEGER(mpi) :: ja
4371 INTEGER(mpi) :: jb
4372 INTEGER(mpi) :: jk
4373 INTEGER(mpi) :: jl
4374 INTEGER(mpi) :: jl1
4375 INTEGER(mpi) :: jn
4376 INTEGER(mpi) :: jnx
4377 INTEGER(mpi) :: joffd
4378 INTEGER(mpi) :: joffi
4379 INTEGER(mpi) :: jproc
4380 INTEGER(mpi) :: jrc
4381 INTEGER(mpi) :: jsp
4382 INTEGER(mpi) :: k
4383 INTEGER(mpi) :: kbdr
4384 INTEGER(mpi) :: kbdrx
4385 INTEGER(mpi) :: kbnd
4386 INTEGER(mpi) :: kfl
4387 INTEGER(mpi) :: kx
4388 INTEGER(mpi) :: lvpgrp
4389 INTEGER(mpi) :: mbdr
4390 INTEGER(mpi) :: mbnd
4391 INTEGER(mpi) :: mside
4392 INTEGER(mpi) :: nalc
4393 INTEGER(mpi) :: nalg
4394 INTEGER(mpi) :: nan
4395 INTEGER(mpi) :: nb
4396 INTEGER(mpi) :: ndf
4397 INTEGER(mpi) :: ndown
4398 INTEGER(mpi) :: neq
4399 INTEGER(mpi) :: nfred
4400 INTEGER(mpi) :: nfrei
4401 INTEGER(mpi) :: ngg
4402 INTEGER(mpi) :: nprdbg
4403 INTEGER(mpi) :: nrank
4404 INTEGER(mpl) :: nrc
4405 INTEGER(mpi) :: nst
4406 INTEGER(mpi) :: nter
4407 INTEGER(mpi) :: nweig
4408 INTEGER(mpi) :: ngrp
4409 INTEGER(mpi) :: npar
4410
4411 INTEGER(mpl), INTENT(IN OUT) :: nrej(6)
4412 INTEGER(mpi), INTENT(IN) :: numfil
4413 INTEGER(mpi), INTENT(IN OUT) :: naccf(numfil)
4414 REAL(mps), INTENT(IN OUT) :: chi2f(numfil)
4415 INTEGER(mpi), INTENT(IN OUT) :: ndff(numfil)
4416
4417 REAL(mps) :: cndl10
4418 REAL(mpd) :: dchi2
4419 REAL(mpd) :: dvar
4420 REAL(mpd) :: dw1
4421 REAL(mpd) :: dw2
4422 REAL(mpd) :: evdmin
4423 REAL(mpd) :: evdmax
4424 REAL(mpd) :: summ
4425 INTEGER(mpi) :: ijprec
4426
4427 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
4428
4429 LOGICAL:: lprnt
4430 LOGICAL::lhist
4431
4432 CHARACTER (LEN=3):: chast
4433 DATA chuber/1.345_mpd/ ! constant for Huber down-weighting
4434 DATA cauchy/2.3849_mpd/ ! constant for Cauchy down-weighting
4435 SAVE chuber,cauchy
4436 ! ...
4437
4438 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
4439 ! reset header, 3 words per thread:
4440 ! number of entries, offset to data, indices
4443 nprdbg=0
4444 iprdbg=-1
4445
4446 ! parallelize record loop
4447 ! private copy of NREJ,.. for each thread, combined at end, init with 0.
4448 !$OMP PARALLEL DO &
4449 !$OMP DEFAULT(PRIVATE) &
4450 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI, &
4451 !$OMP readBufferDataD,writeBufferHeader,writeBufferInfo, &
4452 !$OMP writeBufferData,writeBufferIndices,writeBufferUpdates,globalVector,globalCounter, &
4453 !$OMP globalParameter,globalParLabelIndex,globalIndexUsage,backIndexUsage, &
4454 !$OMP measBins,numMeas,measIndex,measRes,measHists,globalAllParToGroup,globalAllIndexGroups, &
4455 !$OMP localCorrections,localEquations,ifd, &
4456 !$OMP NAGB,NVGB,NAGBN,ICALCM,ICHUNK,NLOOPN,NRECER,NPRDBG,IPRDBG, &
4457 !$OMP NEWITE,CHICUT,LHUBER,CHUBER,ITERAT,NRECPR,MTHRD,NSPC,NAEQN, &
4458 !$OMP DWCUT,CHHUGE,NRECP2,CAUCHY,LFITNP,LFITBB,IMONIT,IMONMD,MONPG1,LUNLOG,MDEBUG,CNDLMX) &
4459 !$OMP REDUCTION(+:NREJ,NBNDR,NACCF,CHI2F,NDFF) &
4460 !$OMP REDUCTION(MAX:NBNDX,NBDRX) &
4461 !$OMP REDUCTION(MIN:NREC3) &
4462 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
4463 DO ibuf=1,numreadbuffer ! buffer for current record
4464 jrc=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
4465 kfl=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
4466 nrc=ifd(kfl)+jrc ! global record number
4467 dw1=real(readbufferdatad(readbufferpointer(ibuf)-1),mpd) ! weight
4468 dw2=sqrt(dw1)
4469
4470 iproc=0
4471 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
4472 ioffb=nagb*iproc ! offset 'f'.
4473 ioffc=nagbn*iproc ! offset 'c'.
4474 ioffe=nvgb*iproc ! offset 'e'
4475 ioffd=writebufferheader(-1)*iproc+writebufferinfo(2,iproc+1) ! offset data
4476 ioffi=writebufferheader(1)*iproc+writebufferinfo(3,iproc+1)+3 ! offset indices
4477 ioffq=naeqn*iproc ! offset equations (measurements)
4478 ! ----- reset ------------------------------------------------------
4479 lprnt=.false.
4480 lhist=(iproc == 0)
4481 rec=real(nrc,mps) ! floating point value
4482 IF(nloopn == 1.AND.mod(nrc,100000_mpl) == 0) THEN
4483 WRITE(*,*) 'Record',nrc,' ... still reading'
4484 IF(monpg1>0) WRITE(lunlog,*) 'Record',nrc,' ... still reading'
4485 END IF
4486
4487 ! printout/debug only for one thread at a time
4488
4489
4490 ! flag for record printout -----------------------------------------
4491
4492 lprnt=.false.
4493 IF(newite.AND.(iterat == 1.OR.iterat == 3)) THEN
4494 IF(nrc == nrecpr) lprnt=.true.
4495 IF(nrc == nrecp2) lprnt=.true.
4496 IF(nrc == nrecer) lprnt=.true.
4497 END IF
4498 IF (lprnt)THEN
4499 !$OMP ATOMIC
4500 nprdbg=nprdbg+1 ! number of threads with debug
4501 IF (nprdbg == 1) iprdbg=iproc ! first thread with debug
4502 IF (iproc /= iprdbg) lprnt=.false.
4503 ! print *, ' LPRNT ', NRC, NPRDBG, IPRDBG, IPROC, LPRNT
4504 END IF
4505 IF(lprnt) THEN
4506 WRITE(1,*) ' '
4507 WRITE(1,*) '------------------ Loop',nloopn, &
4508 ': Printout for record',nrc,iproc
4509 WRITE(1,*) ' '
4510 END IF
4511
4512 ! ----- print data -------------------------------------------------
4513
4514 IF(lprnt) THEN
4515 imeas=0 ! local derivatives
4516 ist=readbufferpointer(ibuf)+1
4518 DO ! loop over measurements
4519 CALL isjajb(nst,ist,ja,jb,jsp)
4520 IF(ja == 0) EXIT
4521 IF(imeas == 0) WRITE(1,1121)
4522 imeas=imeas+1
4523 WRITE(1,1122) imeas,readbufferdatad(ja),readbufferdatad(jb), &
4524 (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
4525 END DO
45261121 FORMAT(/'Measured value and local derivatives'/ &
4527 ' i measured std_dev index...derivative ...')
45281122 FORMAT(i3,2g12.4,3(i3,g12.4)/(27x,3(i3,g12.4)))
4529
4530 imeas=0 ! global derivatives
4531 ist=readbufferpointer(ibuf)+1
4533 DO ! loop over measurements
4534 CALL isjajb(nst,ist,ja,jb,jsp)
4535 IF(ja == 0) EXIT
4536 IF(imeas == 0) WRITE(1,1123)
4537 imeas=imeas+1
4538 IF (jb < ist) THEN
4539 IF(ist-jb > 2) THEN
4540 WRITE(1,1124) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4541 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4542 ELSE
4543 WRITE(1,1125) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4544 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4545 END IF
4546 END IF
4547 END DO
45481123 FORMAT(/'Global derivatives'/ &
4549 ' i label gindex vindex derivative ...')
45501124 FORMAT(i3,2(i9,i7,i7,g12.4)/(3x,2(i9,i7,i7,g12.4)))
45511125 FORMAT(i3,2(i9,i7,i7,g12.4))
4552 END IF
4553
4554 ! ----- first loop -------------------------------------------------
4555 ! ------ prepare local fit ------
4556 ! count local and global derivates
4557 ! subtract actual alignment parameters from the measured data
4558
4559 IF(lprnt) THEN
4560 WRITE(1,*) ' '
4561 WRITE(1,*) 'Data corrections using values of global parameters'
4562 WRITE(1,*) '=================================================='
4563 WRITE(1,101)
4564 END IF
4565 nalg=0 ! count number of global derivatives
4566 nalc=0 ! count number of local derivatives
4567 neq=0 ! count number of equations
4568
4569 ist=readbufferpointer(ibuf)+1
4571 DO ! loop over measurements
4572 CALL isjajb(nst,ist,ja,jb,jsp)
4573 IF(ja == 0) EXIT
4574 rmeas=real(readbufferdatad(ja),mpd) ! data
4575 neq=neq+1 ! count equation
4576 localequations(1,ioffq+neq)=ja
4577 localequations(2,ioffq+neq)=jb
4578 localequations(3,ioffq+neq)=ist
4579 ! subtract global ... from measured value
4580 DO j=1,ist-jb ! global parameter loop
4581 itgbi=readbufferdatai(jb+j) ! global parameter label
4582 rmeas=rmeas-real(readbufferdatad(jb+j),mpd)*globalparameter(itgbi) ! subtract !!! reversed
4583 IF (icalcm == 1) THEN
4584 ij=globalparlabelindex(2,itgbi) ! -> index of variable global parameter
4585 IF(ij > 0) THEN
4586 ijn=backindexusage(ioffe+ij) ! get index of index
4587 IF(ijn == 0) THEN ! not yet included
4588 nalg=nalg+1 ! count
4589 globalindexusage(ioffc+nalg)=ij ! store global index
4590 backindexusage(ioffe+ij)=nalg ! store back index
4591 END IF
4592 END IF
4593 END IF
4594 END DO
4595 IF(lprnt) THEN
4596 IF (jb < ist) WRITE(1,102) neq,readbufferdatad(ja),rmeas,readbufferdatad(jb)
4597 END IF
4598 readbufferdatad(ja)=real(rmeas,mpr8) ! global contribution subtracted
4599 DO j=1,jb-ja-1 ! local parameter loop
4600 ij=readbufferdatai(ja+j)
4601 nalc=max(nalc,ij) ! number of local parameters
4602 END DO
4603 END DO
4604101 FORMAT(' index measvalue corrvalue sigma')
4605102 FORMAT(i6,2x,2g12.4,' +-',g12.4)
4606
4607 IF(nalc <= 0) GO TO 90
4608
4609 ngg=(nalg*nalg+nalg)/2
4610 ngrp=0
4611 IF (icalcm == 1) THEN
4612 localglobalmatrix(:nalg*nalc)=0.0_mpd ! reset global-local matrix
4613 localglobalmap(:nalg*nalc)=0 ! reset global-local map
4614 ! store parameter group indices
4615 CALL sort1k(globalindexusage(ioffc+1),nalg) ! sort global par.
4616 lvpgrp=-1
4617 npar=0
4618 DO k=1,nalg
4619 iext=globalindexusage(ioffc+k)
4620 backindexusage(ioffe+iext)=k ! update back index
4621 ivpgrp=globalallpartogroup(iext) ! group
4622 IF (ivpgrp /= lvpgrp) THEN
4623 ngrp=ngrp+1
4624 writebufferindices(ioffi+ngrp)=ivpgrp ! global par group indices
4625 lvpgrp=ivpgrp
4626 npar=npar+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4627 END IF
4628 END DO
4629 ! check NPAR==NALG
4630 IF (npar /= nalg) THEN
4631 print *, ' mismatch of number of global parameters ', nrc, nalg, npar, ngrp
4632 print *, globalindexusage(ioffc+1:ioffc+nalg)
4633 print *, writebufferindices(ioffi+1:ioffi+ngrp)
4634 j=0
4635 DO k=1,ngrp
4636 ivpgrp=writebufferindices(ioffi+k)
4637 j=j+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4638 IF (globalallpartogroup(globalindexusage(ioffc+j)) /= ivpgrp) &
4639 print *, ' bad group ', k, j, ivpgrp, globalindexusage(ioffc+j)
4640 END DO
4641 CALL peend(35,'Aborted, mismatch of number of global parameters')
4642 stop ' mismatch of number of global parameters '
4643 ENDIF
4644 ! index header
4645 writebufferindices(ioffi-2)=jrc ! record number in file
4646 writebufferindices(ioffi-1)=nalg ! number of global parameters
4647 writebufferindices(ioffi )=ngrp ! number of global par groups
4648 DO k=1,ngg
4649 writebufferupdates(ioffd+k)=0.0_mpd ! reset global-global matrix
4650 END DO
4651 END IF
4652 ! ----- iteration start and check ---------------------------------
4653
4654 nter=1 ! first loop without down-weighting
4655 IF(nloopn /= 1.AND.lhuber /= 0) nter=lhuber
4656 localcorrections(ioffq+1:ioffq+neq) = 0._mpd
4657
4658 ! check matrix for bordered band structure (MBDR+MBND+1 <= NALC)
4659 mbnd=-1
4660 mbdr=nalc
4661 mside=-1 ! side (1: upper/left border, 2: lower/right border)
4662 DO i=1, 2*nalc
4663 ibandh(i)=0
4664 END DO
4665 idiag=1
4666
4667 iter=0
4668 resmax=0.0
4669 DO WHILE(iter < nter) ! outlier suppresssion iteration loop
4670 iter=iter+1
4671 resmax=0.0
4672 IF(lprnt) THEN
4673 WRITE(1,*) ' '
4674 WRITE(1,*) 'Outlier-suppression iteration',iter,' of',nter
4675 WRITE(1,*) '=========================================='
4676 WRITE(1,*) ' '
4677 imeas=0
4678 END IF
4679
4680 ! ----- second loop ------------------------------------------------
4681 ! accumulate normal equations for local fit and determine solution
4682 DO i=1,nalc
4683 blvec(i)=0.0_mpd ! reset vector
4684 END DO
4685 DO i=1,(nalc*nalc+nalc)/2 ! GF: FIXME - not really, local parameter number...
4686 clmat(i)=0.0_mpd ! (p)reset matrix
4687 END DO
4688 ndown=0
4689 nweig=0
4690 cndl10=0.
4691 DO ieq=1,neq! loop over measurements
4692 ja=localequations(1,ioffq+ieq)
4693 jb=localequations(2,ioffq+ieq)
4694 rmeas=real(readbufferdatad(ja),mpd) ! data
4695 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4696 wght =1.0_mpd/rerr**2 ! weight from error
4697 nweig=nweig+1
4698 resid=rmeas-localcorrections(ioffq+ieq) ! subtract previous fit
4699 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4700 IF(iter <= 3) THEN
4701 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4702 wght=wght*chuber*rerr/abs(resid)
4703 ndown=ndown+1
4704 END IF
4705 ELSE ! Cauchy
4706 wght=wght/(1.0+(resid/rerr/cauchy)**2)
4707 END IF
4708 END IF
4709
4710 IF(lprnt.AND.iter /= 1.AND.nter /= 1) THEN
4711 chast=' '
4712 IF(abs(resid) > chuber*rerr) chast='* '
4713 IF(abs(resid) > 3.0*rerr) chast='** '
4714 IF(abs(resid) > 6.0*rerr) chast='***'
4715 IF(imeas == 0) WRITE(1,*) 'Second loop: accumulate'
4716 IF(imeas == 0) WRITE(1,103)
4717 imeas=imeas+1
4718 down=1.0/sqrt(wght)
4719 r1=resid/rerr
4720 r2=resid/down
4721 WRITE(1,104) imeas,rmeas,resid,rerr,r1,chast,r2
4722 END IF
4723103 FORMAT(' index corrvalue residuum sigma', &
4724 ' nresid cnresid')
4725104 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4726
4727 DO j=1,jb-ja-1 ! normal equations, local parameter loop
4728 ij=readbufferdatai(ja+j) ! local parameter index J
4729 blvec(ij)=blvec(ij)+wght*rmeas*real(readbufferdatad(ja+j),mpd)
4730 DO k=1,j
4731 ik=readbufferdatai(ja+k) ! local parameter index K
4732 jk=(ij*ij-ij)/2+ik ! index in symmetric matrix
4733 clmat(jk)=clmat(jk) & ! force double precision
4734 +wght*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)
4735 ! check for band matrix substructure
4736 IF (iter == 1) THEN
4737 id=iabs(ij-ik)+1
4738 im=min(ij,ik) ! upper/left border
4739 ibandh(id)=max(ibandh(id),im)
4740 im=min(nalc+1-ij,nalc+1-ik) ! lower/rght border (mirrored)
4741 ibandh(nalc+id)=max(ibandh(nalc+id),im)
4742 END IF
4743 END DO
4744 END DO
4745 END DO
4746 ! for non trivial fits check for bordered band matrix structure
4747 IF (iter == 1.AND.nalc > 5.AND.lfitbb > 0) THEN
4748 kx=-1
4749 kbdrx=0
4750 icmn=int(nalc,mpl)**3 ! cost (*6) should improve by at least factor 2
4751 ! upper/left border ?
4752 kbdr=0
4753 DO k=nalc,2,-1
4754 kbnd=k-2
4755 kbdr=max(kbdr,ibandh(k))
4756 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4757 IF (icost < icmn) THEN
4758 icmn=icost
4759 kx=k
4760 kbdrx=kbdr
4761 mside=1
4762 END IF
4763 END DO
4764 IF (kx < 0) THEN
4765 ! lower/right border instead?
4766 kbdr=0
4767 DO k=nalc,2,-1
4768 kbnd=k-2
4769 kbdr=max(kbdr,ibandh(k+nalc))
4770 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4771 IF (icost < icmn) THEN
4772 icmn=icost
4773 kx=k
4774 kbdrx=kbdr
4775 mside=2
4776 END IF
4777 END DO
4778 END IF
4779 IF (kx > 0) THEN
4780 mbnd=kx-2
4781 mbdr=kbdrx
4782 END IF
4783 END IF
4784
4785 IF (mbnd >= 0) THEN
4786 ! fast solution for border banded matrix (inverse for ICALCM>0)
4787 IF (nloopn == 1) THEN
4788 nbndr(mside)=nbndr(mside)+1
4789 nbdrx=max(nbdrx,mbdr)
4790 nbndx=max(nbndx,mbnd)
4791 END IF
4792
4793 inv=0
4794 IF (nloopn <= lfitnp.AND.iter == 1) inv=1 ! band part of inverse (for pulls)
4795 IF (icalcm == 1.OR.lprnt) inv=2 ! complete inverse
4796 IF (mside == 1) THEN
4797 CALL sqmibb(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4798 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4799 ELSE
4800 CALL sqmibb2(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4801 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4802 ENDIF
4803 ! log10(condition of band part)
4804 IF (evdmin > 0.0_mpl) cndl10=log10(real(evdmax/evdmin,mps))
4805 IF (lhist.AND.nloopn == 1) CALL hmpent(16,cndl10)
4806 ELSE
4807 ! full inversion and solution
4808 inv=2
4809 CALL sqminv(clmat,blvec,nalc,nrank,scdiag,scflag)
4810 END IF
4811 ! check for NaNs
4812 nan=0
4813 DO k=1, nalc
4814 IF ((.NOT.(blvec(k) <= 0.0_mpd)).AND. (.NOT.(blvec(k) > 0.0_mpd))) nan=nan+1
4815 END DO
4816
4817 IF(lprnt) THEN
4818 WRITE(1,*) ' '
4819 WRITE(1,*) 'Parameter determination:',nalc,' parameters,', ' rank=',nrank
4820 WRITE(1,*) '-----------------------'
4821 IF(ndown /= 0) WRITE(1,*) ' ',ndown,' data down-weighted'
4822 WRITE(1,*) ' '
4823 END IF
4824
4825 ! ----- third loop -------------------------------------------------
4826 ! calculate single residuals remaining after local fit and chi^2
4827
4828 summ=0.0_mpd
4829 suwt=0.0
4830 imeas=0
4831 DO ieq=1,neq! loop over measurements
4832 ja=localequations(1,ioffq+ieq)
4833 jb=localequations(2,ioffq+ieq)
4834 ist=localequations(3,ioffq+ieq)
4835 rmeas=real(readbufferdatad(ja),mpd) ! data (global contrib. subtracted)
4836 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4837 wght =1.0_mpd/rerr**2 ! weight from error
4838 rmloc=0.0 ! local fit result reset
4839 DO j=1,jb-ja-1 ! local parameter loop
4840 ij=readbufferdatai(ja+j)
4841 rmloc=rmloc+real(readbufferdatad(ja+j),mpd)*blvec(ij) ! local fit result
4842 END DO
4843 localcorrections(ioffq+ieq)=rmloc ! save local fit result
4844 rmeas=rmeas-rmloc ! reduced to residual
4845
4846 ! calculate pulls? (needs covariance matrix)
4847 IF(iter == 1.AND.inv > 0.AND.nloopn <= lfitnp) THEN
4848 dvar=0.0_mpd
4849 DO j=1,jb-ja-1
4850 ij=readbufferdatai(ja+j)
4851 jk=(ij*ij-ij)/2 ! index in symmetric matrix, row offset
4852 ! off diagonal (symmetric)
4853 DO k=1,j-1
4854 ik=readbufferdatai(ja+k)
4855 dvar=dvar+clmat(jk+ik)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)*2.0_mpd
4856 END DO
4857 ! diagonal
4858 dvar=dvar+clmat(jk+ij)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+j),mpd)
4859 END DO
4860 ! some variance left to define a pull?
4861 IF (0.999999_mpd/wght > dvar) THEN
4862 pull=rmeas/sqrt(1.0_mpd/wght-dvar)
4863 IF (lhist) THEN
4864 IF (jb < ist) THEN
4865 CALL hmpent(13,real(pull,mps)) ! histogram pull
4866 CALL gmpms(5,rec,real(pull,mps))
4867 ELSE
4868 CALL hmpent(14,real(pull,mps)) ! histogram pull
4869 END IF
4870 END IF
4871 ! monitoring
4872 IF (imonit /= 0) THEN
4873 IF (jb < ist) THEN
4874 ij=readbufferdatai(jb+1) ! group by first global label
4875 if (imonmd == 0) THEN
4876 irbin=min(measbins,max(1,int(pull*rerr/measres(ij)/measbinsize+0.5*real(measbins,mpd))))
4877 ELSE
4878 irbin=min(measbins,max(1,int(pull/measbinsize+0.5*real(measbins,mpd))))
4879 ENDIF
4880 irbin=irbin+measbins*(measindex(ij)-1+nummeas*iproc)
4881 meashists(irbin)=meashists(irbin)+1
4882 ENDIF
4883 ENDIF
4884 END IF
4885 END IF
4886
4887 IF(iter == 1.AND.jb < ist.AND.lhist) &
4888 CALL gmpms(4,rec,real(rmeas/rerr,mps)) ! residual (with global deriv.)
4889
4890 dchi2=wght*rmeas*rmeas
4891 ! DCHIT=DCHI2
4892 resid=rmeas
4893 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4894 IF(iter <= 3) THEN
4895 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4896 wght=wght*chuber*rerr/abs(resid)
4897 dchi2=2.0*chuber*(abs(resid)/rerr-0.5*chuber)
4898 END IF
4899 ELSE
4900 wght=wght/(1.0_mpd+(resid/rerr/cauchy)**2)
4901 dchi2=log(1.0_mpd+(resid/rerr/cauchy)**2)*cauchy**2
4902 END IF
4903 END IF
4904
4905 down=1.0/sqrt(wght)
4906
4907 ! SUWT=SUWT+DCHI2/DCHIT
4908 suwt=suwt+rerr/down
4909 IF(lprnt) THEN
4910 chast=' '
4911 IF(abs(resid) > chuber*rerr) chast='* '
4912 IF(abs(resid) > 3.0*rerr) chast='** '
4913 IF(abs(resid) > 6.0*rerr) chast='***'
4914 IF(imeas == 0) WRITE(1,*) 'Third loop: single residuals'
4915 IF(imeas == 0) WRITE(1,105)
4916 imeas=imeas+1
4917 r1=resid/rerr
4918 r2=resid/down
4919 IF(resid < 0.0) r1=-r1
4920 IF(resid < 0.0) r2=-r2
4921 WRITE(1,106) imeas,readbufferdatad(ja),rmeas,rerr,r1,chast,r2
4922 END IF
4923105 FORMAT(' index corrvalue residuum sigma', &
4924 ' nresid cnresid')
4925106 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4926
4927 IF(iter == nter) THEN
4928 readbufferdatad(ja)=real(rmeas,mpr8) ! store remaining residual
4929 resmax=max(resmax,abs(rmeas)/rerr)
4930 END IF
4931
4932 IF(iter == 1.AND.lhist) THEN
4933 IF (jb < ist) THEN
4934 CALL hmpent( 3,real(rmeas/rerr,mps)) ! histogram norm residual
4935 ELSE
4936 CALL hmpent(12,real(rmeas/rerr,mps)) ! histogram norm residual
4937 END IF
4938 END IF
4939 summ=summ+dchi2 ! accumulate chi-square sum
4940 END DO
4941
4942 ndf=neq-nrank
4943 resing=(real(nweig,mps)-real(suwt,mps))/real(nweig,mps)
4944 IF (lhist) THEN
4945 IF(iter == 1) CALL hmpent( 5,real(ndf,mps)) ! histogram Ndf
4946 IF(iter == 1) CALL hmpent(11,real(nalc,mps)) ! histogram Nlocal
4947 IF(nloopn == 2.AND.iter == nter) CALL hmpent(6,resing)
4948 END IF
4949 IF(lprnt) THEN
4950 WRITE(1,*) ' '
4951 WRITE(1,*) 'Chi^2=',summ,' at',ndf,' degrees of freedom: ', &
4952 '3-sigma limit is',chindl(3,ndf)*real(ndf,mps)
4953 WRITE(1,*) suwt,' is sum of factors, compared to',nweig, &
4954 ' Downweight fraction:',resing
4955 END IF
4956 IF(nan > 0) THEN
4957 nrej(1)=nrej(1)+1 ! count cases
4958 IF (nrec3 == huge(nrec3)) nrec3=nrc
4959 IF(lprnt) THEN
4960 WRITE(1,*) ' NaNs ', nalc, nrank, nan
4961 WRITE(1,*) ' ---> rejected!'
4962 END IF
4963 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-1 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
4964 GO TO 90
4965 END IF
4966 IF(nrank /= nalc) THEN
4967 nrej(2)=nrej(2)+1 ! count cases
4968 IF (nrec3 == huge(nrec3)) nrec3=nrc
4969 IF(lprnt) THEN
4970 WRITE(1,*) ' rank deficit', nalc, nrank
4971 WRITE(1,*) ' ---> rejected!'
4972 END IF
4973 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-2 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
4974 GO TO 90
4975 END IF
4976 IF(cndl10 > cndlmx) THEN
4977 nrej(3)=nrej(3)+1 ! count cases
4978 IF (nrec3 == huge(nrec3)) nrec3=nrc
4979 IF(lprnt) THEN
4980 WRITE(1,*) ' too large condition(band part) ', nalc, nrank, cndl10
4981 WRITE(1,*) ' ---> rejected!'
4982 END IF
4983 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-3 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
4984 GO TO 90
4985 END IF
4986 IF(ndf <= 0) THEN
4987 nrej(4)=nrej(4)+1 ! count cases
4988 IF(lprnt) THEN
4989 WRITE(1,*) ' Ndf<=0', nalc, nrank, ndf
4990 WRITE(1,*) ' ---> rejected!'
4991 END IF
4992 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-4 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
4993 GO TO 90
4994 END IF
4995
4996 chndf=real(summ/real(ndf,mpd),mps)
4997
4998 IF(iter == 1.AND.lhist) CALL hmpent(4,chndf) ! histogram chi^2/Ndf
4999 END DO ! outlier iteration loop
5000
5001 ! ----- reject eventually ------------------------------------------
5002
5003 IF(newite.AND.iterat == 2) THEN ! find record with largest Chi^2/Ndf
5004 IF(nrecp2 < 0.AND.chndf > writebufferdata(2,iproc+1)) THEN
5005 writebufferdata(2,iproc+1)=chndf
5006 writebufferinfo(8,iproc+1)=jrc
5007 writebufferinfo(9,iproc+1)=kfl
5008 END IF
5009 END IF
5010
5011 chichi=chindl(3,ndf)*real(ndf,mps)
5012 ! GF IF(SUMM.GT.50.0*CHICHI) THEN ! huge
5013 ! CHK CHICUT<0: NO cut (1st iteration)
5014 IF(chicut >= 0.0) THEN
5015 IF(summ > chhuge*chichi) THEN ! huge
5016 nrej(5)=nrej(5)+1 ! count cases with huge chi^2
5017 IF(lprnt) THEN
5018 WRITE(1,*) ' ---> rejected!'
5019 END IF
5020 GO TO 90
5021 END IF
5022
5023 IF(chicut > 0.0) THEN
5024 chlimt=chicut*chichi
5025 ! WRITE(*,*) 'chi^2 ',SUMM,CHLIMT,CHICUT,CHINDL(3,NDF),NDF
5026 IF(summ > chlimt) THEN
5027 IF(lprnt) THEN
5028 WRITE(1,*) ' ---> rejected!'
5029 END IF
5030 ! add to FVALUE
5031 dchi2=chlimt ! total contribution limit
5032 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5033 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5034 GO TO 90
5035 END IF
5036 END IF
5037 END IF
5038
5039 IF(lhuber > 1.AND.dwcut /= 0.0.AND.resing > dwcut) THEN
5040 ! add to FVALUE
5041 dchi2=summ ! total contribution
5042 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5043 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5044 ! WRITE(*,*) 'Downweight fraction cut ',RESING,DWCUT,SUMM
5045 IF(lprnt) THEN
5046 WRITE(1,*) ' ---> rejected!'
5047 END IF
5048 GO TO 90
5049 END IF
5050
5051 IF(newite.AND.iterat == 2) THEN ! find record with largest residual
5052 IF(nrecpr < 0.AND.resmax > writebufferdata(1,iproc+1)) THEN
5053 writebufferdata(1,iproc+1)=real(resmax,mps)
5054 writebufferinfo(6,iproc+1)=jrc
5055 writebufferinfo(7,iproc+1)=kfl
5056 END IF
5057 END IF
5058 ! 'track quality' per binary file: accepted records
5059 naccf(kfl)=naccf(kfl)+1
5060 ndff(kfl) =ndff(kfl) +ndf
5061 chi2f(kfl)=chi2f(kfl)+chndf
5062
5063 ! ----- fourth loop ------------------------------------------------
5064 ! update of global matrix and vector according to the "Millepede"
5065 ! principle, from the global/local information
5066
5067 summ=0.0_mpd
5068 DO ieq=1,neq! loop over measurements
5069 ja=localequations(1,ioffq+ieq)
5070 jb=localequations(2,ioffq+ieq)
5071 ist=localequations(3,ioffq+ieq)
5072 rmeas=real(readbufferdatad(ja),mpd) ! data residual
5073 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
5074 wght =1.0_mpd/rerr**2 ! weight from measurement error
5075 dchi2=wght*rmeas*rmeas ! least-square contribution
5076
5077 IF(nloopn /= 1.AND.lhuber /= 0) THEN ! check residual
5078 resid=abs(rmeas)
5079 IF(resid > chuber*rerr) THEN
5080 wght=wght*chuber*rerr/resid ! down-weighting
5081 dchi2=2.0*chuber*(resid/rerr-0.5*chuber) ! modified contribution
5082 END IF
5083 END IF
5084 ! sum up
5085 summ=summ+dchi2
5086
5087 ! global-global matrix contribution: add directly to gg-matrix
5088
5089 DO j=1,ist-jb
5090 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5091 IF (readbufferdatad(jb+j) == 0.0_mpd) cycle ! skip zero global derivatives
5092 IF(ivgbj > 0) THEN
5093 globalvector(ioffb+ivgbj)=globalvector(ioffb+ivgbj) &
5094 +dw1*wght*rmeas*real(readbufferdatad(jb+j),mpd) ! vector !!! reverse
5095 globalcounter(ioffb+ivgbj)=globalcounter(ioffb+ivgbj)+1
5096 IF(icalcm == 1) THEN
5097 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5098 DO k=1,j
5100 IF(ivgbk > 0) THEN
5101 ike=backindexusage(ioffe+ivgbk) ! get index of index, non-zero
5102 ia=max(ije,ike) ! larger
5103 ib=min(ije,ike) ! smaller
5104 ij=ib+(ia*ia-ia)/2
5105 writebufferupdates(ioffd+ij)=writebufferupdates(ioffd+ij) &
5106 -dw1*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(jb+k),mpd)
5107 END IF
5108 END DO
5109 END IF
5110 END IF
5111 END DO
5112
5113 ! normal equations - rectangular matrix for global/local pars
5114 ! global-local matrix contribution: accumulate rectangular matrix
5115 IF (icalcm /= 1) cycle
5116 DO j=1,ist-jb
5117 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5118 IF(ivgbj > 0) THEN
5119 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5120 DO k=1,jb-ja-1
5121 ik=readbufferdatai(ja+k) ! local index
5122 jk=ik+(ije-1)*nalc ! matrix index
5124 dw2*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(ja+k),mpd)
5126 END DO
5127 END IF
5128 END DO
5129 END DO
5130 ! add to total objective function
5131 CALL addsums(iproc+1, summ, ndf, dw1)
5132
5133 ! ----- final matrix update ----------------------------------------
5134 ! update global matrices and vectors
5135 IF(icalcm /= 1) GO TO 90 ! matrix update
5136 ! (inverse local matrix) * (rectang. matrix) -> CORM
5137 ! T
5138 ! resulting symmetrix matrix = G * Gamma^{-1} * G
5139
5140 ! check sparsity of localGlobalMatrix (with par. groups)
5141 isize=nalc+nalg+1 ! row/clolumn offsets
5142 ! check rows
5143 k=0 ! offset
5144 DO i=1, nalg
5145 localglobalstructure(i)=isize
5146 DO j=1, nalc
5147 IF (localglobalmap(k+j) > 0) THEN
5148 localglobalstructure(isize+1)=j ! column
5149 localglobalstructure(isize+2)=k+j ! index
5150 isize=isize+2
5151 ENDIF
5152 END DO
5153 k=k+nalc
5154 END DO
5155 ! <50% non-zero elements?
5156 IF (isize-localglobalstructure(1) < nalc*nalg) THEN
5157 ! check columns (too)
5158 DO j=1, nalc
5159 localglobalstructure(nalg+j)=isize
5160 k=0 ! offset
5161 DO i=1, nalg
5162 IF (localglobalmap(k+j) > 0) THEN
5163 localglobalstructure(isize+1)=i ! row
5164 localglobalstructure(isize+2)=k+j ! index
5165 isize=isize+2
5166 ENDIF
5167 k=k+nalc
5168 END DO
5169 END DO
5170 localglobalstructure(nalg+nalc+1)=isize
5172 ELSE
5173 CALL dbavat(clmat,localglobalmatrix,writebufferupdates(ioffd+1),nalc,nalg,1)
5174 END IF
5175 ! (rectang. matrix) * (local param vector) -> CORV
5176 ! resulting vector = G * q (q = local parameter)
5177 ! CALL DBGAX(DQ(IGLMA/2+1),BLVEC,DQ(ICORV/2+1),NALG,NALC) ! not done
5178 ! the vector update is not done, because after local fit it is zero!
5179
5180 ! update cache status
5181 writebufferinfo(1,iproc+1)=writebufferinfo(1,iproc+1)+1
5182 writebufferinfo(2,iproc+1)=writebufferinfo(2,iproc+1)+ngg
5183 writebufferinfo(3,iproc+1)=writebufferinfo(3,iproc+1)+ngrp+3
5184 ! check free space
5185 nfred=writebufferheader(-1)-writebufferinfo(2,iproc+1)-writebufferheader(-2)
5187 IF (nfred < 0.OR.nfrei < 0) THEN ! need to flush
5188 nb=writebufferinfo(1,iproc+1)
5189 joffd=writebufferheader(-1)*iproc ! offset data
5190 joffi=writebufferheader(1)*iproc+3 ! offset indices
5191 used=real(writebufferinfo(2,iproc+1),mps)/real(writebufferheader(-1),mps)
5192 writebufferinfo(4,iproc+1)=writebufferinfo(4,iproc+1) +nint(1000.0*used,mpi)
5193 used=real(writebufferinfo(3,iproc+1),mps)/real(writebufferheader(1),mps)
5194 writebufferinfo(5,iproc+1)=writebufferinfo(5,iproc+1) +nint(1000.0*used,mpi)
5195 !$OMP CRITICAL
5198
5199 DO ib=1,nb
5200 nalg=writebufferindices(joffi-1)
5201 il=1 ! row in update matrix
5202 DO in=1,writebufferindices(joffi)
5203 i=writebufferindices(joffi+in)
5204 j=writebufferindices(joffi+1) ! 1. group
5205 iprc=ijprec(i,j) ! group pair precision
5206 jl=1 ! col in update matrix
5207 ! start (rows) for continous groups
5208 j1=j
5209 jl1=jl
5210 ! other groups for row
5211 DO jn=2,in
5213 jnx=writebufferindices(joffi+jn) ! next group
5214 iprcnx=ijprec(i,jnx) ! group pair precision
5215 ! end of continous groups?
5216 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5217 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5218 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5219 ! restart continous groups
5220 j1=jnx ! new 1. column
5221 jl1=jl
5222 iprc=iprcnx
5223 END IF
5224 j=jnx ! last group
5225 END DO
5226 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5227 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5229 END DO
5230 joffd=joffd+(il*il-il)/2
5231 joffi=joffi+writebufferindices(joffi)+3
5232 END DO
5233 !$OMP END CRITICAL
5234 ! reset counter, pointers
5235 DO k=1,3
5236 writebufferinfo(k,iproc+1)=0
5237 END DO
5238 END IF
5239
524090 IF(lprnt) THEN
5241 WRITE(1,*) ' '
5242 WRITE(1,*) '------------------ End of printout for record',nrc
5243 WRITE(1,*) ' '
5244 END IF
5245
5246 DO i=1,nalg ! reset global index array
5247 iext=globalindexusage(ioffc+i)
5248 backindexusage(ioffe+iext)=0
5249 END DO
5250
5251 END DO
5252 !$OMP END PARALLEL DO
5253
5254 IF (icalcm == 1) THEN
5255 ! flush remaining matrices
5256 DO k=1,mthrd ! update statistics
5258 used=real(writebufferinfo(2,k),mps)/real(writebufferheader(-1),mps)
5259 writebufferinfo(4,k)=writebufferinfo(4,k)+nint(1000.0*used,mpi)
5262 writebufferinfo(4,k)=0
5264 used=real(writebufferinfo(3,k),mps)/real(writebufferheader(1),mps)
5265 writebufferinfo(5,k)=writebufferinfo(5,k)+nint(1000.0*used,mpi)
5268 writebufferinfo(5,k)=0
5269 END DO
5270
5271 !$OMP PARALLEL &
5272 !$OMP DEFAULT(PRIVATE) &
5273 !$OMP SHARED(writeBufferHeader,writeBufferInfo,writeBufferIndices,writeBufferUpdates,MTHRD) &
5274 !$OMP SHARED(globalAllParToGroup,globalAllIndexGroups,nspc)
5275 iproc=0
5276 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5277 DO jproc=0,mthrd-1
5278 nb=writebufferinfo(1,jproc+1)
5279 ! print *, ' flush end ', JPROC, NRC, NB
5280 joffd=writebufferheader(-1)*jproc ! offset data
5281 joffi=writebufferheader(1)*jproc+3 ! offset indices
5282 DO ib=1,nb
5283 ! print *, ' buf end ', JPROC,IB,writeBufferIndices(JOFFI-2),writeBufferIndices(JOFFI)
5284 nalg=writebufferindices(joffi-1)
5285 il=1 ! row in update matrix
5286 DO in=1,writebufferindices(joffi)
5287 i=writebufferindices(joffi+in)
5288 !$ IF (MOD(I,MTHRD).EQ.IPROC) THEN
5289 j=writebufferindices(joffi+1) ! 1. group
5290 iprc=ijprec(i,j) ! group pair precision
5291 jl=1 ! col in update matrix
5292 ! start (rows) for continous groups
5293 j1=j
5294 jl1=jl
5295 ! other groups for row
5296 DO jn=2,in
5298 jnx=writebufferindices(joffi+jn) ! next group
5299 iprcnx=ijprec(i,jnx) ! group pair precision
5300 ! end of continous groups?
5301 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5302 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5303 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5304 ! restart continous groups
5305 j1=jnx ! new 1. column
5306 jl1=jl
5307 iprc=iprcnx
5308 END IF
5309 j=jnx ! last group
5310 END DO
5311 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5312 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5313 !$ END IF
5315 END DO
5316 joffd=joffd+(il*il-il)/2
5317 joffi=joffi+writebufferindices(joffi)+3
5318 END DO
5319 END DO
5320 !$OMP END PARALLEL
5321 END IF
5322
5323 IF(newite.AND.iterat == 2) THEN ! get worst records (for printrecord -1 -1)
5324 IF (nrecpr < 0) THEN
5325 DO k=1,mthrd
5326 IF (writebufferdata(1,k) > value1) THEN
5329 END IF
5330 END DO
5331 END IF
5332 IF (nrecp2 < 0) THEN
5333 DO k=1,mthrd
5334 IF (writebufferdata(2,k) > value2) THEN
5337 END IF
5338 END DO
5339 END IF
5340 END IF
5341
5342END SUBROUTINE loopbf
5343
5344!***********************************************************************
5345
5348SUBROUTINE prtrej(lun)
5349 USE mpmod
5350
5351 IMPLICIT NONE
5352 INTEGER(mpi), INTENT(IN) :: lun
5353
5354 IF (nrejec(1)>0) WRITE(lun,*) nrejec(1), ' (local solution contains NaNs)'
5355 IF (nrejec(2)>0) WRITE(lun,*) nrejec(2), ' (local matrix with rank deficit)'
5356 IF (nrejec(3)>0) WRITE(lun,*) nrejec(3), ' (local matrix with ill condition)'
5357 IF (nrejec(4)>0) WRITE(lun,*) nrejec(4), ' (local fit with Ndf=0)'
5358 IF (nrejec(5)>0) WRITE(lun,*) nrejec(5), ' (local fit with huge Chi2(Ndf))'
5359 IF (nrejec(6)>0) WRITE(lun,*) nrejec(6), ' (local fit with large Chi2(Ndf))'
5360
5361END SUBROUTINE prtrej
5362
5363!***********************************************************************
5364
5377SUBROUTINE prtglo
5378 USE mpmod
5379
5380 IMPLICIT NONE
5381 REAL(mps):: dpa
5382 REAL(mps):: err
5383 REAL(mps):: gcor
5384 INTEGER(mpi) :: i
5385 INTEGER(mpi) :: icom
5386 INTEGER(mpl) :: icount
5387 INTEGER(mpi) :: ie
5388 INTEGER(mpi) :: iev
5389 INTEGER(mpi) :: ij
5390 INTEGER(mpi) :: imin
5391 INTEGER(mpi) :: iprlim
5392 INTEGER(mpi) :: isub
5393 INTEGER(mpi) :: itgbi
5394 INTEGER(mpi) :: itgbl
5395 INTEGER(mpi) :: ivgbi
5396 INTEGER(mpi) :: j
5397 INTEGER(mpi) :: label
5398 INTEGER(mpi) :: lup
5399 REAL(mps):: par
5400 LOGICAL :: lowstat
5401
5402 REAL(mpd):: diag
5403 REAL(mpd)::gmati
5404 REAL(mpd)::gcor2
5405 INTEGER(mpi) :: labele(3)
5406 REAL(mps):: compnt(3)
5407 SAVE
5408 ! ...
5409
5410 lup=09
5411 CALL mvopen(lup,'millepede.res')
5412
5413 WRITE(*,*) ' '
5414 WRITE(*,*) ' Result of fit for global parameters'
5415 WRITE(*,*) ' ==================================='
5416 WRITE(*,*) ' '
5417
5418 WRITE(*,101)
5419
5420 WRITE(lup,*) 'Parameter ! first 3 elements per line are', &
5421 ' significant (if used as input)'
5422
5423
5424 iprlim=10
5425 DO itgbi=1,ntgb ! all parameter variables
5426 itgbl=globalparlabelindex(1,itgbi)
5427 ivgbi=globalparlabelindex(2,itgbi)
5428 icom=globalparcomments(itgbi) ! comment
5429 IF (icom > 0) WRITE(lup,113) listcomments(icom)%text
5430 par=real(globalparameter(itgbi),mps) ! initial value
5431 icount=0 ! counts
5432 lowstat = .false.
5433 IF(ivgbi > 0) THEN
5434 icount=globalcounter(ivgbi) ! used in last iteration
5435 lowstat = (icount < mreqena) ! too few accepted entries
5436 dpa=real(globalparameter(itgbi)-globalparstart(itgbi),mps) ! difference
5437 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5438 gmati=globalmatd(globalrowoffsets(ivgbi)+ivgbi)
5439 err=sqrt(abs(real(gmati,mps)))
5440 IF(gmati < 0.0_mpd) err=-err
5441 diag=workspacediag(ivgbi)
5442 gcor=-1.0
5443 IF(gmati*diag > 0.0_mpd) THEN ! global correlation
5444 gcor2=1.0_mpd-1.0_mpd/(gmati*diag)
5445 IF(gcor2 >= 0.0_mpd.AND.gcor2 <= 1.0_mpd) gcor=real(sqrt(gcor2),mps)
5446 END IF
5447 END IF
5448 END IF
5449 IF(ipcntr > 1) icount=globalparlabelcounter(itgbi) ! from binary files
5450 IF(lowstat) icount=-(icount+1) ! flag 'lowstat' with icount < 0
5451 IF(ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5452 IF(itgbi <= iprlim) THEN
5453 IF(ivgbi <= 0) THEN
5454 WRITE(* ,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5455 ELSE
5456 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5457 IF (igcorr == 0) THEN
5458 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5459 ELSE
5460 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5461 END IF
5462 ELSE
5463 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5464 END IF
5465 END IF
5466 ELSE IF(itgbi == iprlim+1) THEN
5467 WRITE(* ,*) '... (further printout suppressed, but see log file)'
5468 END IF
5469
5470 ! file output
5471 IF(ivgbi <= 0) THEN
5472 IF (ipcntr /= 0) THEN
5473 WRITE(lup,110) itgbl,par,real(globalparpresigma(itgbi),mps),icount
5474 ELSE
5475 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5476 END IF
5477 ELSE
5478 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5479 IF (ipcntr /= 0) THEN
5480 WRITE(lup,112) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,icount
5481 ELSE IF (igcorr /= 0) THEN
5482 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5483 ELSE
5484 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5485 END IF
5486 ELSE
5487 IF (ipcntr /= 0) THEN
5488 WRITE(lup,111) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,icount
5489 ELSE
5490 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5491 END IF
5492 END IF
5493 END IF
5494 END DO
5495 rewind lup
5496 CLOSE(unit=lup)
5497
5498 IF(metsol == 2) THEN ! diagonalisation: write eigenvectors
5499 CALL mvopen(lup,'millepede.eve')
5500 imin=1
5501 DO i=nagb,1,-1
5502 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
5503 imin=i ! index of smallest pos. eigenvalue
5504 EXIT
5505 ENDIF
5506 END DO
5507 iev=0
5508
5509 DO isub=0,min(15,imin-1)
5510 IF(isub < 10) THEN
5511 i=imin-isub
5512 ELSE
5513 i=isub-9
5514 END IF
5515
5516 ! DO I=IMIN,MAX(1,IMIN-9),-1 ! backward loop, up to 10 vectors
5517 WRITE(*,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5518 WRITE(lup,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5519 DO j=1,nagb
5520 ij=j+(i-1)*nagb ! index with eigenvector array
5521 IF(j <= nvgb) THEN
5522 itgbi=globalparvartototal(j)
5523 label=globalparlabelindex(1,itgbi)
5524 ELSE
5525 label=nvgb-j ! label negative for constraints
5526 END IF
5527 iev=iev+1
5528 labele(iev)=label
5529 compnt(iev)=real(workspaceeigenvectors(ij),mps) ! component
5530 IF(iev == 3) THEN
5531 WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5532 iev=0
5533 END IF
5534 END DO
5535 IF(iev /= 0) WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5536 iev=0
5537 WRITE(lup,*) ' '
5538 END DO
5539
5540 END IF
5541
5542101 FORMAT(1x,' label parameter presigma differ', &
5543 ' error'/ 1x,'-----------',4x,4('-------------'))
5544102 FORMAT(i10,2x,4g14.5,f8.3)
5545103 FORMAT(3(i11,f11.7,2x))
5546110 FORMAT(i10,2x,2g14.5,28x,i12)
5547111 FORMAT(i10,2x,3g14.5,14x,i12)
5548112 FORMAT(i10,2x,4g14.5,i12)
5549113 FORMAT('!',a)
5550END SUBROUTINE prtglo ! print final log file
5551
5552!***********************************************************************
5553
5563SUBROUTINE prtstat
5564 USE mpmod
5565 USE mpdalc
5566
5567 IMPLICIT NONE
5568 REAL(mps):: par
5569 REAL(mps):: presig
5570 INTEGER(mpi) :: icom
5571 INTEGER(mpl) :: icount
5572 INTEGER(mpi) :: ifrst
5573 INTEGER(mpi) :: ilast
5574 INTEGER(mpi) :: inext
5575 INTEGER(mpi) :: itgbi
5576 INTEGER(mpi) :: itgbl
5577 INTEGER(mpi) :: itpgrp
5578 INTEGER(mpi) :: ivgbi
5579 INTEGER(mpi) :: lup
5580 INTEGER(mpi) :: icgrp
5581 INTEGER(mpi) :: ipgrp
5582 INTEGER(mpi) :: j
5583 INTEGER(mpi) :: jpgrp
5584 INTEGER(mpi) :: k
5585 INTEGER(mpi) :: label1
5586 INTEGER(mpi) :: label2
5587 INTEGER(mpi) :: ncon
5588 INTEGER(mpi) :: npair
5589 INTEGER(mpi) :: nstep
5590 CHARACTER :: c1
5591
5592 INTEGER(mpl):: length
5593
5594 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
5595
5596 INTERFACE ! needed for assumed-shape dummy arguments
5597 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
5598 USE mpdef
5599 INTEGER(mpi), INTENT(IN) :: ipgrp
5600 INTEGER(mpi), INTENT(OUT) :: npair
5601 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
5602 END SUBROUTINE ggbmap
5603 END INTERFACE
5604
5605 SAVE
5606 ! ...
5607
5608 lup=09
5609 CALL mvopen(lup,'millepede.res')
5610 WRITE(lup,*) '*** Results of checking input only, no solution performed ***'
5611 WRITE(lup,*) '! === global parameters ==='
5612 WRITE(lup,*) '! fixed-1: by pre-sigma, -2: by entries cut, -3: by iterated entries cut'
5613 IF (ipcntr < 0) THEN
5614 WRITE(lup,*) '! Label Value Pre-sigma SkippedEntries Cons. group Status '
5615 ELSE
5616 WRITE(lup,*) '! Label Value Pre-sigma Entries Cons. group Status '
5617 END IF
5618 !iprlim=10
5619 DO itgbi=1,ntgb ! all parameter variables
5620 itgbl=globalparlabelindex(1,itgbi)
5621 ivgbi=globalparlabelindex(2,itgbi)
5622 icom=globalparcomments(itgbi) ! comment
5623 IF (icom > 0) WRITE(lup,117) listcomments(icom)%text
5624 c1=' '
5625 IF (globalparlabelindex(3,itgbi) == itgbl) c1='>'
5626 par=real(globalparameter(itgbi),mps) ! initial value
5627 presig=real(globalparpresigma(itgbi),mps) ! initial presigma
5628 icount=globalparlabelcounter(itgbi) ! from binary files
5629 IF (ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5630 icgrp=globalparcons(itgbi) ! constraints group
5631
5632 IF (ivgbi <= 0) THEN
5633 ! not used
5634 IF (ivgbi == -4) THEN
5635 WRITE(lup,116) c1,itgbl,par,presig,icount,icgrp
5636 ELSE
5637 WRITE(lup,110) c1,itgbl,par,presig,icount,icgrp,ivgbi
5638 END IF
5639 ELSE
5640 ! variable
5641 WRITE(lup,111) c1,itgbl,par,presig,icount,icgrp
5642 END IF
5643 END DO
5644 ! appearance statistics
5645 IF (icheck > 1) THEN
5646 WRITE(lup,*) '!.'
5647 WRITE(lup,*) '!.Appearance statistics '
5648 WRITE(lup,*) '!. Label First file and record Last file and record #files #paired-par'
5649 DO itgbi=1,ntgb
5650 itpgrp=globalparlabelindex(4,itgbi)
5651 IF (itpgrp > 0) THEN
5652 WRITE(lup,112) globalparlabelindex(1,itgbi), (appearancecounter(itgbi*5+k), k=-4,0), paircounter(itpgrp)
5653 ELSE ! 'empty' parameter
5654 WRITE(lup,112) globalparlabelindex(1,itgbi)
5655 END IF
5656 END DO
5657 END IF
5658 IF (ncgrp > 0) THEN
5659 WRITE(lup,*) '* === constraint groups ==='
5660 IF (icheck == 1) THEN
5661 WRITE(lup,*) '* Group #Cons. Entries First label Last label'
5662 ELSE
5663 WRITE(lup,*) '* Group #Cons. Entries First label Last label Paired label range'
5664 length=ntpgrp+ncgrp
5665 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
5666 END IF
5667 DO icgrp=1, ncgrp
5668 IF (matconsgroups(2,icgrp) <= matconsgroups(3,icgrp)) THEN
5669 label1=globalparlabelindex(1,globalparvartototal(matconsgroups(2,icgrp))) ! first label
5670 label2=globalparlabelindex(1,globalparvartototal(matconsgroups(3,icgrp))) ! last label
5671 ELSE ! empty group/cons.
5672 label1=0
5673 label2=0
5674 END IF
5675 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
5676 WRITE(lup,113) icgrp, ncon,vecconsgroupcounts(icgrp),label1,label2
5677 IF (icheck > 1 .AND. label1 > 0) THEN
5678 ipgrp=globalparlabelindex(4,globalparvartototal(matconsgroups(2,icgrp))) ! first par. group
5679 ! get paired parameter groups
5680 CALL ggbmap(ntpgrp+icgrp,npair,vecpairedpargroups)
5681 vecpairedpargroups(npair+1)=0
5682 ifrst=0
5683 nstep=1
5684 DO j=1, npair
5685 jpgrp=vecpairedpargroups(j)
5686 inext=globaltotindexgroups(1,jpgrp)
5687 DO k=1,globaltotindexgroups(2,jpgrp)
5688 ! end of continous region ?
5689 IF (ifrst /= 0.AND.inext /= (ilast+nstep)) THEN
5690 label1=globalparlabelindex(1,ifrst)
5691 label2=globalparlabelindex(1,ilast)
5692 WRITE(lup,114) label1, label2
5693 ifrst=0
5694 END IF
5695 ! skip 'self-correlations'
5696 IF (globalparcons(inext) /= icgrp) THEN
5697 IF (ifrst == 0) ifrst=inext
5698 ilast=inext
5699 END IF
5700 inext=inext+1
5701 nstep=1
5702 END DO
5703 ! skip 'empty' parameter
5704 IF (jpgrp == vecpairedpargroups(j+1)-1) THEN
5705 nstep=globaltotindexgroups(1,vecpairedpargroups(j+1)) &
5706 -(globaltotindexgroups(1,jpgrp)+globaltotindexgroups(2,jpgrp)-1)
5707 END IF
5708 END DO
5709 IF (ifrst /= 0) THEN
5710 label1=globalparlabelindex(1,ifrst)
5711 label2=globalparlabelindex(1,ilast)
5712 WRITE(lup,114) label1, label2
5713 END IF
5714 END IF
5715 END DO
5716 IF (icheck > 1) THEN
5717 WRITE(lup,*) '*.'
5718 WRITE(lup,*) '*.Appearance statistics '
5719 WRITE(lup,*) '*. Group First file and record Last file and record #files'
5720 DO icgrp=1, ncgrp
5721 WRITE(lup,115) icgrp, (appearancecounter((ntgb+icgrp)*5+k), k=-4,0)
5722 END DO
5723 END IF
5724 END IF
5725
5726 rewind lup
5727 CLOSE(unit=lup)
5728
5729110 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' fixed',i2)
5730111 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' variable')
5731112 FORMAT(' !.',i10,6i11)
5732113 FORMAT(' * ',i6,i8,3i12)
5733114 FORMAT(' *:',48x,i12,' ..',i12)
5734115 FORMAT(' *.',i10,5i11)
5735116 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' redundant')
5736117 FORMAT(' !!',a)
5737END SUBROUTINE prtstat ! print input statistics
5738
5739
5753
5754SUBROUTINE avprds(n,l,x,is,ie,b)
5755 USE mpmod
5756
5757 IMPLICIT NONE
5758 INTEGER(mpi) :: i
5759 INTEGER(mpi) :: ia
5760 INTEGER(mpi) :: ia2
5761 INTEGER(mpi) :: ib
5762 INTEGER(mpi) :: ib2
5763 INTEGER(mpi) :: in
5764 INTEGER(mpi) :: ipg
5765 INTEGER(mpi) :: iproc
5766 INTEGER(mpi) :: ir
5767 INTEGER(mpi) :: j
5768 INTEGER(mpi) :: ja
5769 INTEGER(mpi) :: ja2
5770 INTEGER(mpi) :: jb
5771 INTEGER(mpi) :: jb2
5772 INTEGER(mpi) :: jn
5773 INTEGER(mpi) :: lj
5774
5775 INTEGER(mpi), INTENT(IN) :: n
5776 INTEGER(mpl), INTENT(IN) :: l
5777 REAL(mpd), INTENT(IN) :: x(n)
5778 INTEGER(mpi), INTENT(IN) :: is
5779 INTEGER(mpi), INTENT(IN) :: ie
5780 REAL(mpd), INTENT(OUT) :: b(n)
5781 INTEGER(mpl) :: k
5782 INTEGER(mpl) :: kk
5783 INTEGER(mpl) :: ku
5784 INTEGER(mpl) :: ll
5785 INTEGER(mpl) :: indij
5786 INTEGER(mpl) :: indid
5787 INTEGER(mpl) :: ij
5788 INTEGER(mpi) :: ichunk
5789 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5790 SAVE
5791 ! ...
5792
5793 ichunk=min((n+mthrd-1)/mthrd/8+1,128)
5794 IF(matsto /= 2) THEN
5795 ! full or unpacked (block diagonal) symmetric matrix
5796 ! parallelize row loop
5797 ! private copy of B(N) for each thread, combined at end, init with 0.
5798 ! slot of 128 'I' for next idle thread
5799 !$OMP PARALLEL DO &
5800 !$OMP PRIVATE(J,IJ) &
5801 !$OMP SCHEDULE(DYNAMIC,ichunk)
5802 DO i=1,n
5803 ij=globalrowoffsets(i+l)+l
5804 DO j=is,min(i,ie)
5805 b(i)=b(i)+globalmatd(ij+j)*x(j)
5806 END DO
5807 END DO
5808 !$OMP END PARALLEL DO
5809
5810 !$OMP PARALLEL DO &
5811 !$OMP PRIVATE(J,IJ) &
5812 !$OMP REDUCTION(+:B) &
5813 !$OMP SCHEDULE(DYNAMIC,ichunk)
5814 DO i=is,ie
5815 ij=globalrowoffsets(i+l)+l
5816 DO j=1,i-1
5817 b(j)=b(j)+globalmatd(ij+j)*x(i)
5818 END DO
5819 END DO
5820 !$OMP END PARALLEL DO
5821 ELSE
5822 ! sparse, compressed matrix
5823 IF(sparsematrixoffsets(2,1) /= n) THEN
5824 CALL peend(24,'Aborted, vector/matrix size mismatch')
5825 stop 'AVPRDS: mismatched vector and matrix'
5826 END IF
5827 ! parallelize row (group) loop
5828 ! slot of 1024 'I' for next idle thread
5829 !$OMP PARALLEL DO &
5830 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
5831 !$OMP PRIVATE(IA,IB,IN,JA,JB,IA2,IB2,JA2,JB2) &
5832 !$OMP REDUCTION(+:B) &
5833 !$OMP SCHEDULE(DYNAMIC,ichunk)
5834 DO ipg=1,napgrp
5835 iproc=0
5836 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5837 ! row group
5838 ia=globalallindexgroups(ipg) ! first (global) row
5839 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
5840 in=ib-ia+1 ! number of rows
5841 ! overlap
5842 ia2=max(ia,is)
5843 ib2=min(ib,ie)
5844 ! diagonal elements
5845 IF (ia2 <= ib2) b(ia2:ib2)=b(ia2:ib2)+globalmatd(ia2:ib2)*x(ia2:ib2)
5846 ! off-diagonals double precision
5847 ir=ipg
5848 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5849 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5850 ku=sparsematrixoffsets(1,ir+1)-kk
5851 indid=kk
5852 indij=ll
5853 IF (ku > 0) THEN
5854 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5855 DO i=ia,ib
5856 IF (i <= ie.AND.i >= is) THEN
5857 DO k=1,ku
5858 j=sparsematrixcolumns(indid+k)
5859 b(j)=b(j)+globalmatd(indij+k)*x(i)
5860 END DO
5861 END IF
5862 DO k=1,ku
5863 j=sparsematrixcolumns(indid+k)
5864 IF (j <= ie.AND.j >= is) THEN
5865 b(i)=b(i)+globalmatd(indij+k)*x(j)
5866 END IF
5867 END DO
5868 indij=indij+ku
5869 END DO
5870 ELSE
5871 ! regions of continous column groups
5872 DO k=2,ku-2,2
5873 j=sparsematrixcolumns(indid+k) ! first group
5874 ja=globalallindexgroups(j) ! first (global) column
5875 lj=sparsematrixcolumns(indid+k-1) ! region offset
5876 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5877 jb=ja+jn-1 ! last (global) column
5878 ja2=max(ja,is)
5879 jb2=min(jb,ie)
5880 IF (ja2 <= jb2) THEN
5881 lj=1 ! index (in group region)
5882 DO i=ia,ib
5883 b(i)=b(i)+dot_product(globalmatd(indij+lj+ja2-ja:indij+lj+jb2-ja),x(ja2:jb2))
5884 lj=lj+jn
5885 END DO
5886 END IF
5887 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5888 lj=1
5889 DO j=ja,jb
5890 b(j)=b(j)+dot_product(globalmatd(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),x(ia2:ib2))
5891 lj=lj+1
5892 END DO
5893 END IF
5894 indij=indij+in*jn
5895 END DO
5896 END IF
5897 END IF
5898 ! mixed precision
5899 IF (nspc > 1) THEN
5900 ir=ipg+napgrp+1 ! off-diagonals single precision
5901 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5902 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5903 ku=sparsematrixoffsets(1,ir+1)-kk
5904 indid=kk
5905 indij=ll
5906 IF (ku == 0) cycle
5907 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5908 DO i=ia,ib
5909 IF (i <= ie.AND.i >= is) THEN
5910 DO k=1,ku
5911 j=sparsematrixcolumns(indid+k)
5912 b(j)=b(j)+globalmatf(indij+k)*x(i)
5913 END DO
5914 END IF
5915 DO k=1,ku
5916 j=sparsematrixcolumns(indid+k)
5917 IF (j <= ie.AND.j >= is) THEN
5918 b(i)=b(i)+globalmatf(indij+k)*x(j)
5919 END IF
5920 END DO
5921 indij=indij+ku
5922 END DO
5923 ELSE
5924 ! regions of continous column groups
5925 DO k=2,ku-2,2
5926 j=sparsematrixcolumns(indid+k) ! first group
5927 ja=globalallindexgroups(j) ! first (global) column
5928 lj=sparsematrixcolumns(indid+k-1) ! region offset
5929 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5930 jb=ja+jn-1 ! last (global) column
5931 ja2=max(ja,is)
5932 jb2=min(jb,ie)
5933 IF (ja2 <= jb2) THEN
5934 lj=1 ! index (in group region)
5935 DO i=ia,ib
5936 b(i)=b(i)+dot_product(real(globalmatf(indij+lj+ja2-ja:indij+lj+jb2-ja),mpd),x(ja2:jb2))
5937 lj=lj+jn
5938 END DO
5939 END IF
5940 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5941 lj=1
5942 DO j=ja,jb
5943 b(j)=b(j)+dot_product(real(globalmatf(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),mpd),x(ia2:ib2))
5944 lj=lj+1
5945 END DO
5946 END IF
5947 indij=indij+in*jn
5948 END DO
5949 END IF
5950 END IF
5951 END DO
5952 ENDIF
5953
5954END SUBROUTINE avprds
5955
5967
5968SUBROUTINE avprd0(n,l,x,b)
5969 USE mpmod
5970
5971 IMPLICIT NONE
5972 INTEGER(mpi) :: i
5973 INTEGER(mpi) :: ia
5974 INTEGER(mpi) :: ib
5975 INTEGER(mpi) :: in
5976 INTEGER(mpi) :: ipg
5977 INTEGER(mpi) :: iproc
5978 INTEGER(mpi) :: ir
5979 INTEGER(mpi) :: j
5980 INTEGER(mpi) :: ja
5981 INTEGER(mpi) :: jb
5982 INTEGER(mpi) :: jn
5983 INTEGER(mpi) :: lj
5984
5985 INTEGER(mpi), INTENT(IN) :: n
5986 INTEGER(mpl), INTENT(IN) :: l
5987 REAL(mpd), INTENT(IN) :: x(n)
5988 REAL(mpd), INTENT(OUT) :: b(n)
5989 INTEGER(mpl) :: k
5990 INTEGER(mpl) :: kk
5991 INTEGER(mpl) :: ku
5992 INTEGER(mpl) :: ll
5993 INTEGER(mpl) :: indij
5994 INTEGER(mpl) :: indid
5995 INTEGER(mpl) :: ij
5996 INTEGER(mpi) :: ichunk
5997 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5998 SAVE
5999 ! ...
6000 !$ DO i=1,n
6001 !$ b(i)=0.0_mpd ! reset 'global' B()
6002 !$ END DO
6003 ichunk=min((n+mthrd-1)/mthrd/8+1,1024)
6004 IF(matsto /= 2) THEN
6005 ! full or unpacked (block diagonal) symmetric matrix
6006 ! parallelize row loop
6007 ! private copy of B(N) for each thread, combined at end, init with 0.
6008 ! slot of 1024 'I' for next idle thread
6009 !$OMP PARALLEL DO &
6010 !$OMP PRIVATE(J,IJ) &
6011 !$OMP REDUCTION(+:B) &
6012 !$OMP SCHEDULE(DYNAMIC,ichunk)
6013 DO i=1,n
6014 ij=globalrowoffsets(i+l)+l
6015 b(i)=globalmatd(ij+i)*x(i)
6016 DO j=1,i-1
6017 b(j)=b(j)+globalmatd(ij+j)*x(i)
6018 b(i)=b(i)+globalmatd(ij+j)*x(j)
6019 END DO
6020 END DO
6021 !$OMP END PARALLEL DO
6022 ELSE
6023 ! sparse, compressed matrix
6024 IF(sparsematrixoffsets(2,1) /= n) THEN
6025 CALL peend(24,'Aborted, vector/matrix size mismatch')
6026 stop 'AVPRD0: mismatched vector and matrix'
6027 END IF
6028 ! parallelize row (group) loop
6029 ! slot of 1024 'I' for next idle thread
6030 !$OMP PARALLEL DO &
6031 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
6032 !$OMP PRIVATE(IA,IB,IN,JA,JB) &
6033 !$OMP REDUCTION(+:B) &
6034 !$OMP SCHEDULE(DYNAMIC,ichunk)
6035 DO ipg=1,napgrp
6036 iproc=0
6037 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
6038 ! row group
6039 ia=globalallindexgroups(ipg) ! first (global) row
6040 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6041 in=ib-ia+1 ! number of rows
6042 !
6043 ! diagonal elements
6044 b(ia:ib)=globalmatd(ia:ib)*x(ia:ib)
6045 ! off-diagonals double precision
6046 ir=ipg
6047 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6048 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6049 ku=sparsematrixoffsets(1,ir+1)-kk
6050 indid=kk
6051 indij=ll
6052 IF (ku > 0) THEN
6053 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6054 DO i=ia,ib
6055 DO k=1,ku
6056 j=sparsematrixcolumns(indid+k)
6057 b(j)=b(j)+globalmatd(indij+k)*x(i)
6058 b(i)=b(i)+globalmatd(indij+k)*x(j)
6059 END DO
6060 indij=indij+ku
6061 END DO
6062 ELSE
6063 ! regions of continous column groups
6064 DO k=2,ku-2,2
6065 j=sparsematrixcolumns(indid+k) ! first group
6066 ja=globalallindexgroups(j) ! first (global) column
6067 lj=sparsematrixcolumns(indid+k-1) ! region offset
6068 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6069 jb=ja+jn-1 ! last (global) column
6070 lj=1 ! index (in group region)
6071 DO i=ia,ib
6072 b(i)=b(i)+dot_product(globalmatd(indij+lj:indij+lj+jn-1),x(ja:jb))
6073 lj=lj+jn
6074 END DO
6075 IF (mextnd == 0) THEN
6076 lj=1
6077 DO j=ja,jb
6078 b(j)=b(j)+dot_product(globalmatd(indij+lj:indij+jn*in:jn),x(ia:ib))
6079 lj=lj+1
6080 END DO
6081 END IF
6082 indij=indij+in*jn
6083 END DO
6084 END IF
6085 END IF
6086 ! mixed precision
6087 IF (nspc > 1) THEN
6088 ir=ipg+napgrp+1 ! off-diagonals single precision
6089 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6090 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6091 ku=sparsematrixoffsets(1,ir+1)-kk
6092 indid=kk
6093 indij=ll
6094 IF (ku == 0) cycle
6095 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6096 DO i=ia,ib
6097 DO k=1,ku
6098 j=sparsematrixcolumns(indid+k)
6099 b(j)=b(j)+real(globalmatf(indij+k),mpd)*x(i)
6100 b(i)=b(i)+real(globalmatf(indij+k),mpd)*x(j)
6101 END DO
6102 indij=indij+ku
6103 END DO
6104 ELSE
6105 ! regions of continous column groups
6106 DO k=2,ku-2,2
6107 j=sparsematrixcolumns(indid+k) ! first group
6108 ja=globalallindexgroups(j) ! first (global) column
6109 lj=sparsematrixcolumns(indid+k-1) ! region offset
6110 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6111 jb=ja+jn-1 ! last (global) column
6112 lj=1 ! index (in group region)
6113 DO i=ia,ib
6114 b(i)=b(i)+dot_product(real(globalmatf(indij+lj:indij+lj+jn-1),mpd),x(ja:jb))
6115 lj=lj+jn
6116 END DO
6117 IF (mextnd == 0) THEN
6118 lj=1
6119 DO j=ja,jb
6120 b(j)=b(j)+dot_product(real(globalmatf(indij+lj:indij+jn*in:jn),mpd),x(ia:ib))
6121 lj=lj+1
6122 END DO
6123 END IF
6124 indij=indij+in*jn
6125 END DO
6126 END IF
6127 END IF
6128 END DO
6129 ENDIF
6130
6131END SUBROUTINE avprd0
6132
6133
6136SUBROUTINE anasps
6137 USE mpmod
6138
6139 IMPLICIT NONE
6140 INTEGER(mpi) :: ia
6141 INTEGER(mpi) :: ib
6142 INTEGER(mpi) :: ipg
6143 INTEGER(mpi) :: ir
6144 INTEGER(mpi) :: ispc
6145 INTEGER(mpi) :: lj
6146 REAL(mps) :: avg
6147
6148
6149 INTEGER(mpl) :: in
6150 INTEGER(mpl) :: jn
6151 INTEGER(mpl) :: k
6152 INTEGER(mpl) :: kk
6153 INTEGER(mpl) :: ku
6154 INTEGER(mpl) :: ll
6155 INTEGER(mpl) :: indid
6156 INTEGER(mpl), DIMENSION(12) :: icount
6157 SAVE
6158
6159 ! require sparse storage
6160 IF(matsto /= 2) RETURN
6161 ! reset
6162 icount=0
6163 icount(4)=huge(icount(4))
6164 icount(7)=huge(icount(7))
6165 icount(10)=huge(icount(10))
6166 ! loop over precisions
6167 DO ispc=1,nspc
6168 ! loop over row groups
6169 DO ipg=1,napgrp
6170 ! row group
6171 ia=globalallindexgroups(ipg) ! first (global) row
6172 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6173 in=ib-ia+1 ! number of rows
6174
6175 ir=ipg+(ispc-1)*(napgrp+1)
6176 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6177 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6178 ku=sparsematrixoffsets(1,ir+1)-kk
6179 indid=kk
6180 IF (ku == 0) cycle
6181 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6182 icount(1)=icount(1)+in
6183 icount(2)=icount(2)+in*ku
6184 ELSE
6185 ! regions of continous column groups
6186 DO k=2,ku-2,2
6187 lj=sparsematrixcolumns(indid+k-1) ! region offset
6188 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6189 icount(3)=icount(3)+1 ! block (region) counter
6190 icount(4)=min(icount(4),jn) ! min number of columns per block (region)
6191 icount(5)=icount(5)+jn ! sum number of columns per block (region)
6192 icount(6)=max(icount(6),jn) ! max number of columns per block (region)
6193 icount(7)=min(icount(7),in) ! min number of rows per block (region)
6194 icount(8)=icount(8)+in ! sum number of rows per block (region)
6195 icount(9)=max(icount(9),in) ! max number of rows per block (region)
6196 icount(10)=min(icount(10),in*jn) ! min number of elements per block (region)
6197 icount(11)=icount(11)+in*jn ! sum number of elements per block (region)
6198 icount(12)=max(icount(12),in*jn) ! max number of elements per block (region)
6199 END DO
6200 END IF
6201 END DO
6202 END DO
6203
6204 WRITE(*,*) "analysis of sparsity structure"
6205 IF (icount(1) > 0) THEN
6206 WRITE(*,101) "rows without compression/blocks ", icount(1)
6207 WRITE(*,101) " contained elements ", icount(2)
6208 ENDIF
6209 WRITE(*,101) "number of block matrices ", icount(3)
6210 avg=real(icount(5),mps)/real(icount(3),mps)
6211 WRITE(*,101) "number of columns (min,mean,max) ", icount(4), avg, icount(6)
6212 avg=real(icount(8),mps)/real(icount(3),mps)
6213 WRITE(*,101) "number of rows (min,mean,max) ", icount(7), avg, icount(9)
6214 avg=real(icount(11),mps)/real(icount(3),mps)
6215 WRITE(*,101) "number of elements (min,mean,max) ", icount(10), avg, icount(12)
6216101 FORMAT(2x,a34,i10,f10.3,i10)
6217
6218END SUBROUTINE anasps
6219
6229
6230SUBROUTINE avprod(n,x,b)
6231 USE mpmod
6232
6233 IMPLICIT NONE
6234
6235 INTEGER(mpi), INTENT(IN) :: n
6236 REAL(mpd), INTENT(IN) :: x(n)
6237 REAL(mpd), INTENT(OUT) :: b(n)
6238
6239 SAVE
6240 ! ...
6241 IF(n > nagb) THEN
6242 CALL peend(24,'Aborted, vector/matrix size mismatch')
6243 stop 'AVPROD: mismatched vector and matrix'
6244 END IF
6245 ! input to AVPRD0
6246 vecxav(1:n)=x
6247 vecxav(n+1:nagb)=0.0_mpd
6248 !use elimination for constraints ?
6249 IF(n < nagb) CALL qlmlq(vecxav,1,.false.) ! Q*x
6250 ! calclulate vecBav=globalMat*vecXav
6251 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
6252 !use elimination for constraints ?
6253 IF(n < nagb) CALL qlmlq(vecbav,1,.true.) ! Q^t*x
6254 ! output from AVPRD0
6255 b=vecbav(1:n)
6256
6257END SUBROUTINE avprod
6258
6259
6269
6270SUBROUTINE ijpgrp(itema,itemb,ij,lr,iprc)
6271 USE mpmod
6272
6273 IMPLICIT NONE
6274 INTEGER(mpi) :: ispc
6275 INTEGER(mpi) :: item1
6276 INTEGER(mpi) :: item2
6277 INTEGER(mpi) :: itemc
6278 INTEGER(mpi) :: jtem
6279 INTEGER(mpi) :: jtemn
6280 INTEGER(mpi) :: np
6281
6282 INTEGER(mpi), INTENT(IN) :: itema
6283 INTEGER(mpi), INTENT(IN) :: itemb
6284 INTEGER(mpl), INTENT(OUT) :: ij
6285 INTEGER(mpi), INTENT(OUT) :: lr
6286 INTEGER(mpi), INTENT(OUT) :: iprc
6287
6288 INTEGER(mpl) :: k
6289 INTEGER(mpl) :: kk
6290 INTEGER(mpl) :: kl
6291 INTEGER(mpl) :: ku
6292 INTEGER(mpl) :: ll
6293 ! ...
6294 ij=0
6295 lr=0
6296 iprc=0
6297 item1=max(itema,itemb) ! larger index
6298 item2=min(itema,itemb) ! smaller index
6299 IF(item2 <= 0.OR.item1 > napgrp) RETURN
6300 np=globalallindexgroups(item1+1)-globalallindexgroups(item1) ! size of group item1
6301 ! loop over precisions
6302 outer: DO ispc=1,nspc
6303 kk=sparsematrixoffsets(1,item1) ! offset (column lists)
6304 ll=sparsematrixoffsets(2,item1) ! offset (matrix)
6305 kl=1
6306 ku=sparsematrixoffsets(1,item1+1)-kk
6307 item1=item1+napgrp+1
6308 iprc=ispc
6309 IF (sparsematrixcolumns(kk+1) == 0) THEN ! compression ?
6310 ! compressed (list of continous regions of parameter groups (pairs of offset and 1. group index)
6311 kl=2
6312 ku=ku-2
6313 IF(ku < kl) cycle outer ! not found
6314 DO
6315 k=2*((kl+ku)/4) ! binary search
6316 jtem=sparsematrixcolumns(kk+k) ! first column (group) of region
6317 jtemn=sparsematrixcolumns(kk+k+2) ! first column (group) after region
6318 IF(item2 >= jtem.AND.item2 < jtemn) THEN
6319 ! length of region
6320 lr=sparsematrixcolumns(kk+k+1)-sparsematrixcolumns(kk+k-1)
6321 IF (globalallindexgroups(item2)-globalallindexgroups(jtem) >= lr) cycle outer ! outside region
6322 EXIT ! found
6323 END IF
6324 IF(item2 < jtem) THEN
6325 ku=k-2
6326 ELSE IF(item2 >= jtemn) THEN
6327 kl=k+2
6328 END IF
6329 IF(kl <= ku) cycle
6330 cycle outer ! not found
6331 END DO
6332 ! group offset in row
6333 ij=sparsematrixcolumns(kk+k-1)
6334 ! absolute offset
6335 ij=ll+ij*np+globalallindexgroups(item2)-globalallindexgroups(jtem)+1
6336
6337 ELSE
6338 ! simple column list
6339 itemc=globalallindexgroups(item2) ! first (col) index of group
6340 lr=int(ku,mpi) ! number of columns
6341 IF(ku < kl) cycle outer ! not found
6342 DO
6343 k=(kl+ku)/2 ! binary search
6344 jtem=sparsematrixcolumns(kk+k)
6345 IF(itemc == jtem) EXIT ! found
6346 IF(itemc < jtem) THEN
6347 ku=k-1
6348 ELSE IF(itemc > jtem) THEN
6349 kl=k+1
6350 END IF
6351 IF(kl <= ku) cycle
6352 cycle outer ! not found
6353 END DO
6354 ij=ll+k
6355
6356 END IF
6357 RETURN
6358 END DO outer
6359
6360END SUBROUTINE ijpgrp
6361
6367
6368FUNCTION ijprec(itema,itemb)
6369 USE mpmod
6370
6371 IMPLICIT NONE
6372
6373 INTEGER(mpi) :: lr
6374 INTEGER(mpl) :: ij
6375
6376 INTEGER(mpi), INTENT(IN) :: itema
6377 INTEGER(mpi), INTENT(IN) :: itemb
6378 INTEGER(mpi) :: ijprec
6379
6380 ! ...
6381 ijprec=1
6382 IF (matsto == 2.AND.nspc > 1) THEN ! sparse storage with mixed precision
6383 ! check groups
6384 CALL ijpgrp(itema,itemb,ij,lr,ijprec)
6385 END IF
6386
6387END FUNCTION ijprec
6388
6396
6397FUNCTION ijadd(itema,itemb) ! index using "d" and "z"
6398 USE mpmod
6399
6400 IMPLICIT NONE
6401
6402 INTEGER(mpi) :: item1
6403 INTEGER(mpi) :: item2
6404 INTEGER(mpi) :: ipg1
6405 INTEGER(mpi) :: ipg2
6406 INTEGER(mpi) :: lr
6407 INTEGER(mpi) :: iprc
6408
6409 INTEGER(mpi), INTENT(IN) :: itema
6410 INTEGER(mpi), INTENT(IN) :: itemb
6411
6412 INTEGER(mpl) :: ijadd
6413 INTEGER(mpl) :: ij
6414 ! ...
6415 ijadd=0
6416 item1=max(itema,itemb) ! larger index
6417 item2=min(itema,itemb) ! smaller index
6418 !print *, ' ijadd ', item1, item2
6419 IF(item2 <= 0.OR.item1 > nagb) RETURN
6420 IF(item1 == item2) THEN ! diagonal element
6421 ijadd=item1
6422 RETURN
6423 END IF
6424 ! ! off-diagonal element
6425 ! get parameter groups
6426 ipg1=globalallpartogroup(item1)
6427 ipg2=globalallpartogroup(item2)
6428 ! get offset for groups
6429 CALL ijpgrp(ipg1,ipg2,ij,lr,iprc)
6430 IF (ij == 0) RETURN
6431 ! add offset inside groups
6432 ijadd=ij+(item2-globalallindexgroups(ipg2))+(item1-globalallindexgroups(ipg1))*lr
6433 ! reduced precision?
6434 IF (iprc > 1) ijadd=-ijadd
6435
6436END FUNCTION ijadd
6437
6445
6446FUNCTION ijcsr3(itema,itemb) ! index using "d" and "z"
6447 USE mpmod
6448
6449 IMPLICIT NONE
6450
6451 INTEGER(mpi) :: item1
6452 INTEGER(mpi) :: item2
6453 INTEGER(mpi) :: jtem
6454
6455 INTEGER(mpi), INTENT(IN) :: itema
6456 INTEGER(mpi), INTENT(IN) :: itemb
6457
6458 INTEGER(mpl) :: ijcsr3
6459 INTEGER(mpl) :: kk
6460 INTEGER(mpl) :: ks
6461 INTEGER(mpl) :: ke
6462
6463 ! ...
6464 ijcsr3=0
6465 item1=max(itema,itemb) ! larger index
6466 item2=min(itema,itemb) ! smaller index
6467 !print *, ' ijadd ', item1, item2
6468 IF(item2 <= 0.OR.item1 > nagb) RETURN
6469 ! start of column list for row
6470 ks=csr3rowoffsets(item2)
6471 ! end of column list for row
6472 ke=csr3rowoffsets(item2+1)-1
6473 ! binary search
6474 IF(ke < ks) THEN
6475 ! empty list
6476 print *, ' IJCSR3 empty list ', item1, item2, ks, ke
6477 CALL peend(23,'Aborted, bad matrix index')
6478 stop 'ijcsr3: empty list'
6479 ENDIF
6480 DO
6481 kk=(ks+ke)/2 ! center of rgion
6482 jtem=int(csr3columnlist(kk),mpi)
6483 IF(item1 == jtem) EXIT ! found
6484 IF(item1 < jtem) THEN
6485 ke=kk-1
6486 ELSE
6487 ks=kk+1
6488 END IF
6489 IF(ks <= ke) cycle
6490 ! not found
6491 print *, ' IJCSR3 not found ', item1, item2, ks, ke
6492 CALL peend(23,'Aborted, bad matrix index')
6493 stop 'ijcsr3: not found'
6494 END DO
6495 ijcsr3=kk
6496END FUNCTION ijcsr3
6497
6503
6504FUNCTION matij(itema,itemb)
6505 USE mpmod
6506
6507 IMPLICIT NONE
6508
6509 INTEGER(mpi) :: item1
6510 INTEGER(mpi) :: item2
6511 INTEGER(mpl) :: i
6512 INTEGER(mpl) :: j
6513 INTEGER(mpl) :: ij
6514 INTEGER(mpl) :: ijadd
6515 INTEGER(mpl) :: ijcsr3
6516
6517 INTEGER(mpi), INTENT(IN) :: itema
6518 INTEGER(mpi), INTENT(IN) :: itemb
6519
6520 REAL(mpd) :: matij
6521 ! ...
6522 matij=0.0_mpd
6523 item1=max(itema,itemb) ! larger index
6524 item2=min(itema,itemb) ! smaller index
6525 IF(item2 <= 0.OR.item1 > nagb) RETURN
6526
6527 i=item1
6528 j=item2
6529
6530 IF(matsto < 2) THEN ! full or unpacked (block diagonal) symmetric matrix
6531 ij=globalrowoffsets(i)+j
6532 matij=globalmatd(ij)
6533 ELSE IF(matsto ==2) THEN ! sparse symmetric matrix (custom)
6534 ij=ijadd(item1,item2) ! inline code requires same time
6535 IF(ij > 0) THEN
6536 matij=globalmatd(ij)
6537 ELSE IF (ij < 0) THEN
6538 matij=real(globalmatf(-ij),mpd)
6539 END IF
6540 ELSE ! sparse symmetric matrix (CSR3)
6541 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
6542 ij=ijcsr3(item1,item2) ! inline code requires same time
6543 IF(ij > 0) matij=globalmatd(ij)
6544 ELSE ! sparse symmetric matrix (BSR3)
6545 ! block index
6546 ij=ijcsr3((item1-1)/matbsz+1,(item2-1)/matbsz+1)
6547 IF (ij > 0) THEN
6548 ! index of first element in block
6549 ij=(ij-1)*matbsz*matbsz+1
6550 ! adjust index for position in block
6551 ij=ij+mod(item1-1,matbsz)*matbsz+mod(item2-1,matbsz)
6552 matij=globalmatd(ij)
6553 ENDIF
6554 END IF
6555 END IF
6556
6557END FUNCTION matij
6558
6561
6562SUBROUTINE mhalf2
6563 USE mpmod
6564
6565 IMPLICIT NONE
6566 INTEGER(mpi) :: i
6567 INTEGER(mpi) :: ia
6568 INTEGER(mpi) :: ib
6569 INTEGER(mpi) :: ichunk
6570 INTEGER(mpi) :: in
6571 INTEGER(mpi) :: ipg
6572 INTEGER(mpi) :: ir
6573 INTEGER(mpi) :: ispc
6574 INTEGER(mpi) :: j
6575 INTEGER(mpi) :: ja
6576 INTEGER(mpi) :: jb
6577 INTEGER(mpi) :: jn
6578 INTEGER(mpi) :: lj
6579
6580 INTEGER(mpl) :: ij
6581 INTEGER(mpl) :: ijadd
6582 INTEGER(mpl) :: k
6583 INTEGER(mpl) :: kk
6584 INTEGER(mpl) :: ku
6585 INTEGER(mpl) :: ll
6586 ! ...
6587
6588 ichunk=min((napgrp+mthrd-1)/mthrd/8+1,1024)
6589
6590 DO ispc=1,nspc
6591 ! parallelize row loop
6592 ! slot of 1024 'I' for next idle thread
6593 !$OMP PARALLEL DO &
6594 !$OMP PRIVATE(I,IR,K,KK,LL,KU,IJ,J,LJ) &
6595 !$OMP PRIVATE(IA,IB,IN,JA,JB,JN) &
6596 !$OMP SCHEDULE(DYNAMIC,ichunk)
6597 DO ipg=1,napgrp
6598 ! row group
6599 ia=globalallindexgroups(ipg) ! first (global) row
6600 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6601 in=ib-ia+1 ! number of rows
6602 !
6603 ir=ipg+(ispc-1)*(napgrp+1)
6604 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6605 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6606 ku=sparsematrixoffsets(1,ir+1)-kk
6607 ! regions of continous column groups
6608 DO k=2,ku-2,2
6609 j=sparsematrixcolumns(kk+k) ! first group
6610 ja=globalallindexgroups(j) ! first (global) column
6611 lj=sparsematrixcolumns(kk+k-1) ! region offset
6612 jn=sparsematrixcolumns(kk+k+1)-lj ! number of columns
6613 jb=ja+jn-1 ! last (global) column
6614 ! skip first half
6615 IF (sparsematrixcolumns(kk+k+2) <= ipg) THEN
6616 ll=ll+in*jn
6617 cycle
6618 END IF
6619 ! at diagonal or in second half
6620 DO i=ia,ib ! loop over rows
6621 DO j=ja,jb ! loop over columns
6622 ll=ll+1
6623 IF (j > i) THEN
6624 ij=ijadd(i,j)
6625 IF (ispc==1) THEN
6626 globalmatd(ll)=globalmatd(ij)
6627 ELSE
6628 globalmatf(ll)=globalmatf(-ij)
6629 END IF
6630 END IF
6631 END DO
6632 END DO
6633 END DO
6634 END DO
6635 !$OMP END PARALLEL DO
6636 END DO
6637
6638END SUBROUTINE mhalf2
6639
6648
6649SUBROUTINE sechms(deltat,nhour,minut,secnd)
6650 USE mpdef
6651
6652 IMPLICIT NONE
6653 REAL(mps), INTENT(IN) :: deltat
6654 INTEGER(mpi), INTENT(OUT) :: minut
6655 INTEGER(mpi), INTENT(OUT):: nhour
6656 REAL(mps), INTENT(OUT):: secnd
6657 INTEGER(mpi) :: nsecd
6658 ! DELTAT = time in sec -> NHOUR,MINUT,SECND
6659 ! ...
6660 nsecd=nint(deltat,mpi) ! -> integer
6661 nhour=nsecd/3600
6662 minut=nsecd/60-60*nhour
6663 secnd=deltat-60*(minut+60*nhour)
6664END SUBROUTINE sechms
6665
6693
6694INTEGER(mpi) FUNCTION inone(item) ! translate 1-D identifier to nrs
6695 USE mpmod
6696 USE mpdalc
6697
6698 IMPLICIT NONE
6699 INTEGER(mpi), INTENT(IN) :: item
6700 INTEGER(mpi) :: j
6701 INTEGER(mpi) :: k
6702 INTEGER(mpi) :: iprime
6703 INTEGER(mpl) :: length
6704 INTEGER(mpl), PARAMETER :: four = 4
6705
6706 inone=0
6707 !print *, ' INONE ', item
6708 IF(item <= 0) RETURN
6709 IF(globalparheader(-1) == 0) THEN
6710 length=128 ! initial number
6711 CALL mpalloc(globalparlabelindex,four,length,'INONE: label & index')
6712 CALL mpalloc(globalparlabelcounter,length,'INONE: counter') ! updated in pargrp
6713 CALL mpalloc(globalparhashtable,2*length,'INONE: hash pointer')
6715 globalparheader(-0)=int(length,mpi) ! length of labels/indices
6716 globalparheader(-1)=0 ! number of stored items
6717 globalparheader(-2)=0 ! =0 during build-up
6718 globalparheader(-3)=int(length,mpi) ! next number
6719 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number
6720 globalparheader(-5)=0 ! number of overflows
6721 globalparheader(-6)=0 ! nr of variable parameters
6722 globalparheader(-8)=0 ! number of sorted items
6723 END IF
6724 outer: DO
6725 j=1+mod(item,globalparheader(-4))+globalparheader(-0)
6726 inner: DO ! normal case: find item
6727 k=j
6729 IF(j == 0) EXIT inner ! unused hash code
6730 IF(item == globalparlabelindex(1,j)) EXIT outer ! found
6731 END DO inner
6732 ! not found
6733 IF(globalparheader(-1) == globalparheader(-0).OR.globalparheader(-2) /= 0) THEN
6734 globalparheader(-5)=globalparheader(-5)+1 ! overflow
6735 j=0
6736 RETURN
6737 END IF
6738 globalparheader(-1)=globalparheader(-1)+1 ! increase number of elements
6740 j=globalparheader(-1)
6741 globalparhashtable(k)=j ! hash index
6742 globalparlabelindex(1,j)=item ! add new item
6743 globalparlabelindex(2,j)=0 ! reset index (for variable par.)
6744 globalparlabelindex(3,j)=0 ! reset group info (first label)
6745 globalparlabelindex(4,j)=0 ! reset group info (group index)
6746 globalparlabelcounter(j)=0 ! reset (long) counter
6747 IF(globalparheader(-1) /= globalparheader(-0)) EXIT outer
6748 ! update with larger dimension and redefine index
6750 CALL upone
6751 IF (lvllog > 1) WRITE(lunlog,*) 'INONE: array increased to', &
6752 globalparheader(-3),' words'
6753 END DO outer
6754
6755 ! counting now in pargrp
6756 !IF(globalParHeader(-2) == 0) THEN
6757 ! globalParLabelIndex(2,j)=globalParLabelIndex(2,j)+1 ! increase counter
6758 ! globalParHeader(-7)=globalParHeader(-7)+1
6759 !END IF
6760 inone=j
6761END FUNCTION inone
6762
6764SUBROUTINE upone
6765 USE mpmod
6766 USE mpdalc
6767
6768 IMPLICIT NONE
6769 INTEGER(mpi) :: i
6770 INTEGER(mpi) :: j
6771 INTEGER(mpi) :: k
6772 INTEGER(mpi) :: iprime
6773 INTEGER(mpi) :: nused
6774 LOGICAL :: finalUpdate
6775 INTEGER(mpl) :: oldLength
6776 INTEGER(mpl) :: newLength
6777 INTEGER(mpl), PARAMETER :: four = 4
6778 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArr
6779 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: tempVec
6780 SAVE
6781 ! ...
6782 finalupdate=(globalparheader(-3) == globalparheader(-1))
6783 IF(finalupdate) THEN ! final (cleanup) call
6784 IF (globalparheader(-1) > globalparheader(-8)) THEN
6787 END IF
6788 END IF
6789 ! save old LabelIndex
6790 nused = globalparheader(-1)
6791 oldlength = globalparheader(-0)
6792 CALL mpalloc(temparr,four,oldlength,'INONE: temp array')
6793 temparr(:,1:nused)=globalparlabelindex(:,1:nused)
6794 CALL mpalloc(tempvec,oldlength,'INONE: temp vector')
6795 tempvec(1:nused)=globalparlabelcounter(1:nused)
6799 ! create new LabelIndex
6800 newlength = globalparheader(-3)
6801 CALL mpalloc(globalparlabelindex,four,newlength,'INONE: label & index')
6802 CALL mpalloc(globalparlabelcounter,newlength,'INONE: counter')
6803 CALL mpalloc(globalparhashtable,2*newlength,'INONE: hash pointer')
6805 globalparlabelindex(:,1:nused) = temparr(:,1:nused) ! copy back saved content
6806 globalparlabelcounter(1:nused) = tempvec(1:nused) ! copy back saved content
6807 CALL mpdealloc(tempvec)
6808 CALL mpdealloc(temparr)
6809 globalparheader(-0)=int(newlength,mpi) ! length of labels/indices
6811 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number < LNDA
6812 ! redefine hash
6813 outer: DO i=1,globalparheader(-1)
6815 inner: DO
6816 k=j
6818 IF(j == 0) EXIT inner ! unused hash code
6819 IF(j == i) cycle outer ! found
6820 ENDDO inner
6822 END DO outer
6823 IF(.NOT.finalupdate) RETURN
6824
6825 globalparheader(-2)=1 ! set flag to inhibit further updates
6826 IF (lvllog > 1) THEN
6827 WRITE(lunlog,*) ' '
6828 WRITE(lunlog,*) 'INONE: array reduced to',newlength,' words'
6829 WRITE(lunlog,*) 'INONE:',globalparheader(-1),' items stored.'
6830 END IF
6831END SUBROUTINE upone ! update, redefine
6832
6834SUBROUTINE useone
6835 USE mpmod
6836
6837 IMPLICIT NONE
6838 INTEGER(mpi) :: i
6839 INTEGER(mpi) :: j
6840 INTEGER(mpi) :: k
6841 SAVE
6842 ! ...
6843 IF (globalparheader(-1) > globalparheader(-8)) THEN
6845 ! redefine hash
6847 outer: DO i=1,globalparheader(-1)
6849 inner: DO
6850 k=j
6852 IF(j == 0) EXIT inner ! unused hash code
6853 IF(j == i) cycle outer ! found
6854 ENDDO inner
6856 END DO outer
6858 END IF
6859END SUBROUTINE useone ! make usable
6860
6865
6866INTEGER(mpi) FUNCTION iprime(n)
6867 USE mpdef
6868
6869 IMPLICIT NONE
6870 INTEGER(mpi), INTENT(IN) :: n
6871 INTEGER(mpi) :: nprime
6872 INTEGER(mpi) :: nsqrt
6873 INTEGER(mpi) :: i
6874 ! ...
6875 SAVE
6876 nprime=n ! max number
6877 IF(mod(nprime,2) == 0) nprime=nprime+1 ! ... odd number
6878 outer: DO
6879 nprime=nprime-2 ! next lower odd number
6880 nsqrt=int(sqrt(real(nprime,mps)),mpi)
6881 DO i=3,nsqrt,2 !
6882 IF(i*(nprime/i) == nprime) cycle outer ! test prime number
6883 END DO
6884 EXIT outer ! found
6885 END DO outer
6886 iprime=nprime
6887END FUNCTION iprime
6888
6898SUBROUTINE loop1
6899 USE mpmod
6900 USE mpdalc
6901
6902 IMPLICIT NONE
6903 INTEGER(mpi) :: i
6904 INTEGER(mpi) :: idum
6905 INTEGER(mpi) :: in
6906 INTEGER(mpi) :: indab
6907 INTEGER(mpi) :: itgbi
6908 INTEGER(mpi) :: itgbl
6909 INTEGER(mpi) :: ivgbi
6910 INTEGER(mpi) :: j
6911 INTEGER(mpi) :: jgrp
6912 INTEGER(mpi) :: lgrp
6913 INTEGER(mpi) :: mqi
6914 INTEGER(mpi) :: nc31
6915 INTEGER(mpi) :: nr
6916 INTEGER(mpi) :: nwrd
6917 INTEGER(mpi) :: inone
6918 REAL(mpd) :: param
6919 REAL(mpd) :: presg
6920 REAL(mpd) :: prewt
6921
6922 INTEGER(mpl) :: length
6923 INTEGER(mpl) :: rows
6924 SAVE
6925 ! ...
6926 WRITE(lunlog,*) ' '
6927 WRITE(lunlog,*) 'LOOP1: starting'
6928 CALL mstart('LOOP1')
6929
6930 ! add labels from parameter, constraints, measurements, comments -------------
6931 DO i=1, lenparameters
6932 idum=inone(listparameters(i)%label)
6933 END DO
6934 DO i=1, lenpresigmas
6935 idum=inone(listpresigmas(i)%label)
6936 END DO
6937 DO i=1, lenconstraints
6938 idum=inone(listconstraints(i)%label)
6939 END DO
6940 DO i=1, lenmeasurements
6941 idum=inone(listmeasurements(i)%label)
6942 END DO
6943 DO i=1, lencomments
6944 idum=inone(listcomments(i)%label)
6945 END DO
6946
6947 IF(globalparheader(-1) /= 0) THEN
6948 WRITE(lunlog,*) 'LOOP1:',globalparheader(-1), ' labels from txt data stored'
6949 END IF
6950 WRITE(lunlog,*) 'LOOP1: reading data files'
6951
6952 neqn=0 ! number of equations
6953 negb=0 ! number of equations with global parameters
6954 ndgb=0 ! number of global derivatives
6955 nzgb=0 ! number of zero global derivatives
6956 DO
6957 DO j=1,globalparheader(-1)
6958 globalparlabelindex(2,j)=0 ! reset count
6959 END DO
6960
6961 ! read all data files and add all labels to global labels table ----
6962
6963 IF(mprint /= 0) THEN
6964 WRITE(*,*) 'Read all binary data files:'
6965 END IF
6966 CALL hmpldf(1,'Number of words/record in binary file')
6967 CALL hmpdef(8,0.0,60.0,'not_stored data per record')
6968 ! define read buffer
6969 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
6970 nwrd=nc31+1
6971 length=nwrd*mthrdr
6972 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
6973 nwrd=nc31*10+2+ndimbuf
6974 length=nwrd*mthrdr
6975 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
6976 CALL mpalloc(readbufferdatad,length,'read buffer, double')
6977 ! to read (old) float binary files
6978 length=(ndimbuf+2)*mthrdr
6979 CALL mpalloc(readbufferdataf,length,'read buffer, float')
6980
6981 DO
6982 CALL peread(nr) ! read records
6983 IF (skippedrecords == 0) THEN
6984 CALL peprep(0) ! prepare records
6985 CALL pepgrp ! update parameter group info
6986 END IF
6987 IF(nr <= 0) EXIT ! end of data?
6988 END DO
6989 ! release read buffer
6994 IF (skippedrecords == 0) THEN
6995 EXIT
6996 ELSE
6997 WRITE(lunlog,*) 'LOOP1: reading data files again'
6998 END IF
6999 END DO
7000
7001 IF(nhistp /= 0) THEN
7002 CALL hmprnt(1)
7003 CALL hmprnt(8)
7004 END IF
7005 CALL hmpwrt(1)
7006 CALL hmpwrt(8)
7007 ntgb = globalparheader(-1) ! total number of labels/parameters
7008 IF (ntgb == 0) THEN
7009 CALL peend(21,'Aborted, no labels/parameters defined')
7010 stop 'LOOP1: no labels/parameters defined'
7011 END IF
7012 CALL upone ! finalize the global label table
7013
7014 WRITE(lunlog,*) 'LOOP1:',ntgb, &
7015 ' is total number NTGB of labels/parameters'
7016 ! histogram number of entries per label ----------------------------
7017 CALL hmpldf(2,'Number of entries per label')
7018 DO j=1,ntgb
7019 CALL hmplnt(2,globalparlabelindex(2,j))
7020 END DO
7021 IF(nhistp /= 0) CALL hmprnt(2) ! print histogram
7022 CALL hmpwrt(2) ! write to his file
7023
7024 ! three subarrays for all global parameters ------------------------
7025 length=ntgb
7026 CALL mpalloc(globalparameter,length,'global parameters')
7027 globalparameter=0.0_mpd
7028 CALL mpalloc(globalparpresigma,length,'pre-sigmas') ! presigmas
7030 CALL mpalloc(globalparstart,length,'global parameters at start')
7032 CALL mpalloc(globalparcopy,length,'copy of global parameters')
7033 CALL mpalloc(globalparcons,length,'global parameter constraints')
7035 CALL mpalloc(globalparcomments,length,'global parameter comments')
7037
7038 DO i=1,lenparameters ! parameter start values
7039 param=listparameters(i)%value
7040 in=inone(listparameters(i)%label)
7041 IF(in /= 0) THEN
7042 globalparameter(in)=param
7043 globalparstart(in)=param
7044 ENDIF
7045 END DO
7046
7047 DO i=1, lencomments
7048 in=inone(listcomments(i)%label)
7049 IF(in /= 0) globalparcomments(in)=i
7050 END DO
7051
7052 npresg=0
7053 DO i=1,lenpresigmas ! pre-sigma values
7054 presg=listpresigmas(i)%value
7055 in=inone(listpresigmas(i)%label)
7056 IF(in /= 0) THEN
7057 IF(presg > 0.0) npresg=npresg+1 ! FIXME: check if enough 'entries'?
7058 globalparpresigma(in)=presg ! insert pre-sigma 0 or > 0
7059 END IF
7060 END DO
7061 WRITE(lunlog,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7062 WRITE(*,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7063 IF(npresg == 0) WRITE(*,*) 'Warning: no pre-sigmas defined'
7064
7065 ! build constraint groups, check for redundancy constrints
7066 CALL grpcon
7067
7068 ! determine flag variable (active) or fixed (inactive) -------------
7069
7070 indab=0
7071 DO i=1,ntgb
7072 IF (globalparpresigma(i) < 0.0) THEN
7073 globalparlabelindex(2,i)=-1 ! fixed (pre-sigma), not used in matrix (not active)
7074 ELSE IF(globalparlabelcounter(i) < mreqenf) THEN
7075 globalparlabelindex(2,i)=-2 ! fixed (entries cut), not used in matrix (not active)
7076 ELSE IF (globalparcons(i) < 0) THEN
7077 globalparlabelindex(2,i)=-4 ! fixed (redundant), not used in matrix (not active)
7078 ELSE
7079 indab=indab+1
7080 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7081 END IF
7082 END DO
7083 globalparheader(-6)=indab ! counted variable
7084 nvgb=indab ! nr of variable parameters
7085 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7086 IF(iteren > mreqenf) THEN
7087 IF (mcount == 0) THEN
7088 CALL loop1i ! iterate entries cut
7089 ELSE
7090 WRITE(lunlog,*) 'LOOP1: counting records, NO iteration of entries cut !'
7091 iteren=0
7092 END IF
7093 END IF
7094
7095 ! --- check for parameter groups
7096 CALL hmpdef(15,0.0,120.0,'Number of parameters per group')
7097 ntpgrp=0
7098 DO j=1,ntgb
7099 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7100 ! new group?
7102 globalparlabelindex(4,j)=ntpgrp ! relation total index -> group
7103 END DO
7104 ! check variable parameters
7105 nvpgrp=0
7106 lgrp=-1
7107 DO j=1,ntgb
7108 IF (globalparlabelindex(2,j) <= 0) cycle ! skip fixed parameter
7109 ! new group ?
7110 IF (globalparlabelindex(4,j) /= lgrp) nvpgrp=nvpgrp+1
7111 lgrp=globalparlabelindex(4,j)
7112 END DO
7113 length=ntpgrp; rows=2
7114 CALL mpalloc(globaltotindexgroups,rows,length,'parameter groups, 1. index and size')
7116 ! fill
7117 lgrp=-1
7118 DO j=1,ntgb
7119 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7120 jgrp=globalparlabelindex(4,j)
7121 IF (jgrp /= lgrp) globaltotindexgroups(1,jgrp)=j ! first (total) index
7122 globaltotindexgroups(2,jgrp)=globaltotindexgroups(2,jgrp)+1 ! (total) size
7123 lgrp=jgrp
7124 END DO
7125 DO j=1,ntpgrp
7126 CALL hmpent(15,real(globaltotindexgroups(2,j),mps))
7127 END DO
7128 IF(nhistp /= 0) CALL hmprnt(15) ! print histogram
7129 CALL hmpwrt(15) ! write to his file
7130 WRITE(lunlog,*) 'LOOP1:',ntpgrp, &
7131 ' is total number NTPGRP of label/parameter groups'
7132 !print *, ' globalTotIndexGroups ', globalTotIndexGroups
7133
7134 ! translation table of length NVGB of total global indices ---------
7135 length=nvgb
7136 CALL mpalloc(globalparvartototal,length,'translation table var -> total')
7137 indab=0
7138 DO i=1,ntgb
7139 IF(globalparlabelindex(2,i) > 0) THEN
7140 indab=indab+1
7141 globalparvartototal(indab)=i
7142 END IF
7143 END DO
7144
7145 ! regularization ---------------------------------------------------
7146 CALL mpalloc(globalparpreweight,length,'pre-sigmas weights') ! presigma weights
7147 WRITE(*,112) ' Default pre-sigma =',regpre, &
7148 ' (if no individual pre-sigma defined)'
7149 WRITE(*,*) 'Pre-sigma factor is',regula
7150
7151 IF(nregul == 0) THEN
7152 WRITE(*,*) 'No regularization will be done'
7153 ELSE
7154 WRITE(*,*) 'Regularization will be done, using factor',regula
7155 END IF
7156112 FORMAT(a,e9.2,a)
7157 IF (nvgb <= 0) THEN
7158 CALL peend(22,'Aborted, no variable global parameters')
7159 stop '... no variable global parameters'
7160 ENDIF
7161
7162 DO ivgbi=1,nvgb ! IVGBI = index of variable global parameter
7163 itgbi=globalparvartototal(ivgbi) ! ITGBI = global parameter index
7164 presg=globalparpresigma(itgbi) ! get pre-sigma
7165 prewt=0.0 ! pre-weight
7166 IF(presg > 0.0) THEN
7167 prewt=1.0/presg**2 ! 1/presigma^2
7168 ELSE IF(presg == 0.0.AND.regpre > 0.0) THEN
7169 prewt=1.0/real(regpre**2,mpd) ! default 1/presigma^2
7170 END IF
7171 globalparpreweight(ivgbi)=regula*prewt ! weight = factor / presigma^2
7172 END DO
7173
7174 ! WRITE(*,*) 'GlPa_index GlPa_label array1 array6'
7175 DO i=1,ntgb
7176 itgbl=globalparlabelindex(1,i)
7177 ivgbi=globalparlabelindex(2,i)
7178 IF(ivgbi > 0) THEN
7179 ! WRITE(*,111) I,ITGBL,QM(IND1+I),QM(IND6+IVGBI)
7180 ELSE
7181 ! WRITE(*,111) I,ITGBL,QM(IND1+I)
7182 END IF
7183 END DO
7184 ! 111 FORMAT(I5,I10,F10.5,E12.4)
7185 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7186 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7187 ! To avoid INT(mpi) overflows in diagonalization
7188 IF (metsol == 2.AND.nvgb >= 46340) THEN
7189 metsol=1
7190 WRITE(*,101) 'Too many variable parameters for diagonalization, fallback is inversion'
7191 END IF
7192
7193 ! print overview over important numbers ----------------------------
7194
7195 nrecal=nrec
7196 IF(mprint /= 0) THEN
7197 WRITE(*,*) ' '
7198 WRITE(*,101) ' NREC',nrec,'number of records'
7199 IF (nrecd > 0) WRITE(*,101) ' NRECD',nrec,'number of records containing doubles'
7200 WRITE(*,101) ' NEQN',neqn,'number of equations (measurements)'
7201 WRITE(*,101) ' NEGB',negb,'number of equations with global parameters'
7202 WRITE(*,101) ' NDGB',ndgb,'number of global derivatives'
7203 IF (nzgb > 0) THEN
7204 WRITE(*,101) ' NZGB',nzgb,'number of zero global der. (ignored in entry counts)'
7205 ENDIF
7206 IF (mcount == 0) THEN
7207 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7208 ELSE
7209 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7210 ENDIF
7211 IF(iteren > mreqenf) &
7212 WRITE(*,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7213 WRITE(*,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7214 IF (mreqpe > 1) WRITE(*,101) &
7215 'MREQPE',mreqpe,'required number of pair entries'
7216 IF (msngpe >= 1) WRITE(*,101) &
7217 'MSNGPE',msngpe,'max pair entries single prec. storage'
7218 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7219 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7220 IF(mprint > 1) THEN
7221 WRITE(*,*) ' '
7222 WRITE(*,*) 'Global parameter labels:'
7223 mqi=ntgb
7224 IF(mqi <= 100) THEN
7225 WRITE(*,*) (globalparlabelindex(2,i),i=1,mqi)
7226 ELSE
7227 WRITE(*,*) (globalparlabelindex(2,i),i=1,30)
7228 WRITE(*,*) ' ...'
7229 mqi=((mqi-20)/20)*20+1
7230 WRITE(*,*) (globalparlabelindex(2,i),i=mqi,ntgb)
7231 END IF
7232 END IF
7233 WRITE(*,*) ' '
7234 WRITE(*,*) ' '
7235 END IF
7236 WRITE(8,*) ' '
7237 WRITE(8,101) ' NREC',nrec,'number of records'
7238 IF (nrecd > 0) WRITE(8,101) ' NRECD',nrec,'number of records containing doubles'
7239 WRITE(8,101) ' NEQN',neqn,'number of equations (measurements)'
7240 WRITE(8,101) ' NEGB',negb,'number of equations with global parameters'
7241 WRITE(8,101) ' NDGB',ndgb,'number of global derivatives'
7242 IF (mcount == 0) THEN
7243 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7244 ELSE
7245 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7246 ENDIF
7247 IF(iteren > mreqenf) &
7248 WRITE(8,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7249 WRITE(8,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7250
7251 WRITE(lunlog,*) 'LOOP1: ending'
7252 WRITE(lunlog,*) ' '
7253 CALL mend
7254
7255101 FORMAT(1x,a8,' =',i14,' = ',a)
7256END SUBROUTINE loop1
7257
7265SUBROUTINE loop1i
7266 USE mpmod
7267 USE mpdalc
7268
7269 IMPLICIT NONE
7270 INTEGER(mpi) :: i
7271 INTEGER(mpi) :: ibuf
7272 INTEGER(mpi) :: ij
7273 INTEGER(mpi) :: indab
7274 INTEGER(mpi) :: ist
7275 INTEGER(mpi) :: j
7276 INTEGER(mpi) :: ja
7277 INTEGER(mpi) :: jb
7278 INTEGER(mpi) :: jsp
7279 INTEGER(mpi) :: nc31
7280 INTEGER(mpi) :: nr
7281 INTEGER(mpi) :: nlow
7282 INTEGER(mpi) :: nst
7283 INTEGER(mpi) :: nwrd
7284
7285 INTEGER(mpl) :: length
7286 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: newCounter
7287 SAVE
7288
7289 ! ...
7290 WRITE(lunlog,*) ' '
7291 WRITE(lunlog,*) 'LOOP1: iterating'
7292 WRITE(*,*) ' '
7293 WRITE(*,*) 'LOOP1: iterating'
7294
7295 length=ntgb
7296 CALL mpalloc(newcounter,length,'new entries counter')
7297 newcounter=0
7298
7299 ! define read buffer
7300 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7301 nwrd=nc31+1
7302 length=nwrd*mthrdr
7303 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7304 nwrd=nc31*10+2+ndimbuf
7305 length=nwrd*mthrdr
7306 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7307 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7308 ! to read (old) float binary files
7309 length=(ndimbuf+2)*mthrdr
7310 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7311
7312 DO
7313 CALL peread(nr) ! read records
7314 CALL peprep(1) ! prepare records
7315 DO ibuf=1,numreadbuffer ! buffer for current record
7316 ist=readbufferpointer(ibuf)+1
7318 nwrd=nst-ist+1
7319 DO ! loop over measurements
7320 CALL isjajb(nst,ist,ja,jb,jsp)
7321 IF(ja == 0.AND.jb == 0) EXIT
7322 IF(ja /= 0) THEN
7323 nlow=0
7324 DO j=1,ist-jb
7325 ij=readbufferdatai(jb+j) ! index of global parameter
7326 ij=globalparlabelindex(2,ij) ! change to variable parameter
7327 IF(ij == -2) nlow=nlow+1 ! fixed by entries cut
7328 END DO
7329 IF(nlow == 0) THEN
7330 DO j=1,ist-jb
7331 ij=readbufferdatai(jb+j) ! index of global parameter
7332 newcounter(ij)=newcounter(ij)+1 ! count again
7333 END DO
7334 ENDIF
7335 END IF
7336 END DO
7337 ! end-of-event
7338 END DO
7339 IF(nr <= 0) EXIT ! end of data?
7340 END DO
7341
7342 ! release read buffer
7347
7348 indab=0
7349 DO i=1,ntgb
7350 IF(globalparlabelindex(2,i) > 0) THEN
7351 IF(newcounter(i) >= mreqenf .OR. globalparlabelcounter(i) >= iteren) THEN
7352 indab=indab+1
7353 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7354 ELSE
7355 globalparlabelindex(2,i)=-3 ! fixed (iterated entries cut), not used in matrix (not active)
7356 END IF
7357 END IF
7358 END DO
7359 globalparheader(-6)=indab ! counted variable
7360 nvgb=indab ! nr of variable parameters
7361 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7362 CALL mpdealloc(newcounter)
7363
7364END SUBROUTINE loop1i
7365
7376
7377SUBROUTINE loop2
7378 USE mpmod
7379 USE mpdalc
7380
7381 IMPLICIT NONE
7382 REAL(mps) :: chin2
7383 REAL(mps) :: chin3
7384 REAL(mps) :: cpr
7385 REAL(mps) :: fsum
7386 REAL(mps) :: gbc
7387 REAL(mps) :: gbu
7388 INTEGER(mpi) :: i
7389 INTEGER(mpi) :: ia
7390 INTEGER(mpi) :: ib
7391 INTEGER(mpi) :: ibuf
7392 INTEGER(mpi) :: icblst
7393 INTEGER(mpi) :: icboff
7394 INTEGER(mpi) :: icgb
7395 INTEGER(mpi) :: icgrp
7396 INTEGER(mpi) :: icount
7397 INTEGER(mpi) :: iext
7398 INTEGER(mpi) :: ihis
7399 INTEGER(mpi) :: ij
7400 INTEGER(mpi) :: ij1
7401 INTEGER(mpi) :: ijn
7402 INTEGER(mpi) :: ioff
7403 INTEGER(mpi) :: ipoff
7404 INTEGER(mpi) :: iproc
7405 INTEGER(mpi) :: irecmm
7406 INTEGER(mpi) :: ist
7407 INTEGER(mpi) :: itgbi
7408 INTEGER(mpi) :: itgbij
7409 INTEGER(mpi) :: itgbik
7410 INTEGER(mpi) :: ivgbij
7411 INTEGER(mpi) :: ivgbik
7412 INTEGER(mpi) :: ivpgrp
7413 INTEGER(mpi) :: j
7414 INTEGER(mpi) :: ja
7415 INTEGER(mpi) :: jb
7416 INTEGER(mpi) :: jcgrp
7417 INTEGER(mpi) :: jext
7418 INTEGER(mpi) :: jcgb
7419 INTEGER(mpi) :: jrec
7420 INTEGER(mpi) :: jsp
7421 INTEGER(mpi) :: joff
7422 INTEGER(mpi) :: k
7423 INTEGER(mpi) :: kcgrp
7424 INTEGER(mpi) :: kfile
7425 INTEGER(mpi) :: l
7426 INTEGER(mpi) :: label
7427 INTEGER(mpi) :: labelf
7428 INTEGER(mpi) :: labell
7429 INTEGER(mpi) :: lvpgrp
7430 INTEGER(mpi) :: lu
7431 INTEGER(mpi) :: lun
7432 INTEGER(mpi) :: maeqnf
7433 INTEGER(mpi) :: nall
7434 INTEGER(mpi) :: naeqna
7435 INTEGER(mpi) :: naeqnf
7436 INTEGER(mpi) :: naeqng
7437 INTEGER(mpi) :: npdblk
7438 INTEGER(mpi) :: nc31
7439 INTEGER(mpi) :: ncachd
7440 INTEGER(mpi) :: ncachi
7441 INTEGER(mpi) :: ncachr
7442 INTEGER(mpi) :: ncon
7443 INTEGER(mpi) :: nda
7444 INTEGER(mpi) :: ndf
7445 INTEGER(mpi) :: ndfmax
7446 INTEGER(mpi) :: nfixed
7447 INTEGER(mpi) :: nggd
7448 INTEGER(mpi) :: nggi
7449 INTEGER(mpi) :: nmatmo
7450 INTEGER(mpi) :: noff
7451 INTEGER(mpi) :: npair
7452 INTEGER(mpi) :: npar
7453 INTEGER(mpi) :: nparmx
7454 INTEGER(mpi) :: nr
7455 INTEGER(mpi) :: nrece
7456 INTEGER(mpi) :: nrecf
7457 INTEGER(mpi) :: nrecmm
7458 INTEGER(mpi) :: nst
7459 INTEGER(mpi) :: nwrd
7460 INTEGER(mpi) :: inone
7461 INTEGER(mpi) :: inc
7462 REAL(mps) :: wgh
7463 REAL(mps) :: wolfc3
7464 REAL(mps) :: wrec
7465 REAL(mps) :: chindl
7466
7467 REAL(mpd)::dstat(3)
7468 REAL(mpd)::rerr
7469 INTEGER(mpl):: nblock
7470 INTEGER(mpl):: nbwrds
7471 INTEGER(mpl):: noff8
7472 INTEGER(mpl):: ndimbi
7473 INTEGER(mpl):: ndimsa(4)
7474 INTEGER(mpl):: ndgn
7475 INTEGER(mpl):: nnzero
7476 INTEGER(mpl):: matsiz(2)
7477 INTEGER(mpl):: matwords
7478 INTEGER(mpl):: mbwrds
7479 INTEGER(mpl):: length
7480 INTEGER(mpl):: rows
7481 INTEGER(mpl):: cols
7482 INTEGER(mpl), PARAMETER :: two=2
7483 INTEGER(mpi) :: maxGlobalPar = 0
7484 INTEGER(mpi) :: maxLocalPar = 0
7485 INTEGER(mpi) :: maxEquations = 0
7486
7487 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupList
7488 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupIndex
7489 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
7490 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecBlockCounts
7491
7492 INTERFACE ! needed for assumed-shape dummy arguments
7493 SUBROUTINE ndbits(npgrp,ndims,nsparr,ihst)
7494 USE mpdef
7495 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7496 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7497 INTEGER(mpl), DIMENSION(:,:), INTENT(OUT) :: nsparr
7498 INTEGER(mpi), INTENT(IN) :: ihst
7499 END SUBROUTINE ndbits
7500 SUBROUTINE ckbits(npgrp,ndims)
7501 USE mpdef
7502 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7503 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7504 END SUBROUTINE ckbits
7505 SUBROUTINE spbits(npgrp,nsparr,nsparc)
7506 USE mpdef
7507 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7508 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
7509 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: nsparc
7510 END SUBROUTINE spbits
7511 SUBROUTINE gpbmap(ngroup,npgrp,npair)
7512 USE mpdef
7513 INTEGER(mpi), INTENT(IN) :: ngroup
7514 INTEGER(mpi), DIMENSION(:,:), INTENT(IN) :: npgrp
7515 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npair
7516 END SUBROUTINE gpbmap
7517 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
7518 USE mpdef
7519 INTEGER(mpi), INTENT(IN) :: ipgrp
7520 INTEGER(mpi), INTENT(OUT) :: npair
7521 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
7522 END SUBROUTINE ggbmap
7523 SUBROUTINE pbsbits(npgrp,ibsize,nnzero,nblock,nbkrow)
7524 USE mpdef
7525 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7526 INTEGER(mpi), INTENT(IN) :: ibsize
7527 INTEGER(mpl), INTENT(OUT) :: nnzero
7528 INTEGER(mpl), INTENT(OUT) :: nblock
7529 INTEGER(mpi), DIMENSION(:),INTENT(OUT) :: nbkrow
7530 END SUBROUTINE pbsbits
7531 SUBROUTINE pblbits(npgrp,ibsize,nsparr,nsparc)
7532 USE mpdef
7533 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7534 INTEGER(mpi), INTENT(IN) :: ibsize
7535 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7536 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7537 END SUBROUTINE pblbits
7538 SUBROUTINE prbits(npgrp,nsparr)
7539 USE mpdef
7540 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7541 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparr
7542 END SUBROUTINE prbits
7543 SUBROUTINE pcbits(npgrp,nsparr,nsparc)
7544 USE mpdef
7545 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7546 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7547 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7548 END SUBROUTINE pcbits
7549 END INTERFACE
7550
7551 SAVE
7552
7553 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
7554
7555 ! ...
7556 WRITE(lunlog,*) ' '
7557 WRITE(lunlog,*) 'LOOP2: starting'
7558 CALL mstart('LOOP2')
7559
7560 ! two subarrays to get the global parameter indices, used in an event
7561 length=nvgb
7562 CALL mpalloc(globalindexusage,length,'global index')
7563 CALL mpalloc(backindexusage,length,'back index')
7565 CALL mpalloc(globalindexranges,length,'global index ranges')
7567
7568 length=ntgb
7569 CALL mpalloc(globalparlabelzeros,length,'global label with zero der. counters')
7571
7572 ! prepare constraints - determine number of constraints NCGB
7573 ! - sort and split into blocks
7574 ! - update globalIndexRanges
7575 CALL prpcon
7576
7577 IF (metsol == 3.AND.icelim <= 0) THEN
7578 ! decomposition: enforce elimination
7579 icelim=1
7580 WRITE(lunlog,*) ' Elimination for constraints enforced for solution by decomposition!'
7581 END IF
7582 IF (metsol == 9.AND.icelim > 0) THEN
7583 ! sparsePARDISO: enforce multipliers
7584 icelim=0
7585 WRITE(lunlog,*) ' Lagrange multipliers enforced for solution by sparsePARDISO!'
7586 END IF
7587 IF (matsto > 0.AND.icelim > 1) THEN
7588 ! decomposition: enforce elimination
7589 icelim=1
7590 WRITE(lunlog,*) ' Elimination for constraints with mpqldec enforced (LAPACK only for unpacked storage)!'
7591 END IF
7592 IF (icelim > 0) THEN ! elimination
7593 nagb=nvgb ! total number of parameters
7594 napgrp=nvpgrp ! total number of parameter groups
7595 nfgb=nvgb-ncgb ! number of fit parameters
7596 nprecond(1)=0 ! number of constraints for preconditioner
7597 nprecond(2)=nfgb ! matrix size for preconditioner
7598 nprecond(3)=0 ! number of constraint blocks for preconditioner
7599 ELSE ! Lagrange multipliers
7600 nagb=nvgb+ncgb ! total number of parameters
7601 napgrp=nvpgrp+ncgb ! total number of parameter groups
7602 nfgb=nagb ! number of fit parameters
7603 nprecond(1)=ncgb ! number of constraints for preconditioner
7604 nprecond(2)=nvgb ! matrix size for preconditioner
7605 nprecond(3)=ncblck ! number of constraint blocks for preconditioner
7606 ENDIF
7607 noff8=int(nagb,mpl)*int(nagb-1,mpl)/2
7608
7609 ! all (variable) parameter groups
7610 length=napgrp+1
7611 CALL mpalloc(globalallindexgroups,length,'all parameter groups, 1. index')
7613 ivpgrp=0
7614 lvpgrp=-1
7615 DO i=1,ntgb
7616 ij=globalparlabelindex(2,i)
7617 IF (ij <= 0) cycle ! variable ?
7618 IF (globalparlabelindex(4,i) /= lvpgrp) THEN
7619 ivpgrp=ivpgrp+1
7620 globalallindexgroups(ivpgrp)=ij ! first index
7621 lvpgrp=globalparlabelindex(4,i)
7622 END IF
7623 END DO
7624 ! Lagrange multipliers
7625 IF (napgrp > nvpgrp) THEN
7626 DO jcgb=1, ncgb
7627 ivpgrp=ivpgrp+1
7628 globalallindexgroups(ivpgrp)=nvgb+jcgb
7629 END DO
7630 END IF
7632 ! from all (variable) parameters to group
7633 length=nagb
7634 CALL mpalloc(globalallpartogroup,length,'translation table all (var) par -> group')
7636 DO i=1,napgrp
7639 END DO
7640 END DO
7641 IF (icheck > 2) THEN
7642 print *
7643 print *, ' Variable parameter groups ', nvpgrp
7644 DO i=1,nvpgrp
7646 k=globalparlabelindex(4,itgbi) ! (total) group index
7648 globalparlabelindex(1,itgbi)
7649 END DO
7650 print *
7651 END IF
7652
7653 ! read all data files and add all variable index pairs -------------
7654
7655 IF (icheck > 1) CALL clbmap(ntpgrp+ncgrp)
7656
7657 IF(matsto == 2) THEN
7658 ! MINRES, sparse storage
7659 CALL clbits(napgrp,mreqpe,mhispe,msngpe,mextnd,ndimbi,nspc) ! get dimension for bit storage, encoding, precision info
7660 END IF
7661 IF(matsto == 3) THEN
7662 ! PARDISO, upper triangle (parameter groups) incl. rectangular part (constraints)
7663 CALL plbits(nvpgrp,nvgb,ncgb,ndimbi) ! get dimension for bit storage, global parameters and constraints
7664 END IF
7665
7666 IF (imonit /= 0) THEN
7667 length=ntgb
7668 CALL mpalloc(measindex,length,'measurement counter/index')
7669 measindex=0
7670 CALL mpalloc(measres,length,'measurement resolution')
7671 measres=0.0_mps
7672 lunmon=9
7673 CALL mvopen(lunmon,'millepede.mon')
7674 ENDIF
7675
7676 ! for checking appearance
7677 IF (icheck > 1) THEN
7678 length=5*(ntgb+ncgrp)
7679 CALL mpalloc(appearancecounter,length,'appearance statistics')
7681 length=ntgb
7682 CALL mpalloc(paircounter,length,'pair statistics')
7683 paircounter=0
7684 END IF
7685
7686 ! checking constraint goups
7687 IF (icheck > 0.AND. ncgrp > 0) THEN
7688 length=ncgrp
7689 CALL mpalloc(vecconsgroupcounts,length,'counter for constraint groups')
7691 CALL mpalloc(vecconsgrouplist,length,'constraint group list')
7692 CALL mpalloc(vecconsgroupindex,length,'constraint group index')
7693 vecconsgroupindex=0
7694 END IF
7695
7696 ! reading events===reading events===reading events===reading events=
7697 nrece =0 ! 'empty' records (no variable global parameters)
7698 nrecf =0 ! records with fixed global parameters
7699 naeqng=0 ! count number of equations (with global der.)
7700 naeqnf=0 ! count number of equations ( " , fixed)
7701 naeqna=0 ! all
7702 WRITE(lunlog,*) 'LOOP2: start event reading'
7703 ! monitoring for sparse matrix?
7704 irecmm=0
7705 IF (matsto == 2.AND.matmon /= 0) THEN
7706 nmatmo=0
7707 IF (matmon > 0) THEN
7708 nrecmm=matmon
7709 ELSE
7710 nrecmm=1
7711 END IF
7712 END IF
7713 DO k=1,3
7714 dstat(k)=0.0_mpd
7715 END DO
7716 ! define read buffer
7717 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7718 nwrd=nc31+1
7719 length=nwrd*mthrdr
7720 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7721 nwrd=nc31*10+2+ndimbuf
7722 length=nwrd*mthrdr
7723 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7724 CALL mpalloc(readbufferdatad,length,'read buffer, real')
7725 ! to read (old) float binary files
7726 length=(ndimbuf+2)*mthrdr
7727 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7728
7729 DO
7730 CALL peread(nr) ! read records
7731 CALL peprep(1) ! prepare records
7732 ioff=0
7733 DO ibuf=1,numreadbuffer ! buffer for current record
7734 jrec=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
7735 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7736 nrec=ifd(kfile)+jrec ! global record number
7737 ! Printout for DEBUG
7738 IF(nrec <= mdebug) THEN
7739 nda=0
7740 wrec =real(readbufferdatad(readbufferpointer(ibuf)-1),mps) ! weight
7741 WRITE(*,*) ' '
7742 WRITE(*,*) 'Record number ',nrec,' from file ',kfile
7743 IF (wgh /= 1.0) WRITE(*,*) ' weight ',wrec
7744 ist=readbufferpointer(ibuf)+1
7746 DO ! loop over measurements
7747 CALL isjajb(nst,ist,ja,jb,jsp)
7748 IF(ja == 0) EXIT
7749 nda=nda+1
7750 IF(nda > mdebg2) THEN
7751 IF(nda == mdebg2+1) WRITE(*,*) '... and more data'
7752 cycle
7753 END IF
7754 WRITE(*,*) ' '
7755 WRITE(*,*) nda, ' Measured value =',readbufferdatad(ja),' +- ',readbufferdatad(jb)
7756 WRITE(*,*) 'Local derivatives:'
7757 WRITE(*,107) (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
7758107 FORMAT(6(i3,g12.4))
7759 IF (jb < ist) THEN
7760 WRITE(*,*) 'Global derivatives:'
7761 WRITE(*,108) (globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
7762 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
7763108 FORMAT(3i11,g12.4)
7764 END IF
7765 IF(nda == 1) THEN
7766 WRITE(*,*) 'total_par_label __label__ var_par_index derivative'
7767 END IF
7768 END DO
7769 WRITE(*,*) ' '
7770 END IF
7771
7772 nagbn =0 ! count number of global derivatives
7773 nalcn =0 ! count number of local derivatives
7774 naeqn =0 ! count number of equations
7775 icgrp =0 ! count constraint groups
7776 maeqnf=naeqnf
7777 ist=readbufferpointer(ibuf)+1
7779 nwrd=nst-ist+1
7780 DO ! loop over measurements
7781 CALL isjajb(nst,ist,ja,jb,jsp)
7782 IF(ja == 0.AND.jb == 0) EXIT
7783 naeqn=naeqn+1
7784 naeqna=naeqna+1
7785 IF(ja /= 0) THEN
7786 IF (ist > jb) THEN
7787 naeqng=naeqng+1
7788 ! monitoring, group measurements, sum up entries and errors
7789 IF (imonit /= 0) THEN
7790 rerr =real(readbufferdatad(jb),mpd) ! the error
7791 ij=readbufferdatai(jb+1) ! index of first global parameter, used to group measurements
7792 measindex(ij)=measindex(ij)+1
7793 measres(ij)=measres(ij)+rerr
7794 END IF
7795 END IF
7796 nfixed=0
7797 DO j=1,ist-jb
7798 ij=readbufferdatai(jb+j) ! index of global parameter
7799 IF (nzgb > 0) THEN
7800 ! count zero global derivatives
7801 IF (readbufferdatad(jb+j) == 0.0_mpl) globalparlabelzeros(ij)=globalparlabelzeros(ij)+1
7802 END IF
7803 ! check appearance
7804 IF (icheck > 1) THEN
7805 joff = 5*(ij-1)
7806 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7807 IF (appearancecounter(joff+1) == 0) THEN
7808 appearancecounter(joff+1) = kfile
7809 appearancecounter(joff+2) = jrec ! (local) record number
7810 END IF
7811 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=appearancecounter(joff+5)+1
7812 appearancecounter(joff+3) = kfile
7813 appearancecounter(joff+4) = jrec ! (local) record number
7814 ! count pairs
7815 DO k=1,j
7817 END DO
7818 jcgrp=globalparcons(ij)
7819 ! correlate constraint groups with 'other' parameter groups
7820 DO k=1,j
7821 kcgrp=globalparcons(readbufferdatai(jb+k))
7822 IF (kcgrp == jcgrp) cycle
7823 IF (jcgrp > 0) CALL inbmap(ntpgrp+jcgrp,globalparlabelindex(4,readbufferdatai(jb+k)))
7824 IF (kcgrp > 0) CALL inbmap(ntpgrp+kcgrp,globalparlabelindex(4,ij))
7825 END DO
7826 END IF
7827 ! check constraint groups
7828 IF (icheck > 0.AND.ncgrp > 0) THEN
7829 k=globalparcons(ij) ! constraint group
7830 IF (k > 0) THEN
7831 icount=naeqn
7832 IF (mcount > 0) icount=1 ! count records
7833 IF (vecconsgroupindex(k) == 0) THEN
7834 ! add to list
7835 icgrp=icgrp+1
7836 vecconsgrouplist(icgrp)=k
7837 ! check appearance
7838 IF (icheck > 1) THEN
7839 joff = 5*(ntgb+k-1)
7840 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7841 IF (appearancecounter(joff+1) == 0) THEN
7842 appearancecounter(joff+1) = kfile
7843 appearancecounter(joff+2) = jrec ! (local) record number
7844 END IF
7845 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=&
7846 appearancecounter(joff+5)+1
7847 appearancecounter(joff+3) = kfile
7848 appearancecounter(joff+4) = jrec ! (local) record number
7849 END IF
7850 END IF
7851 IF (vecconsgroupindex(k) < icount) THEN
7852 ! count
7853 vecconsgroupindex(k)=icount
7855 END IF
7856 END IF
7857 END IF
7858
7859 ij=globalparlabelindex(2,ij) ! change to variable parameter
7860 IF(ij > 0) THEN
7861 ijn=backindexusage(ij) ! get index of index
7862 IF(ijn == 0) THEN ! not yet included
7863 nagbn=nagbn+1 ! count
7864 globalindexusage(nagbn)=ij ! store variable index
7865 backindexusage(ij)=nagbn ! store back index
7866 END IF
7867 ELSE
7868 nfixed=nfixed+1
7869 END IF
7870 END DO
7871 IF (nfixed > 0) naeqnf=naeqnf+1
7872 END IF
7873
7874 IF(ja /= 0.AND.jb /= 0) THEN
7875 DO j=1,jb-ja-1 ! local parameters
7876 ij=readbufferdatai(ja+j)
7877 nalcn=max(nalcn,ij)
7878 END DO
7879 END IF
7880 END DO
7881
7882 ! end-of-event
7883 IF (naeqnf > maeqnf) nrecf=nrecf+1
7884 irecmm=irecmm+1
7885 ! end-of-event-end-of-event-end-of-event-end-of-event-end-of-event-e
7886
7887 maxglobalpar=max(nagbn,maxglobalpar) ! maximum number of global parameters
7888 maxlocalpar=max(nalcn,maxlocalpar) ! maximum number of local parameters
7889 maxequations=max(naeqn,maxequations) ! maximum number of equations
7890
7891 ! sample statistics for caching
7892 dstat(1)=dstat(1)+real((nwrd+2)*2,mpd) ! record size
7893 dstat(2)=dstat(2)+real(nagbn+2,mpd) ! indices,
7894 dstat(3)=dstat(3)+real(nagbn*nagbn+nagbn,mpd) ! data for MUPDAT
7895
7896 ! clear constraint groups index
7897 DO k=1, icgrp
7898 vecconsgroupindex(vecconsgrouplist(k))=0
7899 END DO
7900
7901 CALL sort1k(globalindexusage,nagbn) ! sort global par.
7902
7903 IF (nagbn == 0) THEN
7904 nrece=nrece+1
7905 ELSE
7906 ! update parameter range
7909 ENDIF
7910
7911 ! overwrite read buffer with lists of global labels
7912 ioff=ioff+1
7913 readbufferpointer(ibuf)=ioff
7914 readbufferdatai(ioff)=ioff+nagbn
7915 joff=ioff
7916 lvpgrp=-1
7917 DO i=1,nagbn ! reset global index array, store parameter groups
7918 iext=globalindexusage(i)
7919 backindexusage(iext)=0
7920 ivpgrp=globalallpartogroup(iext)
7921 !ivpgrp=iext
7922 IF (ivpgrp /= lvpgrp) THEN
7923 joff=joff+1
7924 readbufferdatai(joff)=ivpgrp
7925 lvpgrp=ivpgrp
7926 END IF
7927 END DO
7928 readbufferdatai(ioff)=joff
7929 ioff=joff
7930
7931 END DO
7932 ioff=0
7933
7934 IF (matsto == 3) THEN
7935 !$OMP PARALLEL &
7936 !$OMP DEFAULT(PRIVATE) &
7937 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7938 iproc=0
7939 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7940 DO ibuf=1,numreadbuffer
7941 ist=readbufferpointer(ibuf)+1
7943 DO i=ist,nst ! store all combinations
7944 iext=readbufferdatai(i) ! variable global index
7945 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct column per thread
7946 DO l=i,nst
7947 jext=readbufferdatai(l)
7948 CALL inbits(iext,jext,1) ! save space
7949 END DO
7950 !$ ENDIF
7951 END DO
7952 END DO
7953 !$OMP END PARALLEL
7954 END IF
7955 IF (matsto == 2) THEN
7956 !$OMP PARALLEL &
7957 !$OMP DEFAULT(PRIVATE) &
7958 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7959 iproc=0
7960 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7961 DO ibuf=1,numreadbuffer
7962 ist=readbufferpointer(ibuf)+1
7964 DO i=ist,nst ! store all combinations
7965 iext=readbufferdatai(i) ! variable global index
7966 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct rows per thread
7967 DO l=ist,i
7968 jext=readbufferdatai(l)
7969 CALL inbits(iext,jext,1) ! save space
7970 END DO
7971 !$ ENDIF
7972 END DO
7973 END DO
7974 !$OMP END PARALLEL
7975 ! monitoring
7976 IF (matmon /= 0.AND. &
7977 (irecmm >= nrecmm.OR.irecmm == mxrec)) THEN
7978 IF (nmatmo == 0) THEN
7979 WRITE(*,*)
7980 WRITE(*,*) 'Monitoring of sparse matrix construction'
7981 WRITE(*,*) ' records ........ off-diagonal elements ', &
7982 '....... compression memory'
7983 WRITE(*,*) ' non-zero used(double) used', &
7984 '(float) [%] [GB]'
7985 END IF
7986 nmatmo=nmatmo+1
7987 CALL ckbits(globalallindexgroups,ndimsa)
7988 gbc=1.0e-9*real((mpi*ndimsa(2)+mpd*ndimsa(3)+mps*ndimsa(4))/mpi*(bit_size(1_mpi)/8),mps) ! GB compressed
7989 gbu=1.0e-9*real(((mpi+mpd)*(ndimsa(3)+ndimsa(4)))/mpi*(bit_size(1_mpi)/8),mps) ! GB uncompressed
7990 cpr=100.0*gbc/gbu
7991 WRITE(*,1177) irecmm,ndimsa(1),ndimsa(3),ndimsa(4),cpr,gbc
79921177 FORMAT(i9,3i13,f10.2,f11.6)
7993 DO WHILE(irecmm >= nrecmm)
7994 IF (matmon > 0) THEN
7995 nrecmm=nrecmm+matmon
7996 ELSE
7997 nrecmm=nrecmm*2
7998 END IF
7999 END DO
8000 END IF
8001
8002 END IF
8003
8004 IF (nr <= 0) EXIT ! next block of events ?
8005 END DO
8006 ! release read buffer
8011
8012 WRITE(lunlog,*) 'LOOP2: event reading ended - end of data'
8013 DO k=1,3
8014 dstat(k)=dstat(k)/real(nrec,mpd)
8015 END DO
8016 ! end=of=data=end=of=data=end=of=data=end=of=data=end=of=data=end=of
8017
8018 IF (icheck > 0.AND. ncgrp > 0) THEN
8019 CALL mpdealloc(vecconsgroupindex)
8020 CALL mpdealloc(vecconsgrouplist)
8021 END IF
8022
8023 IF (icheck > 1) THEN
8025 END IF
8026 IF (icheck > 3) THEN
8027 length=ntpgrp+ncgrp
8028 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
8029 print *
8030 print *, ' Total parameter groups pairs', ntpgrp
8031 DO i=1,ntpgrp
8032 itgbi=globaltotindexgroups(1,i)
8033 CALL ggbmap(i,npair,vecpairedpargroups)
8034 k=globalparlabelindex(4,itgbi) ! (total) group index
8035 print *, i, itgbi, globalparlabelindex(1,itgbi), npair, ':', vecpairedpargroups(:npair)
8036 END DO
8037 print *
8038 END IF
8039
8040 ! check constraints
8041 IF(matsto == 2) THEN
8042
8043 ! constraints and index pairs with Lagrange multiplier
8044 inc=max(mreqpe, msngpe+1) ! keep constraints in double precision
8045
8046 ! loop over (sorted) constraints
8047 DO jcgb=1,ncgb
8048 icgb=matconssort(3,jcgb) ! unsorted constraint index
8049 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8050 label=listconstraints(i)%label
8051 itgbi=inone(label)
8052 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8053 IF(ij > 0 .AND. nagb > nvgb) THEN
8055 END IF
8056 END DO
8057 END DO
8058 END IF
8059 IF(matsto == 3) THEN
8060 ! loop over (sorted) constraints
8061 DO jcgb=1,ncgb
8062 icgb=matconssort(3,jcgb) ! unsorted constraint index
8063 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8064 label=listconstraints(i)%label
8065 itgbi=inone(label)
8066 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8067 IF(ij > 0.AND.listconstraints(i)%value /= 0.0_mpd) THEN
8068 ! non-zero coefficient
8069 CALL irbits(ij,jcgb)
8070 END IF
8071 END DO
8072 END DO
8073 END IF
8074
8075 ! check measurements
8076 IF(matsto == 2 .OR. matsto == 3) THEN
8077 ! measurements - determine index-pairs
8078
8079 i=1
8080 DO WHILE (i <= lenmeasurements)
8081 i=i+2
8082 ! loop over label/factor pairs
8083 ia=i
8084 DO
8085 i=i+1
8086 IF(i > lenmeasurements) EXIT
8087 IF(listmeasurements(i)%label < 0) EXIT
8088 END DO
8089 ib=i-1
8090
8091 DO j=ia,ib
8092 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8093 ! first index
8094 ivgbij=0
8095 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8096 DO k=ia,j
8097 itgbik=inone(listmeasurements(k)%label) ! total parameter index
8098 ! second index
8099 ivgbik=0
8100 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
8101 IF(ivgbij > 0.AND.ivgbik > 0) THEN
8103 IF (mprint > 1) WRITE(*,*) 'add index pair ',ivgbij,ivgbik
8104 END IF
8105 END DO
8106 END DO
8107
8108 END DO
8109 ELSE
8110 ! more checks for block diagonal structure
8111 ! loop over measurements
8112 i=1
8113 DO WHILE (i <= lenmeasurements)
8114 i=i+2
8115 ! loop over label/factor pairs
8116 ia=i
8117 DO
8118 i=i+1
8119 IF(i > lenmeasurements) EXIT
8120 IF(listmeasurements(i)%label < 0) EXIT
8121 END DO
8122 ib=i-1
8123 ij1=nvgb
8124 ijn=1
8125 DO j=ia,ib
8126 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8127 ! first index
8128 ij=0
8129 IF(itgbij /= 0) ij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8130 IF (ij > 0) THEN
8131 ij1=min(ij1,ij)
8132 ijn=max(ijn,ij)
8133 END IF
8134 END DO
8135 globalindexranges(ij1)=max(globalindexranges(ij1),ijn)
8136 END DO
8137
8138 END IF
8139
8140 nummeas=0 ! number of measurement groups
8141 IF (imonit /= 0) THEN
8142 DO i=1,ntgb
8143 IF (measindex(i) > 0) THEN
8145 measres(i) = measres(i)/real(measindex(i),mpd)
8146 measindex(i) = nummeas
8147 END IF
8148 END DO
8149 length=nummeas*mthrd*measbins
8150 CALL mpalloc(meashists,length,'measurement counter')
8151 END IF
8152
8153 ! check for block diagonal structure, count blocks
8154 npblck=0
8155 l=0
8156 DO i=1,nvgb
8157 IF (i > l) npblck=npblck+1
8158 l=max(l,globalindexranges(i))
8159 globalindexranges(i)=npblck ! block number
8160 END DO
8161
8162 length=npblck+1; rows=2
8163 ! parameter blocks
8164 CALL mpalloc(matparblockoffsets,rows,length,'global parameter blocks (I)')
8166 CALL mpalloc(vecparblockconoffsets,length,'global parameter blocks (I)')
8168 ! fill matParBlocks
8169 l=0
8170 DO i=1,nvgb
8171 IF (globalindexranges(i) > l) THEN
8172 l=globalindexranges(i) ! block number
8173 matparblockoffsets(1,l)=i-1 ! block offset
8174 END IF
8175 END DO
8177 nparmx=0
8178 DO i=1,npblck
8179 rows=matparblockoffsets(1,i+1)-matparblockoffsets(1,i)
8180 nparmx=max(nparmx,int(rows,mpi))
8181 END DO
8182
8183 ! connect constraint blocks
8184 DO i=1,ncblck
8185 ia=matconsblocks(2,i) ! first parameter in constraint block
8186 IF (ia > matconsblocks(3,i)) cycle
8187 ib=globalindexranges(ia) ! parameter block number
8188 matparblockoffsets(2,ib+1)=i
8189 END DO
8190
8191 ! use diagonal block matrix storage?
8192 IF (npblck > 1) THEN
8193 IF (icheck > 0) THEN
8194 WRITE(*,*)
8195 DO i=1,npblck
8196 ia=matparblockoffsets(1,i)
8197 ib=matparblockoffsets(1,i+1)
8198 ja=matparblockoffsets(2,i)
8199 jb=matparblockoffsets(2,i+1)
8202 WRITE(*,*) ' Parameter block', i, ib-ia, jb-ja, labelf, labell
8203 ENDDO
8204 ENDIF
8205 WRITE(lunlog,*)
8206 WRITE(lunlog,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8207 WRITE(*,*)
8208 WRITE(*,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8209 IF ((metsol == 1.OR.metsol == 3.OR.metsol>=7).AND.nagb == nvgb) THEN
8210 WRITE(*,*) 'Using block diagonal storage mode'
8211 ELSE
8212 ! keep single block = full matrix
8213 DO i=1,2
8215 END DO
8216 npblck=1
8217 DO i=1,nvgb
8219 END DO
8220 END IF
8221 END IF
8222
8223 ! print numbers ----------------------------------------------------
8224
8225 IF (nagb >= 65536) THEN
8226 noff=int(noff8/1000,mpi)
8227 ELSE
8228 noff=int(noff8,mpi)
8229 END IF
8230 ndgn=0
8231 matwords=0
8232 IF(matsto == 2) THEN
8233 ihis=0
8234 IF (mhispe > 0) THEN
8235 ihis=15
8236 CALL hmpdef(ihis,0.0,real(mhispe,mps), 'NDBITS: #off-diagonal elements')
8237 END IF
8238 length=(napgrp+1)*nspc
8239 CALL mpalloc(sparsematrixoffsets,two,length, 'sparse matrix row offsets')
8241 ndgn=ndimsa(3)+ndimsa(4) ! actual number of off-diagonal elements
8242 matwords=ndimsa(2)+length*4 ! size of sparsity structure
8243
8244 IF (mhispe > 0) THEN
8245 IF (nhistp /= 0) CALL hmprnt(ihis)
8246 CALL hmpwrt(ihis)
8247 END IF
8248 END IF
8249 IF (matsto == 3) THEN
8250 length=nagb+1
8251 CALL mpalloc(csr3rowoffsets,length, 'sparse matrix row offsets (CSR3)')
8252 IF (mpdbsz > 1) THEN
8253 ! BSR3, check (for optimal) block size
8254 mbwrds=0
8255 DO i=1,mpdbsz
8256 npdblk=(nagb-1)/ipdbsz(i)+1
8257 length=int(npdblk,mpl)
8258 CALL mpalloc(vecblockcounts,length, 'sparse matrix row offsets (CSR3)')
8259 CALL pbsbits(globalallindexgroups,ipdbsz(i),nnzero,nblock,vecblockcounts)
8260 nbwrds=2*int(nblock,mpl)*int(ipdbsz(i)*ipdbsz(i)+1,mpl) ! number of words needed
8261 IF ((i == 1).OR.(nbwrds < mbwrds)) THEN
8262 matbsz=ipdbsz(i)
8263 mbwrds=nbwrds
8264 csr3rowoffsets(1)=1
8265 DO k=1,npdblk
8266 csr3rowoffsets(k+1)=csr3rowoffsets(k)+vecblockcounts(k)
8267 END DO
8268 END IF
8269 CALL mpdealloc(vecblockcounts)
8270 END DO
8271 ELSE
8272 ! CSR3
8274 !csr3RowOffsets(nvgb+2:)=csr3RowOffsets(nvgb+1) ! Lagrange multipliers (empty)
8275 END IF
8276 END IF
8277
8278 nagbn=maxglobalpar ! max number of global parameters in one event
8279 nalcn=maxlocalpar ! max number of local parameters in one event
8280 naeqn=maxequations ! max number of equations in one event
8283 ! matrices for event matrices
8284 ! split up cache
8285 IF (fcache(2) == 0.0) THEN ! from data (DSTAT)
8286 fcache(1)=real(dstat(1),mps)*fcache(1) ! leave some part free for fluctuations
8287 fcache(2)=real(dstat(2),mps)
8288 fcache(3)=real(dstat(3),mps)
8289 END IF
8290 fsum=fcache(1)+fcache(2)+fcache(3)
8291 DO k=1,3
8292 fcache(k)=fcache(k)/fsum
8293 END DO
8294 ncachr=nint(real(ncache,mps)*fcache(1),mpi) ! read cache
8295 ! define read buffer
8296 nc31=ncachr/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
8297 nwrd=nc31+1
8298 length=nwrd*mthrdr
8299 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
8300 nwrd=nc31*10+2+ndimbuf
8301 length=nwrd*mthrdr
8302 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
8303 CALL mpalloc(readbufferdatad,length,'read buffer, real')
8304 ! to read (old) float binary files
8305 length=(ndimbuf+2)*mthrdr
8306 CALL mpalloc(readbufferdataf,length,'read buffer, float')
8307
8308 ncachi=nint(real(ncache,mps)*fcache(2),mpi) ! index cache
8309 ncachd=ncache-ncachr-ncachi ! data cache
8310 nggd=(nagbn*nagbn+nagbn)/2+ncachd/(2*mthrd) ! number of double
8311 nggi=2+nagbn+ncachi/mthrd ! number of ints
8312 length=nagbn*mthrd
8313 CALL mpalloc(globalindexusage,length, 'global parameters (dim =max/event)')
8314 length=nvgb*mthrd
8315 CALL mpalloc(backindexusage,length,'global variable-index array')
8317 length=nagbn*nalcn
8318 CALL mpalloc(localglobalmatrix,length,'local/global matrix, content')
8319 CALL mpalloc(localglobalmap,length,'local/global matrix, map (counts)')
8320 length=2*nagbn*nalcn+nagbn+nalcn+1
8321 CALL mpalloc(localglobalstructure,length,'local/global matrix, (sparsity) structure')
8322 length=nggd*mthrd
8323 CALL mpalloc(writebufferupdates,length,'symmetric update matrices')
8324 writebufferheader(-1)=nggd ! number of words per thread
8325 writebufferheader(-2)=(nagbn*nagbn+nagbn)/2 ! min free (double) words
8326 length=nggi*mthrd
8327 CALL mpalloc(writebufferindices,length,'symmetric update matrix indices')
8328 rows=9; cols=mthrd
8329 CALL mpalloc(writebufferinfo,rows,cols,'write buffer status (I)')
8330 rows=2; cols=mthrd
8331 CALL mpalloc(writebufferdata,rows,cols,'write buffer status (F)')
8332 writebufferheader(1)=nggi ! number of words per thread
8333 writebufferheader(2)=nagbn+3 ! min free words
8334
8335 ! print all relevant dimension parameters
8336
8337 DO lu=6,8,2 ! unit 6 and 8
8338
8339 WRITE(lu,*) ' '
8340 WRITE(lu,101) 'NTGB',ntgb,'total number of parameters'
8341 WRITE(lu,102) '(all parameters, appearing in binary files)'
8342 WRITE(lu,101) 'NVGB',nvgb,'number of variable parameters'
8343 WRITE(lu,102) '(appearing in fit matrix/vectors)'
8344 WRITE(lu,101) 'NAGB',nagb,'number of all parameters'
8345 WRITE(lu,102) '(including Lagrange multiplier or reduced)'
8346 WRITE(lu,101) 'NTPGRP',ntpgrp,'total number of parameter groups'
8347 WRITE(lu,101) 'NVPGRP',nvpgrp,'number of variable parameter groups'
8348 WRITE(lu,101) 'NFGB',nfgb,'number of fit parameters'
8349 IF(metsol >= 4.AND. metsol <7) THEN ! band matrix as MINRES preconditioner
8350 WRITE(lu,101) 'MBANDW',mbandw,'band width of preconditioner matrix'
8351 WRITE(lu,102) '(if <0, no preconditioner matrix)'
8352 END IF
8353 IF (nagb >= 65536) THEN
8354 WRITE(lu,101) 'NOFF/K',noff,'max number of off-diagonal elements'
8355 ELSE
8356 WRITE(lu,101) 'NOFF',noff,'max number of off-diagonal elements'
8357 END IF
8358 IF(ndgn /= 0) THEN
8359 IF (nagb >= 65536) THEN
8360 WRITE(lu,101) 'NDGN/K',ndgn/1000,'actual number of off-diagonal elements'
8361 ELSE
8362 WRITE(lu,101) 'NDGN',ndgn,'actual number of off-diagonal elements'
8363 ENDIF
8364 ENDIF
8365 WRITE(lu,101) 'NCGB',ncgb,'number of constraints'
8366 WRITE(lu,101) 'NAGBN',nagbn,'max number of global parameters in an event'
8367 WRITE(lu,101) 'NALCN',nalcn,'max number of local parameters in an event'
8368 WRITE(lu,101) 'NAEQN',naeqn,'max number of equations in an event'
8369 IF (mprint > 1) THEN
8370 WRITE(lu,101) 'NAEQNA',naeqna,'number of equations'
8371 WRITE(lu,101) 'NAEQNG',naeqng, &
8372 'number of equations with global parameters'
8373 WRITE(lu,101) 'NAEQNF',naeqnf, &
8374 'number of equations with fixed global parameters'
8375 WRITE(lu,101) 'NRECF',nrecf, &
8376 'number of records with fixed global parameters'
8377 END IF
8378 IF (nrece > 0) THEN
8379 WRITE(lu,101) 'NRECE',nrece, &
8380 'number of records without variable parameters'
8381 END IF
8382 IF (ncache > 0) THEN
8383 WRITE(lu,101) 'NCACHE',ncache,'number of words for caching'
8384 WRITE(lu,111) (fcache(k)*100.0,k=1,3)
8385111 FORMAT(22x,'cache splitting ',3(f6.1,' %'))
8386 END IF
8387 WRITE(lu,*) ' '
8388
8389 WRITE(lu,*) ' '
8390 WRITE(lu,*) 'Solution method and matrix-storage mode:'
8391 IF(metsol == 1) THEN
8392 WRITE(lu,*) ' METSOL = 1: matrix inversion'
8393 ELSE IF(metsol == 2) THEN
8394 WRITE(lu,*) ' METSOL = 2: diagonalization'
8395 ELSE IF(metsol == 3) THEN
8396 WRITE(lu,*) ' METSOL = 3: decomposition'
8397 ELSE IF(metsol == 4) THEN
8398 WRITE(lu,*) ' METSOL = 4: MINRES (rtol', mrestl,')'
8399 ELSE IF(metsol == 5) THEN
8400 WRITE(lu,*) ' METSOL = 5: MINRES-QLP (rtol', mrestl,')'
8401 ELSE IF(metsol == 6) THEN
8402 WRITE(lu,*) ' METSOL = 6: GMRES'
8403#ifdef LAPACK64
8404 ELSE IF(metsol == 7) THEN
8405 WRITE(lu,*) ' METSOL = 7: LAPACK factorization'
8406 ELSE IF(metsol == 8) THEN
8407 WRITE(lu,*) ' METSOL = 8: LAPACK factorization'
8408#ifdef PARDISO
8409 ELSE IF(metsol == 9) THEN
8410 WRITE(lu,*) ' METSOL = 9: Intel oneMKL PARDISO'
8411#endif
8412#endif
8413 END IF
8414 WRITE(lu,*) ' with',mitera,' iterations'
8415 IF(matsto == 0) THEN
8416 WRITE(lu,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
8417 ELSE IF(matsto == 1) THEN
8418 WRITE(lu,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
8419 ELSE IF(matsto == 2) THEN
8420 WRITE(lu,*) ' MATSTO = 2: sparse matrix (custom)'
8421 ELSE IF(matsto == 3) THEN
8422 IF (matbsz < 2) THEN
8423 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
8424 ELSE
8425 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
8426 WRITE(lu,*) ' block size', matbsz
8427 END IF
8428 END IF
8429 IF(npblck > 1) THEN
8430 WRITE(lu,*) ' block diagonal with', npblck, ' blocks'
8431 END IF
8432 IF(mextnd>0) WRITE(lu,*) ' with extended storage'
8433 IF(dflim /= 0.0) THEN
8434 WRITE(lu,103) 'Convergence assumed, if expected dF <',dflim
8435 END IF
8436 IF(ncgb > 0) THEN
8437 IF(nfgb < nvgb) THEN
8438 IF (icelim > 1) THEN
8439 WRITE(lu,*) 'Constraints handled by elimination with LAPACK'
8440 ELSE
8441 WRITE(lu,*) 'Constraints handled by elimination'
8442 END IF
8443 ELSE
8444 WRITE(lu,*) 'Constraints handled by Lagrange multipliers'
8445 ENDIF
8446 END IF
8447
8448 END DO ! print loop
8449
8450 IF(nalcn == 0) THEN
8451 CALL peend(28,'Aborted, no local parameters')
8452 stop 'LOOP2: stopping due to missing local parameters'
8453 END IF
8454
8455 ! Wolfe conditions
8456
8457 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8458 IF(wolfc1 == 0.0) wolfc1=1.0e-4
8459 IF(wolfc2 == 0.0) wolfc2=0.9
8460 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8461 IF(wolfc1 <= 0.0) wolfc1=1.0e-4
8462 IF(wolfc2 >= 1.0) wolfc2=0.9
8463 IF(wolfc1 > wolfc2) THEN ! exchange
8464 wolfc3=wolfc1
8466 wolfc2=wolfc3
8467 ELSE
8468 wolfc1=1.0e-4
8469 wolfc2=0.9
8470 END IF
8471 WRITE(*,105) wolfc1,wolfc2
8472 WRITE(lun,105) wolfc1,wolfc2
8473105 FORMAT(' Constants C1, C2 for Wolfe conditions:',g12.4,', ',g12.4)
8474
8475 ! prepare matrix and gradient storage ------------------------------
847632 matsiz=0 ! number of words for double, single precision storage
8477 IF (matsto == 3) THEN ! sparse matrix (CSR3, BSR3)
8478 npdblk=(nagb-1)/matbsz+1 ! number of row blocks
8479 length=csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
8480 matsiz(1)=length*int(matbsz*matbsz,mpl)
8481 matwords=(length+nagb+1)*2 ! size of sparsity structure
8482 CALL mpalloc(csr3columnlist,length,'sparse matrix column list (CSR3)')
8483 IF (matbsz > 1) THEN
8485 ELSE
8487 END IF
8488 ELSE IF (matsto == 2) THEN ! sparse matrix (custom)
8489 matsiz(1)=ndimsa(3)+nagb
8490 matsiz(2)=ndimsa(4)
8491 CALL mpalloc(sparsematrixcolumns,ndimsa(2),'sparse matrix column list')
8493 CALL anasps ! analyze sparsity structure
8494 ELSE ! full or unpacked matrix, optional block diagonal
8495 length=nagb
8496 CALL mpalloc(globalrowoffsets,length,'global row offsets (full or unpacked (block) storage)')
8497 ! loop over blocks (multiple blocks only with elimination !)
8499 DO i=1,npblck
8500 ipoff=matparblockoffsets(1,i)
8501 icboff=matparblockoffsets(2,i) ! constraint block offset
8502 icblst=matparblockoffsets(2,i+1) ! constraint block offset
8503 npar=matparblockoffsets(1,i+1)-ipoff ! size of block (number of parameters)
8504 IF (icblst > icboff) THEN
8505 ncon=matconsblocks(1,icblst+1)-matconsblocks(1,icboff+1) ! number of constraints in (parameter) block
8506 ELSE
8507 ncon=0
8508 ENDIF
8510 nall = npar; IF (icelim <= 0) nall=npar+ncon ! add Lagrange multipliers
8511 DO k=1,nall
8512 globalrowoffsets(ipoff+k)=matsiz(1)-ipoff
8513 IF (matsto == 1) THEN
8514 matsiz(1)=matsiz(1)+k ! full ('triangular')
8515 ELSE
8516 matsiz(1)=matsiz(1)+nall ! unpacked ('quadratic')
8517 END IF
8518 END DO
8519 END DO
8520 END IF
8521 matwords=matwords+matsiz(1)*2+matsiz(2) ! #words for matrix storage
8522
8523 CALL feasma ! prepare constraint matrices
8524
8525 IF (icheck <= 0) CALL vmprep(matsiz) ! prepare matrix and gradient storage
8526 WRITE(*,*) ' '
8527 IF (matwords < 250000) THEN
8528 WRITE(*,*) 'Size of global matrix: < 1 MB'
8529 ELSE
8530 WRITE(*,*) 'Size of global matrix:',int(real(matwords,mps)*4.0e-6,mpi),' MB'
8531 ENDIF
8532 ! print chi^2 cut tables
8533
8534 ndfmax=naeqn-1
8535 WRITE(lunlog,*) ' '
8536 WRITE(lunlog,*) ' Cut values of Chi^2/Ndf and Chi2,'
8537 WRITE(lunlog,*) ' corresponding to 2 and 3 standard deviations'
8538 WRITE(lunlog,*) ' Ndf Chi^2/Ndf(2) Chi^2(2) ', &
8539 ' Chi^2/Ndf(3) Chi^2(3)'
8540 ndf=0
8541 DO
8542 IF(ndf > naeqn) EXIT
8543 IF(ndf < 10) THEN
8544 ndf=ndf+1
8545 ELSE IF(ndf < 20) THEN
8546 ndf=ndf+2
8547 ELSE IF(ndf < 100) THEN
8548 ndf=ndf+5
8549 ELSE IF(ndf < 200) THEN
8550 ndf=ndf+10
8551 ELSE
8552 EXIT
8553 END IF
8554 chin2=chindl(2,ndf)
8555 chin3=chindl(3,ndf)
8556 WRITE(lunlog,106) ndf,chin2,chin2*real(ndf,mps),chin3, chin3*real(ndf,mps)
8557 END DO
8558
8559 WRITE(lunlog,*) 'LOOP2: ending'
8560 WRITE(lunlog,*) ' '
8561 ! warnings from check input mode
8562 IF (icheck > 0) THEN
8563 IF (ncgbe /= 0) THEN
8564 WRITE(*,199) ' '
8565 WRITE(*,199) ' '
8566 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8567 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8568 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8569 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8570 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8571 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8572 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8573 WRITE(*,199) ' '
8574 WRITE(*,*) ' Number of empty constraints =',abs(ncgbe), ', should be 0'
8575 WRITE(*,*) ' => please check constraint definition, mille data'
8576 WRITE(*,199) ' '
8577 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8578 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8579 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8580 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8581 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8582 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8583 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8584 WRITE(*,199) ' '
8585 END IF
8586 END IF
8587 CALL mend
8588101 FORMAT(1x,a8,' =',i14,' = ',a)
8589102 FORMAT(22x,a)
8590103 FORMAT(1x,a,g12.4)
8591106 FORMAT(i6,2(3x,f9.3,f12.1,3x))
8592199 FORMAT(7x,a)
8593END SUBROUTINE loop2
8594
8599SUBROUTINE monres
8600 USE mpmod
8601 USE mpdalc
8602
8603 IMPLICIT NONE
8604 INTEGER(mpi) :: i
8605 INTEGER(mpi) :: ij
8606 INTEGER(mpi) :: imed
8607 INTEGER(mpi) :: j
8608 INTEGER(mpi) :: k
8609 INTEGER(mpi) :: nent
8610 INTEGER(mpi), DIMENSION(measBins) :: isuml ! location
8611 INTEGER(mpi), DIMENSION(measBins) :: isums ! scale
8612 REAL(mps) :: amed
8613 REAL(mps) :: amad
8614
8615 INTEGER(mpl) :: ioff
8616 LOGICAL :: lfirst
8617 SAVE
8618 DATA lfirst /.true./
8619
8620 ! combine data from threads
8621 ioff=0
8622 DO i=2,mthrd
8623 ioff=ioff+measbins*nummeas
8624 DO j=1,measbins*nummeas
8625 meashists(j)=meashists(j)+meashists(ioff+j)
8626 END DO
8627 END DO
8628
8629 IF (lfirst) THEN
8630 IF (imonmd == 0) THEN
8631 WRITE(lunmon,'(A)') '*** Normalized residuals grouped by first global label (per local fit cycle) ***'
8632 ELSE
8633 WRITE(lunmon,'(A)') '*** Pulls grouped by first global label (per local fit cycle) ***'
8634 ENDIF
8635 WRITE(lunmon,'(A)') '! LFC Label Entries Median RMS(MAD) <error>'
8636 lfirst=.false.
8637 END IF
8638
8639 !$POMP INST BEGIN(monres)
8640 ! analyze histograms
8641 ioff=0
8642 DO i=1,ntgb
8643 IF (measindex(i) > 0) THEN
8644 isuml=0
8645 ! sum up content
8646 isuml(1)=meashists(ioff+1)
8647 DO j=2,measbins
8648 isuml(j)=isuml(j-1)+meashists(ioff+j)
8649 END DO
8650 nent=isuml(measbins)
8651 IF (nent > 0) THEN
8652 ! get median (for location)
8653 DO j=2,measbins
8654 IF (2*isuml(j) > nent) EXIT
8655 END DO
8656 imed=j
8657 amed=real(j,mps)
8658 IF (isuml(j) > isuml(j-1)) amed=amed+real(nent-2*isuml(j-1),mps)/real(2*isuml(j)-2*isuml(j-1),mps)
8659 amed=real(measbinsize,mps)*(amed-real(measbins/2,mps))
8660 ! sum up differences
8661 isums = 0
8662 DO j=imed,measbins
8663 k=j-imed+1
8664 isums(k)=isums(k)+meashists(ioff+j)
8665 END DO
8666 DO j=imed-1,1,-1
8667 k=imed-j
8668 isums(k)=isums(k)+meashists(ioff+j)
8669 END DO
8670 DO j=2, measbins
8671 isums(j)=isums(j)+isums(j-1)
8672 END DO
8673 ! get median (for scale)
8674 DO j=2,measbins
8675 IF (2*isums(j) > nent) EXIT
8676 END DO
8677 amad=real(j-1,mps)
8678 IF (isums(j) > isums(j-1)) amad=amad+real(nent-2*isums(j-1),mps)/real(2*isums(j)-2*isums(j-1),mps)
8679 amad=real(measbinsize,mps)*amad
8680 ELSE
8681 amed=0.0
8682 amad=0.0
8683 END IF
8684 ij=globalparlabelindex(1,i)
8685 WRITE(lunmon,110) nloopn, ij, nent, amed, amad*1.4826, real(measres(i),mps)
8686 !
8687 ioff=ioff+measbins
8688 END IF
8689 END DO
8690 !$POMP INST END(monres)
8691
8692110 FORMAT(i5,2i10,3g14.5)
8693END SUBROUTINE monres
8694
8695
8699
8700SUBROUTINE vmprep(msize)
8701 USE mpmod
8702 USE mpdalc
8703
8704 IMPLICIT NONE
8705 INTEGER(mpi) :: i
8706 INTEGER(mpi) :: ib
8707 INTEGER(mpi) :: ioff
8708 INTEGER(mpi) :: ipar0
8709 INTEGER(mpi) :: ncon
8710 INTEGER(mpi) :: npar
8711 INTEGER(mpi) :: nextra
8712#ifdef LAPACK64
8713 INTEGER :: nbopt, nboptx, ILAENV
8714#endif
8715 !
8716 INTEGER(mpl), INTENT(IN) :: msize(2)
8717
8718 INTEGER(mpl) :: length
8719 INTEGER(mpl) :: nwrdpc
8720 INTEGER(mpl), PARAMETER :: three = 3
8721
8722 SAVE
8723 ! ...
8724 ! Vector/matrix storage
8725 length=nagb*mthrd
8726 CALL mpalloc(globalvector,length,'rhs vector') ! double precision vector
8727 CALL mpalloc(globalcounter,length,'rhs counter') ! integer vector
8729 length=naeqn*mthrd
8730 CALL mpalloc(localcorrections,length,'residual vector of one record')
8731 CALL mpalloc(localequations,three,length,'mesurements indices (ISJAJB) of one record')
8732 length=nalcn*nalcn
8733 CALL mpalloc(aux,length,' local fit scratch array: aux')
8734 CALL mpalloc(vbnd,length,' local fit scratch array: vbnd')
8735 CALL mpalloc(vbdr,length,' local fit scratch array: vbdr')
8736 length=((nalcn+1)*nalcn)/2
8737 CALL mpalloc(clmat,length,' local fit matrix: clmat')
8738 CALL mpalloc(vbk,length,' local fit scratch array: vbk')
8739 length=nalcn
8740 CALL mpalloc(blvec,length,' local fit vector: blvec')
8741 CALL mpalloc(vzru,length,' local fit scratch array: vzru')
8742 CALL mpalloc(scdiag,length,' local fit scratch array: scdiag')
8743 CALL mpalloc(scflag,length,' local fit scratch array: scflag')
8744 CALL mpalloc(ibandh,2*length,' local fit band width hist.: ibandh')
8745
8746 CALL mpalloc(globalmatd,msize(1),'global matrix (D)' )
8747 CALL mpalloc(globalmatf,msize(2),'global matrix (F)')
8748
8749 mszpcc=0
8750 IF(metsol >= 4.AND.metsol < 7.AND. mbandw >= 0) THEN ! GMRES/MINRES algorithms
8751 ! array space is:
8752 ! variable-width band matrix or diagonal matrix for parameters
8753 ! followed by symmetric matrix for constraints
8754 ! followed by rectangular matrix for constraints
8755 nwrdpc=0
8756 ncon=nagb-nvgb ! number of Lagrange multipliers
8757 ! constraint block info
8758 length=4*ncblck; IF(ncon == 0) length=0
8759 CALL mpalloc(blockprecond,length,'preconditioner: constraint blocks')
8760 length=ncon
8761 CALL mpalloc(offprecond,length,'preconditioner: constraint offsets')
8762 !END IF
8763 ! variable-width band matrix ?
8764 IF(mbandw > 0) THEN
8765 length=nagb
8766 CALL mpalloc(indprecond,length,'pointer-array variable-band matrix')
8767 nwrdpc=nwrdpc+length
8768 DO i=1,min(mbandw,nvgb)
8769 indprecond(i)=(i*i+i)/2 ! increasing number
8770 END DO
8771 DO i=min(mbandw,nvgb)+1,nvgb
8772 indprecond(i)=indprecond(i-1)+mbandw ! fixed band width
8773 END DO
8774 DO i=nvgb+1,nagb ! reset
8775 indprecond(i)=0
8776 END DO
8777 END IF
8778 ! symmetric part
8779 length=(ncon*ncon+ncon)/2
8780 ! add 'band' part
8781 IF(mbandw > 0) THEN ! variable-width band matrix
8782 length=length+indprecond(nvgb)
8783 ELSE ! default preconditioner (diagonal)
8784 length=length+nvgb
8785 END IF
8786 ! add rectangular part (compressed, constraint blocks)
8787 IF(ncon > 0) THEN
8788 ioff=0
8789 ! extra space (for forward solution in EQUDEC)
8790 nextra=max(0,mbandw-1)
8791 DO ib=1,ncblck
8792 ! first constraint in block
8793 blockprecond(ioff+1)=matconsblocks(1,ib)
8794 ! last constraint in block
8795 blockprecond(ioff+2)=matconsblocks(1,ib+1)-1
8796 ! parameter offset
8797 ipar0=matconsblocks(2,ib)-1
8798 blockprecond(ioff+3)=ipar0
8799 ! number of parameters (-> columns)
8800 npar=matconsblocks(3,ib)-ipar0
8801 blockprecond(ioff+4)=npar+nextra
8802 DO i=blockprecond(ioff+1),blockprecond(ioff+2)
8803 offprecond(i)=length-ipar0
8804 length=length+npar+nextra
8805 mszpcc=mszpcc+npar+nextra
8806 END DO
8807 ioff=ioff+4
8808 END DO
8809 ELSE
8810 IF(mbandw == 0) length=length+1 ! for valid precons argument matPreCond((ncon*ncon+ncon)/2+nvgb+1)
8811 END IF
8812 ! allocate
8813 IF(mbandw > 0) THEN
8814 CALL mpalloc(matprecond,length,'variable-band preconditioner matrix')
8815 ELSE
8816 CALL mpalloc(matprecond,length,'default preconditioner matrix')
8817 END IF
8818 nwrdpc=nwrdpc+2*length
8819 IF (nwrdpc > 250000) THEN
8820 WRITE(*,*)
8821 WRITE(*,*) 'Size of preconditioner matrix:',int(real(nwrdpc,mps)*4.0e-6,mpi),' MB'
8822 END IF
8823
8824 END IF
8825
8826
8827 length=nagb
8828 CALL mpalloc(globalcorrections,length,'corrections') ! double prec corrections
8829
8830 length=nagb
8831 CALL mpalloc(workspaced,length,'auxiliary array (D1)') ! double aux 1
8832 CALL mpalloc(workspacelinesearch,length,'auxiliary array (D2)') ! double aux 2
8833 CALL mpalloc(workspacei, length,'auxiliary array (I)') ! int aux 1
8834
8835 IF(metsol == 1) THEN
8836 CALL mpalloc(workspacediag,length,'diagonal of global matrix)') ! double aux 1
8837 CALL mpalloc(workspacerow,length,'(pivot) row of global matrix)')
8838 ! CALL MEGARR('t D',2*NAGB,'auxiliary array') ! double aux 8
8839 END IF
8840
8841 IF(metsol == 2) THEN
8842 IF(nagb>46300) THEN
8843 CALL peend(23,'Aborted, bad matrix index (will exceed 32bit)')
8844 stop 'vmprep: bad index (matrix to large for diagonalization)'
8845 END IF
8846 CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8847 CALL mpalloc(workspacediagonalization,length,'auxiliary array (D3)') ! double aux 3
8848 CALL mpalloc(workspaceeigenvalues,length,'auxiliary array (D6)') ! double aux 6
8849 length=nagb*nagb
8850 CALL mpalloc(workspaceeigenvectors,length,'(rotation) matrix U') ! rotation matrix
8851 END IF
8852
8853 IF(metsol >= 4.AND.metsol < 7) THEN
8854 CALL mpalloc(vecxav,length,'vector X (AVPROD)') ! double aux 1
8855 CALL mpalloc(vecbav,length,'vector B (AVPROD)') ! double aux 1
8856 END IF
8857
8858#ifdef LAPACK64
8859 IF(metsol == 7) THEN
8860 IF(nagb > nvgb) CALL mpalloc(lapackipiv, length,'IPIV for DSPTRG (L)') ! pivot indices for DSPTRF
8861 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8862 END IF
8863 IF(metsol == 8) THEN
8864 IF(nagb > nvgb) THEN
8865 CALL mpalloc(lapackipiv, length,'LAPACK IPIV (L)')
8866 nbopt = ilaenv( 1_mpl, 'DSYTRF', 'U', int(nagb,mpl), int(nagb,mpl), -1_mpl, -1_mpl ) ! optimal block size
8867 print *
8868 print *, 'LAPACK optimal block size for DSYTRF:', nbopt
8869 lplwrk=length*int(nbopt,mpl)
8870 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8871 ELSE IF(nfgb < nvgb.AND.icelim > 1) THEN
8872 ! elimination of constraints with LAPACK
8873 lplwrk=1
8874 DO i=1,npblck
8875 npar=matparblockoffsets(1,i+1)-matparblockoffsets(1,i) ! number of parameters in block
8876 ncon=vecparblockconoffsets(i+1)-vecparblockconoffsets(i) ! number of constraints in block
8877 nbopt = ilaenv( 1_mpl, 'DORMQL', 'RN', int(npar,mpl), int(npar,mpl), int(ncon,mpl), int(npar,mpl) ) ! optimal buffer size
8878 IF (int(npar,mpl)*int(nbopt,mpl) > lplwrk) THEN
8879 lplwrk=int(npar,mpl)*int(nbopt,mpl)
8880 nboptx=nbopt
8881 END IF
8882 END DO
8883 print *
8884 print *, 'LAPACK optimal block size for DORMQL:', nboptx
8885 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8886 END IF
8887 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8888 END IF
8889#endif
8890
8891END SUBROUTINE vmprep
8892
8896
8897SUBROUTINE minver
8898 USE mpmod
8899
8900 IMPLICIT NONE
8901 INTEGER(mpi) :: i
8902 INTEGER(mpi) :: ib
8903 INTEGER(mpi) :: icoff
8904 INTEGER(mpi) :: ipoff
8905 INTEGER(mpi) :: j
8906 INTEGER(mpi) :: lun
8907 INTEGER(mpi) :: ncon
8908 INTEGER(mpi) :: nfit
8909 INTEGER(mpi) :: npar
8910 INTEGER(mpi) :: nrank
8911 INTEGER(mpl) :: imoff
8912 INTEGER(mpl) :: ioff1
8913 REAL(mpd) :: matij
8914
8915 EXTERNAL avprds
8916
8917 SAVE
8918 ! ...
8919 lun=lunlog ! log file
8920
8921 IF(icalcm == 1) THEN
8922 ! save diagonal (for global correlation)
8923 DO i=1,nagb
8924 workspacediag(i)=matij(i,i)
8925 END DO
8926 ! use elimination for constraints ?
8927 IF(nfgb < nvgb) THEN
8928 ! monitor progress
8929 IF(monpg1 > 0) THEN
8930 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
8932 END IF
8933 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
8934 IF(monpg1 > 0) CALL monend()
8935 END IF
8936 END IF
8937
8938 ! loop over blocks (multiple blocks only with elimination !)
8939 DO ib=1,npblck
8940 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
8941 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
8942 icoff=vecparblockconoffsets(ib) ! constraint offset for block
8943 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
8944 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
8945 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
8946 ! use elimination for constraints ?
8947 IF(nfit < npar) THEN
8948 CALL qlsetb(ib)
8949 ! solve L^t*y=d by backward substitution
8951 ! transform, reduce rhs
8952 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
8953 ! correction from eliminated part
8954 DO i=1,nfit
8955 DO j=1,ncon
8956 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
8958 END DO
8959 END DO
8960 END IF
8961
8962 IF(icalcm == 1) THEN
8963 ! monitor progress
8964 IF(monpg1 > 0) THEN
8965 WRITE(lunlog,*) 'Inversion of global matrix (A->A^-1)'
8967 END IF
8968 ! invert and solve
8969 CALL sqminl(globalmatd(imoff+1:), globalcorrections(ipoff+1:),nfit,nrank, &
8971 IF(monpg1 > 0) CALL monend()
8972 IF(nfit /= nrank) THEN
8973 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
8974 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8975 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
8976 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
8977 IF (iforce == 0 .AND. isubit == 0) THEN
8978 isubit=1
8979 WRITE(*,*) ' --> enforcing SUBITO mode'
8980 WRITE(lun,*) ' --> enforcing SUBITO mode'
8981 END IF
8982 ELSE IF(ndefec == 0) THEN
8983 IF(npblck == 1) THEN
8984 WRITE(lun,*) 'No rank defect of the symmetric matrix'
8985 ELSE
8986 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
8987 END IF
8988 END IF
8989 ndefec=ndefec+nfit-nrank ! rank defect
8990
8991 ELSE ! multiply gradient by inverse matrix
8992 workspaced(:nfit)=globalcorrections(ipoff+1:ipoff+nfit)
8993 CALL dbsvxl(globalmatd(imoff+1:),workspaced,globalcorrections(ipoff+1:),nfit)
8994 END IF
8995
8996 !use elimination for constraints ?
8997 IF(nfit < npar) THEN
8998 ! extend, transform back solution
8999 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9000 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9001 END IF
9002 END DO
9003
9004END SUBROUTINE minver
9005
9009
9010SUBROUTINE mchdec
9011 USE mpmod
9012
9013 IMPLICIT NONE
9014 INTEGER(mpi) :: i
9015 INTEGER(mpi) :: ib
9016 INTEGER(mpi) :: icoff
9017 INTEGER(mpi) :: ipoff
9018 INTEGER(mpi) :: j
9019 INTEGER(mpi) :: lun
9020 INTEGER(mpi) :: ncon
9021 INTEGER(mpi) :: nfit
9022 INTEGER(mpi) :: npar
9023 INTEGER(mpi) :: nrank
9024 INTEGER(mpl) :: imoff
9025 INTEGER(mpl) :: ioff1
9026
9027 REAL(mpd) :: evmax
9028 REAL(mpd) :: evmin
9029
9030 EXTERNAL avprds
9031
9032 SAVE
9033 ! ...
9034 lun=lunlog ! log file
9035
9036 IF(icalcm == 1) THEN
9037 ! use elimination for constraints ?
9038 ! monitor progress
9039 IF(monpg1 > 0) THEN
9040 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9042 END IF
9043 IF(nfgb < nvgb) CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9044 IF(monpg1 > 0) CALL monend()
9045 END IF
9046
9047 ! loop over blocks (multiple blocks only with elimination !)
9048 DO ib=1,npblck
9049 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9050 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9051 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9052 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9053 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9054 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9055 ! use elimination for constraints ?
9056 IF(nfit < npar) THEN
9057 CALL qlsetb(ib)
9058 ! solve L^t*y=d by backward substitution
9060 ! transform, reduce rhs
9061 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9062 ! correction from eliminated part
9063 DO i=1,nfit
9064 DO j=1,ncon
9065 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9067 END DO
9068 END DO
9069 END IF
9070
9071 IF(icalcm == 1) THEN
9072 ! monitor progress
9073 IF(monpg1 > 0) THEN
9074 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9076 END IF
9077 ! decompose and solve
9078 CALL chdec2(globalmatd(imoff+1:),nfit,nrank,evmax,evmin,monpg1)
9079 IF(monpg1 > 0) CALL monend()
9080 IF(nfit /= nrank) THEN
9081 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
9082 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9083 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
9084 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9085 IF (iforce == 0 .AND. isubit == 0) THEN
9086 isubit=1
9087 WRITE(*,*) ' --> enforcing SUBITO mode'
9088 WRITE(lun,*) ' --> enforcing SUBITO mode'
9089 END IF
9090 ELSE IF(ndefec == 0) THEN
9091 IF(npblck == 1) THEN
9092 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9093 ELSE
9094 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9095 END IF
9096 WRITE(lun,*) ' largest diagonal element (LDLt)', evmax
9097 WRITE(lun,*) ' smallest diagonal element (LDLt)', evmin
9098 END IF
9099 ndefec=ndefec+nfit-nrank ! rank defect
9100
9101 END IF
9102 ! backward/forward substitution
9103 CALL chslv2(globalmatd(imoff+1:),globalcorrections(ipoff+1:),nfit)
9104
9105 !use elimination for constraints ?
9106 IF(nfit < npar) THEN
9107 ! extend, transform back solution
9108 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9109 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9110 END IF
9111 END DO
9112
9113END SUBROUTINE mchdec
9114
9115#ifdef LAPACK64
9116
9121
9122SUBROUTINE mdptrf
9123 USE mpmod
9124
9125 IMPLICIT NONE
9126 INTEGER(mpi) :: i
9127 INTEGER(mpi) :: ib
9128 INTEGER(mpi) :: icoff
9129 INTEGER(mpi) :: ipoff
9130 INTEGER(mpi) :: j
9131 INTEGER(mpi) :: lun
9132 INTEGER(mpi) :: ncon
9133 INTEGER(mpi) :: nfit
9134 INTEGER(mpi) :: npar
9135 INTEGER(mpl) :: imoff
9136 INTEGER(mpl) :: ioff1
9137 INTEGER(mpi) :: infolp
9138 REAL(mpd) :: matij
9139
9140 EXTERNAL avprds
9141
9142 SAVE
9143 ! ...
9144 lun=lunlog ! log file
9145
9146 IF(icalcm == 1) THEN
9147 IF(ilperr == 1) THEN
9148 ! save diagonal (for global correlation)
9149 DO i=1,nagb
9150 workspacediag(i)=matij(i,i)
9151 END DO
9152 END IF
9153 ! use elimination for constraints ?
9154 IF(nfgb < nvgb) THEN
9155 ! monitor progress
9156 IF(monpg1 > 0) THEN
9157 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9159 END IF
9160 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9161 IF(monpg1 > 0) CALL monend()
9162 END IF
9163 END IF
9164
9165 ! loop over blocks (multiple blocks only with elimination !)
9166 DO ib=1,npblck
9167 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9168 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9169 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9170 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9171 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9172 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9173 ! use elimination for constraints ?
9174 IF(nfit < npar) THEN
9175 CALL qlsetb(ib)
9176 ! solve L^t*y=d by backward substitution
9178 ! transform, reduce rhs
9179 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9180 ! correction from eliminated part
9181 DO i=1,nfit
9182 DO j=1,ncon
9183 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9185 END DO
9186 END DO
9187 END IF
9188
9189 IF(icalcm == 1) THEN
9190 ! multipliers?
9191 IF (nfit > npar) THEN
9192 ! monitor progress
9193 IF(monpg1 > 0) THEN
9194 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9196 END IF
9197 !$POMP INST BEGIN(dsptrf)
9198 CALL dsptrf('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),infolp)
9199 !$POMP INST END(dsptrf)
9200 IF(monpg1 > 0) CALL monend()
9201 ELSE
9202 ! monitor progress
9203 IF(monpg1 > 0) THEN
9204 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9206 END IF
9207 !$POMP INST BEGIN(dpptrf)
9208 CALL dpptrf('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
9209 !$POMP INST END(dpptrf)
9210 IF(monpg1 > 0) CALL monend()
9211 ENDIF
9212 ! check result
9213 IF(infolp==0) THEN
9214 IF(npblck == 1) THEN
9215 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9216 ELSE
9217 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9218 END IF
9219 ELSE
9220 ndefec=ndefec+1 ! (lower limit of) rank defect
9221 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9222 '-by-',nfit,' failed at index ', infolp
9223 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9224 '-by-',nfit,' failed at index ', infolp
9225 CALL peend(29,'Aborted, factorization of global matrix failed')
9226 stop 'mdptrf: bad matrix'
9227 END IF
9228 END IF
9229 ! backward/forward substitution
9230 ! multipliers?
9231 IF (nfit > npar) THEN
9232 CALL dsptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),lapackipiv(ipoff+1:),&
9233 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9234 IF(infolp /= 0) print *, ' DSPTRS failed: ', infolp
9235 ELSE
9236 CALL dpptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),&
9237 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9238 IF(infolp /= 0) print *, ' DPPTRS failed: ', infolp
9239 ENDIF
9240
9241 !use elimination for constraints ?
9242 IF(nfit < npar) THEN
9243 ! extend, transform back solution
9244 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9245 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9246 END IF
9247 END DO
9248
9249END SUBROUTINE mdptrf
9250
9256
9257SUBROUTINE mdutrf
9258 USE mpmod
9259
9260 IMPLICIT NONE
9261 INTEGER(mpi) :: i
9262 INTEGER(mpi) :: ib
9263 INTEGER(mpi) :: icoff
9264 INTEGER(mpi) :: ipoff
9265 INTEGER(mpi) :: j
9266 INTEGER(mpi) :: lun
9267 INTEGER(mpi) :: ncon
9268 INTEGER(mpi) :: nfit
9269 INTEGER(mpi) :: npar
9270 INTEGER(mpl) :: imoff
9271 INTEGER(mpl) :: ioff1
9272 INTEGER(mpl) :: iloff
9273 INTEGER(mpi) :: infolp
9274
9275 REAL(mpd) :: matij
9276
9277 EXTERNAL avprds
9278
9279 SAVE
9280 ! ...
9281 lun=lunlog ! log file
9282
9283 IF(icalcm == 1) THEN
9284 IF(ilperr == 1) THEN
9285 ! save diagonal (for global correlation)
9286 DO i=1,nagb
9287 workspacediag(i)=matij(i,i)
9288 END DO
9289 END IF
9290 ! use elimination for constraints ?
9291 IF(nfgb < nvgb) THEN
9292 ! monitor progress
9293 IF(monpg1 > 0) THEN
9294 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9296 END IF
9297 IF (icelim > 1) THEN
9298 CALL lpavat(.true.)
9299 ELSE
9300 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9301 END IF
9302 IF(monpg1 > 0) CALL monend()
9303 END IF
9304 END IF
9305
9306 ! loop over blocks (multiple blocks only with elimination !)
9307 iloff=0 ! offset of L in lapackQL
9308 DO ib=1,npblck
9309 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9310 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9311 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9312 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9313 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9314 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9315 ! use elimination for constraints ?
9316 IF(nfit < npar) THEN
9317 IF (icelim > 1) THEN
9318 ! solve L^t*y=d by backward substitution
9319 vecconssolution(1:ncon)=vecconsresiduals(icoff+1:icoff+ncon)
9320 CALL dtrtrs('L','T','N',int(ncon,mpl),1_mpl,lapackql(iloff+npar-ncon+1:),int(npar,mpl),&
9321 vecconssolution,int(ncon,mpl),infolp)
9322 IF(infolp /= 0) print *, ' DTRTRS failed: ', infolp
9323 ! transform, reduce rhs, Q^t*b
9324 CALL dormql('L','T',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9325 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9326 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9327 ELSE
9328 CALL qlsetb(ib)
9329 ! solve L^t*y=d by backward substitution
9331 ! transform, reduce rhs
9332 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9333 END IF
9334 ! correction from eliminated part
9335 DO i=1,nfit
9336 DO j=1,ncon
9337 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9339 END DO
9340 END DO
9341 END IF
9342
9343 IF(icalcm == 1) THEN
9344 ! multipliers?
9345 IF (nfit > npar) THEN
9346 ! monitor progress
9347 IF(monpg1 > 0) THEN
9348 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9350 END IF
9351 !$POMP INST BEGIN(dsytrf)
9352 CALL dsytrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
9353 lapackipiv(ipoff+1:),lapackwork,lplwrk,infolp)
9354 !$POMP INST END(dsytrf)
9355 IF(monpg1 > 0) CALL monend()
9356 ELSE
9357 ! monitor progress
9358 IF(monpg1 > 0) THEN
9359 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9361 END IF
9362 !$POMP INST BEGIN(dpotrf)
9363 CALL dpotrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
9364 !$POMP INST END(dpotrf)
9365 IF(monpg1 > 0) CALL monend()
9366 ENDIF
9367 ! check result
9368 IF(infolp==0) THEN
9369 IF(npblck == 1) THEN
9370 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9371 ELSE
9372 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9373 END IF
9374 ELSE
9375 ndefec=ndefec+1 ! (lower limit of) rank defect
9376 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9377 '-by-',nfit,' failed at index ', infolp
9378 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9379 '-by-',nfit,' failed at index ', infolp
9380 CALL peend(29,'Aborted, factorization of global matrix failed')
9381 stop 'mdutrf: bad matrix'
9382 END IF
9383 END IF
9384 ! backward/forward substitution
9385 ! multipliers?
9386 IF (nfit > npar) THEN
9387 CALL dsytrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(nfit,mpl),&
9388 lapackipiv(ipoff+1:),globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9389 IF(infolp /= 0) print *, ' DSYTRS failed: ', infolp
9390 ELSE
9391 CALL dpotrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(npar,mpl),&
9392 globalcorrections(ipoff+1:),int(npar,mpl),infolp)
9393 IF(infolp /= 0) print *, ' DPOTRS failed: ', infolp
9394 ENDIF
9395
9396 !use elimination for constraints ?
9397 IF(nfit < npar) THEN
9398 IF (icelim > 1) THEN
9399 ! correction from eliminated part
9400 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9401 ! extend, transform back solution, Q*x
9402 CALL dormql('L','N',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9403 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9404 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9405 ELSE
9406 ! extend, transform back solution
9407 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9408 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9409 END IF
9410 END IF
9411 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9412 END DO
9413
9414END SUBROUTINE mdutrf
9415
9426SUBROUTINE lpqldec(a,emin,emax)
9427 USE mpmod
9428 USE mpdalc
9429
9430 IMPLICIT NONE
9431 INTEGER(mpi) :: ib
9432 INTEGER(mpi) :: icb
9433 INTEGER(mpi) :: icboff
9434 INTEGER(mpi) :: icblst
9435 INTEGER(mpi) :: icoff
9436 INTEGER(mpi) :: icfrst
9437 INTEGER(mpi) :: iclast
9438 INTEGER(mpi) :: ipfrst
9439 INTEGER(mpi) :: iplast
9440 INTEGER(mpi) :: ipoff
9441 INTEGER(mpi) :: i
9442 INTEGER(mpi) :: j
9443 INTEGER(mpi) :: ncon
9444 INTEGER(mpi) :: npar
9445 INTEGER(mpi) :: npb
9446 INTEGER(mpl) :: imoff
9447 INTEGER(mpl) :: iloff
9448 INTEGER(mpi) :: infolp
9449 INTEGER :: nbopt, ILAENV
9450
9451 REAL(mpd), INTENT(IN) :: a(mszcon)
9452 REAL(mpd), INTENT(OUT) :: emin
9453 REAL(mpd), INTENT(OUT) :: emax
9454 SAVE
9455
9456 print *
9457 ! loop over blocks (multiple blocks only with elimination !)
9458 iloff=0 ! size of unpacked constraint matrix
9459 DO ib=1,npblck
9460 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9461 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9462 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9463 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9464 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9465 END DO
9466 ! allocate
9467 CALL mpalloc(lapackql, iloff, 'LAPACK QL (QL decomp.) ')
9468 lapackql=0.
9469 iloff=ncgb
9470 CALL mpalloc(lapacktau, iloff, 'LAPACK TAU (QL decomp.) ')
9471 ! fill
9472 iloff=0 ! offset of unpacked constraint matrix block
9473 imoff=0 ! offset of packed constraint matrix block
9474 DO ib=1,npblck
9475 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9476 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9477 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9478 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9479 IF(ncon <= 0) cycle
9480 ! block with constraints
9481 icboff=matparblockoffsets(2,ib) ! constraint block offset
9482 icblst=matparblockoffsets(2,ib+1) ! constraint block offset
9483 DO icb=icboff+1,icboff+icblst
9484 icfrst=matconsblocks(1,icb) ! first constraint in block
9485 iclast=matconsblocks(1,icb+1)-1 ! last constraint in block
9486 DO j=icfrst,iclast
9487 ipfrst=matconsranges(3,j)-ipoff ! first (rel.) parameter
9488 iplast=matconsranges(4,j)-ipoff ! last (rel.) parameters
9489 npb=iplast-ipfrst+1
9490 lapackql(iloff+ipfrst:iloff+iplast)=a(imoff+1:imoff+npb)
9491 imoff=imoff+npb
9492 iloff=iloff+npar
9493 END DO
9494 END DO
9495 END DO
9496 ! decompose
9497 iloff=0 ! offset of unpacked constraint matrix block
9498 emax=-1.
9499 emin=1.
9500 DO ib=1,npblck
9501 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9502 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9503 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9504 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9505 IF(ncon <= 0) cycle
9506 ! block with constraints
9507 nbopt = ilaenv( 1_mpl, 'DGEQLF', '', int(npar,mpl), int(ncon,mpl), int(npar,mpl), -1_mpl ) ! optimal block size
9508 print *, 'LAPACK optimal block size for DGEQLF:', nbopt
9509 lplwrk=int(ncon,mpl)*int(nbopt,mpl)
9510 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (d)')
9511 !$POMP INST BEGIN(dgeqlf)
9512 CALL dgeqlf(int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9513 lapacktau(icoff+1:),lapackwork,lplwrk,infolp)
9514 IF(infolp /= 0) print *, ' DGEQLF failed: ', infolp
9515 !$POMP INST END(dgeqlf)
9516 CALL mpdealloc(lapackwork)
9517 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9518 ! get min/max diaginal element of L
9519 imoff=iloff
9520 IF(emax < emin) THEN
9521 emax=lapackql(imoff)
9522 emin=emax
9523 END IF
9524 DO i=1,ncon
9525 IF (abs(emax) < abs(lapackql(imoff))) emax=lapackql(imoff)
9526 IF (abs(emin) > abs(lapackql(imoff))) emin=lapackql(imoff)
9527 imoff=imoff-npar-1
9528 END DO
9529 END DO
9530 print *
9531END SUBROUTINE lpqldec
9532
9542SUBROUTINE lpavat(t)
9543 USE mpmod
9544
9545 IMPLICIT NONE
9546 INTEGER(mpi) :: i
9547 INTEGER(mpi) :: ib
9548 INTEGER(mpi) :: icoff
9549 INTEGER(mpi) :: ipoff
9550 INTEGER(mpi) :: j
9551 INTEGER(mpi) :: ncon
9552 INTEGER(mpi) :: npar
9553 INTEGER(mpl) :: imoff
9554 INTEGER(mpl) :: iloff
9555 INTEGER(mpi) :: infolp
9556 CHARACTER (LEN=1) :: transr, transl
9557
9558 LOGICAL, INTENT(IN) :: t
9559 SAVE
9560
9561 IF (t) THEN ! Q^t*A*Q
9562 transr='N'
9563 transl='T'
9564 ELSE ! Q*A*Q^t
9565 transr='T'
9566 transl='N'
9567 ENDIF
9568
9569 ! loop over blocks (multiple blocks only with elimination !)
9570 iloff=0 ! offset of L in lapackQL
9571 DO ib=1,npblck
9572 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9573 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9574 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9575 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9576 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9577 IF(ncon <= 0 ) cycle
9578
9579 !$POMP INST BEGIN(dormql)
9580 ! expand matrix (copy lower to upper triangle)
9581 ! parallelize row loop
9582 ! slot of 32 'I' for next idle thread
9583 !$OMP PARALLEL DO &
9584 !$OMP PRIVATE(J) &
9585 !$OMP SCHEDULE(DYNAMIC,32)
9586 DO i=ipoff+1,ipoff+npar
9587 DO j=ipoff+1,i-1
9589 ENDDO
9590 ENDDO
9591 ! A*Q
9592 CALL dormql('R',transr,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9593 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9594 lapackwork,lplwrk,infolp)
9595 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9596 ! Q^t*(A*Q)
9597 CALL dormql('L',transl,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9598 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9599 lapackwork,lplwrk,infolp)
9600 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9601 !$POMP INST END(dormql)
9602
9603 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9604 END DO
9605
9606END SUBROUTINE lpavat
9607
9608#ifdef PARDISO
9609include 'mkl_pardiso.f90'
9610!===============================================================================
9611! Copyright 2004-2022 Intel Corporation.
9612!
9613! This software and the related documents are Intel copyrighted materials, and
9614! your use of them is governed by the express license under which they were
9615! provided to you (License). Unless the License provides otherwise, you may not
9616! use, modify, copy, publish, distribute, disclose or transmit this software or
9617! the related documents without Intel's prior written permission.
9618!
9619! This software and the related documents are provided as is, with no express
9620! or implied warranties, other than those that are expressly stated in the
9621! License.
9622!===============================================================================
9623!
9624! Content : Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO Fortran-90
9625! use case
9626!
9627!*******************************************************************************
9628
9633SUBROUTINE mspardiso
9634 USE mkl_pardiso
9635 USE mpmod
9636 USE mpdalc
9637 IMPLICIT NONE
9638
9639 !.. Internal solver memory pointer
9640 TYPE(mkl_pardiso_handle) :: pt(64) ! Handle to internal data structure
9641 !.. All other variables
9642 INTEGER(mpl), PARAMETER :: maxfct =1 ! Max. number of factors with identical sparsity structure kept in memory
9643 INTEGER(mpl), PARAMETER :: mnum = 1 ! Actual factor to use
9644 INTEGER(mpl), PARAMETER :: nrhs = 1 ! Number of right hand sides
9645
9646 INTEGER(mpl) :: mtype ! Matrix type (symmetric, pos. def.: 2, indef.: -2)
9647 INTEGER(mpl) :: phase ! Solver phase(s) to be executed
9648 INTEGER(mpl) :: error ! Error code
9649 INTEGER(mpl) :: msglvl ! Message level
9650
9651 INTEGER(mpi) :: i
9652 INTEGER(mpl) :: ij
9653 INTEGER(mpl) :: idum(1)
9654 INTEGER(mpi) :: lun
9655 INTEGER(mpl) :: length
9656 INTEGER(mpi) :: nfill
9657 INTEGER(mpi) :: npdblk
9658 REAL(mpd) :: adum(1)
9659 REAL(mpd) :: ddum(1)
9660
9661 INTEGER(mpl) :: iparm(64)
9662 REAL(mpd), ALLOCATABLE :: b( : ) ! Right hand side (of equations system)
9663 REAL(mpd), ALLOCATABLE :: x( : ) ! Solution (of equations system)
9664 SAVE
9665
9666 lun=lunlog ! log file
9667
9668 error = 0 ! initialize error flag
9669 msglvl = ipddbg ! print statistical information
9670 npdblk=(nfgb-1)/matbsz+1 ! number of row blocks
9671
9672 IF(icalcm == 1) THEN
9673 mtype = 2 ! positive definite symmetric matrix
9674 IF (nfgb > nvgb) mtype = -2 ! indefinte symmetric matrix (Lagrange multipliers)
9675
9676 !$POMP INST BEGIN(mspd00)
9677 WRITE(*,*)
9678 WRITE(*,*) 'MSPARDISO: number of non-zero elements = ', csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
9679 ! fill up last block?
9680 nfill = npdblk*matbsz-nfgb
9681 IF (nfill > 0) THEN
9682 WRITE(*,*) 'MSPARDISO: number of rows to fill up = ', nfill
9683 ! end of last block
9684 ij = (csr3rowoffsets(npdblk+1)-csr3rowoffsets(1))*int(matbsz,mpl)*int(matbsz,mpl)
9685 DO i=1,nfill
9686 globalmatd(ij) = 1.0_mpd
9687 ij = ij-matbsz-1 ! back one row and one column in last block
9688 END DO
9689 END IF
9690
9691 ! close previous PARADISO run
9692 IF (ipdmem > 0) THEN
9693 !.. Termination and release of memory
9694 phase = -1 ! release internal memory
9695 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), adum, idum, idum, &
9696 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9697 IF (error /= 0) THEN
9698 WRITE(lun,*) 'The following ERROR was detected: ', error
9699 WRITE(*,'(A,2I10)') ' PARDISO release failed (phase, error): ', phase, error
9700 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9701 CALL peend(40,'Aborted, other error: PARDISO release')
9702 stop 'MSPARDISO: stopping due to error in PARDISO release'
9703 END IF
9704 ipdmem=0
9705 END IF
9706
9707 !..
9708 !.. Set up PARDISO control parameter
9709 !..
9710 iparm=0 ! using defaults
9711 iparm(2) = 2 ! fill-in reordering from METIS
9712 iparm(10) = 8 ! perturb the pivot elements with 1E-8
9713 iparm(18) = -1 ! Output: number of nonzeros in the factor LU
9714 iparm(19) = -1 ! Output: Mflops for LU factorization
9715 iparm(21) = 1 ! pivoting for symmetric indefinite matrices
9716 DO i=1, lenpardiso
9717 iparm(listpardiso(i)%label)=listpardiso(i)%ivalue
9718 END DO
9719 IF (iparm(1) == 0) WRITE(lun,*) 'PARDISO using defaults '
9720 IF (iparm(43) /= 0) THEN
9721 WRITE(lun,*) 'PARDISO: computation of the diagonal of inverse matrix not implemented !'
9722 iparm(43) = 0 ! no computation of the diagonal of inverse matrix
9723 END IF
9724
9725 ! necessary for the FIRST call of the PARDISO solver.
9726 DO i = 1, 64
9727 pt(i)%DUMMY = 0
9728 END DO
9729 !$POMP INST END(mspd00)
9730 END IF
9731
9732 IF(icalcm == 1) THEN
9733 ! monitor progress
9734 IF(monpg1 > 0) THEN
9735 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9737 END IF
9738 ! decompose and solve
9739 !.. Reordering and Symbolic Factorization, This step also allocates
9740 ! all memory that is necessary for the factorization
9741 !$POMP INST BEGIN(mspd11)
9742 phase = 11 ! only reordering and symbolic factorization
9743 IF (matbsz > 1) THEN
9744 iparm(1) = 1 ! non default setting
9745 iparm(37) = matbsz ! using BSR3 instead of CSR3
9746 END IF
9747 IF (ipddbg > 0) THEN
9748 DO i=1,64
9749 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9750 END DO
9751 END IF
9752 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9753 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9754 !$POMP INST END(mspd11)
9755 WRITE(lun,*) 'PARDISO reordering completed ... '
9756 WRITE(lun,*) 'PARDISO peak memory required (KB)', iparm(15)
9757 IF (ipddbg > 0) THEN
9758 DO i=1,64
9759 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9760 END DO
9761 END IF
9762 IF (error /= 0) THEN
9763 WRITE(lun,*) 'The following ERROR was detected: ', error
9764 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9765 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9766 CALL peend(40,'Aborted, other error: PARDISO reordering')
9767 stop 'MSPARDISO: stopping due to error in PARDISO reordering'
9768 END IF
9769 IF (iparm(60) == 0) THEN
9770 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(17) ! in core
9771 ELSE
9772 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(63) ! out of core
9773 END IF
9774 WRITE(lun,*) 'Size (KB) of allocated memory = ',ipdmem
9775 WRITE(lun,*) 'Number of nonzeros in factors = ',iparm(18)
9776 WRITE(lun,*) 'Number of factorization MFLOPS = ',iparm(19)
9777
9778 !.. Factorization.
9779 !$POMP INST BEGIN(mspd22)
9780 phase = 22 ! only factorization
9781 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9782 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9783 !$POMP INST END(mspd22)
9784 WRITE(lun,*) 'PARDISO factorization completed ... '
9785 IF (ipddbg > 0) THEN
9786 DO i=1,64
9787 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9788 END DO
9789 END IF
9790 IF (error /= 0) THEN
9791 WRITE(lun,*) 'The following ERROR was detected: ', error
9792 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9793 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9794 CALL peend(40,'Aborted, other error: PARDISO factorization')
9795 stop 'MSPARDISO: stopping due to error in PARDISO factorization'
9796 ENDIF
9797 IF (mtype < 0) THEN
9798 IF (iparm(14) > 0) &
9799 WRITE(lun,*) 'Number of perturbed pivots = ',iparm(14)
9800 WRITE(lun,*) 'Number of positive eigenvalues = ',iparm(22)-nfill
9801 WRITE(lun,*) 'Number of negative eigenvalues = ',iparm(23)
9802 ELSE IF (iparm(30) > 0) THEN
9803 WRITE(lun,*) 'Equation with bad pivot (<=0.) = ',iparm(30)
9804 END IF
9805
9806 IF (monpg1 > 0) CALL monend()
9807 END IF
9808
9809 ! backward/forward substitution
9810 !.. Back substitution and iterative refinement
9811 length=nfgb+nfill
9812 CALL mpalloc(b,length,' PARDISO r.h.s')
9813 CALL mpalloc(x,length,' PARDISO solution')
9815 !$POMP INST BEGIN(mspd33)
9816 iparm(6) = 0 ! don't update r.h.s. with solution
9817 phase = 33 ! only solving
9818 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9819 idum, nrhs, iparm, msglvl, b, x, error)
9820 !$POMP INST END(mspd33)
9822 CALL mpdealloc(x)
9823 CALL mpdealloc(b)
9824 WRITE(lun,*) 'PARDISO solve completed ... '
9825 IF (error /= 0) THEN
9826 WRITE(lun,*) 'The following ERROR was detected: ', error
9827 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9828 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9829 CALL peend(40,'Aborted, other error: PARDISO solve')
9830 stop 'MSPARDISO: stopping due to error in PARDISO solve'
9831 ENDIF
9832
9833END SUBROUTINE mspardiso
9834#endif
9835#endif
9836
9838SUBROUTINE mdiags
9839 USE mpmod
9840
9841 IMPLICIT NONE
9842 REAL(mps) :: evalue
9843 INTEGER(mpi) :: i
9844 INTEGER(mpi) :: iast
9845 INTEGER(mpi) :: idia
9846 INTEGER(mpi) :: imin
9847 INTEGER(mpl) :: ioff1
9848 INTEGER(mpi) :: j
9849 INTEGER(mpi) :: last
9850 INTEGER(mpi) :: lun
9851 INTEGER(mpi) :: nmax
9852 INTEGER(mpi) :: nmin
9853 INTEGER(mpi) :: ntop
9854 REAL(mpd) :: matij
9855 !
9856 EXTERNAL avprds
9857
9858 SAVE
9859 ! ...
9860
9861 lun=lunlog ! log file
9862
9863 ! save diagonal (for global correlation)
9864 IF(icalcm == 1) THEN
9865 DO i=1,nagb
9866 workspacediag(i)=matij(i,i)
9867 END DO
9868 ENDIF
9869
9870 !use elimination for constraints ?
9871 IF(nfgb < nvgb) THEN
9872 IF(icalcm == 1) THEN
9873 ! monitor progress
9874 IF(monpg1 > 0) THEN
9875 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9877 END IF
9878 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9879 IF(monpg1 > 0) CALL monend()
9880 ENDIF
9881 ! solve L^t*y=d by backward substitution
9883 ! transform, reduce rhs
9884 CALL qlmlq(globalcorrections,1,.true.) ! Q^t*b
9885 ! correction from eliminated part
9886 DO i=1,nfgb
9887 DO j=1,ncgb
9888 ioff1=globalrowoffsets(nfgb+j)+i ! global (nfit+j,i)
9890 END DO
9891 END DO
9892 END IF
9893
9894 IF(icalcm == 1) THEN
9895 ! eigenvalues eigenvectors symm_input
9896 workspaceeigenvalues=0.0_mpd
9899
9900 ! histogram of positive eigenvalues
9901
9902 nmax=int(1.0+log10(real(workspaceeigenvalues(1),mps)),mpi) ! > log of largest eigenvalue
9903 imin=1
9904 DO i=nfgb,1,-1
9905 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
9906 imin=i ! index of smallest pos. eigenvalue
9907 EXIT
9908 END IF
9909 END DO
9910 nmin=int(log10(real(workspaceeigenvalues(imin),mps)),mpi) ! log of smallest pos. eigenvalue
9911 ntop=nmin+6
9912 DO WHILE(ntop < nmax)
9913 ntop=ntop+3
9914 END DO
9915
9916 CALL hmpdef(7,real(nmin,mps),real(ntop,mps), 'log10 of positive eigenvalues')
9917 DO idia=1,nfgb
9918 IF(workspaceeigenvalues(idia) > 0.0_mpd) THEN ! positive
9919 evalue=log10(real(workspaceeigenvalues(idia),mps))
9920 CALL hmpent(7,evalue)
9921 END IF
9922 END DO
9923 IF(nhistp /= 0) CALL hmprnt(7)
9924 CALL hmpwrt(7)
9925
9926 iast=max(1,imin-60)
9927 CALL gmpdef(3,2,'low-value end of eigenvalues')
9928 DO i=iast,nfgb
9929 evalue=real(workspaceeigenvalues(i),mps)
9930 CALL gmpxy(3,real(i,mps),evalue)
9931 END DO
9932 IF(nhistp /= 0) CALL gmprnt(3)
9933 CALL gmpwrt(3)
9934
9935 DO i=1,nfgb
9936 workspacediagonalization(i)=0.0_mpd
9937 IF(workspaceeigenvalues(i) /= 0.0_mpd) THEN
9938 workspacediagonalization(i)=max(0.0_mpd,log10(abs(workspaceeigenvalues(i)))+3.0_mpd)
9940 END IF
9941 END DO
9942 last=min(nfgb,nvgb)
9943 WRITE(lun,*) ' '
9944 WRITE(lun,*) 'The first (largest) eigenvalues ...'
9945 WRITE(lun,102) (workspaceeigenvalues(i),i=1,min(20,nagb))
9946 WRITE(lun,*) ' '
9947 WRITE(lun,*) 'The last eigenvalues ... up to',last
9948 WRITE(lun,102) (workspaceeigenvalues(i),i=max(1,last-19),last)
9949 WRITE(lun,*) ' '
9950 IF(nagb > nvgb) THEN
9951 WRITE(lun,*) 'The eigenvalues from',nvgb+1,' to',nagb
9952 WRITE(lun,102) (workspaceeigenvalues(i),i=nvgb+1,nagb)
9953 WRITE(lun,*) ' '
9954 ENDIF
9955 WRITE(lun,*) 'Log10 + 3 of ',nfgb,' eigenvalues in decreasing', ' order'
9956 WRITE(lun,*) '(for Eigenvalue < 0.001 the value 0.0 is shown)'
9957 WRITE(lun,101) (workspacediagonalization(i),i=1,nfgb)
9958 IF(workspacediagonalization(nfgb) < 0) WRITE(lun,*) 'Negative values are ', &
9959 'printed for negative eigenvalues'
9961 WRITE(lun,*) ' '
9962 WRITE(lun,*) last,' significances: insignificant if ', &
9963 'compatible with N(0,1)'
9964 WRITE(lun,101) (workspacediagonalization(i),i=1,last)
9965
9966
9967101 FORMAT(10f7.1)
9968102 FORMAT(5e14.6)
9969
9970 END IF
9971
9972 ! solution ---------------------------------------------------------
9974 ! eigenvalues eigenvectors
9976
9977 !use elimination for constraints ?
9978 IF(nfgb < nvgb) THEN
9979 ! extend, transform back solution
9981 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
9982 END IF
9983
9984END SUBROUTINE mdiags
9985
9987SUBROUTINE zdiags
9988 USE mpmod
9989
9990 IMPLICIT NONE
9991 INTEGER(mpi) :: i
9992 INTEGER(mpl) :: ioff1
9993 INTEGER(mpl) :: ioff2
9994 INTEGER(mpi) :: j
9995
9996 ! eigenvalue eigenvectors cov.matrix
9998
9999 !use elimination for constraints ?
10000 IF(nfgb < nvgb) THEN
10001 ! extend, transform eigenvectors
10002 ioff1=nfgb*nfgb
10003 ioff2=nfgb*nvgb
10004 workspaceeigenvectors(ioff2+1:)=0.0_mpd
10005 DO i=nfgb,1,-1
10006 ioff1=ioff1-nfgb
10007 ioff2=ioff2-nvgb
10008 DO j=nfgb,1,-1
10010 END DO
10011 workspaceeigenvectors(ioff2+nfgb+1:ioff2+nvgb)=0.0_mpd
10012 END DO
10013 CALL qlmlq(workspaceeigenvectors,nvgb,.false.) ! Q*U
10014 END IF
10015
10016END SUBROUTINE zdiags
10017
10023
10024SUBROUTINE mminrs
10025 USE mpmod
10026 USE minresmodule, ONLY: minres
10027
10028 IMPLICIT NONE
10029 INTEGER(mpi) :: istop
10030 INTEGER(mpi) :: itn
10031 INTEGER(mpi) :: itnlim
10032 INTEGER(mpi) :: lun
10033 INTEGER(mpi) :: nout
10034 INTEGER(mpi) :: nrkd
10035 INTEGER(mpi) :: nrkd2
10036
10037 REAL(mpd) :: shift
10038 REAL(mpd) :: rtol
10039 REAL(mpd) :: anorm
10040 REAL(mpd) :: acond
10041 REAL(mpd) :: arnorm
10042 REAL(mpd) :: rnorm
10043 REAL(mpd) :: ynorm
10044 LOGICAL :: checka
10045 EXTERNAL avprds, avprod, mvsolv, mcsolv
10046 SAVE
10047 ! ...
10048 lun=lunlog ! log file
10049
10050 nout=lun
10051 itnlim=2000 ! iteration limit
10052 shift =0.0_mpd ! not used
10053 rtol = mrestl ! from steering
10054 checka=.false.
10055
10057 !use elimination for constraints ?
10058 IF(nfgb < nvgb) THEN
10059 ! solve L^t*y=d by backward substitution
10061 ! input to AVPRD0
10062 vecxav(1:nfgb)=0.0_mpd
10064 CALL qlmlq(vecxav,1,.false.) ! Q*x
10065 ! calclulate vecBav=globalMat*vecXav
10066 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10067 ! correction from eliminated part
10069 ! transform, reduce rhs
10070 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10071 END IF
10072
10073 IF(mbandw == 0) THEN ! default preconditioner
10074 IF(icalcm == 1) THEN
10075 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10076 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10077 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10079 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10080 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10081 IF(monpg1 > 0) CALL monend()
10082 END IF
10083 CALL minres(nfgb, avprod, mcsolv, workspaced, shift, checka ,.true. , &
10084 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10085 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10086 IF(icalcm == 1) THEN
10087 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10088 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10089 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10091 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10092 IF(monpg1 > 0) CALL monend()
10093 END IF
10094 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.true. , &
10095 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10096 ELSE
10097 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.false. , &
10098 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10099 END IF
10100
10101 !use elimination for constraints ?
10102 IF(nfgb < nvgb) THEN
10103 ! extend, transform back solution
10105 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10106 END IF
10107
10108 iitera=itn
10109 istopa=istop
10110 mnrsit=mnrsit+itn
10111
10112 IF (istopa == 0) print *, 'MINRES: istop=0, exact solution x=0.'
10113
10114END SUBROUTINE mminrs
10115
10121
10122SUBROUTINE mminrsqlp
10123 USE mpmod
10124 USE minresqlpmodule, ONLY: minresqlp
10125
10126 IMPLICIT NONE
10127 INTEGER(mpi) :: istop
10128 INTEGER(mpi) :: itn
10129 INTEGER(mpi) :: itnlim
10130 INTEGER(mpi) :: lun
10131 INTEGER(mpi) :: nout
10132 INTEGER(mpi) :: nrkd
10133 INTEGER(mpi) :: nrkd2
10134
10135 REAL(mpd) :: rtol
10136 REAL(mpd) :: mxxnrm
10137 REAL(mpd) :: trcond
10138
10139 EXTERNAL avprds, avprod, mvsolv, mcsolv
10140 SAVE
10141 ! ...
10142 lun=lunlog ! log file
10143
10144 nout=lun
10145 itnlim=2000 ! iteration limit
10146 rtol = mrestl ! from steering
10147 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
10148 IF(mrmode == 1) THEN
10149 trcond = 1.0_mpd/epsilon(trcond) ! only QR
10150 ELSE IF(mrmode == 2) THEN
10151 trcond = 1.0_mpd ! only QLP
10152 ELSE
10153 trcond = mrtcnd ! QR followed by QLP
10154 END IF
10155
10157 !use elimination for constraints ?
10158 IF(nfgb < nvgb) THEN
10159 ! solve L^t*y=d by backward substitution
10161 ! input to AVPRD0
10162 vecxav(1:nfgb)=0.0_mpd
10164 CALL qlmlq(vecxav,1,.false.) ! Q*x
10165 ! calclulate vecBav=globalMat*vecXav
10166 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10167 ! correction from eliminated part
10169 ! transform, reduce rhs
10170 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10171 END IF
10172
10173 IF(mbandw == 0) THEN ! default preconditioner
10174 IF(icalcm == 1) THEN
10175 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10176 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10177 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10179 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10180 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10181 IF(monpg1 > 0) CALL monend()
10182 END IF
10183 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mcsolv, nout=nout, &
10184 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10185 x=globalcorrections, istop=istop, itn=itn)
10186 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10187 IF(icalcm == 1) THEN
10188 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10189 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10190 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10192 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10193 IF(monpg1 > 0) CALL monend()
10194 END IF
10195
10196 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mvsolv, nout=nout, &
10197 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10198 x=globalcorrections, istop=istop, itn=itn)
10199 ELSE
10200 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, nout=nout, &
10201 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10202 x=globalcorrections, istop=istop, itn=itn)
10203 END IF
10204
10205 !use elimination for constraints ?
10206 IF(nfgb < nvgb) THEN
10207 ! extend, transform back solution
10209 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10210 END IF
10211
10212 iitera=itn
10213 istopa=istop
10214 mnrsit=mnrsit+itn
10215
10216 IF (istopa == 3) print *, 'MINRES: istop=0, exact solution x=0.'
10217
10218END SUBROUTINE mminrsqlp
10219
10227
10228SUBROUTINE mcsolv(n,x,y) ! solve M*y = x
10229 USE mpmod
10230
10231 IMPLICIT NONE
10232 INTEGER(mpi),INTENT(IN) :: n
10233 REAL(mpd), INTENT(IN) :: x(n)
10234 REAL(mpd), INTENT(OUT) :: y(n)
10235 SAVE
10236 ! ...
10238 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),y,x)
10239END SUBROUTINE mcsolv
10240
10248
10249SUBROUTINE mvsolv(n,x,y) ! solve M*y = x
10250 USE mpmod
10251
10252 IMPLICIT NONE
10253
10254 INTEGER(mpi), INTENT(IN) :: n
10255 REAL(mpd), INTENT(IN) :: x(n)
10256 REAL(mpd), INTENT(OUT) :: y(n)
10257
10258 SAVE
10259 ! ...
10260 y=x ! copy to output vector
10261
10263END SUBROUTINE mvsolv
10264
10265
10266
10267!***********************************************************************
10268
10281
10282SUBROUTINE xloopn !
10283 USE mpmod
10284
10285 IMPLICIT NONE
10286 REAL(mps) :: catio
10287 REAL(mps) :: concu2
10288 REAL(mps) :: concut
10289 REAL, DIMENSION(2) :: ta
10290 REAL etime
10291 INTEGER(mpi) :: i
10292 INTEGER(mpi) :: iact
10293 INTEGER(mpi) :: iagain
10294 INTEGER(mpi) :: idx
10295 INTEGER(mpi) :: info
10296 INTEGER(mpi) :: ib
10297 INTEGER(mpi) :: ipoff
10298 INTEGER(mpi) :: icoff
10299 INTEGER(mpl) :: ioff
10300 INTEGER(mpi) :: itgbi
10301 INTEGER(mpi) :: ivgbi
10302 INTEGER(mpi) :: jcalcm
10303 INTEGER(mpi) :: k
10304 INTEGER(mpi) :: labelg
10305 INTEGER(mpi) :: litera
10306 INTEGER(mpl) :: lrej
10307 INTEGER(mpi) :: lun
10308 INTEGER(mpi) :: lunp
10309 INTEGER(mpi) :: minf
10310 INTEGER(mpi) :: mrati
10311 INTEGER(mpi) :: nan
10312 INTEGER(mpi) :: ncon
10313 INTEGER(mpi) :: nfaci
10314 INTEGER(mpi) :: nloopsol
10315 INTEGER(mpi) :: npar
10316 INTEGER(mpi) :: nrati
10317 INTEGER(mpl) :: nrej
10318 INTEGER(mpi) :: nsol
10319 INTEGER(mpi) :: inone
10320#ifdef LAPACK64
10321 INTEGER(mpi) :: infolp
10322 INTEGER(mpi) :: nfit
10323 INTEGER(mpl) :: imoff
10324#endif
10325
10326 REAL(mpd) :: stp
10327 REAL(mpd) :: dratio
10328 REAL(mpd) :: dwmean
10329 REAL(mpd) :: db
10330 REAL(mpd) :: db1
10331 REAL(mpd) :: db2
10332 REAL(mpd) :: dbdot
10333 REAL(mpd) :: dbsig
10334 LOGICAL :: btest
10335 LOGICAL :: warner
10336 LOGICAL :: warners
10337 LOGICAL :: warnerss
10338 LOGICAL :: warners3
10339 LOGICAL :: lsflag
10340 CHARACTER (LEN=7) :: cratio
10341 CHARACTER (LEN=7) :: cfacin
10342 CHARACTER (LEN=7) :: crjrat
10343 EXTERNAL avprds
10344 SAVE
10345 ! ...
10346
10347 ! Printout of algorithm for solution and important parameters ------
10348
10349 lun=lunlog ! log file
10350
10351 DO lunp=6,lunlog,lunlog-6
10352 WRITE(lunp,*) ' '
10353 WRITE(lunp,*) 'Solution algorithm: '
10354 WRITE(lunp,121) '=================================================== '
10355
10356 IF(metsol == 1) THEN
10357 WRITE(lunp,121) 'solution method:','matrix inversion'
10358 ELSE IF(metsol == 2) THEN
10359 WRITE(lunp,121) 'solution method:','diagonalization'
10360 ELSE IF(metsol == 3) THEN
10361 WRITE(lunp,121) 'solution method:','decomposition'
10362 ELSE IF(metsol == 4) THEN
10363 WRITE(lunp,121) 'solution method:', 'minres (Paige/Saunders)'
10364 ELSE IF(metsol == 5) THEN
10365 WRITE(lunp,121) 'solution method:', 'minres-qlp (Choi/Paige/Saunders)'
10366 IF(mrmode == 1) THEN
10367 WRITE(lunp,121) ' ', ' using QR factorization' ! only QR
10368 ELSE IF(mrmode == 2) THEN
10369 WRITE(lunp,121) ' ', ' using QLP factorization' ! only QLP
10370 ELSE
10371 WRITE(lunp,121) ' ', ' using QR and QLP factorization' ! QR followed by QLP
10372 WRITE(lunp,123) 'transition condition', mrtcnd
10373 END IF
10374 ELSE IF(metsol == 6) THEN
10375 WRITE(lunp,121) 'solution method:', &
10376 'gmres (generalized minimzation of residuals)'
10377#ifdef LAPACK64
10378 ELSE IF(metsol == 7) THEN
10379 IF (nagb > nvgb) THEN
10380 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSPTRF)'
10381 ELSE
10382 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPPTRF)'
10383 ENDIF
10384 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10385 ELSE IF(metsol == 8) THEN
10386 IF (nagb > nvgb) THEN
10387 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSYTRF)'
10388 ELSE
10389 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPOTRF)'
10390 ENDIF
10391 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10392#ifdef PARDISO
10393 ELSE IF(metsol == 9) THEN
10394 IF (matbsz < 2) THEN
10395 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (CSR3))'
10396 ELSE
10397 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (BSR3))'
10398 ENDIF
10399#endif
10400#endif
10401 END IF
10402 WRITE(lunp,123) 'convergence limit at Delta F=',dflim
10403 WRITE(lunp,122) 'maximum number of iterations=',mitera
10404 matrit=min(matrit,mitera)
10405 IF(matrit > 1) THEN
10406 WRITE(lunp,122) 'matrix recalculation up to ',matrit, '. iteration'
10407 END IF
10408 IF(metsol >= 4.AND.metsol < 7) THEN
10409 IF(matsto == 1) THEN
10410 WRITE(lunp,121) 'matrix storage:','full'
10411 ELSE IF(matsto == 2) THEN
10412 WRITE(lunp,121) 'matrix storage:','sparse'
10413 END IF
10414 WRITE(lunp,122) 'pre-con band-width parameter=',mbandw
10415 IF(mbandw == 0) THEN
10416 WRITE(lunp,121) 'pre-conditioning:','default'
10417 ELSE IF(mbandw < 0) THEN
10418 WRITE(lunp,121) 'pre-conditioning:','none!'
10419 ELSE IF(mbandw > 0) THEN
10420 IF(lprecm > 0) THEN
10421 WRITE(lunp,121) 'pre-conditioning=','skyline-matrix (rank preserving)'
10422 ELSE
10423 WRITE(lunp,121) 'pre-conditioning=','band-matrix'
10424 ENDIF
10425 END IF
10426 END IF
10427 IF(regpre == 0.0_mpd.AND.npresg == 0) THEN
10428 WRITE(lunp,121) 'using pre-sigmas:','no'
10429 ELSE
10430 ! FIXME: NPRESG contains parameters that failed the 'entries' cut...
10431 WRITE(lunp,124) 'pre-sigmas defined for', &
10432 REAL(100*npresg,mps)/REAL(nvgb,mps),' % of variable parameters'
10433 WRITE(lunp,123) 'default pre-sigma=',regpre
10434 END IF
10435 IF(nregul == 0) THEN
10436 WRITE(lunp,121) 'regularization:','no'
10437 ELSE
10438 WRITE(lunp,121) 'regularization:','yes'
10439 WRITE(lunp,123) 'regularization factor=',regula
10440 END IF
10441
10442 IF(chicut /= 0.0) THEN
10443 WRITE(lunp,121) 'Chi square cut equiv 3 st.dev applied'
10444 WRITE(lunp,123) '... in first iteration with factor',chicut
10445 WRITE(lunp,123) '... in second iteration with factor',chirem
10446 WRITE(lunp,121) ' (reduced by sqrt in next iterations)'
10447 END IF
10448 IF(iscerr > 0) THEN
10449 WRITE(lunp,121) 'Scaling of measurement errors applied'
10450 WRITE(lunp,123) '... factor for "global" measuements',dscerr(1)
10451 WRITE(lunp,123) '... factor for "local" measuements',dscerr(2)
10452 END IF
10453 IF(lhuber /= 0) THEN
10454 WRITE(lunp,122) 'Down-weighting of outliers in', lhuber,' iterations'
10455 WRITE(lunp,123) 'Cut on downweight fraction',dwcut
10456 END IF
10457
10458
10459121 FORMAT(1x,a40,3x,a)
10460122 FORMAT(1x,a40,3x,i0,a)
10461123 FORMAT(1x,a40,2x,e9.2)
10462124 FORMAT(1x,a40,3x,f5.1,a)
10463 END DO
10464
10465 ! initialization of iterations -------------------------------------
10466
10467 iitera=0
10468 nsol =0 ! counter for solutions
10469 info =0
10470 lsinfo=0
10471 stp =0.0_mpd
10472 stepl =real(stp,mps)
10473 concut=1.0e-12 ! initial constraint accuracy
10474 concu2=1.0e-06 ! constraint accuracy
10475 icalcm=1 ! require matrix calculation
10476 iterat=0 ! iteration counter
10477 iterat=-1
10478 litera=-2
10479 nloopsol=0 ! (new) solution from this nloopn
10480 nrej=0 ! reset number of rejects
10481 IF(metsol == 1) THEN
10482 wolfc2=0.5 ! not accurate
10483 minf=1
10484 ELSE IF(metsol == 2) THEN
10485 wolfc2=0.5 ! not acurate
10486 minf=2
10487 ELSE IF(metsol == 3) THEN
10488 wolfc2=0.5 ! not acurate
10489 minf=1
10490 ELSE IF(metsol == 4) THEN
10491 wolfc2=0.1 ! accurate
10492 minf=3
10493 ELSE IF(metsol == 5) THEN
10494 wolfc2=0.1 ! accurate
10495 minf=3
10496 ELSE IF(metsol == 6) THEN
10497 wolfc2=0.1 ! accurate
10498 minf=3
10499 ELSE
10500 wolfc2=0.5 ! not accurate
10501 minf=1
10502 END IF
10503
10504 ! check initial feasibility of constraint equations ----------------
10505
10506 WRITE(*,*) ' '
10507 IF(nofeas == 0) THEN ! make parameter feasible
10508 WRITE(lunlog,*) 'Checking feasibility of parameters:'
10509 WRITE(*,*) 'Checking feasibility of parameters:'
10510 CALL feasib(concut,iact) ! check feasibility
10511 IF(iact /= 0) THEN ! done ...
10512 WRITE(*,102) concut
10513 WRITE(*,*) ' parameters are made feasible'
10514 WRITE(lunlog,102) concut
10515 WRITE(lunlog,*) ' parameters are made feasible'
10516 ELSE ! ... was OK
10517 WRITE(*,*) ' parameters are feasible (i.e. satisfy constraints)'
10518 WRITE(lunlog,*) ' parameters are feasible (i.e. satisfy constraints)'
10519 END IF
10520 concut=concu2 ! cut for constraint check
10521 END IF
10522 iact=1 ! set flag for new data loop
10523 nofeas=0 ! set check-feasibility flag
10524
10525 WRITE(*,*) ' '
10526 WRITE(*,*)'Reading files and accumulating vectors/matrices ...'
10527 WRITE(*,*) ' '
10528 IF(monpg1>0) THEN
10529 WRITE(lunlog,*)
10530 WRITE(lunlog,*)'Reading files and accumulating vectors/matrices ...'
10531 WRITE(lunlog,*)
10532 END IF
10533
10534 rstart=etime(ta)
10535 iterat=-1
10536 litera= 0
10537 jcalcm=-1
10538 iagain= 0
10539
10540 icalcm=1
10541
10542 ! Block 1: data loop with vector (and matrix) calculation ----------
10543
10544 DO
10545 IF(iterat >= 0) THEN
10546 lcalcm=jcalcm+3 ! mode (1..4) of last loop
10547 IF(jcalcm+1 /= 0) THEN
10548 IF(iterat == 0) THEN
10549 CALL ploopa(6) ! header
10550 CALL ploopb(6)
10551 CALL ploopa(lunlog) ! iteration line
10552 CALL ploopb(lunlog)
10553 iterat=1
10554 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10555 ELSE
10556 IF(iterat /= litera) THEN
10557 CALL ploopb(6)
10558 ! CALL PLOOPA(LUNLOG)
10559 CALL ploopb(lunlog)
10560 litera=iterat
10561 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,delfun) ! fcn-value (with expected)
10562 IF(metsol == 4 .OR. metsol == 5) THEN ! extend to 6, i.e. GMRES?
10563 CALL gmpxy(2,real(iterat,mps),real(iitera,mps)) ! MINRES iterations
10564 END IF
10565 ELSE
10566 CALL ploopc(6) ! sub-iteration line
10567 CALL ploopc(lunlog)
10568 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10569 END IF
10570 END IF
10571 ELSE
10572 CALL ploopd(6) ! solution line
10573 CALL ploopd(lunlog)
10574 END IF
10575 rstart=etime(ta)
10576 ! CHK
10577 IF (iabs(jcalcm) <= 1) THEN
10578 idx=jcalcm+4
10579 times(idx )=(times(idx )*times(idx+3)+deltim) /(times(idx+3)+1.0)
10580 times(idx+3)= times(idx+3)+1.0
10581 END IF
10582 END IF
10583 jcalcm=icalcm
10584
10585 IF(icalcm >= 0) THEN ! ICALCM = +1 & 0
10586 CALL loopn ! data loop
10587 CALL addcst ! constraints
10588 lrej=nrej
10589 nrej=sum(nrejec) ! total number of rejects
10590 IF(3*nrej > nrecal) THEN
10591 WRITE(*,*) ' '
10592 WRITE(*,*) 'Data records rejected in previous loop: '
10593 CALL prtrej(6)
10594 WRITE(*,*) 'Too many rejects (>33.3%) - stop'
10595 CALL peend(26,'Aborted, too many rejects')
10596 stop
10597 END IF
10598 ! fill second half (j>i) of global matrix for extended storage, experimental
10599 IF (icalcm == 1.AND.mextnd > 0) CALL mhalf2()
10600 END IF
10601 ! Block 2: new iteration with calculation of solution --------------
10602 IF(abs(icalcm) == 1) THEN ! ICALCM = +1 & -1
10603 DO i=1,nagb
10604 globalcorrections(i)=globalvector(i) ! copy rhs
10605 END DO
10606 DO i=1,nvgb
10607 itgbi=globalparvartototal(i)
10608 workspacelinesearch(i)=globalparameter(itgbi) ! copy X for line search
10609 END DO
10610
10611 iterat=iterat+1 ! increase iteration count
10612 IF(metsol == 1) THEN
10613 CALL minver ! inversion
10614 ELSE IF(metsol == 2) THEN
10615 CALL mdiags ! diagonalization
10616 ELSE IF(metsol == 3) THEN
10617 CALL mchdec ! decomposition
10618 ELSE IF(metsol == 4) THEN
10619 CALL mminrs ! MINRES
10620 ELSE IF(metsol == 5) THEN
10621 CALL mminrsqlp ! MINRES-QLP
10622 ELSE IF(metsol == 6) THEN
10623 WRITE(*,*) '... reserved for GMRES (not yet!)'
10624 CALL mminrs ! GMRES not yet
10625#ifdef LAPACK64
10626 ELSE IF(metsol == 7) THEN
10627 CALL mdptrf ! LAPACK (packed storage)
10628 ELSE IF(metsol == 8) THEN
10629 CALL mdutrf ! LAPACK (unpacked storage)
10630#ifdef PARDISO
10631 ELSE IF(metsol == 9) THEN
10632 CALL mspardiso ! Intel oneMKL PARDISO (sparse matrix (CSR3, upper triangle))
10633#endif
10634#endif
10635 END IF
10636 nloopsol=nloopn ! (new) solution for this nloopn
10637
10638 ! check feasibility and evtl. make step vector feasible
10639
10640 DO i=1,nvgb
10641 itgbi=globalparvartototal(i)
10642 globalparcopy(itgbi)=globalparameter(itgbi) ! save
10643 globalparameter(itgbi)=globalparameter(itgbi)+globalcorrections(i) ! update
10644 END DO
10645 CALL feasib(concut,iact) ! improve constraints
10646 concut=concu2 ! new cut for constraint check
10647 DO i=1,nvgb
10648 itgbi=globalparvartototal(i)
10649 globalcorrections(i)=globalparameter(itgbi)-globalparcopy(itgbi) ! feasible stp
10650 globalparameter(itgbi)=globalparcopy(itgbi) ! restore
10651 END DO
10652
10655 db2=dbdot(nvgb,globalvector,globalvector)
10656 delfun=real(db,mps)
10657 angras=real(db/sqrt(db1*db2),mps)
10658 dbsig=16.0_mpd*sqrt(max(db1,db2))*epsilon(db) ! significant change
10659
10660 ! do line search for this iteration/solution ?
10661 ! lsearch >2: all, =2: all with (next) chicut =1., =1: last, <1: none
10662 lsflag=(lsearch > 2 .OR. (lsearch == 2 .AND. chicut < 2.25) .OR. &
10663 (lsearch == 1 .AND. chicut < 2.25 .AND. (delfun <= dflim .OR. iterat >= mitera)))
10664 lsflag=lsflag .AND. (db > dbsig) ! require significant change
10665 IF (lsflag) THEN
10666 ! initialize line search based on slopes and prepare next
10667 CALL ptldef(wolfc2, 10.0, minf,10)
10668 IF(metsol == 1) THEN
10669 wolfc2=0.5 ! not accurate
10670 minf=3
10671 ELSE IF(metsol == 2) THEN
10672 wolfc2=0.5 ! not acurate
10673 minf=3
10674 ELSE IF(metsol == 3) THEN
10675 wolfc2=0.5 ! not acurate
10676 minf=3
10677 ELSE IF(metsol == 4) THEN
10678 wolfc2=0.1 ! accurate
10679 minf=4
10680 ELSE IF(metsol == 5) THEN
10681 wolfc2=0.1 ! accurate
10682 minf=4
10683 ELSE IF(metsol == 6) THEN
10684 wolfc2=0.1 ! accurate
10685 minf=4
10686 ELSE
10687 wolfc2=0.5 ! not accurate
10688 minf=3
10689 END IF
10690 ENDIF
10691
10692 ! change significantly negative ?
10693 IF(db <= -dbsig) THEN
10694 WRITE(*,*) 'Function not decreasing:',db
10695 IF(db > -1.0e-3_mpd) THEN ! 100311, VB/CK: allow some margin for numerics
10696 iagain=iagain+1
10697 IF (iagain <= 1) THEN
10698 WRITE(*,*) '... again matrix calculation'
10699 icalcm=1
10700 cycle
10701 ELSE
10702 WRITE(*,*) '... aborting iterations'
10703 GO TO 90
10704 END IF
10705 ELSE
10706 WRITE(*,*) '... stopping iterations'
10707 iagain=-1
10708 GO TO 90
10709 END IF
10710 ELSE
10711 iagain=0
10712 END IF
10713 icalcm=0 ! switch
10714 ENDIF
10715 ! Block 3: line searching ------------------------------------------
10716
10717 IF(icalcm+2 == 0) EXIT
10718 IF (lsflag) THEN
10719 CALL ptline(nvgb,workspacelinesearch, & ! current parameter values
10720 flines, & ! chi^2 function value
10721 globalvector, & ! gradient
10722 globalcorrections, & ! step vector stp
10723 stp, & ! returned step factor
10724 info) ! returned information
10725 ! WRITE(*,*) 'PTLINE returns INFO, STP=',INFO, STP
10726 ELSE ! skip line search
10727 info=10
10728 stepl=1.0
10729 IF (nloopn == nloopsol) THEN ! new solution: update corrections
10731 ENDIF
10732 ENDIF
10733 lsinfo=info
10734
10735 stepl=real(stp,mps)
10736 nan=0
10737 DO i=1,nvgb
10738 itgbi=globalparvartototal(i)
10739 IF ((.NOT.(workspacelinesearch(i) <= 0.0_mpd)).AND. &
10740 (.NOT.(workspacelinesearch(i) > 0.0_mpd))) nan=nan+1
10741 globalparameter(itgbi)=workspacelinesearch(i) ! current parameter values
10742 END DO
10743
10744 IF (nan > 0) THEN
10745 WRITE(*,*) 'Result vector containes ', nan,' NaNs - stop'
10746 CALL peend(25,'Aborted, result vector contains NaNs')
10747 stop
10748 END IF
10749
10750 ! subito exit, if required -----------------------------------------
10751
10752 IF(isubit /= 0) THEN ! subito
10753 WRITE(*,*) 'Subito! Exit after first step.'
10754 GO TO 90
10755 END IF
10756
10757 IF(info == 0) THEN
10758 WRITE(*,*) 'INFO=0 should not happen (line search input err)'
10759 IF (iagain <= 0) THEN
10760 icalcm=1
10761 cycle
10762 ENDIF
10763 END IF
10764 IF(info < 0 .OR. nloopn == nloopsol) cycle
10765 ! Block 4: line search convergence ---------------------------------
10766
10767 CALL ptlprt(lunlog)
10768 CALL feasib(concut,iact) ! check constraints
10769 IF(iact /= 0.OR.chicut > 1.0) THEN
10770 icalcm=-1
10771 IF(iterat < matrit) icalcm=+1
10772 cycle ! iterate
10773 END IF
10774 IF(delfun <= dflim) GO TO 90 ! convergence
10775 IF(iterat >= mitera) GO TO 90 ! ending
10776 icalcm=-1
10777 IF(iterat < matrit) icalcm=+1
10778 cycle ! next iteration
10779
10780 ! Block 5: iteration ending ----------------------------------------
10781
1078290 icalcm=-2
10783 END DO
10784 IF(sum(nrejec) /= 0) THEN
10785 WRITE(*,*) ' '
10786 WRITE(*,*) 'Data records rejected in last loop: '
10787 CALL prtrej(6)
10788 END IF
10789
10790 ! monitoring of residuals
10791 IF (imonit > 0 .AND. btest(imonit,1)) CALL monres
10792 IF (lunmon > 0) CLOSE(unit=lunmon)
10793
10794 ! construct inverse from diagonalization
10795 IF(metsol == 2) CALL zdiags
10796
10797 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
10798#ifdef LAPACK64
10799 IF (metsol == 7.OR.metsol == 8) THEN
10800 ! inverse from factorization
10801 ! loop over blocks (multiple blocks only with elimination !)
10802 DO ib=1,npblck
10803 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10804 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10805 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10806 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10807 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
10808 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
10809 IF (nfit > npar) THEN
10810 ! monitor progress
10811 IF(monpg1 > 0) THEN
10812 WRITE(lunlog,*) 'Inverse of global matrix from LDLt factorization'
10814 END IF
10815 IF (matsto == 1) THEN
10816 !$POMP INST BEGIN(dsptri)
10817 CALL dsptri('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),workspaced,infolp)
10818 IF(infolp /= 0) print *, ' DSPTRI failed: ', infolp
10819 !$POMP INST END(dsptri)
10820 IF(monpg1 > 0) CALL monend()
10821 ELSE
10822 !$POMP INST BEGIN(dsytri)
10823 CALL dsytri('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
10824 lapackipiv(ipoff+1:),workspaced,infolp)
10825 IF(infolp /= 0) print *, ' DSYTRI failed: ', infolp
10826 !$POMP INST END(dsytri)
10827 IF(monpg1 > 0) CALL monend()
10828 END IF
10829 ELSE
10830 IF(monpg1 > 0) THEN
10831 WRITE(lunlog,*) 'Inverse of global matrix from LLt factorization'
10833 END IF
10834 IF (matsto == 1) THEN
10835 !$POMP INST BEGIN(dpptri)
10836 CALL dpptri('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
10837 IF(infolp /= 0) print *, ' DPPTRI failed: ', infolp
10838 !$POMP INST END(dpptri)
10839 ELSE
10840 !$POMP INST BEGIN(dpotri)
10841 CALL dpotri('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
10842 IF(infolp /= 0) print *, ' DPOTRI failed: ', infolp
10843 !$POMP INST END(dpotri)
10844 END IF
10845 IF(monpg1 > 0) CALL monend()
10846 END IF
10847 END DO
10848 END IF
10849#endif
10850 !use elimination for constraints ?
10851 IF(nfgb < nvgb) THEN
10852 ! extend, transform matrix
10853 ! loop over blocks
10854 DO ib=1,npblck
10855 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10856 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10857 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10858 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10859 DO i=npar-ncon+1,npar
10860 ioff=globalrowoffsets(i+ipoff)+ipoff
10861 globalmatd(ioff+1:ioff+i)=0.0_mpd
10862 END DO
10863 END DO
10864 ! monitor progress
10865 IF(monpg1 > 0) THEN
10866 WRITE(lunlog,*) 'Expansion of global matrix (A->Q*A*Q^t)'
10868 END IF
10869 IF(icelim < 2) THEN
10870 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.false.) ! Q*A*Q^t
10871#ifdef LAPACK64
10872 ELSE ! unpack storage, use LAPACK
10873 CALL lpavat(.false.)
10874#endif
10875 END IF
10876 IF(monpg1 > 0) CALL monend()
10877 END IF
10878 END IF
10879
10880 dwmean=sumndf/real(ndfsum,mpd)
10881 dratio=fvalue/dwmean/real(ndfsum-nfgb,mpd)
10882 catio=real(dratio,mps)
10883 IF(nloopn /= 1.AND.lhuber /= 0) THEN
10884 catio=catio/0.9326 ! correction Huber downweighting (in global chi2)
10885 END IF
10886 mrati=nint(100.0*catio,mpi)
10887
10888 DO lunp=6,lunlog,lunlog-6
10889 WRITE(lunp,*) ' '
10890 IF (nfilw <= 0) THEN
10891 WRITE(lunp,*) 'Sum(Chi^2)/Sum(Ndf) =',fvalue
10892 WRITE(lunp,*) ' / (',ndfsum,'-',nfgb,')'
10893 WRITE(lunp,*) ' =',dratio
10894 ELSE
10895 WRITE(lunp,*) 'Sum(W*Chi^2)/Sum(Ndf)/<W> =',fvalue
10896 WRITE(lunp,*) ' / (',ndfsum,'-', nfgb,')'
10897 WRITE(lunp,*) ' /',dwmean
10898 WRITE(lunp,*) ' =',dratio
10899 END IF
10900 WRITE(lunp,*) ' '
10901 IF(nloopn /= 1.AND.lhuber /= 0) WRITE(lunp,*) &
10902 ' with correction for down-weighting ',catio
10903 END DO
10904 nrej=sum(nrejec) ! total number of rejects
10905
10906 ! ... the end with exit code ???????????????????????????????????????
10907
10908 ! WRITE(*,199) ! write exit code
10909 ! + '-----------------------------------------------------------'
10910 ! IF(ITEXIT.EQ.0) WRITE(*,199)
10911 ! + 'Exit code = 0: Convergence reached'
10912 ! IF(ITEXIT.EQ.1) WRITE(*,199)
10913 ! + 'Exit code = 1: No improvement in last iteration'
10914 ! IF(ITEXIT.EQ.2) WRITE(*,199)
10915 ! + 'Exit code = 2: Maximum number of iterations reached'
10916 ! IF(ITEXIT.EQ.3) WRITE(*,199)
10917 ! + 'Exit code = 3: Failure'
10918 ! WRITE(*,199)
10919 ! + '-----------------------------------------------------------'
10920 ! WRITE(*,199) ' '
10921
10922
10923 nrati=nint(10000.0*real(nrej,mps)/real(nrecal,mps),mpi)
10924 WRITE(crjrat,197) 0.01_mpd*real(nrati,mpd)
10925 nfaci=nint(100.0*sqrt(catio),mpi)
10926
10927 WRITE(cratio,197) 0.01_mpd*real(mrati,mpd)
10928 WRITE(cfacin,197) 0.01_mpd*real(nfaci,mpd)
10929
10930 warner=.false. ! warnings
10931 IF(mrati < 90.OR.mrati > 110) warner=.true.
10932 IF(nrati > 100) warner=.true.
10933 IF(ncgbe /= 0) warner=.true.
10934 warners = .false. ! severe warnings
10935 IF(nalow /= 0) warners=.true.
10936 warnerss = .false. ! more severe warnings
10937 IF(nmiss1 /= 0) warnerss=.true.
10938 IF(iagain /= 0) warnerss=.true.
10939 IF(ndefec /= 0) warnerss=.true.
10940 IF(ndefpg /= 0) warnerss=.true.
10941 warners3 = .false. ! more severe warnings
10942 IF(nrderr /= 0) warners3=.true.
10943
10944 IF(warner.OR.warners.OR.warnerss.Or.warners3) THEN
10945 WRITE(*,199) ' '
10946 WRITE(*,199) ' '
10947 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
10948 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
10949 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
10950 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
10951 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
10952 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
10953 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
10954
10955 IF(mrati < 90.OR.mrati > 110) THEN
10956 WRITE(*,199) ' '
10957 WRITE(*,*) ' Chi^2/Ndf = ',cratio, ' (should be close to 1)'
10958 WRITE(*,*) ' => multiply all input standard ', &
10959 'deviations by factor',cfacin
10960 END IF
10961
10962 IF(nrati > 100) THEN
10963 WRITE(*,199) ' '
10964 WRITE(*,*) ' Fraction of rejects =',crjrat,' %', &
10965 ' (should be far below 1 %)'
10966 WRITE(*,*) ' => please provide correct mille data'
10967 CALL chkrej ! check (and print) rejection details
10968 END IF
10969
10970 IF(iagain /= 0) THEN
10971 WRITE(*,199) ' '
10972 WRITE(*,*) ' Matrix not positiv definite '// &
10973 '(function not decreasing)'
10974 WRITE(*,*) ' => please provide correct mille data'
10975 END IF
10976
10977 IF(ndefec /= 0) THEN
10978 WRITE(*,199) ' '
10979 WRITE(*,*) ' Rank defect =',ndefec, &
10980 ' for global matrix, should be 0'
10981 WRITE(*,*) ' => please provide correct mille data'
10982 END IF
10983
10984 IF(ndefpg /= 0) THEN
10985 WRITE(*,199) ' '
10986 WRITE(*,*) ' Rank defect for',ndefpg, &
10987 ' parameter groups, should be 0'
10988 WRITE(*,*) ' => please provide correct mille data'
10989 END IF
10990
10991 IF(nmiss1 /= 0) THEN
10992 WRITE(*,199) ' '
10993 WRITE(*,*) ' Rank defect =',nmiss1, &
10994 ' for constraint equations, should be 0'
10995 WRITE(*,*) ' => please correct constraint definition'
10996 END IF
10997
10998 IF(ncgbe /= 0) THEN
10999 WRITE(*,199) ' '
11000 WRITE(*,*) ' Number of empty constraints =',ncgbe, ', should be 0'
11001 WRITE(*,*) ' => please check constraint definition, mille data'
11002 END IF
11003
11004 IF(nxlow /= 0) THEN
11005 WRITE(*,199) ' '
11006 WRITE(*,*) ' Possible rank defects =',nxlow, ' for global matrix'
11007 WRITE(*,*) ' (too few accepted entries)'
11008 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11009 END IF
11010
11011 IF(nalow /= 0) THEN
11012 WRITE(*,199) ' '
11013 WRITE(*,*) ' Possible bad elements =',nalow, ' in global vector'
11014 WRITE(*,*) ' (toos few accepted entries)'
11015 IF(ipcntr > 0) WRITE(*,*) ' (indicated in millepede.res by counts<0)'
11016 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11017 END IF
11018
11019 IF(nrderr /= 0) THEN
11020 WRITE(*,199) ' '
11021 WRITE(*,*) ' Binary file(s) with read errors =',nrderr, ' (treated as EOF)'
11022 WRITE(*,*) ' => please check mille data'
11023 END IF
11024
11025 WRITE(*,199) ' '
11026 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
11027 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
11028 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
11029 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
11030 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
11031 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
11032 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
11033 WRITE(*,199) ' '
11034
11035 ENDIF
11036
11037 CALL mend ! modul ending
11038
11039 ! ------------------------------------------------------------------
11040
11041 IF(metsol == 1) THEN
11042
11043 ELSE IF(metsol == 2) THEN
11044 ! CALL zdiags moved up (before qlssq)
11045 ELSE IF(metsol == 3) THEN
11046 ! decomposition - nothing foreseen yet
11047 ELSE IF(metsol == 4 .OR. metsol == 5) THEN
11048 ! errors and correlations from MINRES
11049 DO k=1,mnrsel
11050 labelg=lbmnrs(k)
11051 IF(labelg == 0) cycle
11052 itgbi=inone(labelg)
11053 ivgbi=0
11054 IF(itgbi /= 0) ivgbi=globalparlabelindex(2,itgbi)
11055 IF(ivgbi < 0) ivgbi=0
11056 IF(ivgbi == 0) cycle
11057 ! determine error and global correlation for parameter IVGBI
11058 IF (metsol == 4) THEN
11059 CALL solglo(ivgbi)
11060 ELSE
11061 CALL solgloqlp(ivgbi)
11062 ENDIF
11063 END DO
11064
11065 ELSE IF(metsol == 6) THEN
11066
11067#ifdef LAPACK64
11068 ELSE IF(metsol == 7) THEN
11069 ! LAPACK - nothing foreseen yet
11070#endif
11071 END IF
11072
11073 CALL prtglo ! print result
11074
11075 IF (warners3) THEN
11076 CALL peend(4,'Ended with severe warnings (bad binary file(s))')
11077 ELSE IF (warnerss) THEN
11078 CALL peend(3,'Ended with severe warnings (bad global matrix)')
11079 ELSE IF (warners) THEN
11080 CALL peend(2,'Ended with severe warnings (insufficient measurements)')
11081 ELSE IF (warner) THEN
11082 CALL peend(1,'Ended with warnings (bad measurements)')
11083 ELSE
11084 CALL peend(0,'Ended normally')
11085 END IF
11086
11087102 FORMAT(' Call FEASIB with cut=',g10.3)
11088 ! 103 FORMAT(1X,A,G12.4)
11089197 FORMAT(f7.2)
11090199 FORMAT(7x,a)
11091END SUBROUTINE xloopn ! standard solution
11092
11093
11098
11099SUBROUTINE chkrej
11100 USE mpmod
11101 USE mpdalc
11102
11103 IMPLICIT NONE
11104 INTEGER(mpi) :: i
11105 INTEGER(mpi) :: kfl
11106 INTEGER(mpi) :: kmin
11107 INTEGER(mpi) :: kmax
11108 INTEGER(mpi) :: nrc
11109 INTEGER(mpl) :: nrej
11110
11111 REAL(mps) :: fmax
11112 REAL(mps) :: fmin
11113 REAL(mps) :: frac
11114
11115 REAL(mpd) :: sumallw
11116 REAL(mpd) :: sumrejw
11117
11118 sumallw=0.; sumrejw=0.;
11119 kmin=0; kmax=0;
11120 fmax=-1.; fmin=2;
11121
11122 DO i=1,nfilb
11123 kfl=kfd(2,i)
11124 nrc=-kfd(1,i)
11125 IF (nrc > 0) THEN
11126 nrej=nrc-jfd(kfl)
11127 sumallw=sumallw+real(nrc,mpd)*wfd(kfl)
11128 sumrejw=sumrejw+real(nrej,mpd)*wfd(kfl)
11129 frac=real(nrej,mps)/real(nrc,mps)
11130 IF (frac > fmax) THEN
11131 kmax=kfl
11132 fmax=frac
11133 END IF
11134 IF (frac < fmin) THEN
11135 kmin=kfl
11136 fmin=frac
11137 END IF
11138 END IF
11139 END DO
11140 IF (nfilw > 0) &
11141 WRITE(*,"(' Weighted fraction =',F8.2,' %')") 100.*sumrejw/sumallw
11142 IF (nfilb > 1) THEN
11143 WRITE(*,"(' File with max. fraction ',I6,' :',F8.2,' %')") kmax, 100.*fmax
11144 WRITE(*,"(' File with min. fraction ',I6,' :',F8.2,' %')") kmin, 100.*fmin
11145 END IF
11146
11147END SUBROUTINE chkrej
11148
11162
11163SUBROUTINE filetc
11164 USE mpmod
11165 USE mpdalc
11166
11167 IMPLICIT NONE
11168 INTEGER(mpi) :: i
11169 INTEGER(mpi) :: ia
11170 INTEGER(mpi) :: iargc
11171 INTEGER(mpi) :: ib
11172 INTEGER(mpi) :: ie
11173 INTEGER(mpi) :: ierrf
11174 INTEGER(mpi) :: ieq
11175 INTEGER(mpi) :: ifilb
11176 INTEGER(mpi) :: ioff
11177 INTEGER(mpi) :: iopt
11178 INTEGER(mpi) :: ios
11179 INTEGER(mpi) :: iosum
11180 INTEGER(mpi) :: it
11181 INTEGER(mpi) :: k
11182 INTEGER(mpi) :: mat
11183 INTEGER(mpi) :: nab
11184 INTEGER(mpi) :: nline
11185 INTEGER(mpi) :: npat
11186 INTEGER(mpi) :: ntext
11187 INTEGER(mpi) :: nu
11188 INTEGER(mpi) :: nuf
11189 INTEGER(mpi) :: nums
11190 INTEGER(mpi) :: nufile
11191 INTEGER(mpi) :: lenfileInfo
11192 INTEGER(mpi) :: lenFileNames
11193 INTEGER(mpi) :: matint
11194 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: vecfileInfo
11195 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArray
11196 INTEGER(mpl) :: rows
11197 INTEGER(mpl) :: cols
11198 INTEGER(mpl) :: newcols
11199 INTEGER(mpl) :: length
11200
11201 CHARACTER (LEN=1024) :: text
11202 CHARACTER (LEN=1024) :: fname
11203 CHARACTER (LEN=14) :: bite(3)
11204 CHARACTER (LEN=32) :: keystx
11205 INTEGER(mpi), PARAMETER :: mnum=100
11206 REAL(mpd) :: dnum(mnum)
11207
11208#ifdef READ_C_FILES
11209 INTERFACE
11210 SUBROUTINE initc(nfiles) BIND(c)
11211 USE iso_c_binding
11212 INTEGER(c_int), INTENT(IN), VALUE :: nfiles
11213 END SUBROUTINE initc
11214 END INTERFACE
11215#endif
11216
11217 SAVE
11218 DATA bite/'C_binary','text ','Fortran_binary'/
11219 ! ...
11220 CALL mstart('FILETC/X')
11221
11222 nuf=1 ! C binary is default
11223 DO i=1,8
11224 times(i)=0.0
11225 END DO
11226
11227 ! read command line options ----------------------------------------
11228
11229 filnam=' ' ! print command line options and find steering file
11230 DO i=1,iargc()
11231 IF(i == 1) THEN
11232 WRITE(*,*) ' '
11233 WRITE(*,*) 'Command line options: '
11234 WRITE(*,*) '--------------------- '
11235 END IF
11236 CALL getarg(i,text) ! get I.th text from command line
11237 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11238 WRITE(*,101) i,text(1:nab) ! echo print
11239 IF(text(ia:ia) /= '-') THEN
11240 nu=nufile(text(ia:ib)) ! inquire on file existence
11241 IF(nu == 2) THEN ! existing text file
11242 IF(filnam /= ' ') THEN
11243 WRITE(*,*) 'Second text file in command line - stop'
11244 CALL peend(12,'Aborted, second text file in command line')
11245 stop
11246 ELSE
11247 filnam=text
11248 END IF
11249 ELSE
11250 WRITE(*,*) 'Open error for file:',text(ia:ib),' - stop'
11251 CALL peend(16,'Aborted, open error for file')
11252 IF(text(ia:ia) /= '/') THEN
11253 CALL getenv('PWD',text)
11254 CALL rltext(text,ia,ib,nab)
11255 WRITE(*,*) 'PWD:',text(ia:ib)
11256 END IF
11257 stop
11258 END IF
11259 ELSE
11260 IF(index(text(ia:ib),'b') /= 0) THEN
11261 mdebug=3 ! debug flag
11262 WRITE(*,*) 'Debugging requested'
11263 END IF
11264 it=index(text(ia:ib),'t')
11265 IF(it /= 0) THEN
11266 ictest=1 ! internal test files
11267 ieq=index(text(ia+it:ib),'=')+it
11268 IF (it /= ieq) THEN
11269 IF (index(text(ia+ieq:ib),'SL0' ) /= 0) ictest=2
11270 IF (index(text(ia+ieq:ib),'SLE' ) /= 0) ictest=3
11271 IF (index(text(ia+ieq:ib),'BP' ) /= 0) ictest=4
11272 IF (index(text(ia+ieq:ib),'BRLF') /= 0) ictest=5
11273 IF (index(text(ia+ieq:ib),'BRLC') /= 0) ictest=6
11274 END IF
11275 END IF
11276 IF(index(text(ia:ib),'s') /= 0) isubit=1 ! like "subito"
11277 IF(index(text(ia:ib),'f') /= 0) iforce=1 ! like "force"
11278 IF(index(text(ia:ib),'c') /= 0) icheck=1 ! like "checkinput"
11279 IF(index(text(ia:ib),'C') /= 0) icheck=2 ! like "checkinput 2"
11280 END IF
11281 IF(i == iargc()) WRITE(*,*) '--------------------- '
11282 END DO
11283
11284
11285 ! create test files for option -t ----------------------------------
11286
11287 IF(ictest >= 1) THEN
11288 WRITE(*,*) ' '
11289 IF (ictest == 1) THEN
11290 CALL mptest ! 'wire chamber'
11291 ELSE
11292 CALL mptst2(ictest-2) ! 'silicon tracker'
11293 END IF
11294 IF(filnam == ' ') filnam='mp2str.txt'
11295 WRITE(*,*) ' '
11296 END IF
11297
11298 ! check default steering file with file-name "steerfile" -----------
11299
11300 IF(filnam == ' ') THEN ! check default steering file
11301 text='steerfile'
11302 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11303 nu=nufile(text(ia:ib)) ! inquire on file existence and type
11304 IF(nu > 0) THEN
11305 filnam=text
11306 ELSE
11307 CALL peend(10,'Aborted, no steering file')
11308 stop 'in FILETC: no steering file. .'
11309 END IF
11310 END IF
11311
11312
11313 ! open, read steering file:
11314 ! end
11315 ! fortranfiles
11316 ! cfiles
11317
11318
11319 CALL rltext(filnam,ia,ib,nfnam) ! return indices for non-blank area
11320 WRITE(*,*) ' '
11321 WRITE(*,*) 'Listing of steering file: ',filnam(1:nfnam)
11322 WRITE(*,*) '-------------------------'
11323 OPEN(10,file=filnam(1:nfnam),iostat=ios)
11324 IF(ios /= 0) THEN
11325 WRITE(*,*) 'Open error for steering file - stop'
11326 CALL peend(11,'Aborted, open error for steering file')
11327 IF(filnam(1:1) /= '/') THEN
11328 CALL getenv('PWD',text)
11329 CALL rltext(text,ia,ib,nab)
11330 WRITE(*,*) 'PWD:',text(ia:ib)
11331 END IF
11332 stop
11333 END IF
11334 ifile =0
11335 nfiles=0
11336
11337 lenfileinfo=2
11338 lenfilenames=0
11339 rows=6; cols=lenfileinfo
11340 CALL mpalloc(vecfileinfo,rows,cols,'file info from steering')
11341 nline=0
11342 DO
11343 READ(10,102,iostat=ierrf) text ! read steering file
11344 IF (ierrf < 0) EXIT ! eof
11345 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11346 nline=nline+1
11347 IF(nline <= 50) THEN ! print up to 50 lines
11348 WRITE(*,101) nline,text(1:nab)
11349 IF(nline == 50) WRITE(*,*) ' ...'
11350 END IF
11351 IF(ia == 0) cycle ! skip empty lines
11352
11353 CALL rltext(text,ia,ib,nab) ! test content 'end'
11354 IF(ib == ia+2) THEN
11355 mat=matint(text(ia:ib),'end',npat,ntext)
11356 IF(mat == max(npat,ntext)) THEN ! exact matching
11357 text=' '
11358 CALL intext(text,nline)
11359 WRITE(*,*) ' end-statement after',nline,' text lines'
11360 EXIT
11361 END IF
11362 END IF
11363
11364 keystx='fortranfiles'
11365 mat=matint(text(ia:ib),keystx,npat,ntext)
11366 IF(mat == max(npat,ntext)) THEN ! exact matching
11367 nuf=3
11368 ! WRITE(*,*) 'Fortran files'
11369 cycle
11370 END IF
11371
11372 keystx='Cfiles'
11373 mat=matint(text(ia:ib),keystx,npat,ntext)
11374 IF(mat == max(npat,ntext)) THEN ! exact matching
11375 nuf=1
11376 ! WRITE(*,*) 'Cfiles'
11377 cycle
11378 END IF
11379
11380 keystx='closeandreopen' ! don't keep binary files open
11381 mat=matint(text(ia:ib),keystx,npat,ntext)
11382 IF(mat == max(npat,ntext)) THEN ! exact matching
11383 keepopen=0
11384 cycle
11385 END IF
11386
11387 ! file names
11388 ! check for file options (' -- ')
11389 ie=ib
11390 iopt=index(text(ia:ib),' -- ')
11391 IF (iopt > 0) ie=iopt-1
11392
11393 IF(nab == 0) cycle
11394 nu=nufile(text(ia:ie)) ! inquire on file existence
11395 IF(nu > 0) THEN ! existing file
11396 IF (nfiles == lenfileinfo) THEN ! increase length
11397 CALL mpalloc(temparray,rows,cols,'temp file info from steering')
11398 temparray=vecfileinfo
11399 CALL mpdealloc(vecfileinfo)
11400 lenfileinfo=lenfileinfo*2
11401 newcols=lenfileinfo
11402 CALL mpalloc(vecfileinfo,rows,newcols,'file info from steering')
11403 vecfileinfo(:,1:cols)=temparray(:,1:cols)
11404 CALL mpdealloc(temparray)
11405 cols=newcols
11406 ENDIF
11407 nfiles=nfiles+1 ! count number of files
11408 IF(nu == 1) nu=nuf !
11409 lenfilenames=lenfilenames+ie-ia+1 ! total length of file names
11410 vecfileinfo(1,nfiles)=nline ! line number
11411 vecfileinfo(2,nfiles)=nu ! cbinary =1, text =2, fbinary=3
11412 vecfileinfo(3,nfiles)=ia ! file name start
11413 vecfileinfo(4,nfiles)=ie ! file name end
11414 vecfileinfo(5,nfiles)=iopt ! option start
11415 vecfileinfo(6,nfiles)=ib ! option end
11416 ELSE
11417 ! WRITE(*,*) 'Open error for file ',TEXT(IA:IB)
11418 ! STOP
11419 END IF
11420 END DO
11421 rewind 10
11422 ! read again to fill dynamic arrays with file info
11423 length=nfiles
11424 CALL mpalloc(mfd,length,'file type')
11425 CALL mpalloc(nfd,length,'file line (in steering)')
11426 CALL mpalloc(lfd,length,'file name length')
11427 CALL mpalloc(ofd,length,'file option')
11428 length=lenfilenames
11429 CALL mpalloc(tfd,length,'file name')
11430 nline=0
11431 i=1
11432 ioff=0
11433 DO
11434 READ(10,102,iostat=ierrf) text ! read steering file
11435 IF (ierrf < 0) EXIT ! eof
11436 nline=nline+1
11437 IF (nline == vecfileinfo(1,i)) THEN
11438 nfd(i)=vecfileinfo(1,i)
11439 mfd(i)=vecfileinfo(2,i)
11440 ia=vecfileinfo(3,i)-1
11441 lfd(i)=vecfileinfo(4,i)-ia ! length file name
11442 DO k=1,lfd(i)
11443 tfd(ioff+k)=text(ia+k:ia+k)
11444 END DO
11445 ! tfd(i)=text(vecFileInfo(3,i):vecFileInfo(4,i)) ! file name
11446 ioff=ioff+lfd(i)
11447 ofd(i)=1.0 ! option for file
11448 IF (vecfileinfo(5,i) > 0) THEN
11449 CALL ratext(text(vecfileinfo(5,i)+4:vecfileinfo(6,i)),nums,dnum,mnum) ! translate text to DP numbers
11450 IF (nums > 0) ofd(i)=real(dnum(1),mps)
11451 END IF
11452 i=i+1
11453 IF (i > nfiles) EXIT
11454 ENDIF
11455 ENDDO
11456 CALL mpdealloc(vecfileinfo)
11457 rewind 10
11458 ! additional info for binary files
11459 length=nfiles; rows=2
11460 CALL mpalloc(ifd,length,'integrated record numbers (=offset)')
11461 CALL mpalloc(jfd,length,'number of accepted records')
11462 CALL mpalloc(kfd,rows,length,'number of records in file, file order')
11463 CALL mpalloc(dfd,length,'ndf sum')
11464 CALL mpalloc(xfd,length,'max. record size')
11465 CALL mpalloc(wfd,length,'file weight')
11466 CALL mpalloc(cfd,length,'chi2 sum')
11467 CALL mpalloc(sfd,rows,length,'start, end of file name in TFD')
11468 CALL mpalloc(yfd,length,'modification date')
11469 yfd=0
11470 !
11471 WRITE(*,*) '-------------------------'
11472 WRITE(*,*) ' '
11473
11474 ! print table of files ---------------------------------------------
11475
11476 IF (mprint > 1) THEN
11477 WRITE(*,*) 'Table of files:'
11478 WRITE(*,*) '---------------'
11479 END IF
11480 WRITE(8,*) ' '
11481 WRITE(8,*) 'Text and data files:'
11482 ioff=0
11483 DO i=1,nfiles
11484 DO k=1,lfd(i)
11485 fname(k:k)=tfd(ioff+k)
11486 END DO
11487 ! fname=tfd(i)(1:lfd(i))
11488 IF (mprint > 1) WRITE(*,103) i,bite(mfd(i)),fname(1:lfd(i))
11489 WRITE(8,103) i,bite(mfd(i)),fname(1:lfd(i))
11490 ioff=ioff+lfd(i)
11491 END DO
11492 IF (mprint > 1) THEN
11493 WRITE(*,*) '---------------'
11494 WRITE(*,*) ' '
11495 END IF
11496
11497 ! open the binary Fortran (data) files on unit 11, 12, ...
11498
11499 iosum=0
11500 nfilf=0
11501 nfilb=0
11502 nfilw=0
11503 ioff=0
11504 ifilb=0
11505 IF (keepopen < 1) ifilb=1
11506 DO i=1,nfiles
11507 IF(mfd(i) == 3) THEN
11508 nfilf=nfilf+1
11509 nfilb=nfilb+1
11510 ! next file name
11511 sfd(1,nfilb)=ioff
11512 sfd(2,nfilb)=lfd(i)
11513 CALL binopn(nfilb,ifilb,ios)
11514 IF(ios == 0) THEN
11515 wfd(nfilb)=ofd(i)
11516 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11517 ELSE ! failure
11518 iosum=iosum+1
11519 nfilf=nfilf-1
11520 nfilb=nfilb-1
11521 END IF
11522 END IF
11523 ioff=ioff+lfd(i)
11524 END DO
11525
11526 ! open the binary C files
11527
11528 nfilc=-1
11529 ioff=0
11530 DO i=1,nfiles ! Cfiles
11531 IF(mfd(i) == 1) THEN
11532#ifdef READ_C_FILES
11533 IF(nfilc < 0) THEN ! initialize
11534 CALL initc(max(nfiles,mthrdr)) ! uncommented by GF
11535 nfilc=0
11536 END IF
11537 nfilc=nfilc+1
11538 nfilb=nfilb+1
11539 ! next file name
11540 sfd(1,nfilb)=ioff
11541 sfd(2,nfilb)=lfd(i)
11542 CALL binopn(nfilb,ifilb,ios)
11543 IF(ios == 0) THEN
11544 wfd(nfilb)=ofd(i)
11545 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11546 ELSE ! failure
11547 iosum=iosum+1
11548 nfilc=nfilc-1
11549 nfilb=nfilb-1
11550 END IF
11551#else
11552 WRITE(*,*) 'Opening of C-files not supported.'
11553 ! GF add
11554 iosum=iosum+1
11555 ! GF add end
11556#endif
11557 END IF
11558 ioff=ioff+lfd(i)
11559 END DO
11560
11561 DO k=1,nfilb
11562 kfd(1,k)=1 ! reset (negated) record counters
11563 kfd(2,k)=k ! set file number
11564 ifd(k)=0 ! reset integrated record numbers
11565 xfd(k)=0 ! reset max record size
11566 END DO
11567
11568 IF(iosum /= 0) THEN
11569 CALL peend(15,'Aborted, open error(s) for binary files')
11570 stop 'FILETC: open error '
11571 END IF
11572 IF(nfilb == 0) THEN
11573 CALL peend(14,'Aborted, no binary files')
11574 stop 'FILETC: no binary files '
11575 END IF
11576 IF (keepopen > 0) THEN
11577 WRITE(*,*) nfilb,' binary files opened' ! corrected by GF
11578 ELSE
11579 WRITE(*,*) nfilb,' binary files opened and closed' ! corrected by GF
11580 END IF
11581101 FORMAT(i3,2x,a)
11582102 FORMAT(a)
11583103 FORMAT(i3,2x,a14,3x,a)
11584 ! CALL mend
11585 RETURN
11586END SUBROUTINE filetc
11587
11638
11639SUBROUTINE filetx ! ---------------------------------------------------
11640 USE mpmod
11641
11642 IMPLICIT NONE
11643 INTEGER(mpi) :: i
11644 INTEGER(mpi) :: ia
11645 INTEGER(mpi) :: ib
11646 INTEGER(mpi) :: ierrf
11647 INTEGER(mpi) :: ioff
11648 INTEGER(mpi) :: ios
11649 INTEGER(mpi) :: iosum
11650 INTEGER(mpi) :: k
11651 INTEGER(mpi) :: mat
11652 INTEGER(mpi) :: nab
11653 INTEGER(mpi) :: nfiln
11654 INTEGER(mpi) :: nline
11655 INTEGER(mpi) :: nlinmx
11656 INTEGER(mpi) :: npat
11657 INTEGER(mpi) :: ntext
11658 INTEGER(mpi) :: matint
11659
11660 ! CALL MSTART('FILETX')
11661
11662 CHARACTER (LEN=1024) :: text
11663 CHARACTER (LEN=1024) :: fname
11664
11665 WRITE(*,*) ' '
11666 WRITE(*,*) 'Processing text files ...'
11667 WRITE(*,*) ' '
11668
11669 iosum=0
11670 ioff=0
11671 DO i=0,nfiles
11672 IF(i == 0) THEN
11673 WRITE(*,*) 'File ',filnam(1:nfnam)
11674 nlinmx=100
11675 ELSE
11676 nlinmx=10
11677 ia=ioff
11678 ioff=ioff+lfd(i)
11679 IF(mfd(i) /= 2) cycle ! exclude binary files
11680 DO k=1,lfd(i)
11681 fname(k:k)=tfd(ia+k)
11682 END DO
11683 WRITE(*,*) 'File ',fname(1:lfd(i))
11684 IF (mprint > 1) WRITE(*,*) ' '
11685 OPEN(10,file=fname(1:lfd(i)),iostat=ios,form='FORMATTED')
11686 IF(ios /= 0) THEN
11687 WRITE(*,*) 'Open error for file ',fname(1:lfd(i))
11688 iosum=iosum+1
11689 cycle
11690 END IF
11691 END IF
11692
11693 nline=0
11694 nfiln=1
11695 ! read text file
11696 DO
11697 READ(10,102,iostat=ierrf) text
11698 IF (ierrf < 0) THEN
11699 text=' '
11700 CALL intext(text,nline)
11701 WRITE(*,*) ' end-of-file after',nline,' text lines'
11702 EXIT ! eof
11703 ENDIF
11704 nline=nline+1
11705 IF(nline <= nlinmx.AND.mprint > 1) THEN ! print first 10 lines of every text fiLE
11706 CALL rltext(text,ia,ib,nab)
11707 nab=max(1,nab)
11708 WRITE(*,101) nline,text(1:nab)
11709 IF(nline == nlinmx) WRITE(*,*) ' ...'
11710 END IF
11711
11712 CALL rltext(text,ia,ib,nab) ! test content 'end'
11713 IF(ib == ia+2) THEN
11714 mat=matint(text(ia:ib),'end',npat,ntext)
11715 IF(mat == max(npat,ntext)) THEN ! exact matching
11716 text=' '
11717 CALL intext(text,nline)
11718 WRITE(*,*) ' end-statement after',nline,' text lines'
11719 EXIT
11720 END IF
11721 END IF
11722
11723 IF(i == 0) THEN ! first text file - exclude lines with file names
11724 IF(nfiln <= nfiles) THEN
11725 IF(nline == nfd(nfiln)) THEN
11726 nfiln=nfiln+1
11727 text=' '
11728 ! WRITE(*,*) 'line is excluded ',TEXT(1:10)
11729 END IF
11730 END IF
11731 END IF
11732 ! WRITE(*,*) TEXT(1:40),' < interprete text'
11733 CALL intext(text,nline) ! interprete text
11734 END DO
11735 WRITE(*,*) ' '
11736 rewind 10
11737 CLOSE(unit=10)
11738 END DO
11739
11740 IF(iosum /= 0) THEN
11741 CALL peend(16,'Aborted, open error(s) for text files')
11742 stop 'FILETX: open error(s) in text files '
11743 END IF
11744
11745 WRITE(*,*) '... end of text file processing.'
11746 WRITE(*,*) ' '
11747
11748 IF(lunkno /= 0) THEN
11749 WRITE(*,*) ' '
11750 WRITE(*,*) lunkno,' unknown keywords in steering files, ', &
11751 'or file non-existing,'
11752 WRITE(*,*) ' see above!'
11753 WRITE(*,*) '------------> stop'
11754 WRITE(*,*) ' '
11755 CALL peend(13,'Aborted, unknown keywords in steering file')
11756 stop
11757 END IF
11758
11759 ! check methods
11760
11761 IF(metsol == 0) THEN ! if undefined
11762 IF(matsto == 0) THEN ! if unpacked symmetric
11763 metsol=8 ! LAPACK
11764 ELSE IF(matsto == 1) THEN ! if full symmetric
11765 metsol=4 ! MINRES
11766 ELSE IF(matsto == 2) THEN ! if sparse
11767 metsol=4 ! MINRES
11768 END IF
11769 ELSE IF(metsol == 1) THEN ! if inversion
11770 matsto=1
11771 ELSE IF(metsol == 2) THEN ! if diagonalization
11772 matsto=1
11773 ELSE IF(metsol == 3) THEN ! if decomposition
11774 matsto=1
11775 ELSE IF(metsol == 4) THEN ! if MINRES
11776 ! MATSTO=2 or 1
11777 ELSE IF(metsol == 5) THEN ! if MINRES-QLP
11778 ! MATSTO=2 or 1
11779 ELSE IF(metsol == 6) THEN ! if GMRES
11780 ! MATSTO=2 or 1
11781#ifdef LAPACK64
11782 ELSE IF(metsol == 7) THEN ! if LAPACK
11783 matsto=1
11784 ELSE IF(metsol == 8) THEN ! if LAPACK
11785 matsto=0
11786#ifdef PARDISO
11787 ELSE IF(metsol == 9) THEN ! if Intel oneMKL PARDISO
11788 matsto=3
11789#endif
11790#endif
11791 ELSE
11792 WRITE(*,*) 'MINRES forced with sparse matrix!'
11793 WRITE(*,*) ' '
11794 WRITE(*,*) 'MINRES forced with sparse matrix!'
11795 WRITE(*,*) ' '
11796 WRITE(*,*) 'MINRES forced with sparse matrix!'
11797 metsol=4 ! forced
11798 matsto=2 ! forced
11799 END IF
11800 IF(matsto > 4) THEN
11801 WRITE(*,*) 'MINRES forced with sparse matrix!'
11802 WRITE(*,*) ' '
11803 WRITE(*,*) 'MINRES forced with sparse matrix!'
11804 WRITE(*,*) ' '
11805 WRITE(*,*) 'MINRES forced with sparse matrix!'
11806 metsol=4 ! forced
11807 matsto=2 ! forced
11808 END IF
11809
11810 ! print information about methods and matrix storage modes
11811
11812 WRITE(*,*) ' '
11813 WRITE(*,*) 'Solution method and matrix-storage mode:'
11814 IF(metsol == 1) THEN
11815 WRITE(*,*) ' METSOL = 1: matrix inversion'
11816 ELSE IF(metsol == 2) THEN
11817 WRITE(*,*) ' METSOL = 2: diagonalization'
11818 ELSE IF(metsol == 3) THEN
11819 WRITE(*,*) ' METSOL = 3: decomposition'
11820 ELSE IF(metsol == 4) THEN
11821 WRITE(*,*) ' METSOL = 4: MINRES'
11822 ELSE IF(metsol == 5) THEN
11823 WRITE(*,*) ' METSOL = 5: MINRES-QLP'
11824 ELSE IF(metsol == 6) THEN
11825 WRITE(*,*) ' METSOL = 6: GMRES (-> MINRES)'
11826#ifdef LAPACK64
11827 ELSE IF(metsol == 7) THEN
11828 WRITE(*,*) ' METSOL = 7: LAPACK factorization'
11829 ELSE IF(metsol == 8) THEN
11830 WRITE(*,*) ' METSOL = 8: LAPACK factorization'
11831#ifdef PARDISO
11832 ELSE IF(metsol == 9) THEN
11833 WRITE(*,*) ' METSOL = 9: Intel oneMKL PARDISO'
11834#endif
11835#endif
11836 END IF
11837
11838 WRITE(*,*) ' with',mitera,' iterations'
11839
11840 IF(matsto == 0) THEN
11841 WRITE(*,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
11842 ELSEIF(matsto == 1) THEN
11843 WRITE(*,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
11844 ELSE IF(matsto == 2) THEN
11845 WRITE(*,*) ' MATSTO = 2: sparse matrix (custom)'
11846 ELSE IF(matsto == 3) THEN
11847 IF (mpdbsz == 0) THEN
11848 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
11849 ELSE
11850 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
11851 END IF
11852 END IF
11853 IF(mbandw /= 0.AND.(metsol >= 4.AND. metsol <7)) THEN ! band matrix as MINRES preconditioner
11854 WRITE(*,*) ' and band matrix, width',mbandw
11855 END IF
11856
11857 IF(chicut /= 0.0) THEN
11858 WRITE(*,*) 'Chi square cut equiv 3 st.dev applied ...'
11859 WRITE(*,*) ' in first iteration with factor',chicut
11860 WRITE(*,*) ' in second iteration with factor',chirem
11861 WRITE(*,*) ' (reduced by sqrt in next iterations)'
11862 END IF
11863
11864 IF(lhuber /= 0) THEN
11865 WRITE(*,*) ' Down-weighting of outliers in', lhuber,' iterations'
11866 WRITE(*,*) ' Cut on downweight fraction',dwcut
11867 END IF
11868
11869 WRITE(*,*) 'Iterations (solutions) with line search:'
11870 IF(lsearch > 2) THEN
11871 WRITE(*,*) ' All'
11872 ELSEIF (lsearch == 1) THEN
11873 WRITE(*,*) ' Last'
11874 ELSEIF (lsearch < 1) THEN
11875 WRITE(*,*) ' None'
11876 ELSE
11877 IF (chicut /= 0.0) THEN
11878 WRITE(*,*) ' All with Chi square cut scaling factor <= 1.'
11879 ELSE
11880 WRITE(*,*) ' All'
11881 ENDIF
11882 ENDIF
11883
11884 IF(nummeasurements>0) THEN
11885 WRITE(*,*)
11886 WRITE(*,*) ' Number of external measurements ', nummeasurements
11887 ENDIF
11888
11889 CALL mend
11890
11891101 FORMAT(i3,2x,a)
11892102 FORMAT(a)
11893END SUBROUTINE filetx
11894
11904
11905INTEGER(mpi) FUNCTION nufile(fname)
11906 USE mpdef
11907
11908 IMPLICIT NONE
11909 INTEGER(mpi) :: ios
11910 INTEGER(mpi) :: l1
11911 INTEGER(mpi) :: ll
11912 INTEGER(mpi) :: nm
11913 INTEGER(mpi) :: npat
11914 INTEGER(mpi) :: ntext
11915 INTEGER(mpi) :: nuprae
11916 INTEGER(mpi) :: matint
11917
11918 CHARACTER (LEN=*), INTENT(INOUT) :: fname
11919 LOGICAL :: ex
11920 SAVE
11921 ! ...
11922 nufile=0
11923 nuprae=0
11924 IF(len(fname) > 5) THEN
11925 IF(fname(1:5) == 'rfio:') nuprae=1
11926 IF(fname(1:5) == 'dcap:') nuprae=2
11927 IF(fname(1:5) == 'root:') nuprae=3
11928 END IF
11929 IF(nuprae == 0) THEN
11930 INQUIRE(file=fname,iostat=ios,exist=ex)
11931 IF(ios /= 0) nufile=-abs(ios)
11932 IF(ios /= 0) RETURN
11933 ELSE IF(nuprae == 1) THEN ! rfio:
11934 ll=len(fname)
11935 fname=fname(6:ll)
11936 ex=.true.
11937 nufile=1
11938 RETURN
11939 ELSE
11940 ex=.true. ! assume file existence
11941 END IF
11942 IF(ex) THEN
11943 nufile=1 ! binary
11944 ll=len(fname)
11945 l1=max(1,ll-3)
11946 nm=matint('xt',fname(l1:ll),npat,ntext)
11947 IF(nm == 2) nufile=2 ! text
11948 IF(nm < 2) THEN
11949 nm=matint('tx',fname(l1:ll),npat,ntext)
11950 IF(nm == 2) nufile=2 ! text
11951 END IF
11952 END IF
11953END FUNCTION nufile
11954
11962SUBROUTINE intext(text,nline)
11963 USE mpmod
11964 USE mptext
11965
11966 IMPLICIT NONE
11967 INTEGER(mpi) :: i
11968 INTEGER(mpi) :: ia
11969 INTEGER(mpi) :: ib
11970 INTEGER(mpi) :: ier
11971 INTEGER(mpi) :: iomp
11972 INTEGER(mpi) :: j
11973 INTEGER(mpi) :: k
11974 INTEGER(mpi) :: kkey
11975 INTEGER(mpi) :: label
11976 INTEGER(mpi) :: lkey
11977 INTEGER(mpi) :: mat
11978 INTEGER(mpi) :: miter
11979 INTEGER(mpi) :: nab
11980 INTEGER(mpi) :: nkey
11981 INTEGER(mpi) :: nkeys
11982 INTEGER(mpi) :: nl
11983 INTEGER(mpi) :: nmeth
11984 INTEGER(mpi) :: npat
11985 INTEGER(mpi) :: ntext
11986 INTEGER(mpi) :: nums
11987 INTEGER(mpi) :: matint
11988
11989 CHARACTER (LEN=*), INTENT(IN) :: text
11990 INTEGER(mpi), INTENT(IN) :: nline
11991
11992#ifdef LAPACK64
11993#ifdef PARDISO
11994 parameter(nkeys=7,nmeth=10)
11995#else
11996 parameter(nkeys=6,nmeth=9)
11997#endif
11998#else
11999 parameter(nkeys=6,nmeth=7)
12000#endif
12001 CHARACTER (LEN=16) :: methxt(nmeth)
12002 CHARACTER (LEN=16) :: keylst(nkeys)
12003 CHARACTER (LEN=32) :: keywrd
12004 CHARACTER (LEN=32) :: keystx
12005 CHARACTER (LEN=itemCLen) :: ctext
12006 INTEGER(mpi), PARAMETER :: mnum=100
12007 REAL(mpd) :: dnum(mnum)
12008#ifdef LAPACK64
12009#ifdef PARDISO
12010 INTEGER(mpi) :: ipvs ! ... integer value
12011#endif
12012#endif
12013 INTEGER(mpi) :: lpvs ! ... integer label
12014 REAL(mpd) :: plvs ! ... float value
12015
12016 INTERFACE
12017 SUBROUTINE additem(length,list,label,value)
12018 USE mpmod
12019 INTEGER(mpi), INTENT(IN OUT) :: length
12020 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12021 INTEGER(mpi), INTENT(IN) :: label
12022 REAL(mpd), INTENT(IN) :: value
12023 END SUBROUTINE additem
12024 SUBROUTINE additemc(length,list,label,text)
12025 USE mpmod
12026 INTEGER(mpi), INTENT(IN OUT) :: length
12027 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12028 INTEGER(mpi), INTENT(IN) :: label
12029 CHARACTER(LEN = itemCLen), INTENT(IN) :: text
12030 END SUBROUTINE additemc
12031 SUBROUTINE additemi(length,list,label,ivalue)
12032 USE mpmod
12033 INTEGER(mpi), INTENT(IN OUT) :: length
12034 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12035 INTEGER(mpi), INTENT(IN) :: label
12036 INTEGER(mpi), INTENT(IN) :: ivalue
12037 END SUBROUTINE additemi
12038 END INTERFACE
12039
12040 SAVE
12041#ifdef LAPACK64
12042#ifdef PARDISO
12043 DATA keylst/'unknown','parameter','constraint','measurement','method','comment','pardiso'/
12044 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12045 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK', &
12046 'sparsePARDISO'/
12047#else
12048 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12049 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12050 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK'/
12051#endif
12052#else
12053 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12054 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12055 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition'/
12056#endif
12057 DATA lkey/-1/ ! last keyword
12058
12059 ! ...
12060 nkey=-1 ! new keyword
12061 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
12062 IF(nab == 0) GOTO 10
12063 CALL ratext(text(1:nab),nums,dnum,mnum) ! translate text to DP numbers
12064
12065 IF(nums /= 0) nkey=0
12066 IF(keyb /= 0) THEN
12067 keywrd=text(keya:keyb) ! text is TEXT(KEYA)...TEXT(KEYB)
12068 ! WRITE(*,*) 'Keyword is ',KEYWRD
12069
12070 ! compare keywords
12071
12072 DO nkey=2,nkeys ! loop over all pede keywords
12073 keystx=keylst(nkey) ! copy NKEY.th pede keyword
12074 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12075 IF(100*mat >= 80*max(npat,ntext)) GO TO 10 ! 80% (symmetric) matching
12076 END DO
12077
12078 ! more comparisons
12079
12080 keystx='print'
12081 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12082 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12083 mprint=1
12084 IF(nums > 0) mprint=nint(dnum(1),mpi)
12085 RETURN
12086 END IF
12087
12088 keystx='debug'
12089 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12090 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12091 mdebug=3
12092 ! GF IF(NUMS.GT.0) MPRINT=DNUM(1)
12093 IF(nums > 0) mdebug=nint(dnum(1),mpi)
12094 IF(nums > 1) mdebg2=nint(dnum(2),mpi)
12095 RETURN
12096 END IF
12097
12098 keystx='entries'
12099 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12100 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12101 IF(nums > 0 .AND. dnum(1) > 0.5) mreqenf=nint(dnum(1),mpi)
12102 IF(nums > 1 .AND. dnum(2) > 0.5) mreqena=nint(dnum(2),mpi)
12103 IF(nums > 2 .AND. dnum(3) > 0.5) iteren=nint(dnum(1)*dnum(3),mpi)
12104 RETURN
12105 END IF
12106
12107 keystx='printrecord'
12108 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12109 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12110 IF(nums > 0) nrecpr=nint(dnum(1),mpi)
12111 IF(nums > 1) nrecp2=nint(dnum(2),mpi)
12112 RETURN
12113 END IF
12114
12115 keystx='maxrecord'
12116 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12117 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12118 IF (nums > 0.AND.dnum(1) > 0.) mxrec=nint(dnum(1),mpi)
12119 RETURN
12120 END IF
12121
12122 keystx='cache'
12123 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12124 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12125 IF (nums > 0.AND.dnum(1) >= 0.) ncache=nint(dnum(1),mpi) ! cache size, <0 keeps default
12126 IF (nums == 2.AND.dnum(2) > 0..AND.dnum(2) <= 1.0) & ! read cache fill level
12127 fcache(1)=real(dnum(2),mps)
12128 IF (nums >= 4) THEN ! explicit cache splitting
12129 DO k=1,3
12130 fcache(k)=real(dnum(k+1),mps)
12131 END DO
12132 END IF
12133 RETURN
12134 END IF
12135
12136 keystx='chisqcut'
12137 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12138 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12139 IF(nums == 0) THEN ! always 3-sigma cut
12140 chicut=1.0
12141 chirem=1.0
12142 ELSE
12143 chicut=real(dnum(1),mps)
12144 IF(chicut < 1.0) chicut=-1.0
12145 IF(nums == 1) THEN
12146 chirem=1.0 ! 3-sigma cut, if not specified
12147 ELSE
12148 chirem=real(dnum(2),mps)
12149 IF(chirem < 1.0) chirem=1.0
12150 IF(chicut >= 1.0) chirem=min(chirem,chicut)
12151 END IF
12152 END IF
12153 RETURN
12154 END IF
12155
12156 ! GF added:
12157 keystx='hugecut'
12158 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12159 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12160 IF(nums > 0) chhuge=real(dnum(1),mps)
12161 IF(chhuge < 1.0) chhuge=1.0 ! at least (!!) 3-sigma
12162 RETURN
12163 END IF
12164 ! GF added end
12165
12166 keystx='linesearch'
12167 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12168 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12169 IF(nums > 0) lsearch=nint(dnum(1),mpi)
12170 RETURN
12171 END IF
12172
12173 keystx='localfit'
12174 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12175 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12176 IF(nums > 0) lfitnp=nint(dnum(1),mpi)
12177 IF(nums > 1) lfitbb=nint(dnum(2),mpi)
12178 RETURN
12179 END IF
12180
12181 keystx='regularization'
12182 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12183 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12184 nregul=1
12185 regula=real(dnum(1),mps)
12186 IF(nums >= 2) regpre=real(dnum(2),mps)
12187 RETURN
12188 END IF
12189
12190 keystx='regularisation'
12191 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12192 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12193 nregul=1
12194 regula=real(dnum(1),mps)
12195 IF(nums >= 2) regpre=real(dnum(2),mps)
12196 RETURN
12197 END IF
12198
12199 keystx='presigma'
12200 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12201 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12202 regpre=real(dnum(1),mps)
12203 RETURN
12204 END IF
12205
12206 keystx='matiter'
12207 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12208 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12209 matrit=nint(dnum(1),mpi)
12210 RETURN
12211 END IF
12212
12213 keystx='matmoni'
12214 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12215 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12216 matmon=-1
12217 IF (nums > 0.AND.dnum(1) > 0.) matmon=nint(dnum(1),mpi)
12218 RETURN
12219 END IF
12220
12221 keystx='bandwidth'
12222 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12223 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12224 IF(nums > 0) mbandw=nint(dnum(1),mpi)
12225 IF(mbandw < 0) mbandw=-1
12226 IF(nums > 1) lprecm=nint(dnum(2),mpi)
12227 RETURN
12228 END IF
12229
12230 ! KEYSTX='outlierrejection'
12231 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12232 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12233 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12234 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12235 ! CHDFRJ=DNUM(1)
12236 ! IF(CHDFRJ.LT.3.0) CHDFRJ=100.0
12237 ! RETURN
12238 ! END IF
12239
12240 ! KEYSTX='outliersuppression'
12241 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12242 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12243 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12244 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12245 ! LHUBER=DNUM(1)
12246 ! IF(LHUBER.LE.2) LHUBER=2 ! at least 2 Huber iterations
12247 ! RETURN
12248 ! END IF
12249
12250 keystx='outlierdownweighting'
12251 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12252 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12253 lhuber=nint(dnum(1),mpi)
12254 IF(lhuber > 0.AND.lhuber <= 2) lhuber=2 ! at least 2 Huber iterations (if any)
12255 RETURN
12256 END IF
12257
12258 keystx='dwfractioncut'
12259 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12260 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12261 dwcut=real(dnum(1),mps)
12262 IF(dwcut > 0.5) dwcut=0.5
12263 RETURN
12264 END IF
12265
12266 keystx='maxlocalcond'
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.0) cndlmx=real(dnum(1),mps)
12270 RETURN
12271 END IF
12272
12273 keystx='pullrange'
12274 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12275 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12276 prange=abs(real(dnum(1),mps))
12277 RETURN
12278 END IF
12279
12280 keystx='subito'
12281 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12282 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12283 isubit=1
12284 RETURN
12285 END IF
12286
12287 keystx='force'
12288 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12289 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12290 iforce=1
12291 RETURN
12292 END IF
12293
12294 keystx='memorydebug'
12295 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12296 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12297 memdbg=1
12298 IF (nums > 0.AND.dnum(1) > 0.0) memdbg=nint(dnum(1),mpi)
12299 RETURN
12300 END IF
12301
12302 keystx='globalcorr'
12303 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12304 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12305 igcorr=1
12306 RETURN
12307 END IF
12308
12309 keystx='printcounts'
12310 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12311 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12312 ipcntr=1
12313 IF (nums > 0) ipcntr=nint(dnum(1),mpi)
12314 RETURN
12315 END IF
12316
12317 keystx='weightedcons'
12318 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12319 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12320 iwcons=1
12321 IF (nums > 0) iwcons=nint(dnum(1),mpi)
12322 RETURN
12323 END IF
12324
12325 keystx='skipemptycons'
12326 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12327 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12328 iskpec=1
12329 RETURN
12330 END IF
12331
12332 keystx='resolveredundancycons'
12333 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12334 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12335 irslvrc=1
12336 RETURN
12337 END IF
12338
12339 keystx='withelimination'
12340 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12341 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12342 icelim=1
12343 RETURN
12344 END IF
12345
12346#ifdef LAPACK64
12347 keystx='withLAPACKelimination'
12348 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12349 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12350 icelim=2
12351 RETURN
12352 END IF
12353#endif
12354
12355 keystx='withmultipliers'
12356 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12357 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12358 icelim=0
12359 RETURN
12360 END IF
12361
12362 keystx='checkinput'
12363 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12364 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12365 icheck=1
12366 IF (nums > 0) icheck=nint(dnum(1),mpi)
12367 RETURN
12368 END IF
12369
12370 keystx='checkparametergroups'
12371 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12372 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12373 ichkpg=1
12374 RETURN
12375 END IF
12376
12377 keystx='monitorresiduals'
12378 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12379 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12380 imonit=3
12381 IF (nums > 0) imonit=nint(dnum(1),mpi)
12382 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12383 RETURN
12384 END IF
12385
12386 keystx='monitorpulls'
12387 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12388 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12389 imonit=3
12390 imonmd=1
12391 IF (nums > 0) imonit=nint(dnum(1),mpi)
12392 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12393 RETURN
12394 END IF
12395
12396 keystx='monitorprogress'
12397 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12398 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12399 monpg1=1
12400 monpg2=1024
12401 IF (nums > 0) monpg1=max(1,nint(dnum(1),mpi))
12402 IF (nums > 1) monpg2=max(1,nint(dnum(2),mpi))
12403 RETURN
12404 END IF
12405
12406 keystx='scaleerrors'
12407 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12408 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12409 iscerr=1
12410 IF (nums > 0) dscerr(1:2)=dnum(1)
12411 IF (nums > 1) dscerr(2)=dnum(2)
12412 RETURN
12413 END IF
12414
12415 keystx='iterateentries'
12416 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12417 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12418 iteren=huge(iteren)
12419 IF (nums > 0) iteren=nint(dnum(1),mpi)
12420 RETURN
12421 END IF
12422
12423 keystx='threads'
12424 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12425 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12426 iomp=0
12427 !$ IOMP=1
12428 !$ IF (IOMP.GT.0) THEN
12429 !$ IF (NUMS.GE.1.AND.DNUM(1).GT.0.) MTHRD =NINT(dnum(1),mpi)
12430 !$ MTHRDR=MTHRD
12431 !$ IF (NUMS.GE.2.AND.DNUM(2).GT.0.) MTHRDR=NINT(dnum(2),mpi)
12432 !$ ELSE
12433 WRITE(*,*) 'WARNING: multithreading not available'
12434 !$ ENDIF
12435 RETURN
12436 END IF
12437
12438 keystx='compress'
12439 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12440 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12441 WRITE(*,*) 'WARNING: keyword COMPRESS is obsolete (compression is default)'
12442 RETURN
12443 END IF
12444
12445 ! still experimental
12446 !keystx='extendedStorage'
12447 !mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12448 !IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12449 ! mextnd=1
12450 ! RETURN
12451 !END IF
12452
12453 keystx='countrecords'
12454 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12455 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12456 mcount=1
12457 RETURN
12458 END IF
12459
12460 keystx='errlabels'
12461 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12462 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12463 nl=min(nums,100-mnrsel)
12464 DO k=1,nl
12465 lbmnrs(mnrsel+k)=nint(dnum(k),mpi)
12466 END DO
12467 mnrsel=mnrsel+nl
12468 RETURN
12469 END IF
12470
12471 keystx='pairentries'
12472 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12473 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12474 ! This option could be implemented to get rid of parameter pairs
12475 ! that have very few entries - to save matrix memory size.
12476 IF (nums > 0.AND.dnum(1) > 0.0) THEN
12477 mreqpe=nint(dnum(1),mpi)
12478 IF (nums >= 2.AND.dnum(2) >= dnum(1)) mhispe=nint(dnum(2),mpi)
12479 IF (nums >= 3.AND.dnum(3) >= dnum(1)) msngpe=nint(dnum(3),mpi)
12480 END IF
12481 RETURN
12482 END IF
12483
12484 keystx='wolfe'
12485 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12486 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12487 wolfc1=real(dnum(1),mps)
12488 wolfc2=real(dnum(2),mps)
12489 RETURN
12490 END IF
12491
12492 ! GF added:
12493 ! convergence tolerance for minres:
12494 keystx='mrestol'
12495 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12496 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12497 IF(nums > 0) THEN
12498 IF (dnum(1) < 1.0e-10_mpd.OR.dnum(1) > 1.0e-04_mpd) THEN
12499 WRITE(*,*) 'ERROR: need 1.0D-10 <= MRESTL ', &
12500 '<= 1.0D-04, but get ', dnum(1)
12501 ELSE
12502 mrestl=dnum(1)
12503 END IF
12504 END IF
12505 RETURN
12506 END IF
12507 ! GF added end
12508
12509 keystx='mrestranscond'
12510 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12511 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12512 IF(nums > 0) THEN
12513 mrtcnd = dnum(1)
12514 END IF
12515 RETURN
12516 END IF
12517
12518 keystx='mresmode'
12519 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12520 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12521 IF(nums > 0) THEN
12522 mrmode = int(dnum(1),mpi)
12523 END IF
12524 RETURN
12525 END IF
12526
12527 keystx='nofeasiblestart'
12528 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12529 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12530 nofeas=1 ! do not make parameters feasible at start
12531 RETURN
12532 END IF
12533
12534 keystx='histprint'
12535 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12536 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12537 nhistp=1 ! print histograms
12538 RETURN
12539 END IF
12540
12541 keystx='readerroraseof' ! treat (C) read errors as eof
12542 mat=matint(text(ia:ib),keystx,npat,ntext)
12543 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12544 ireeof=1
12545 RETURN
12546 END IF
12547
12548#ifdef LAPACK64
12549 keystx='LAPACKwitherrors' ! calculate parameter errors with LAPACK
12550 mat=matint(text(ia:ib),keystx,npat,ntext)
12551 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12552 ilperr=1
12553 RETURN
12554 END IF
12555#ifdef PARDISO
12556 keystx='debugPARDISO' ! enable debug for Intel oneMKL PARDISO
12557 mat=matint(text(ia:ib),keystx,npat,ntext)
12558 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12559 ipddbg=1
12560 RETURN
12561 END IF
12562
12563 keystx='blocksizePARDISO' ! use BSR3 for Intel oneMKL PARDISO, list of (increasing) block sizes to be tried
12564 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12565 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12566 nl=min(nums,10-mpdbsz)
12567 DO k=1,nl
12568 IF (nint(dnum(k),mpi) > 0) THEN
12569 IF (mpdbsz == 0) THEN
12570 mpdbsz=mpdbsz+1
12571 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12572 ELSE IF (nint(dnum(k),mpi) > ipdbsz(mpdbsz)) THEN
12573 mpdbsz=mpdbsz+1
12574 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12575 END IF
12576 END IF
12577 END DO
12578 RETURN
12579 END IF
12580#endif
12581#endif
12582 keystx='fortranfiles'
12583 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12584 IF(mat == max(npat,ntext)) RETURN
12585
12586 keystx='Cfiles'
12587 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12588 IF(mat == max(npat,ntext)) RETURN
12589
12590 keystx='closeandreopen'
12591 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12592 IF(mat == max(npat,ntext)) RETURN
12593
12594 keystx=keylst(1)
12595 nkey=1 ! unknown keyword
12596 IF(nums /= 0) nkey=0
12597
12598 WRITE(*,*) ' '
12599 WRITE(*,*) '**************************************************'
12600 WRITE(*,*) ' '
12601 WRITE(*,*) 'Unknown keyword(s): ',text(1:min(nab,50))
12602 WRITE(*,*) ' '
12603 WRITE(*,*) '**************************************************'
12604 WRITE(*,*) ' '
12605 lunkno=lunkno+1
12606
12607 END IF
12608 ! result: NKEY = -1 blank
12609 ! NKEY = 0 numerical data, no text keyword or unknown
12610 ! NKEY > 0 keyword NKEY from list, keyword = KEYSTX
12611
12612
12613 ! content/lastcontent
12614 ! -------------------
12615 ! blank -1
12616 ! data 0
12617 ! keyword
12618 ! unknown 1
12619 ! parameter 2
12620 ! constraint 3
12621 ! measurement 4
12622 ! method 5
12623
12624
1262510 IF(nkey > 0) THEN ! new keyword
12626 lkey=nkey
12627 IF(lkey == 2) THEN ! parameter
12628 IF(nums == 3) THEN
12629 lpvs=nint(dnum(1),mpi) ! label
12630 IF(lpvs /= 0) THEN
12631 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12632 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12633 ELSE
12634 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12635 END IF
12636 ELSE IF(nums /= 0) THEN
12637 kkey=1 ! switch to "unknown" ?
12638 WRITE(*,*) 'Wrong text in line',nline
12639 WRITE(*,*) 'Status: new parameter'
12640 WRITE(*,*) '> ',text(1:nab)
12641 END IF
12642 ELSE IF(lkey == 3) THEN ! constraint
12643 ! WRITE(*,*) 'Keyword is constraint!',NUMS,' numerical data'
12644 IF(nums >= 1.AND.nums <= 2) THEN ! start constraint
12645 lpvs=-nline ! r = r.h.s. value
12646 CALL additem(lenconstraints,listconstraints,lpvs,dnum(1))
12647 lpvs=-1 ! constraint
12648 IF(iwcons > 0) lpvs=-2 ! weighted constraint
12649 plvs=0.0
12650 IF(nums == 2) plvs=dnum(2) ! sigma
12651 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12652 ELSE
12653 kkey=1 ! switch to "unknown"
12654 WRITE(*,*) 'Wrong text in line',nline
12655 WRITE(*,*) 'Status: new keyword constraint'
12656 WRITE(*,*) '> ',text(1:nab)
12657 END IF
12658 ELSE IF(lkey == 4) THEN ! measurement
12659 IF(nums == 2) THEN ! start measurement
12660 nummeasurements=nummeasurements+1
12661 lpvs=-nline ! r = r.h.s. value
12662 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(1))
12663 lpvs=-1 ! sigma
12664 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(2))
12665 ELSE
12666 kkey=1 ! switch to "unknown"
12667 WRITE(*,*) 'Wrong text in line',nline
12668 WRITE(*,*) 'Status: new keyword measurement'
12669 WRITE(*,*) '> ',text(1:nab)
12670 END IF
12671 ELSE IF(lkey == 5.AND.keyb < keyc) THEN ! method with text argument
12672 miter=mitera
12673 IF(nums >= 1) miter=nint(dnum(1),mpi)
12674 IF(miter >= 1) mitera=miter
12675 dflim=real(dnum(2),mps)
12676 lkey=0
12677 DO i=1,nmeth
12678 keystx=methxt(i)
12679 mat=matint(text(keyb+1:keyc),keystx,npat,ntext) ! comparison
12680 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12681 IF(i == 1) THEN ! diagonalization
12682 metsol=2
12683 matsto=1
12684 ELSE IF(i == 2) THEN ! inversion
12685 metsol=1
12686 matsto=1
12687 ELSE IF(i == 3) THEN ! fullMINRES
12688 metsol=4
12689 matsto=1
12690 ELSE IF(i == 4) THEN ! sparseMINRES
12691 metsol=4
12692 matsto=2
12693 ELSE IF(i == 5) THEN ! fullMINRES-QLP
12694 metsol=5
12695 matsto=1
12696 ELSE IF(i == 6) THEN ! sparseMINRES-QLP
12697 metsol=5
12698 matsto=2
12699 ELSE IF(i == 7) THEN ! decomposition
12700 metsol=3
12701 matsto=1
12702#ifdef LAPACK64
12703 ELSE IF(i == 8) THEN ! fullLAPACK factorization
12704 metsol=7
12705 matsto=1
12706 ELSE IF(i == 9) THEN ! unpackedLAPACK factorization
12707 metsol=8
12708 matsto=0
12709#ifdef PARDISO
12710 ELSE IF(i == 10) THEN ! Intel oneMKL PARDISO (sparse matrix (CSR3 or BSR3, upper triangle))
12711 metsol=9
12712 matsto=3
12713#endif
12714#endif
12715 END IF
12716 END IF
12717 END DO
12718 END IF
12719 ELSE IF(nkey == 0) THEN ! data for continuation
12720 IF(lkey == 2) THEN ! parameter
12721 IF(nums >= 3) THEN ! store data from this line
12722 lpvs=nint(dnum(1),mpi) ! label
12723 IF(lpvs /= 0) THEN
12724 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12725 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12726 ELSE
12727 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12728 END IF
12729 ELSE IF(nums > 1.AND.nums < 3) THEN
12730 kkey=1 ! switch to "unknown" ?
12731 WRITE(*,*) 'Wrong text in line',nline
12732 WRITE(*,*) 'Status continuation parameter'
12733 WRITE(*,*) '> ',text(1:nab)
12734 END IF
12735
12736 ELSE IF(lkey == 3) THEN ! constraint
12737 ier=0
12738 DO i=1,nums,2
12739 label=nint(dnum(i),mpi)
12740 IF(label <= 0) ier=1
12741 END DO
12742 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12743 IF(ier == 0) THEN
12744 DO i=1,nums,2
12745 lpvs=nint(dnum(i),mpi) ! label
12746 plvs=dnum(i+1) ! factor
12747 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12748 END DO
12749 ELSE
12750 kkey=0
12751 WRITE(*,*) 'Wrong text in line',nline
12752 WRITE(*,*) 'Status continuation constraint'
12753 WRITE(*,*) '> ',text(1:nab)
12754 END IF
12755
12756 ELSE IF(lkey == 4) THEN ! measurement
12757 ! WRITE(*,*) 'continuation < ',NUMS
12758 ier=0
12759 DO i=1,nums,2
12760 label=nint(dnum(i),mpi)
12761 IF(label <= 0) ier=1
12762 END DO
12763 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12764 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12765 IF(ier == 0) THEN
12766 DO i=1,nums,2
12767 lpvs=nint(dnum(i),mpi) ! label
12768 plvs=dnum(i+1) ! factor
12769 CALL additem(lenmeasurements,listmeasurements,lpvs,plvs)
12770 END DO
12771 ELSE
12772 kkey=0
12773 WRITE(*,*) 'Wrong text in line',nline
12774 WRITE(*,*) 'Status continuation measurement'
12775 WRITE(*,*) '> ',text(1:nab)
12776 END IF
12777 ELSE IF(lkey == 6) THEN ! comment
12778 IF(nums == 1) THEN
12779 lpvs=nint(dnum(1),mpi) ! label
12780 IF(lpvs /= 0) THEN
12781 ! skip label
12782 DO j=ia,ib
12783 IF (text(j:j) == ' ') EXIT
12784 END DO
12785 ctext=text(j:ib)
12786 CALL additemc(lencomments,listcomments,lpvs,ctext)
12787 ELSE
12788 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12789 END IF
12790 ELSE IF(nums /= 0) THEN
12791 kkey=1 ! switch to "unknown"
12792 WRITE(*,*) 'Wrong text in line',nline
12793 WRITE(*,*) 'Status: continuation comment'
12794 WRITE(*,*) '> ',text(1:nab)
12795 END IF
12796#ifdef LAPACK64
12797#ifdef PARDISO
12798 ELSE IF(lkey == 7) THEN ! Intel oneMKL PARDISO parameters
12799 ier=0
12800 DO i=1,nums,2
12801 label=nint(dnum(i),mpi)
12802 IF(label <= 0.OR.label > 64) ier=1
12803 END DO
12804 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12805 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12806 IF(ier == 0) THEN
12807 DO i=1,nums,2
12808 lpvs=nint(dnum(i),mpi) ! label
12809 ipvs=nint(dnum(i+1),mpi) ! parameter
12810 CALL additemi(lenpardiso,listpardiso,lpvs,ipvs)
12811 END DO
12812 ELSE
12813 kkey=0
12814 WRITE(*,*) 'Wrong text in line',nline
12815 WRITE(*,*) 'Status continuation measurement'
12816 WRITE(*,*) '> ',text(1:nab)
12817 END IF
12818#endif
12819#endif
12820 END IF
12821 END IF
12822END SUBROUTINE intext
12823
12831SUBROUTINE additem(length,list,label,value)
12832 USE mpdef
12833 USE mpdalc
12834
12835 INTEGER(mpi), INTENT(IN OUT) :: length
12836 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12837 INTEGER(mpi), INTENT(IN) :: label
12838 REAL(mpd), INTENT(IN) :: value
12839
12840 INTEGER(mpl) :: newSize
12841 INTEGER(mpl) :: oldSize
12842 TYPE(listitem), DIMENSION(:), ALLOCATABLE :: tempList
12843
12844 IF (label > 0.AND.value == 0.) RETURN ! skip zero for valid labels
12845 IF (length == 0 ) THEN ! initial list with size = 100
12846 newsize = 100
12847 CALL mpalloc(list,newsize,' list ')
12848 ENDIF
12849 oldsize=size(list,kind=mpl)
12850 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12851 newsize = oldsize + oldsize/5 + 100
12852 CALL mpalloc(templist,oldsize,' temp. list ')
12853 templist=list
12854 CALL mpdealloc(list)
12855 CALL mpalloc(list,newsize,' list ')
12856 list(1:oldsize)=templist(1:oldsize)
12857 CALL mpdealloc(templist)
12858 ENDIF
12859 ! add to end of list
12860 length=length+1
12861 list(length)%label=label
12862 list(length)%value=value
12863
12864END SUBROUTINE additem
12865
12873SUBROUTINE additemc(length,list,label,text)
12874 USE mpdef
12875 USE mpdalc
12876
12877 INTEGER(mpi), INTENT(IN OUT) :: length
12878 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12879 INTEGER(mpi), INTENT(IN) :: label
12880 CHARACTER(len = itemCLen), INTENT(IN) :: text
12881
12882 INTEGER(mpl) :: newSize
12883 INTEGER(mpl) :: oldSize
12884 TYPE(listitemc), DIMENSION(:), ALLOCATABLE :: tempList
12885
12886 IF (label > 0.AND.text == '') RETURN ! skip empty text for valid labels
12887 IF (length == 0 ) THEN ! initial list with size = 100
12888 newsize = 100
12889 CALL mpalloc(list,newsize,' list ')
12890 ENDIF
12891 oldsize=size(list,kind=mpl)
12892 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12893 newsize = oldsize + oldsize/5 + 100
12894 CALL mpalloc(templist,oldsize,' temp. list ')
12895 templist=list
12896 CALL mpdealloc(list)
12897 CALL mpalloc(list,newsize,' list ')
12898 list(1:oldsize)=templist(1:oldsize)
12899 CALL mpdealloc(templist)
12900 ENDIF
12901 ! add to end of list
12902 length=length+1
12903 list(length)%label=label
12904 list(length)%text=text
12905
12906END SUBROUTINE additemc
12907
12915SUBROUTINE additemi(length,list,label,ivalue)
12916 USE mpdef
12917 USE mpdalc
12918
12919 INTEGER(mpi), INTENT(IN OUT) :: length
12920 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12921 INTEGER(mpi), INTENT(IN) :: label
12922 INTEGER(mpi), INTENT(IN) :: ivalue
12923
12924 INTEGER(mpl) :: newSize
12925 INTEGER(mpl) :: oldSize
12926 TYPE(listitemi), DIMENSION(:), ALLOCATABLE :: tempList
12927
12928 IF (length == 0 ) THEN ! initial list with size = 100
12929 newsize = 100
12930 CALL mpalloc(list,newsize,' list ')
12931 ENDIF
12932 oldsize=size(list,kind=mpl)
12933 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12934 newsize = oldsize + oldsize/5 + 100
12935 CALL mpalloc(templist,oldsize,' temp. list ')
12936 templist=list
12937 CALL mpdealloc(list)
12938 CALL mpalloc(list,newsize,' list ')
12939 list(1:oldsize)=templist(1:oldsize)
12940 CALL mpdealloc(templist)
12941 ENDIF
12942 ! add to end of list
12943 length=length+1
12944 list(length)%label=label
12945 list(length)%ivalue=ivalue
12946
12947END SUBROUTINE additemi
12948
12950SUBROUTINE mstart(text)
12951 USE mpdef
12952 USE mpmod, ONLY: textl
12953
12954 IMPLICIT NONE
12955 INTEGER(mpi) :: i
12956 INTEGER(mpi) :: ka
12957 INTEGER(mpi) :: kb
12958 INTEGER(mpi) :: l
12959 CHARACTER (LEN=*), INTENT(IN) :: text
12960 CHARACTER (LEN=16) :: textc
12961 SAVE
12962 ! ...
12963 DO i=1,74
12964 textl(i:i)='_'
12965 END DO
12966 l=len(text)
12967 ka=(74-l)/2
12968 kb=ka+l-1
12969 textl(ka:kb)=text(1:l)
12970 WRITE(*,*) ' '
12971 WRITE(*,*) textl
12972 WRITE(*,*) ' '
12973 textc=text(1:l)//'-end'
12974
12975 DO i=1,74
12976 textl(i:i)='_'
12977 END DO
12978 l=l+4
12979 ka=(74-l)/2
12980 kb=ka+l-1
12981 textl(ka:kb)=textc(1:l)
12982 RETURN
12983END SUBROUTINE mstart
12984
12986SUBROUTINE mend
12987 USE mpmod, ONLY: textl
12988
12989 IMPLICIT NONE
12990 WRITE(*,*) ' '
12991 WRITE(*,*) textl
12992 CALL petime
12993 WRITE(*,*) ' '
12994END SUBROUTINE mend
12995
13002
13003SUBROUTINE mvopen(lun,fname)
13004 USE mpdef
13005
13006 IMPLICIT NONE
13007 INTEGER(mpi) :: l
13008 INTEGER(mpi), INTENT(IN) :: lun
13009 CHARACTER (LEN=*), INTENT(IN) :: fname
13010 CHARACTER (LEN=33) :: nafile
13011 CHARACTER (LEN=33) :: nbfile
13012 LOGICAL :: ex
13013 SAVE
13014 ! ...
13015 l=len(fname)
13016 IF(l > 32) THEN
13017 CALL peend(17,'Aborted, file name too long')
13018 stop 'File name too long '
13019 END IF
13020 nafile=fname
13021 nafile(l+1:l+1)='~'
13022
13023 INQUIRE(file=nafile(1:l),exist=ex)
13024 IF(ex) THEN
13025 INQUIRE(file=nafile(1:l+1),exist=ex)
13026 IF(ex) THEN
13027 CALL system('rm '//nafile)
13028 END IF
13029 nbfile=nafile
13030 nafile(l+1:l+1)=' '
13031 CALL system('mv '//nafile//nbfile)
13032 END IF
13033 OPEN(unit=lun,file=fname)
13034END SUBROUTINE mvopen
13035
13039
13040SUBROUTINE petime
13041 USE mpdef
13042
13043 IMPLICIT NONE
13044 REAL, DIMENSION(2) :: ta
13045 REAL etime
13046 REAL :: rst
13047 REAL :: delta
13048 REAL :: rstp
13049 REAL :: secnd1
13050 REAL :: secnd2
13051 INTEGER :: ncount
13052 INTEGER :: nhour1
13053 INTEGER :: minut1
13054 INTEGER :: nsecd1
13055 INTEGER :: nhour2
13056 INTEGER :: minut2
13057 INTEGER :: nsecd2
13058
13059 SAVE
13060 DATA ncount/0/
13061 ! ...
13062 ncount=ncount+1
13063 rst=etime(ta)
13064 IF(ncount > 1) THEN
13065 delta=rst
13066 nsecd1=int(delta,mpi) ! -> integer
13067 nhour1=nsecd1/3600
13068 minut1=nsecd1/60-60*nhour1
13069 secnd1=delta-60*(minut1+60*nhour1)
13070 delta=rst-rstp
13071 nsecd2=int(delta,mpi) ! -> integer
13072 nhour2=nsecd2/3600
13073 minut2=nsecd2/60-60*nhour2
13074 secnd2=delta-60*(minut2+60*nhour2)
13075 WRITE(*,101) nhour1,minut1,secnd1, nhour2,minut2,secnd2
13076 END IF
13077
13078 rstp=rst
13079 RETURN
13080101 FORMAT(i4,' h',i3,' min',f5.1,' sec total',18x,'elapsed', &
13081 i4,' h',i3,' min',f5.1,' sec')
13082END SUBROUTINE petime ! print
13083
13090
13091SUBROUTINE peend(icode, cmessage)
13092 USE mpdef
13093
13094 IMPLICIT NONE
13095 INTEGER(mpi), INTENT(IN) :: icode
13096 CHARACTER (LEN=*), INTENT(IN) :: cmessage
13097
13098 CALL mvopen(9,'millepede.end')
13099 WRITE(9,101) icode, cmessage
13100101 FORMAT(1x,i4,3x,a)
13101 CLOSE(9)
13102 RETURN
13103
13104END SUBROUTINE peend
13105
13112SUBROUTINE binopn(kfile, ithr, ierr)
13113 USE mpmod
13114
13115 IMPLICIT NONE
13116 INTEGER(mpi), INTENT(IN) :: kfile
13117 INTEGER(mpi), INTENT(IN) :: ithr
13118 INTEGER(mpi), INTENT(OUT) :: ierr
13119
13120 INTEGER(mpi), DIMENSION(13) :: ibuff
13121 INTEGER(mpi) :: ioff
13122 INTEGER(mpi) :: ios
13123 INTEGER(mpi) :: k
13124 INTEGER(mpi) :: lfn
13125 INTEGER(mpi) :: lun
13126 INTEGER(mpi) :: moddate
13127 CHARACTER (LEN=1024) :: fname
13128 CHARACTER (LEN=7) :: cfile
13129 INTEGER stat
13130
13131#ifdef READ_C_FILES
13132 INTERFACE
13133 SUBROUTINE openc(filename, lfn, lun, ios) BIND(c)
13134 USE iso_c_binding
13135 CHARACTER(kind=c_char), DIMENSION(*), INTENT(IN) :: filename
13136 INTEGER(c_int), INTENT(IN), VALUE :: lfn
13137 INTEGER(c_int), INTENT(IN), VALUE :: lun
13138 INTEGER(c_int), INTENT(INOUT) :: ios
13139 END SUBROUTINE openc
13140 END INTERFACE
13141#endif
13142
13143 ierr=0
13144 lun=ithr
13145 ! modification date (=0: open for first time, >0: reopen, <0: unknown )
13146 moddate=yfd(kfile)
13147 ! file name
13148 ioff=sfd(1,kfile)
13149 lfn=sfd(2,kfile)
13150 DO k=1,lfn
13151 fname(k:k)=tfd(ioff+k)
13152 END DO
13153 !print *, " opening binary ", kfile, ithr, moddate, " : ", fname(1:lfn)
13154 ! open
13155 ios=0
13156 IF(kfile <= nfilf) THEN
13157 ! Fortran file
13158 lun=kfile+10
13159 OPEN(lun,file=fname(1:lfn),iostat=ios, form='UNFORMATTED')
13160 print *, ' lun ', lun, ios
13161#ifdef READ_C_FILES
13162 ELSE
13163 ! C file
13164 CALL openc(fname(1:lfn),lfn,lun,ios)
13165#else
13166 WRITE(*,*) 'Opening of C-files not supported.'
13167 ierr=1
13168 RETURN
13169#endif
13170 END IF
13171 IF(ios /= 0) THEN
13172 ierr=1
13173 WRITE(*,*) 'Open error for file ',fname(1:lfn), ios
13174 IF (moddate /= 0) THEN
13175 WRITE(cfile,'(I7)') kfile
13176 CALL peend(15,'Aborted, open error(s) for binary file ' // cfile)
13177 stop 'PEREAD: open error'
13178 ENDIF
13179 RETURN
13180 END IF
13181 ! get status
13182 ios=stat(fname(1:lfn),ibuff)
13183 !print *, ' STAT ', ios, ibuff(10), moddate
13184 IF(ios /= 0) THEN
13185 ierr=1
13186 WRITE(*,*) 'STAT error for file ',fname(1:lfn), ios
13187 ibuff(10)=-1
13188 END IF
13189 ! check/store modification date
13190 IF (moddate /= 0) THEN
13191 IF (ibuff(10) /= moddate) THEN
13192 WRITE(cfile,'(I7)') kfile
13193 CALL peend(19,'Aborted, binary file modified (date) ' // cfile)
13194 stop 'PEREAD: file modified'
13195 END IF
13196 ELSE
13197 yfd(kfile)=ibuff(10)
13198 END IF
13199 RETURN
13200
13201END SUBROUTINE binopn
13202
13208SUBROUTINE bincls(kfile, ithr)
13209 USE mpmod
13210
13211 IMPLICIT NONE
13212 INTEGER(mpi), INTENT(IN) :: kfile
13213 INTEGER(mpi), INTENT(IN) :: ithr
13214
13215 INTEGER(mpi) :: lun
13216
13217#ifdef READ_C_FILES
13218 INTERFACE
13219 SUBROUTINE closec(lun) BIND(c)
13220 USE iso_c_binding
13221 INTEGER(c_int), INTENT(IN), VALUE :: lun
13222 END SUBROUTINE closec
13223 END INTERFACE
13224#endif
13225
13226 lun=ithr
13227 !print *, " closing binary ", kfile, ithr
13228 IF(kfile <= nfilf) THEN ! Fortran file
13229 lun=kfile+10
13230 CLOSE(lun)
13231#ifdef READ_C_FILES
13232 ELSE ! C file
13233 CALL closec(lun)
13234#endif
13235 END IF
13236
13237END SUBROUTINE bincls
13238
13243SUBROUTINE binrwd(kfile)
13244 USE mpmod
13245
13246 IMPLICIT NONE
13247 INTEGER(mpi), INTENT(IN) :: kfile
13248
13249 INTEGER(mpi) :: lun
13250
13251#ifdef READ_C_FILES
13252 INTERFACE
13253 SUBROUTINE resetc(lun) BIND(c)
13254 USE iso_c_binding
13255 INTEGER(c_int), INTENT(IN), VALUE :: lun
13256 END SUBROUTINE resetc
13257 END INTERFACE
13258#endif
13259
13260 !print *, " rewinding binary ", kfile
13261 IF (kfile <= nfilf) THEN
13262 lun=kfile+10
13263 rewind lun
13264#ifdef READ_C_FILES
13265 ELSE
13266 lun=kfile-nfilf
13267 CALL resetc(lun)
13268#endif
13269 END IF
13270
13271END SUBROUTINE binrwd
13272
13274SUBROUTINE ckpgrp
13275 USE mpmod
13276 USE mpdalc
13277
13278 IMPLICIT NONE
13279 INTEGER(mpi) :: i
13280 INTEGER(mpi) :: ipgrp
13281 INTEGER(mpi) :: irank
13282 INTEGER(mpi) :: isize
13283 INTEGER(mpi) :: ivoff
13284 INTEGER(mpi) :: itgbi
13285 INTEGER(mpi) :: j
13286 INTEGER(mpi) :: msize
13287 INTEGER(mpi), PARAMETER :: mxsize = 1000
13288 INTEGER(mpl):: ij
13289 INTEGER(mpl):: length
13290
13291 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
13292 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
13293 REAL(mpd), DIMENSION(:), ALLOCATABLE :: resParGroup
13294 REAL(mpd), DIMENSION(:), ALLOCATABLE :: blockParGroup
13295 REAL(mpd) :: matij
13296 SAVE
13297
13298 ! maximal group size
13299 msize=0
13300 DO ipgrp=1,nvpgrp
13301 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13302 IF (isize <= mxsize) THEN
13303 msize=max(msize,isize)
13304 ELSE
13305 print *, ' CKPGRP: par. group', ipgrp, ' not checked -- too large: ', isize
13306 END IF
13307 END DO
13308 IF (msize == 0) RETURN
13309
13310 ! (matrix) block for parameter groups
13311 length=int(msize,mpl)*(int(msize,mpl)+1)/2
13312 CALL mpalloc(blockpargroup,length,'(matrix) block for parameter groups (D)')
13313 length=msize
13314 CALL mpalloc(respargroup,length,'residuals for parameter groups (D)') ! double aux 1
13315 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
13316 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
13317
13318 respargroup=0
13319 print *
13320 print *,' CKPGRP par. group first label size rank'
13321 DO ipgrp=1,nvpgrp
13322 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13323 IF (isize > mxsize) cycle
13324 ! copy matrix block
13325 ivoff=globalallindexgroups(ipgrp)-1
13326 ij=0
13327 DO i=1,isize
13328 DO j=1,i
13329 ij=ij+1
13330 blockpargroup(ij)=matij(ivoff+i,ivoff+j)
13331 END DO
13332 END DO
13333 ! inversion of matrix block
13334 CALL sqminv(blockpargroup,respargroup,isize,irank, auxvectord, auxvectori)
13335 !
13337 IF (isize == irank) THEN
13338 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank
13339 ELSE
13340 ndefpg=ndefpg+1
13341 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank, ' rank deficit !!!'
13342 END IF
13343 END DO
13344
13345 ! clean up
13346 CALL mpdealloc(auxvectord)
13347 CALL mpdealloc(auxvectori)
13348 CALL mpdealloc(respargroup)
13349 CALL mpdealloc(blockpargroup)
13350
13351END SUBROUTINE ckpgrp
13352
13354SUBROUTINE chkmat
13355 USE mpmod
13356
13357 IMPLICIT NONE
13358 INTEGER(mpl) :: i
13359 INTEGER(mpl) :: nan
13360 INTEGER(mpl) :: neg
13361
13362 print *, ' Checking global matrix(D) for NANs ', size(globalmatd,kind=mpl)
13363 nan=0
13364 DO i=1,size(globalmatd,kind=mpl)
13365 IF(.NOT.(globalmatd(i) <= 0.0_mpd).AND..NOT.(globalmatd(i) > 0.0_mpd)) THEN
13366 nan=nan+1
13367 print *, ' i, nan ', i, nan
13368 END IF
13369 END DO
13370
13371 IF (matsto > 1) RETURN
13372 print *
13373 print *, ' Checking diagonal elements ', nagb
13374 neg=0
13375 DO i=1,nagb
13376 IF(.NOT.(globalmatd(globalrowoffsets(i)+i) > 0.0_mpd)) THEN
13377 neg=neg+1
13378 print *, ' i, neg ', i, neg
13379 END IF
13380 END DO
13381 print *
13382 print *, ' CHKMAT summary ', nan, neg
13383 print *
13384
13385END SUBROUTINE chkmat
13386
13387
13388! ----- accurate summation ----(from mpnum) ---------------------------------
13389
13399
13400SUBROUTINE addsums(ithrd, chi2, ndf, dw)
13401 USE mpmod
13402
13403 IMPLICIT NONE
13404 REAL(mpd), INTENT(IN) :: chi2
13405 INTEGER(mpi), INTENT(IN) :: ithrd
13406 INTEGER(mpi), INTENT(IN) :: ndf
13407 REAL(mpd), INTENT(IN) :: dw
13408
13409 INTEGER(mpl) ::nadd
13410 REAL(mpd) ::add
13411 ! ...
13412 add=chi2*dw ! apply (file) weight
13413 nadd=int(add,mpl) ! convert to integer
13414 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+nadd ! sum integer
13415 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)+(add-real(nadd,mpd)) ! sum remainder
13416 IF(globalchi2sumd(ithrd) > 16.0_mpd) THEN ! + - 16
13417 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)-16.0_mpd
13418 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+16_mpl
13419 END IF
13420 globalndfsum(ithrd)=globalndfsum(ithrd)+int(ndf,mpl)
13421 globalndfsumw(ithrd)=globalndfsumw(ithrd)+real(ndf,mpd)*dw
13422 RETURN
13423END SUBROUTINE addsums
13424
13432
13433SUBROUTINE getsums(chi2, ndf, wndf)
13434 USE mpmod
13435
13436 IMPLICIT NONE
13437 REAL(mpd), INTENT(OUT) ::chi2
13438 INTEGER(mpl), INTENT(OUT) ::ndf
13439 REAL(mpd), INTENT(OUT) ::wndf
13440 ! ...
13441 chi2=sum(globalchi2sumd)+real(sum(globalchi2sumi),mpd)
13442 ndf=sum(globalndfsum)
13443 wndf=sum(globalndfsumw)
13444 globalchi2sumd=0.0_mpd
13445 globalchi2sumi=0_mpl
13446 globalndfsum=0_mpl
13447 globalndfsumw=0.0_mpd
13448 RETURN
13449END SUBROUTINE getsums
allocate array
Definition: mpdalc.f90:36
deallocate array
Definition: mpdalc.f90:42
subroutine ptlopt(nf, m, slopes, steps)
Get details.
Definition: linesrch.f90:259
subroutine ptline(n, x, f, g, s, step, info)
Perform linesearch.
Definition: linesrch.f90:90
subroutine ptldef(gtole, stmax, minfe, maxfe)
Initialize line search.
Definition: linesrch.f90:233
subroutine ptlprt(lunp)
Print line search data.
Definition: linesrch.f90:295
subroutine pcbits(npgrp, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:1018
subroutine ndbits(npgrp, ndims, nsparr, ihst)
Analyze bit fields.
Definition: mpbits.f90:302
subroutine clbits(in, jreqpe, jhispe, jsngpe, jextnd, idimb, ispc)
Calculate bit (field) array size, encoding.
Definition: mpbits.f90:179
subroutine plbits(in, inar, inac, idimb)
Calculate bit field array size (PARDISO).
Definition: mpbits.f90:252
subroutine spbits(npgrp, nsparr, nsparc)
Create sparsity information.
Definition: mpbits.f90:1205
subroutine irbits(i, j)
Fill bit fields (counters, rectangular part).
Definition: mpbits.f90:146
subroutine clbmap(in)
Clear (additional) bit map.
Definition: mpbits.f90:1342
subroutine inbmap(im, jm)
Fill bit map.
Definition: mpbits.f90:1374
subroutine ckbits(npgrp, ndims)
Check sparsity of matrix.
Definition: mpbits.f90:1112
subroutine ggbmap(ipgrp, npair, npgrp)
Get paired (parameter) groups from map.
Definition: mpbits.f90:1454
subroutine prbits(npgrp, nsparr)
Analyze bit fields.
Definition: mpbits.f90:919
subroutine gpbmap(ngroup, npgrp, npair)
Get pairs (statistic) from map.
Definition: mpbits.f90:1408
subroutine pblbits(npgrp, ibsize, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:752
subroutine pbsbits(npgrp, ibsize, nnzero, nblock, nbkrow)
Analyze bit fields.
Definition: mpbits.f90:575
subroutine inbits(im, jm, inc)
Fill bit fields (counters, triangular part).
Definition: mpbits.f90:70
subroutine hmplun(lunw)
unit for output
Definition: mphistab.f90:329
subroutine gmpdef(ig, ityp, text)
book, reset XY storage
Definition: mphistab.f90:702
subroutine gmpxy(ig, x, y)
add (X,Y) pair
Definition: mphistab.f90:767
subroutine hmpdef(ih, xa, xb, text)
book, reset histogram
Definition: mphistab.f90:122
subroutine gmplun(lunw)
unit for output
Definition: mphistab.f90:975
subroutine gmpxyd(ig, x, y, dx, dy)
add (X,Y,DX,DY)
Definition: mphistab.f90:782
subroutine hmpwrt(ih)
write histogram text file
Definition: mphistab.f90:341
subroutine gmpwrt(ig)
write XY text file
Definition: mphistab.f90:987
subroutine hmpldf(ih, text)
book, reset log histogram
Definition: mphistab.f90:158
subroutine gmprnt(ig)
print XY data
Definition: mphistab.f90:869
subroutine hmpent(ih, x)
entry flt.pt.
Definition: mphistab.f90:183
subroutine hmplnt(ih, ix)
entry integer
Definition: mphistab.f90:223
subroutine gmpms(ig, x, y)
mean sigma(X) from Y
Definition: mphistab.f90:805
subroutine hmprnt(ih)
print, content vert
Definition: mphistab.f90:254
subroutine monend()
End monitoring.
Definition: mpmon.f90:83
subroutine monini(l, n1, n2)
Initialize monitoring.
Definition: mpmon.f90:43
subroutine 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:696
subroutine qldecb(a, bpar, bcon, rcon)
QL decomposition (for disjoint block matrix).
Definition: mpqldec.f90:216
subroutine qlmlq(x, m, t)
Multiply left by Q(t) (per block).
Definition: mpqldec.f90:395
subroutine qlsetb(ib)
Set block.
Definition: mpqldec.f90:997
subroutine qlbsub(d, y)
Backward substitution (per block).
Definition: mpqldec.f90:970
subroutine qlini(n, m, l, s, k)
Initialize QL decomposition.
Definition: mpqldec.f90:58
subroutine qlgete(emin, emax)
Get eigenvalues.
Definition: mpqldec.f90:934
subroutine qlssq(aprod, A, s, roff, t)
Similarity transformation by Q(t).
Definition: mpqldec.f90:564
subroutine mptest
Generate test files.
Definition: mptest1.f90:79
subroutine mptst2(imodel)
Generate test files.
Definition: mptest2.f90:112
integer(mpi) function matint(pat, text, npat, ntext)
Approximate string matching.
Definition: mptext.f90:309
subroutine ratext(text, nums, dnum, mnum)
Translate text.
Definition: mptext.f90:51
subroutine rltext(text, ia, ib, nab)
Analyse text range.
Definition: mptext.f90:256
MINRES solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite and/...
subroutine, public minres(n, Aprod, Msolve, b, shift, checkA, precon, x, itnlim, nout, rtol, istop, itn, Anorm, Acond, rnorm, Arnorm, ynorm)
Solution of linear equation system.
MINRESQLP solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite a...
subroutine, public minresqlp(n, Aprod, b, shift, Msolve, disable, nout, itnlim, rtol, maxxnorm, trancond, Acondlim, x, istop, itn, rnorm, Arnorm, xnorm, Anorm, Acond)
Solution of linear equation system or least squares problem.
(De)Allocate vectors and arrays.
Definition: mpdalc.f90:24
integer(mpl) maxwordsalloc
peak dynamic memory allocation (words)
Definition: mpdalc.f90:30
integer(mpi) printflagalloc
print flag for dynamic allocations
Definition: mpdalc.f90:33
Definition of constants.
Definition: mpdef.f90:24
integer, parameter mpl
long integer
Definition: mpdef.f90:36
integer, parameter mps
single precision
Definition: mpdef.f90:37
integer, parameter mpi
integer
Definition: mpdef.f90:35
Parameters, variables, dynamic arrays.
Definition: mpmod.f90:28
integer(mpl), dimension(:), allocatable csr3columnlist
list of columns for sparse matrix
Definition: mpmod.f90: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
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:363
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:354
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:356
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:372
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:373
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:359
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:371
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:369
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:368
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:361
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:364
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:362
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(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:355
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:365
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:352
integer(mpi) ntpgrp
number of parameter groups
Definition: mpmod.f90:136
character, dimension(:), allocatable tfd
file names (concatenation)
Definition: mpmod.f90:366
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:360
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:367
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:353
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:370
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:351
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:358
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:357
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:3831
subroutine mchdec
Solution by Cholesky decomposition.
Definition: pede.f90:9011
subroutine bincls(kfile, ithr)
Close binary file.
Definition: pede.f90:13209
subroutine prpcon
Prepare constraints.
Definition: pede.f90:1926
subroutine mminrs
Solution with MINRES.
Definition: pede.f90:10025
subroutine prtrej(lun)
Print rejection statistics.
Definition: pede.f90:5349
subroutine mcsolv(n, x, y)
Solution for zero band width preconditioner.
Definition: pede.f90:10229
subroutine mupdat(i, j, add)
Update element of global matrix.
Definition: pede.f90:4053
subroutine peend(icode, cmessage)
Print exit code.
Definition: pede.f90:13092
subroutine loopn
Loop with fits and sums.
Definition: pede.f90:3396
subroutine loop1
First data loop (get global labels).
Definition: pede.f90:6899
subroutine feasma
Matrix for feasible solution.
Definition: pede.f90:2226
subroutine xloopn
Standard solution algorithm.
Definition: pede.f90:10283
subroutine ploopa(lunp)
Print title for iteration.
Definition: pede.f90:3810
subroutine isjajb(nst, is, ja, jb, jsp)
Decode Millepede record.
Definition: pede.f90:3345
subroutine additem(length, list, label, value)
add item to list
Definition: pede.f90:12832
subroutine mgupdt(i, j1, j2, il, jl, n, sub)
Update global matrix for parameter group.
Definition: pede.f90:4138
subroutine lpavat(t)
Similarity transformation by Q(t).
Definition: pede.f90:9543
subroutine binrwd(kfile)
Rewind binary file.
Definition: pede.f90:13244
subroutine zdiags
Covariance matrix for diagonalization (,correction of eigenvectors).
Definition: pede.f90:9988
subroutine solglo(ivgbi)
Error for single global parameter from MINRES.
Definition: pede.f90:1387
subroutine upone
Update, redefine hash indices.
Definition: pede.f90:6765
subroutine pargrp(inds, inde)
Parameter group info update for block of parameters.
Definition: pede.f90:3228
subroutine prtglo
Print final log file.
Definition: pede.f90:5378
subroutine monres
Monitor input residuals.
Definition: pede.f90:8600
subroutine intext(text, nline)
Interprete text.
Definition: pede.f90:11963
integer(mpl) function ijadd(itema, itemb)
Index for sparse storage (custom).
Definition: pede.f90:6398
subroutine mdiags
Solution by diagonalization.
Definition: pede.f90:9839
program mptwo
Millepede II main program Pede.
Definition: pede.f90:900
subroutine prtstat
Print input statistic.
Definition: pede.f90:5564
real(mpd) function matij(itema, itemb)
Get matrix element at (i,j).
Definition: pede.f90:6505
subroutine grpcon
Group constraints.
Definition: pede.f90:1628
subroutine loopbf(nrej, numfil, naccf, chi2f, ndff)
Loop over records in read buffer (block), fits and sums.
Definition: pede.f90:4306
subroutine peread(more)
Read (block of) records from binary files.
Definition: pede.f90:2562
subroutine filetx
Interprete text files.
Definition: pede.f90:11640
integer(mpi) function iprime(n)
largest prime number < N.
Definition: pede.f90:6867
subroutine ploopc(lunp)
Print sub-iteration line.
Definition: pede.f90:3888
integer(mpl) function ijcsr3(itema, itemb)
Index for sparse storage (CSR3).
Definition: pede.f90:6447
subroutine useone
Make usable (sort items and redefine hash indices).
Definition: pede.f90:6835
subroutine mvopen(lun, fname)
Open file.
Definition: pede.f90:13004
subroutine chkrej
Check rejection details.
Definition: pede.f90:11100
subroutine avprd0(n, l, x, b)
Product symmetric (sub block) matrix times vector.
Definition: pede.f90:5969
subroutine addsums(ithrd, chi2, ndf, dw)
Accurate summation.
Definition: pede.f90:13401
subroutine solgloqlp(ivgbi)
Error for single global parameter from MINRES-QLP.
Definition: pede.f90:1471
subroutine lpqldec(a, emin, emax)
QL decomposition.
Definition: pede.f90:9427
subroutine addcst
Add constraint information to matrix and vector.
Definition: pede.f90:1554
subroutine petime
Print times.
Definition: pede.f90:13041
subroutine mstart(text)
Start of 'module' printout.
Definition: pede.f90:12951
subroutine mend
End of 'module' printout.
Definition: pede.f90:12987
subroutine anasps
Analyse sparsity structure.
Definition: pede.f90:6137
subroutine minver
Solution by matrix inversion.
Definition: pede.f90:8898
subroutine peprep(mode)
Prepare records.
Definition: pede.f90:2913
integer(mpi) function ijprec(itema, itemb)
Precision for storage of parameter groups.
Definition: pede.f90:6369
subroutine explfc(lunit)
Print explanation of iteration table.
Definition: pede.f90:3962
subroutine getsums(chi2, ndf, wndf)
Get accurate sums.
Definition: pede.f90:13434
subroutine chkmat
Check global matrix.
Definition: pede.f90:13355
subroutine binopn(kfile, ithr, ierr)
Open binary file.
Definition: pede.f90:13113
subroutine pepgrp
Parameter group info update.
Definition: pede.f90:3080
subroutine sechms(deltat, nhour, minut, secnd)
Time conversion.
Definition: pede.f90:6650
integer(mpi) function inone(item)
Translate labels to indices (for global parameters).
Definition: pede.f90:6695
subroutine avprds(n, l, x, is, ie, b)
Product symmetric (sub block) matrix times sparse vector.
Definition: pede.f90:5755
subroutine avprod(n, x, b)
Product symmetric matrix times vector.
Definition: pede.f90:6231
subroutine ijpgrp(itema, itemb, ij, lr, iprc)
Index (region length and precision) for sparse storage of parameter groups.
Definition: pede.f90:6271
subroutine loop1i
Iteration of first data loop.
Definition: pede.f90:7266
subroutine mhalf2
Fill 2nd half of matrix for extended storage.
Definition: pede.f90:6563
subroutine ckpgrp
Check (rank of) parameter groups.
Definition: pede.f90:13275
subroutine additemi(length, list, label, ivalue)
add item to list
Definition: pede.f90:12916
subroutine mminrsqlp
Solution with MINRES-QLP.
Definition: pede.f90:10123
subroutine filetc
Interprete command line option, steering file.
Definition: pede.f90:11164
subroutine feasib(concut, iact)
Make parameters feasible.
Definition: pede.f90:2401
subroutine mspardiso
Solution with Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO.
Definition: pede.f90:9634
subroutine mdutrf
Solution by factorization.
Definition: pede.f90:9258
subroutine mdptrf
Solution by factorization.
Definition: pede.f90:9123
subroutine mvsolv(n, x, y)
Solution for finite band width preconditioner.
Definition: pede.f90:10250
subroutine vmprep(msize)
Prepare storage for vectors and matrices.
Definition: pede.f90:8701
subroutine ploopd(lunp)
Print solution line.
Definition: pede.f90:3936
subroutine pechk(ibuf, nerr)
Check Millepede record.
Definition: pede.f90:3008
subroutine loop2
Second data loop (number of derivatives, global label pairs).
Definition: pede.f90:7378
integer(mpi) function nufile(fname)
Inquire on file.
Definition: pede.f90:11906
subroutine additemc(length, list, label, text)
add character item to list
Definition: pede.f90:12874
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