Millepede-II V04-17-04
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
276
563
564
824
862
905
906#ifdef SCOREP_USER_ENABLE
907#include "scorep/SCOREP_User.inc"
908#endif
909
911PROGRAM mptwo
912 USE mpmod
913 USE mpdalc
914 USE mptest1, ONLY: nplan,del,dvd
915 USE mptest2, ONLY: nlyr,nmx,nmy,sdevx,sdevy,ntot
916
917 IMPLICIT NONE
918 REAL(mps) :: andf
919 REAL(mps) :: c2ndf
920 REAL(mps) :: deltat
921 REAL(mps) :: diff
922 REAL(mps) :: err
923 REAL(mps) :: gbu
924 REAL(mps) :: gmati
925 REAL(mps) :: rej
926 REAL :: rloop1
927 REAL :: rloop2
928 REAL :: rstext
929 REAL(mps) :: secnd
930 REAL :: rst
931 REAL :: rstp
932 REAL, DIMENSION(2) :: ta
933 INTEGER(mpi) :: i
934 INTEGER(mpi) :: ii
935 INTEGER(mpi) :: iopnmp
936 INTEGER(mpi) :: ix
937 INTEGER(mpi) :: ixv
938 INTEGER(mpi) :: iy
939 INTEGER(mpi) :: k
940 INTEGER(mpi) :: kfl
941 INTEGER(mpi) :: lun
942 INTEGER :: minut
943 INTEGER :: nhour
944 INTEGER(mpi) :: nmxy
945 INTEGER(mpi) :: nrc
946 INTEGER(mpi) :: nsecnd
947 INTEGER(mpi) :: ntsec
948
949 CHARACTER (LEN=24) :: chdate
950 CHARACTER (LEN=24) :: chost
951#ifdef LAPACK64
952 CHARACTER (LEN=6) :: c6
953 INTEGER major, minor, patch
954#endif
955
956 INTEGER(mpl) :: rows
957 INTEGER(mpl) :: cols
958
959 REAL(mpd) :: sums(9)
960 !$ INTEGER(mpi) :: OMP_GET_NUM_PROCS,OMP_GET_MAX_THREADS
961 !$ INTEGER(mpi) :: MXTHRD
962 !$ INTEGER(mpi) :: NPROC
963
964 REAL etime
965
966 SAVE
967 ! ...
968 rstp=etime(ta)
969 CALL fdate(chdate)
970
971 ! millepede monitoring file
972 lunmon=0
973 ! millepede.log file
974 lunlog=8
975 lvllog=1
976 CALL mvopen(lunlog,'millepede.log')
977 CALL getenv('HOSTNAME',chost)
978 IF (chost(1:1) == ' ') CALL getenv('HOST',chost)
979 WRITE(*,*) '($Id: dd0c569a1aafb6f6eb2f26b9b9537a685639ca25 $)'
980 iopnmp=0
981 !$ iopnmp=1
982 !$ WRITE(*,*) 'using OpenMP (TM)'
983#ifdef LAPACK64
984 CALL ilaver( major,minor, patch )
985 WRITE(*,110) lapack64, major,minor, patch
986110 FORMAT(' using LAPACK64 with ',(a),', version ',i0,'.',i0,'.',i0)
987#ifdef PARDISO
988 WRITE(*,*) 'using Intel oneMKL PARDISO'
989#endif
990#endif
991#ifdef __GFORTRAN__
992 WRITE(*,111) __gnuc__ , __gnuc_minor__ , __gnuc_patchlevel__
993111 FORMAT(' compiled with gcc ',i0,'.',i0,'.',i0)
994#endif
995#ifdef __PGIC__
996 WRITE(*,111) __pgic__ , __pgic_minor__ , __pgic_patchlevel__
997111 FORMAT(' compiled with pgi ',i0,'.',i0,'.',i0)
998#endif
999#ifdef SCOREP_USER_ENABLE
1000 WRITE(*,*) 'instrumenting Score-P user regions'
1001#endif
1002 WRITE(*,*) ' '
1003 WRITE(*,*) ' < Millepede II-P starting ... ',chdate
1004 WRITE(*,*) ' ',chost
1005 WRITE(*,*) ' '
1006
1007 WRITE(8,*) '($Id: dd0c569a1aafb6f6eb2f26b9b9537a685639ca25 $)'
1008 WRITE(8,*) ' '
1009 WRITE(8,*) 'Log-file Millepede II-P ', chdate
1010 WRITE(8,*) ' ', chost
1011
1012 CALL peend(-1,'Still running or crashed')
1013 ! read command line and text files
1014
1015 CALL filetc ! command line and steering file analysis
1016 CALL filetx ! read text files
1017 ! dummy call for dynamic memory allocation
1018 CALL gmpdef(0,nfilb,'dummy call')
1019
1020 IF (icheck > 0) THEN
1021 WRITE(*,*) '!!! Checking input only, no calculation of a solution !!!'
1022 WRITE(8,*) '!!! Checking input only, no calculation of a solution !!!'
1023 END IF
1024 lvllog=mprint ! export print level
1025 IF (memdbg > 0) printflagalloc=1 ! debug memory management
1026 !$ WRITE(*,*)
1027 !$ NPROC=1
1028 !$ MXTHRD=1
1029 !$ NPROC=OMP_GET_NUM_PROCS() ! number of processors available
1030 !$ CALL OMP_SET_NUM_THREADS(MTHRD) ! set max number of threads to MTHRD
1031 !$ MXTHRD=OMP_GET_MAX_THREADS() ! get max number of threads back
1032 !$ WRITE(*,*) 'Number of processors available: ', NPROC
1033 !$ WRITE(*,*) 'Maximum number of OpenMP threads: ', MXTHRD
1034 !$ WRITE(*,*) 'Number of threads for processing: ', MTHRD
1035 !$ IF (MXREC.GT.0) MTHRDR=1 ! to get allways the same MXREC records
1036 !$ IF (ICHECK.GT.1) MTHRDR=1 ! to get allways the same order of records
1037 !$ WRITE(*,*) 'Number of threads for reading: ', MTHRDR
1038 !$POMP INST INIT ! start profiling with ompP
1039#ifdef LAPACK64
1040 IF(iopnmp > 0) THEN
1041 CALL getenv('OMP_NUM_THREADS',c6)
1042 ELSE
1043 CALL getenv(lapack64//'_NUM_THREADS',c6)
1044 END IF
1045 IF (c6(1:1) == ' ') THEN
1046 IF(iopnmp > 0) THEN
1047 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty OMP_NUM_THREADS)'
1048 ELSE
1049 WRITE(*,*) 'Number of threads for LAPACK: unkown (empty ',lapack64//'_NUM_THREADS)'
1050 END IF
1051 ELSE
1052 WRITE(*,*) 'Number of threads for LAPACK: ', c6
1053 END IF
1054#endif
1055 cols=mthrd
1056 CALL mpalloc(globalchi2sumd,cols,'fractional part of Chi2 sum')
1057 globalchi2sumd=0.0_mpd
1058 CALL mpalloc(globalchi2sumi,cols,'integer part of Chi2 sum')
1059 globalchi2sumi=0_mpl
1060 CALL mpalloc(globalndfsum,cols,'NDF sum')
1061 globalndfsum=0_mpl
1062 CALL mpalloc(globalndfsumw,cols,'weighted NDF sum')
1063 globalndfsumw=0.0_mpd
1064
1065 IF (ncache < 0) THEN
1066 ncache=25000000*mthrd ! default cache size (100 MB per thread)
1067 ENDIF
1068 rows=6; cols=mthrdr
1069 CALL mpalloc(readbufferinfo,rows,cols,'read buffer header')
1070 ! histogram file
1071 lun=7
1072 CALL mvopen(lun,'millepede.his')
1073 CALL hmplun(lun) ! unit for histograms
1074 CALL gmplun(lun) ! unit for xy data
1075
1076 ! debugging
1077 IF(nrecpr /= 0.OR.nrecp2 /= 0) THEN
1078 CALL mvopen(1,'mpdebug.txt')
1079 END IF
1080
1081 rstext=etime(ta)
1082 times(0)=rstext-rstp ! time for text processing
1083
1084 ! preparation of data sub-arrays
1085
1086 CALL loop1
1087 rloop1=etime(ta)
1088 times(1)=rloop1-rstext ! time for LOOP1
1089
1090 CALL loop2
1091 IF(chicut /= 0.0) THEN
1092 WRITE(8,*) 'Chi square cut equiv 3 st.dev applied ...'
1093 WRITE(8,*) ' in first iteration with factor',chicut
1094 WRITE(8,*) ' in second iteration with factor',chirem
1095 WRITE(8,*) ' (reduced by sqrt in next iterations)'
1096 END IF
1097
1098 IF(lhuber /= 0) THEN
1099 WRITE(8,*) 'Down-weighting of outliers in', lhuber,' iterations'
1100 WRITE(8,*) 'Cut on downweight fraction',dwcut
1101 END IF
1102
1103 rloop2=etime(ta)
1104 times(2)=rloop2-rloop1 ! time for LOOP2
1105
1106 IF(icheck > 0) THEN
1107 CALL prtstat
1108 IF (ncgbe < 0) THEN
1109 CALL peend(5,'Ended without solution (empty constraints)')
1110 ELSE
1111 CALL peend(0,'Ended normally')
1112 END IF
1113 GOTO 99 ! only checking input
1114 END IF
1115
1116 ! use different solution methods
1117
1118 CALL mstart('Iteration') ! Solution module starting
1119
1120 CALL xloopn ! all methods
1121
1122 ! ------------------------------------------------------------------
1123
1124 IF(nloopn > 2.AND.nhistp /= 0) THEN ! last iteration
1125 CALL hmprnt(3) ! scaled residual of single measurement (with global deriv.)
1126 CALL hmprnt(12) ! scaled residual of single measurement (no global deriv.)
1127 CALL hmprnt(4) ! chi^2/Ndf
1128 END IF
1129 IF(nloopn > 2) THEN
1130 CALL hmpwrt(3)
1131 CALL hmpwrt(12)
1132 CALL hmpwrt(4)
1133 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
1134 IF (nloopn <= lfitnp) THEN
1135 CALL hmpwrt(13)
1136 CALL hmpwrt(14)
1137 CALL gmpwrt(5)
1138 END IF
1139 END IF
1140 IF(nhistp /= 0) THEN
1141 CALL gmprnt(1)
1142 CALL gmprnt(2)
1143 END IF
1144 CALL gmpwrt(1) ! output of xy data
1145 CALL gmpwrt(2) ! output of xy data
1146 ! 'track quality' per binary file
1147 IF (nfilb > 1) THEN
1148 CALL gmpdef(6,1,'log10(#records) vs file number')
1149 CALL gmpdef(7,1,'final rejection fraction vs file number')
1150 CALL gmpdef(8,1, &
1151 'final <Chi^2/Ndf> from accepted local fits vs file number')
1152 CALL gmpdef(9,1, '<Ndf> from accepted local fits vs file number')
1153
1154 DO i=1,nfilb
1155 kfl=kfd(2,i)
1156 nrc=-kfd(1,i)
1157 IF (nrc > 0) THEN
1158 rej=real(nrc-jfd(kfl),mps)/real(nrc,mps)
1159 CALL gmpxy(6,real(kfl,mps),log10(real(nrc,mps))) ! log10(#records) vs file
1160 CALL gmpxy(7,real(kfl,mps),rej) ! rejection fraction vs file
1161 END IF
1162 IF (jfd(kfl) > 0) THEN
1163 c2ndf=cfd(kfl)/real(jfd(kfl),mps)
1164 CALL gmpxy(8,real(kfl,mps),c2ndf) ! <Chi2/NDF> vs file
1165 andf=real(dfd(kfl),mps)/real(jfd(kfl),mps)
1166 CALL gmpxy(9,real(kfl,mps),andf) ! <NDF> vs file
1167 END IF
1168 END DO
1169 IF(nhistp /= 0) THEN
1170 CALL gmprnt(6)
1171 CALL gmprnt(7)
1172 CALL gmprnt(8)
1173 CALL gmprnt(9)
1174 END IF
1175 CALL gmpwrt(6) ! output of xy data
1176 CALL gmpwrt(7) ! output of xy data
1177 CALL gmpwrt(8) ! output of xy data
1178 CALL gmpwrt(9) ! output of xy data
1179 END IF
1180
1181 IF(ictest == 1) THEN
1182 WRITE(*,*) ' '
1183 WRITE(*,*) 'Misalignment test wire chamber'
1184 WRITE(*,*) ' '
1185
1186 CALL hmpdef( 9,-0.0015,+0.0015,'True - fitted displacement')
1187 CALL hmpdef(10,-0.0015,+0.0015,'True - fitted Vdrift')
1188 DO i=1,4
1189 sums(i)=0.0_mpd
1190 END DO
1191 DO i=1,nplan
1192 diff=real(-del(i)-globalparameter(i),mps)
1193 sums(1)=sums(1)+diff
1194 sums(2)=sums(2)+diff*diff
1195 diff=real(-dvd(i)-globalparameter(100+i),mps)
1196 sums(3)=sums(3)+diff
1197 sums(4)=sums(4)+diff*diff
1198 END DO
1199 sums(1)=0.01_mpd*sums(1)
1200 sums(2)=sqrt(0.01_mpd*sums(2))
1201 sums(3)=0.01_mpd*sums(3)
1202 sums(4)=sqrt(0.01_mpd*sums(4))
1203 WRITE(*,143) 'Parameters 1 - 100: mean =',sums(1), 'rms =',sums(2)
1204 WRITE(*,143) 'Parameters 101 - 200: mean =',sums(3), 'rms =',sums(4)
1205143 FORMAT(6x,a28,f9.6,3x,a5,f9.6)
1206 WRITE(*,*) ' '
1207 WRITE(*,*) ' '
1208 WRITE(*,*) ' I label simulated fitted diff'
1209 WRITE(*,*) ' -------------------------------------------- '
1210 DO i=1,100
1211 WRITE(*,102) i,globalparlabelindex(1,i),-del(i),globalparameter(i),-del(i)-globalparameter(i)
1212 diff=real(-del(i)-globalparameter(i),mps)
1213 CALL hmpent( 9,diff)
1214 END DO
1215 DO i=101,200
1216 WRITE(*,102) i,globalparlabelindex(1,i),-dvd(i-100),globalparameter(i),-dvd(i-100)-globalparameter(i)
1217 diff=real(-dvd(i-100)-globalparameter(i),mps)
1218 CALL hmpent(10,diff)
1219 END DO
1220 IF(nhistp /= 0) THEN
1221 CALL hmprnt( 9)
1222 CALL hmprnt(10)
1223 END IF
1224 CALL hmpwrt( 9)
1225 CALL hmpwrt(10)
1226 END IF
1227 IF(ictest > 1) THEN
1228 WRITE(*,*) ' '
1229 WRITE(*,*) 'Misalignment test Si tracker'
1230 WRITE(*,*) ' '
1231
1232 CALL hmpdef( 9,-0.0025,+0.0025,'True - fitted displacement X')
1233 CALL hmpdef(10,-0.025,+0.025,'True - fitted displacement Y')
1234 DO i=1,9
1235 sums(i)=0.0_mpd
1236 END DO
1237 nmxy=nmx*nmy
1238 ix=0
1239 iy=ntot
1240 DO i=1,nlyr
1241 DO k=1,nmxy
1242 ix=ix+1
1243 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1244 sums(1)=sums(1)+1.0_mpd
1245 sums(2)=sums(2)+diff
1246 sums(3)=sums(3)+diff*diff
1247 ixv=globalparlabelindex(2,ix)
1248 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1249 ii=(ixv*ixv+ixv)/2
1250 gmati=real(globalmatd(ii),mps)
1251 err=sqrt(abs(gmati))
1252 diff=diff/err
1253 sums(7)=sums(7)+1.0_mpd
1254 sums(8)=sums(8)+diff
1255 sums(9)=sums(9)+diff*diff
1256 END IF
1257 END DO
1258 IF (mod(i,3) == 1) THEN
1259 DO k=1,nmxy
1260 iy=iy+1
1261 diff=-real(sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1262 sums(4)=sums(4)+1.0_mpd
1263 sums(5)=sums(5)+diff
1264 sums(6)=sums(6)+diff*diff
1265 ixv=globalparlabelindex(2,iy)
1266 IF (ixv > 0.AND.metsol == 1.OR.metsol == 2) THEN
1267 ii=(ixv*ixv+ixv)/2
1268 gmati=real(globalmatd(ii),mps)
1269 err=sqrt(abs(gmati))
1270 diff=diff/err
1271 sums(7)=sums(7)+1.0_mpd
1272 sums(8)=sums(8)+diff
1273 sums(9)=sums(9)+diff*diff
1274 END IF
1275 END DO
1276 END IF
1277 END DO
1278 sums(2)=sums(2)/sums(1)
1279 sums(3)=sqrt(sums(3)/sums(1))
1280 sums(5)=sums(5)/sums(4)
1281 sums(6)=sqrt(sums(6)/sums(4))
1282 WRITE(*,143) 'Parameters 1 - 500: mean =',sums(2), 'rms =',sums(3)
1283 WRITE(*,143) 'Parameters 501 - 700: mean =',sums(5), 'rms =',sums(6)
1284 IF (sums(7) > 0.5_mpd) THEN
1285 sums(8)=sums(8)/sums(7)
1286 sums(9)=sqrt(sums(9)/sums(7))
1287 WRITE(*,143) 'Parameter pulls, all: mean =',sums(8), 'rms =',sums(9)
1288 END IF
1289 WRITE(*,*) ' '
1290 WRITE(*,*) ' '
1291 WRITE(*,*) ' I label simulated fitted diff'
1292 WRITE(*,*) ' -------------------------------------------- '
1293 ix=0
1294 iy=ntot
1295 DO i=1,nlyr
1296 DO k=1,nmxy
1297 ix=ix+1
1298 diff=real(-sdevx((i-1)*nmxy+k)-globalparameter(ix),mps)
1299 CALL hmpent( 9,diff)
1300 WRITE(*,102) ix,globalparlabelindex(1,ix),-sdevx((i-1)*nmxy+k),globalparameter(ix),-diff
1301 END DO
1302 END DO
1303 DO i=1,nlyr
1304 IF (mod(i,3) == 1) THEN
1305 DO k=1,nmxy
1306 iy=iy+1
1307 diff=real(-sdevy((i-1)*nmxy+k)-globalparameter(iy),mps)
1308 CALL hmpent(10,diff)
1309 WRITE(*,102) iy,globalparlabelindex(1,iy),-sdevy((i-1)*nmxy+k),globalparameter(iy),-diff
1310 END DO
1311 END IF
1312 END DO
1313 IF(nhistp /= 0) THEN
1314 CALL hmprnt( 9)
1315 CALL hmprnt(10)
1316 END IF
1317 CALL hmpwrt( 9)
1318 CALL hmpwrt(10)
1319 END IF
1320
1321 IF(nrec1+nrec2 > 0) THEN
1322 WRITE(8,*) ' '
1323 IF(nrec1 > 0) THEN
1324 WRITE(8,*) 'Record',nrec1,' has largest residual:',value1
1325 END IF
1326 IF(nrec2 > 0) THEN
1327 WRITE(8,*) 'Record',nrec2,' has largest Chi^2/Ndf:',value2
1328 END IF
1329 END IF
1330 IF(nrec3 < huge(nrec3)) THEN
1331 WRITE(8,*) 'Record',nrec3, ' is first with error (rank deficit/NaN)'
1332 END IF
133399 WRITE(8,*) ' '
1334 IF (iteren > mreqenf) THEN
1335 WRITE(8,*) 'In total 3 +',nloopn,' loops through the data files'
1336 ELSE
1337 WRITE(8,*) 'In total 2 +',nloopn,' loops through the data files'
1338 ENDIF
1339 IF (mnrsit > 0) THEN
1340 WRITE(8,*) ' '
1341 WRITE(8,*) 'In total ',mnrsit,' internal MINRES iterations'
1342 END IF
1343
1344 WRITE(8,103) times(0),times(1),times(2),times(4),times(7), &
1345 times(5),times(8),times(3),times(6)
1346
1347 rst=etime(ta)
1348 deltat=rst-rstp
1349 ntsec=nint(deltat,mpi)
1350 CALL sechms(deltat,nhour,minut,secnd)
1351 nsecnd=nint(secnd,mpi) ! round
1352 WRITE(8,*) 'Total time =',ntsec,' seconds =',nhour,' h',minut, &
1353 ' m',nsecnd,' seconds'
1354 CALL fdate(chdate)
1355 WRITE(8,*) 'end ', chdate
1356 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1357 WRITE(8,*) ' '
1358 WRITE(8,105) gbu
1359
1360 ! Rejects ----------------------------------------------------------
1361
1362 IF(sum(nrejec) /= 0) THEN
1363 WRITE(8,*) ' '
1364 WRITE(8,*) 'Data records rejected in last iteration: '
1365 CALL prtrej(8)
1366 WRITE(8,*) ' '
1367 END IF
1368 IF (icheck <= 0) CALL explfc(8)
1369
1370 WRITE(*,*) ' '
1371 WRITE(*,*) ' < Millepede II-P ending ... ', chdate ! with exit code',ITEXIT,' >'
1372 WRITE(*,*) ' '
1373 gbu=1.0e-9*real(maxwordsalloc*(bit_size(1_mpi)/8),mps) ! GB used
1374 WRITE(*,105) gbu
1375#ifdef LAPACK64
1376#ifdef PARDISO
1377 IF(ipdmem > 0) WRITE(*,106) real(ipdmem,mps)*1.e-6
1378106 FORMAT(' PARDISO dyn. memory allocation: ',f11.6,' GB')
1379#endif
1380#endif
1381 WRITE(*,*) ' '
1382 ! close files
1383 CLOSE(unit=7) ! histogram file
1384 CLOSE(unit=8) ! log file
1385
1386 ! post processing?
1387 IF (lenpostproc > 0) THEN
1388 WRITE(*,*) 'Postprocessing:'
1389 IF (lenpostproc >= 80) THEN
1390 WRITE(*,*) cpostproc(1:38) // ' .. ' // cpostproc(lenpostproc-37:lenpostproc)
1391 ELSE
1392 WRITE(*,*) cpostproc(1:lenpostproc)
1393 ENDIF
1394 WRITE(*,*) ' '
1395 CALL system(cpostproc(1:lenpostproc))
1396 END IF
1397
1398102 FORMAT(2x,i4,i10,2x,3f10.5)
1399103 FORMAT(' Times [in sec] for text processing',f12.3/ &
1400 ' LOOP1',f12.3/ &
1401 ' LOOP2',f12.3/ &
1402 ' func. value ',f12.3,' *',f4.0/ &
1403 ' func. value, global matrix, solution',f12.3,' *',f4.0/ &
1404 ' new solution',f12.3,' *',f4.0/)
1405105 FORMAT(' Peak dynamic memory allocation: ',f11.6,' GB')
1406END PROGRAM mptwo ! Mille
1407
1414
1415SUBROUTINE solglo(ivgbi)
1416 USE mpmod
1417 USE minresmodule, ONLY: minres
1418
1419 IMPLICIT NONE
1420 REAL(mps) :: par
1421 REAL(mps) :: dpa
1422 REAL(mps) :: err
1423 REAL(mps) :: gcor2
1424 INTEGER(mpi) :: iph
1425 INTEGER(mpi) :: istop
1426 INTEGER(mpi) :: itgbi
1427 INTEGER(mpi) :: itgbl
1428 INTEGER(mpi) :: itn
1429 INTEGER(mpi) :: itnlim
1430 INTEGER(mpi) :: nout
1431
1432 INTEGER(mpi), INTENT(IN) :: ivgbi
1433
1434 REAL(mpd) :: shift
1435 REAL(mpd) :: rtol
1436 REAL(mpd) :: anorm
1437 REAL(mpd) :: acond
1438 REAL(mpd) :: arnorm
1439 REAL(mpd) :: rnorm
1440 REAL(mpd) :: ynorm
1441 REAL(mpd) :: gmati
1442 REAL(mpd) :: diag
1443 REAL(mpd) :: matij
1444 LOGICAL :: checka
1445 EXTERNAL avprod, mcsolv, mvsolv
1446 SAVE
1447 DATA iph/0/
1448 ! ...
1449 IF(iph == 0) THEN
1450 iph=1
1451 WRITE(*,101)
1452 END IF
1453 itgbi=globalparvartototal(ivgbi)
1454 itgbl=globalparlabelindex(1,itgbi)
1455
1456 globalvector=0.0_mpd ! reset rhs vector IGVEC
1457 globalvector(ivgbi)=1.0_mpd
1458
1459 ! NOUT =6
1460 nout =0
1461 itnlim=200
1462 shift =0.0_mpd
1463 rtol = mrestl ! from steering
1464 checka=.false.
1465
1466
1467 IF(mbandw == 0) THEN ! default preconditioner
1468 CALL minres(nagb, avprod, mcsolv, globalvector, shift, checka ,.true. , &
1469 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1470
1471 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1472 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.true. , &
1473 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1474 ELSE
1475 CALL minres(nagb, avprod, mvsolv, globalvector, shift, checka ,.false. , &
1476 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
1477 END IF
1478
1479 par=real(globalparameter(itgbi),mps)
1480 dpa=real(par-globalparstart(itgbi),mps)
1481 gmati=globalcorrections(ivgbi)
1482 err=sqrt(abs(real(gmati,mps)))
1483 IF(gmati < 0.0_mpd) err=-err
1484 diag=matij(ivgbi,ivgbi)
1485 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1486 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1487101 FORMAT(1x,' label parameter presigma differ', &
1488 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1489102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1490END SUBROUTINE solglo
1491
1498
1499SUBROUTINE solgloqlp(ivgbi)
1500 USE mpmod
1501 USE minresqlpmodule, ONLY: minresqlp
1502
1503 IMPLICIT NONE
1504 REAL(mps) :: par
1505 REAL(mps) :: dpa
1506 REAL(mps) :: err
1507 REAL(mps) :: gcor2
1508 INTEGER(mpi) :: iph
1509 INTEGER(mpi) :: istop
1510 INTEGER(mpi) :: itgbi
1511 INTEGER(mpi) :: itgbl
1512 INTEGER(mpi) :: itn
1513 INTEGER(mpi) :: itnlim
1514 INTEGER(mpi) :: nout
1515
1516 INTEGER(mpi), INTENT(IN) :: ivgbi
1517
1518 REAL(mpd) :: shift
1519 REAL(mpd) :: rtol
1520 REAL(mpd) :: mxxnrm
1521 REAL(mpd) :: trcond
1522 REAL(mpd) :: gmati
1523 REAL(mpd) :: diag
1524 REAL(mpd) :: matij
1525
1526 EXTERNAL avprod, mcsolv, mvsolv
1527 SAVE
1528 DATA iph/0/
1529 ! ...
1530 IF(iph == 0) THEN
1531 iph=1
1532 WRITE(*,101)
1533 END IF
1534 itgbi=globalparvartototal(ivgbi)
1535 itgbl=globalparlabelindex(1,itgbi)
1536
1537 globalvector=0.0_mpd ! reset rhs vector IGVEC
1538 globalvector(ivgbi)=1.0_mpd
1539
1540 ! NOUT =6
1541 nout =0
1542 itnlim=200
1543 shift =0.0_mpd
1544 rtol = mrestl ! from steering
1545 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
1546 IF(mrmode == 1) THEN
1547 trcond = 1.0_mpd/epsilon(trcond) ! only QR
1548 ELSE IF(mrmode == 2) THEN
1549 trcond = 1.0_mpd ! only QLP
1550 ELSE
1551 trcond = mrtcnd ! QR followed by QLP
1552 END IF
1553
1554 IF(mbandw == 0) THEN ! default preconditioner
1555 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mcsolv, nout=nout, &
1556 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1557 x=globalcorrections, istop=istop, itn=itn)
1558 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
1559 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, msolve=mvsolv, nout=nout, &
1560 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1561 x=globalcorrections, istop=istop, itn=itn)
1562 ELSE
1563 CALL minresqlp( n=nagb, aprod=avprod, b=globalvector, nout=nout, &
1564 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
1565 x=globalcorrections, istop=istop, itn=itn)
1566 END IF
1567
1568 par=real(globalparameter(itgbi),mps)
1569 dpa=real(par-globalparstart(itgbi),mps)
1570 gmati=globalcorrections(ivgbi)
1571 err=sqrt(abs(real(gmati,mps)))
1572 IF(gmati < 0.0_mpd) err=-err
1573 diag=matij(ivgbi,ivgbi)
1574 gcor2=real(1.0_mpd-1.0_mpd/(gmati*diag),mps) ! global correlation (squared)
1575 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor2,itn
1576101 FORMAT(1x,' label parameter presigma differ', &
1577 ' Error gcor^2 iit'/ 1x,'---------',2x,5('-----------'),2x,'----')
1578102 FORMAT(i10,2x,4g12.4,f7.4,i6,i4)
1579END SUBROUTINE solgloqlp
1580
1582SUBROUTINE addcst
1583 USE mpmod
1584
1585 IMPLICIT NONE
1586 REAL(mpd) :: climit
1587 REAL(mpd) :: factr
1588 REAL(mpd) :: sgm
1589
1590 INTEGER(mpi) :: i
1591 INTEGER(mpi) :: icgb
1592 INTEGER(mpi) :: irhs
1593 INTEGER(mpi) :: itgbi
1594 INTEGER(mpi) :: ivgb
1595 INTEGER(mpi) :: j
1596 INTEGER(mpi) :: jcgb
1597 INTEGER(mpi) :: l
1598 INTEGER(mpi) :: label
1599 INTEGER(mpi) :: nop
1600 INTEGER(mpi) :: inone
1601
1602 REAL(mpd) :: rhs
1603 REAL(mpd) :: drhs(4)
1604 INTEGER(mpi) :: idrh (4)
1605 SAVE
1606 ! ...
1607 nop=0
1608 IF(lenconstraints == 0) RETURN ! no constraints
1609 climit=1.0e-5 ! limit for printout
1610 irhs=0 ! number of values in DRHS(.), to be printed
1611
1612 DO jcgb=1,ncgb
1613 icgb=matconssort(3,jcgb) ! unsorted constraint index
1614 i=vecconsstart(icgb)
1615 rhs=listconstraints(i )%value ! right hand side
1616 sgm=listconstraints(i+1)%value ! sigma parameter
1617 DO j=i+2,vecconsstart(icgb+1)-1
1618 label=listconstraints(j)%label
1619 factr=listconstraints(j)%value
1620 itgbi=inone(label) ! -> ITGBI= index of parameter label
1621 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
1622
1623 IF(icalcm == 1.AND.nagb > nvgb.AND.ivgb > 0) THEN
1624 CALL mupdat(nvgb+jcgb,ivgb,factr) ! add to matrix
1625 END IF
1626
1627 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
1628 END DO
1629 IF(abs(rhs) > climit) THEN
1630 irhs=irhs+1
1631 idrh(irhs)=jcgb
1632 drhs(irhs)=rhs
1633 nop=1
1634 IF(irhs == 4) THEN
1635 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1636 irhs=0
1637 END IF
1638 END IF
1639 vecconsresiduals(jcgb)=rhs
1640 IF (nagb > nvgb) globalvector(nvgb+jcgb)=rhs
1641 END DO
1642
1643 IF(irhs /= 0) THEN
1644 WRITE(*,101) (idrh(l),drhs(l),l=1,irhs)
1645 END IF
1646 IF(nop == 0) RETURN
1647 WRITE(*,102) ' Constraints: only equation values >', climit,' are printed'
1648101 FORMAT(' ',4(i6,g11.3))
1649102 FORMAT(a,g11.2,a)
1650END SUBROUTINE addcst
1651
1656SUBROUTINE grpcon
1657 USE mpmod
1658 USE mpdalc
1659
1660 IMPLICIT NONE
1661 INTEGER(mpi) :: i
1662 INTEGER(mpi) :: icgb
1663 INTEGER(mpi) :: icgrp
1664 INTEGER(mpi) :: ioff
1665 INTEGER(mpi) :: itgbi
1666 INTEGER(mpi) :: j
1667 INTEGER(mpi) :: jcgb
1668 INTEGER(mpi) :: label
1669 INTEGER(mpi) :: labelf
1670 INTEGER(mpi) :: labell
1671 INTEGER(mpi) :: last
1672 INTEGER(mpi) :: line1
1673 INTEGER(mpi) :: ncon
1674 INTEGER(mpi) :: ndiff
1675 INTEGER(mpi) :: npar
1676 INTEGER(mpi) :: inone
1677 INTEGER(mpi) :: itype
1678 INTEGER(mpi) :: ncgbd
1679 INTEGER(mpi) :: ncgbr
1680 INTEGER(mpi) :: ncgbw
1681 INTEGER(mpi) :: ncgrpd
1682 INTEGER(mpi) :: ncgrpr
1683 INTEGER(mpi) :: next
1684
1685 INTEGER(mpl):: length
1686 INTEGER(mpl) :: rows
1687
1688 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsOffsets
1689 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecParConsList
1690 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParOffsets
1691 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsParList
1692 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1693
1694 ncgb=0
1695 ncgbw=0
1696 IF(lenconstraints == 0) RETURN ! no constraints
1697
1698 i=0
1699 last=0
1700 itype=0
1701 ! find next constraint header and count nr of constraints
1702 DO WHILE(i < lenconstraints)
1703 i=i+1
1704 label=listconstraints(i)%label
1705 IF(last < 0.AND.label < 0) THEN
1706 ncgb=ncgb+1
1707 itype=-label
1708 IF(itype == 2) ncgbw=ncgbw+1
1709 END IF
1710 last=label
1711 IF(label > 0) THEN
1712 itgbi=inone(label) ! -> ITGBI= index of parameter label
1713 globalparcons(itgbi)=globalparcons(itgbi)+1
1714 END IF
1715 IF(label > 0.AND.itype == 2) THEN ! weighted constraints
1716 itgbi=inone(label) ! -> ITGBI= index of parameter label
1718 END IF
1719 END DO
1720
1721 WRITE(*,*)
1722 IF (ncgbw == 0) THEN
1723 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files'
1724 ELSE
1725 WRITE(*,*) 'GRPCON:',ncgb,' constraints found in steering files,',ncgbw, 'weighted'
1726 END IF
1727 WRITE(*,*)
1728
1729 ! keys and index for sorting of constraints
1730 length=ncgb+1; rows=3
1731 CALL mpalloc(matconssort,rows,length,'keys and index for sorting (I)')
1732 matconssort(1,ncgb+1)=ntgb+1
1733 ! start of constraint in list
1734 CALL mpalloc(vecconsstart,length,'start of constraint in list (I)')
1736 ! start and parameter range of constraint groups
1737 CALL mpalloc(matconsgroups,rows,length,'start of constraint groups, par. range (I)')
1738 ! parameter ranges (all, variable) of constraints
1739 length=ncgb; rows=4
1740 CALL mpalloc(matconsranges,rows,length,'parameter ranges for constraint (I)')
1741
1742 length=ncgb; rows=3
1743 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
1744 matconsgroupindex=0
1745 length=ncgb+1
1746 CALL mpalloc(vecconsparoffsets,length,'offsets for global par list for cons. (I)')
1747 length=ntgb+1
1748 CALL mpalloc(vecparconsoffsets,length,'offsets for cons. list for global par. (I)')
1749 vecparconsoffsets(1)=0
1750 DO i=1,ntgb
1751 vecparconsoffsets(i+1)=vecparconsoffsets(i)+globalparcons(i)
1752 END DO
1754
1755 length=vecparconsoffsets(ntgb+1)
1756 CALL mpalloc(vecconsparlist,length,'global par. list for constraint (I)')
1757 CALL mpalloc(vecparconslist,length,'constraint list for global par. (I)')
1758
1759 ! prepare
1760 i=1
1761 ioff=0
1762 vecconsparoffsets(1)=ioff
1763 DO icgb=1,ncgb
1764 ! new constraint
1765 vecconsstart(icgb)=i
1766 line1=-listconstraints(i)%label
1767 npar=0
1768 i=i+2
1769 DO
1770 label=listconstraints(i)%label
1771 itgbi=inone(label) ! -> ITGBI= index of parameter label
1772 ! list of constraints for 'itgbi'
1773 globalparcons(itgbi)=globalparcons(itgbi)+1
1774 vecparconslist(vecparconsoffsets(itgbi)+globalparcons(itgbi))=icgb
1775 npar=npar+1
1776 vecconsparlist(ioff+npar)=itgbi
1777 i=i+1
1778 IF(i > lenconstraints) EXIT
1779 IF(listconstraints(i)%label < 0) EXIT
1780 END DO
1781 ! sort to find duplicates
1782 CALL sort1k(vecconsparlist(ioff+1),npar)
1783 last=-1
1784 ndiff=0
1785 DO j=1,npar
1786 next=vecconsparlist(ioff+j)
1787 IF (next /= last) THEN
1788 ndiff=ndiff+1
1789 vecconsparlist(ioff+ndiff) = next
1790 END IF
1791 last=next
1792 END DO
1793 matconsranges(1,icgb)=vecconsparlist(ioff+1) ! min parameter
1794 matconsranges(3,icgb)=vecconsparlist(ioff+1) ! min parameter
1795 ioff=ioff+ndiff
1796 matconsranges(2,icgb)=vecconsparlist(ioff) ! max parameter
1797 matconsranges(4,icgb)=vecconsparlist(ioff) ! max parameter
1798 vecconsparoffsets(icgb+1)=ioff
1799 END DO
1801
1802 ! sort (by first, last parameter)
1803 DO icgb=1,ncgb
1804 matconssort(1,icgb)=matconsranges(1,icgb) ! first par.
1805 matconssort(2,icgb)=matconsranges(2,icgb) ! last par.
1806 matconssort(3,icgb)=icgb ! index
1807 END DO
1808 CALL sort2i(matconssort,ncgb)
1809
1810 IF (icheck>1) THEN
1811 print *, ' Constraint #parameters first par. last par. first line'
1812 END IF
1813 ! split into disjoint groups
1814 ncgrp=0
1816 DO jcgb=1,ncgb
1817 icgb=matconssort(3,jcgb)
1818 IF (icheck>0) THEN
1819 npar=vecconsparoffsets(icgb+1)-vecconsparoffsets(icgb)
1820 line1=-listconstraints(vecconsstart(icgb))%label
1821 labelf=globalparlabelindex(1,matconsranges(1,icgb))
1822 labell=globalparlabelindex(1,matconsranges(2,icgb))
1823 print *, jcgb, npar, labelf, labell, line1
1824 END IF
1825 ! already part of group?
1826 icgrp=matconsgroupindex(1,icgb)
1827 IF (icgrp == 0) THEN
1828 ! check all parameters
1829 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1830 itgbi=vecconsparlist(i)
1831 ! check all related constraints
1832 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1833 icgrp=matconsgroupindex(1,vecparconslist(j))
1834 ! already part of group?
1835 IF (icgrp > 0) EXIT
1836 END DO
1837 IF (icgrp > 0) EXIT
1838 END DO
1839 IF (icgrp == 0) THEN
1840 ! new group
1841 ncgrp=ncgrp+1
1842 icgrp=ncgrp
1843 END IF
1844 END IF
1845 ! add to group
1846 matconsgroupindex(2,icgb)=jcgb
1847 matconsgroupindex(3,icgb)=icgb
1848 DO i=vecconsparoffsets(icgb)+1, vecconsparoffsets(icgb+1)
1849 itgbi=vecconsparlist(i)
1850 globalparcons(itgbi)=icgrp
1851 ! mark all related constraints
1852 DO j=vecparconsoffsets(itgbi)+1,vecparconsoffsets(itgbi+1)
1853 matconsgroupindex(1,vecparconslist(j))=icgrp
1854 END DO
1855 END DO
1856 END DO
1857 WRITE(*,*) 'GRPCON:',ncgrp,' disjoint constraints groups built'
1858
1859 ! sort by group number
1860 CALL sort2i(matconsgroupindex,ncgb)
1861
1862 matconsgroups(1,1:ncgrp)=0
1863 DO jcgb=1,ncgb
1864 ! set up matConsSort
1865 icgb=matconsgroupindex(3,jcgb)
1866 matconssort(1,jcgb)=matconsranges(1,icgb)
1867 matconssort(2,jcgb)=matconsranges(2,icgb)
1868 matconssort(3,jcgb)=icgb
1869 ! set up matConsGroups
1870 icgrp=matconsgroupindex(1,jcgb)
1871 IF (matconsgroups(1,icgrp) == 0) THEN
1872 matconsgroups(1,icgrp)=jcgb
1873 matconsgroups(2,icgrp)=matconsranges(1,icgb)
1874 matconsgroups(3,icgrp)=matconsranges(2,icgb)
1875 ELSE
1876 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
1877 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
1878 END IF
1879 END DO
1880 matconsgroups(1,ncgrp+1)=ncgb+1
1881 matconsgroups(2,ncgrp+1)=ntgb+1
1882
1883 ! check for redundancy constraint groups
1884 ncgbr=0
1885 ncgrpr=0
1886 ncgbd=0
1887 ncgrpd=0
1888 IF (icheck>0) THEN
1889 print *
1890 print *, ' cons.group first con. first par. last par. #cons #par'
1891 ENDIF
1892 DO icgrp=1,ncgrp
1893 npar=0
1894 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1895 IF (globalparcons(i) == icgrp) npar=npar+1
1896 END DO
1897 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
1898 IF (icheck>0) THEN
1899 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1900 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1901 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ncon, npar
1902 END IF
1903 ! redundancy constraints?
1904 IF (ncon == npar) THEN
1905 IF (irslvrc > 0) THEN
1906 ncgrpr=ncgrpr+1
1907 ncgbr=ncgbr+ncon
1908 IF (icheck > 0) THEN
1909 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1910 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1911 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group resolved'
1912 END IF
1913 ! flag redundant parameters
1914 DO i=matconsgroups(2,icgrp),matconsgroups(3,icgrp)
1915 IF (globalparcons(i) == icgrp) globalparcons(i)=-icgrp
1916 END DO
1917 ! flag constraint group
1918 matconsgroups(2,icgrp)=ntgb+1
1919 matconsgroups(3,icgrp)=ntgb
1920 ELSE
1921 ncgrpd=ncgrpd+1
1922 ncgbd=ncgbd+ncon
1923 IF (icheck > 0) THEN
1924 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
1925 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
1926 print *, icgrp, matconsgroups(1,icgrp), labelf, labell, ' : cons.group redundant'
1927 END IF
1928 END IF
1929 END IF
1930 END DO
1931 IF (ncgrpr > 0) THEN
1932 WRITE(*,*) 'GRPCON:',ncgbr,' redundancy constraints in ', ncgrpr, ' groups resolved'
1933 ! all constraint groups resolved ?
1934 IF (ncgrpr == ncgrp) ncgrp=0
1935 ENDIF
1936 IF (ncgrpd > 0) THEN
1937 WRITE(*,*) 'GRPCON:',ncgbd,' redundancy constraints in ', ncgrpd, ' groups detected'
1938 ENDIF
1939 WRITE(*,*)
1940
1941 ! clean up
1942 CALL mpdealloc(vecparconslist)
1943 CALL mpdealloc(vecconsparlist)
1944 CALL mpdealloc(vecparconsoffsets)
1945 CALL mpdealloc(vecconsparoffsets)
1946 CALL mpdealloc(matconsgroupindex)
1947
1948END SUBROUTINE grpcon
1949
1953
1954SUBROUTINE prpcon
1955 USE mpmod
1956 USE mpdalc
1957
1958 IMPLICIT NONE
1959 INTEGER(mpi) :: i
1960 INTEGER(mpi) :: icgb
1961 INTEGER(mpi) :: icgrp
1962 INTEGER(mpi) :: ifrst
1963 INTEGER(mpi) :: ilast
1964 INTEGER(mpi) :: isblck
1965 INTEGER(mpi) :: itgbi
1966 INTEGER(mpi) :: ivgb
1967 INTEGER(mpi) :: j
1968 INTEGER(mpi) :: jcgb
1969 INTEGER(mpi) :: jfrst
1970 INTEGER(mpi) :: label
1971 INTEGER(mpi) :: labelf
1972 INTEGER(mpi) :: labell
1973 INTEGER(mpi) :: ncon
1974 INTEGER(mpi) :: ngrp
1975 INTEGER(mpi) :: npar
1976 INTEGER(mpi) :: ncnmxb
1977 INTEGER(mpi) :: ncnmxg
1978 INTEGER(mpi) :: nprmxb
1979 INTEGER(mpi) :: nprmxg
1980 INTEGER(mpi) :: inone
1981 INTEGER(mpi) :: nvar
1982
1983 INTEGER(mpl):: length
1984 INTEGER(mpl) :: rows
1985
1986 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: matConsGroupIndex
1987
1988 ncgbe=0
1989 !
1990 ! constraint groups already built in GRPCON based on steering,
1991 ! now care about fixed parameters
1992 !
1993 IF(ncgrp == 0) THEN ! no constraints groups
1994 ncgb=0
1995 ncblck=0
1996 RETURN
1997 END IF
1998
1999 length=ncgrp+1; rows=3
2000 ! start and parameter range of constraint blocks
2001 CALL mpalloc(matconsblocks,rows,length,'start of constraint blocks, par. range (I)')
2002
2003 length=ncgb; rows=3
2004 CALL mpalloc(matconsgroupindex,rows,length,'group index for constraint (I)')
2005 matconsgroupindex=0
2006
2007 ! check for empty constraints, redefine (accepted/active) constraints and groups
2008 ngrp=0
2009 ncgb=0
2010 DO icgrp=1,ncgrp
2011 ncon=ncgb
2012 ! resolved group ?
2013 IF (matconsgroups(2,icgrp) > matconsgroups(3,icgrp)) cycle
2014 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2015 icgb=matconssort(3,jcgb)
2016 i=vecconsstart(icgb)+2
2017 npar=0
2018 nvar=0
2019 matconsranges(1,icgb)=ntgb
2020 matconsranges(2,icgb)=1
2021 DO
2022 label=listconstraints(i)%label
2023 itgbi=inone(label) ! -> ITGBI= index of parameter label
2024 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2025 npar=npar+1
2026 IF(ivgb > 0) THEN
2027 nvar=nvar+1
2028 matconsranges(1,icgb)=min(matconsranges(1,icgb),itgbi)
2029 matconsranges(2,icgb)=max(matconsranges(2,icgb),itgbi)
2030 ENDIF
2031 i=i+1
2032 IF(i > lenconstraints) EXIT
2033 IF(listconstraints(i)%label < 0) EXIT
2034 END DO
2035 IF (nvar == 0) THEN
2036 ncgbe=ncgbe+1
2037 ! reset range
2038 matconsranges(1,icgb)=matconsranges(3,icgb)
2039 matconsranges(2,icgb)=matconsranges(4,icgb)
2040 END IF
2041 IF (nvar > 0 .OR. iskpec == 0) THEN
2042 ! constraint accepted (or kept)
2043 ncgb=ncgb+1
2044 matconsgroupindex(1,ncgb)=ngrp+1
2045 matconsgroupindex(2,ncgb)=icgb
2046 matconsgroupindex(3,ncgb)=nvar
2047 END IF
2048 END DO
2049 IF (ncgb > ncon) ngrp=ngrp+1
2050 END DO
2051 ncgrp=ngrp
2052
2053 IF (ncgbe > 0) THEN
2054 IF (iskpec > 0) THEN
2055 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints skipped'
2056 ELSE
2057 WRITE(*,*) 'PRPCON:',ncgbe,' empty constraints detected, to be fixed !!!'
2058 WRITE(*,*) ' (use option "skipemptycons" to skip those)'
2059 IF (icheck == 0) THEN
2060 icheck=2 ! switch to '-C'
2061 ncgbe=-ncgbe ! indicate that
2062 WRITE(*,*)
2063 WRITE(*,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2064 WRITE(8,*) '!!! Switch to "-C" (checking input only), no calculation of a solution !!!'
2065 WRITE(*,*)
2066 END IF
2067 END IF
2068 END IF
2069 WRITE(*,*) 'PRPCON:',ncgb,' constraints accepted'
2070 WRITE(*,*)
2071
2072 IF(ncgb == 0) RETURN ! no constraints left
2073
2074 ! already sorted by group number
2075
2076 matconsgroups(1,1:ncgrp)=0
2077 DO jcgb=1,ncgb
2078 ! set up matConsSort
2079 icgb=matconsgroupindex(2,jcgb)
2080 matconssort(1,jcgb)=matconsranges(1,icgb)
2081 matconssort(2,jcgb)=matconsranges(2,icgb)
2082 matconssort(3,jcgb)=icgb
2083 ! set up matConsGroups
2084 icgrp=matconsgroupindex(1,jcgb)
2085 IF (matconsgroups(1,icgrp) == 0) THEN
2086 matconsgroups(1,icgrp)=jcgb
2087 matconsgroups(2,icgrp)=matconsranges(1,icgb)
2088 matconsgroups(3,icgrp)=matconsranges(2,icgb)
2089 ELSE
2090 matconsgroups(2,icgrp)=min(matconsgroups(2,icgrp),matconsranges(1,icgb))
2091 matconsgroups(3,icgrp)=max(matconsgroups(3,icgrp),matconsranges(2,icgb))
2092 END IF
2093 END DO
2094 matconsgroups(1,ncgrp+1)=ncgb+1
2095 matconsgroups(2,ncgrp+1)=ntgb+1
2096
2097 ! loop over constraints groups, combine into non overlapping blocks
2098 ncblck=0
2099 ncnmxg=0
2100 nprmxg=0
2101 ncnmxb=0
2102 nprmxb=0
2103 mszcon=0
2104 mszprd=0
2105 isblck=1
2106 ilast=0
2107 IF (icheck > 0) THEN
2108 WRITE(*,*)
2109 IF (icheck > 1) &
2110 WRITE(*,*) ' Cons. sorted index #var.par. first line first label last label'
2111 WRITE(*,*) ' Cons. group index first cons. last cons. first label last label'
2112 WRITE(*,*) ' Cons. block index first group last group first label last label'
2113 END IF
2114 DO icgrp=1,ncgrp
2115 IF (icheck > 1) THEN
2116 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2117 icgb=matconssort(3,jcgb)
2118 nvar=matconsgroupindex(3,jcgb)
2119 labelf=globalparlabelindex(1,matconssort(1,jcgb))
2120 labell=globalparlabelindex(1,matconssort(2,jcgb))
2121 IF (nvar > 0) THEN
2122 WRITE(*,*) ' Cons. sorted', jcgb, nvar, &
2123 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2124 ELSE
2125 WRITE(*,*) ' Cons. sorted', jcgb, ' empty (0)', &
2126 -listconstraints(vecconsstart(icgb))%label, labelf, labell
2127 END IF
2128 END DO
2129 END IF
2130 IF (icheck > 0) THEN
2131 !ivgb=globalParLabelIndex(2,matConsGroups(2,icgrp)) ! -> index of variable global parameter
2132 labelf=globalparlabelindex(1,matconsgroups(2,icgrp))
2133 labell=globalparlabelindex(1,matconsgroups(3,icgrp))
2134 WRITE(*,*) ' Cons. group ', icgrp, matconsgroups(1,icgrp), &
2135 matconsgroups(1,icgrp+1)-1, labelf, labell
2136 ENDIF
2137 ! combine into non overlapping blocks
2138 ilast=max(ilast, matconsgroups(3,icgrp))
2139 IF (matconsgroups(2,icgrp+1) > ilast) THEN
2140 ncblck=ncblck+1
2141 ifrst=matconsgroups(2,isblck)
2143 matconsblocks(2,ncblck)=ifrst ! save first parameter in block
2144 matconsblocks(3,ncblck)=ilast ! save last parameter in block
2145 ! update matConsSort
2146 jfrst=matconsgroups(2,icgrp)
2147 DO i=icgrp,isblck,-1
2148 DO j=matconsgroups(1,i),matconsgroups(1,i+1)-1
2149 ! non zero range (from group)
2150 matconsranges(1,j)=matconsgroups(2,i)
2152 ! storage range (from max group, ilast)
2153 jfrst=min(jfrst,matconsgroups(2,i))
2154 matconsranges(3,j)=jfrst
2155 matconsranges(4,j)=ilast
2156 END DO
2157 END DO
2158 IF (icheck > 0) THEN
2159 labelf=globalparlabelindex(1,ifrst)
2160 labell=globalparlabelindex(1,ilast)
2161 WRITE(*,*) ' Cons. block ', ncblck, isblck, icgrp, labelf, labell
2162 ENDIF
2163 ! reset for new block
2164 isblck=icgrp+1
2165 END IF
2166 END DO
2168
2169 ! convert from total parameter index to index of variable global parameter
2170 DO i=1,ncblck
2171 ifrst=globalparlabelindex(2,matconsblocks(2,i)) ! -> index of variable global parameter
2172 ilast=globalparlabelindex(2,matconsblocks(3,i)) ! -> index of variable global parameter
2173 IF (ifrst > 0) THEN
2174 matconsblocks(2,i)=ifrst
2175 matconsblocks(3,i)=ilast
2176 ! statistics
2177 ncon=matconsblocks(1,i+1)-matconsblocks(1,i)
2178 npar=ilast+1-ifrst
2179 ncnmxb=max(ncnmxb,ncon)
2180 nprmxb=max(nprmxb,npar)
2181 ! update index ranges
2182 globalindexranges(ifrst)=max(globalindexranges(ifrst),ilast)
2183 ELSE
2184 ! empty
2185 matconsblocks(2,i)=1
2186 matconsblocks(3,i)=0
2187 END IF
2188 END DO
2189 DO icgrp=1,ncgrp
2190 ifrst=globalparlabelindex(2,matconsgroups(2,icgrp)) ! -> index of variable global parameter
2191 ilast=globalparlabelindex(2,matconsgroups(3,icgrp)) ! -> index of variable global parameter
2192 IF (ifrst > 0) THEN
2193 matconsgroups(2,icgrp)=ifrst
2194 matconsgroups(3,icgrp)=ilast
2195 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2196 DO i=1,4
2197 ivgb=globalparlabelindex(2,matconsranges(i,jcgb)) ! -> index of variable global parameter
2198 matconsranges(i,jcgb)=ivgb
2199 END DO
2200 END DO
2201 ! storage sizes, statistics
2202 jcgb=matconsgroups(1,icgrp) ! first cons.
2203 ncon=matconsgroups(1,icgrp+1)-jcgb
2204 npar=matconsranges(4,jcgb)+1-matconsranges(3,jcgb)
2205 ncnmxg=max(ncnmxg,ncon)
2206 nprmxg=max(nprmxg,npar)
2207 mszcon=mszcon+int(ncon,mpl)*int(npar,mpl) ! (sum of) block size for constraint matrix
2208 mszprd=mszprd+int(ncon,mpl)*int(ncon+1,mpl)/2 ! (sum of) block size for product matrix
2209 ELSE
2210 ! empty
2211 matconsgroups(2,icgrp)=1
2212 matconsgroups(3,icgrp)=0
2213 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2214 matconsranges(1,jcgb)=1
2215 matconsranges(2,jcgb)=0
2216 matconsranges(3,jcgb)=1
2217 matconsranges(4,jcgb)=0
2218 END DO
2219 END IF
2220 END DO
2221
2222 ! clean up
2223 CALL mpdealloc(matconsgroupindex)
2224
2225 ! save constraint group for global parameters
2227 DO icgrp=1,ncgrp
2228 DO jcgb=matconsgroups(1,icgrp),matconsgroups(1,icgrp+1)-1
2229 ! index in list
2230 icgb=matconssort(3,jcgb)
2231 DO j=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
2232 label=listconstraints(j)%label
2233 itgbi=inone(label) ! -> ITGBI= index of parameter label
2234 globalparcons(itgbi)=icgrp ! save constraint group
2235 END DO
2236 END DO
2237 END DO
2238
2239 IF (ncgrp+icheck > 1) THEN
2240 WRITE(*,*)
2241 WRITE(*,*) 'PRPCON: constraints split into ', ncgrp, '(disjoint) groups,'
2242 WRITE(*,*) ' groups combined into ', ncblck, '(non overlapping) blocks'
2243 WRITE(*,*) ' max group size (cons., par.) ', ncnmxg, nprmxg
2244 WRITE(*,*) ' max block size (cons., par.) ', ncnmxb, nprmxb
2245 IF (icheck > 0) WRITE(*,*) ' total block matrix sizes ', mszcon, mszprd
2246 END IF
2247
2248END SUBROUTINE prpcon
2249
2253
2254SUBROUTINE feasma
2255 USE mpmod
2256 USE mpdalc
2257
2258 IMPLICIT NONE
2259 REAL(mpd) :: factr
2260 REAL(mpd) :: sgm
2261 INTEGER(mpi) :: i
2262 INTEGER(mpi) :: icgb
2263 INTEGER(mpi) :: icgrp
2264 INTEGER(mpl) :: ij
2265 INTEGER(mpi) :: ifirst
2266 INTEGER(mpi) :: ilast
2267 INTEGER(mpl) :: ioffc
2268 INTEGER(mpl) :: ioffp
2269 INTEGER(mpi) :: irank
2270 INTEGER(mpi) :: ipar0
2271 INTEGER(mpi) :: itgbi
2272 INTEGER(mpi) :: ivgb
2273 INTEGER(mpi) :: j
2274 INTEGER(mpi) :: jcgb
2275 INTEGER(mpl) :: ll
2276 INTEGER(mpi) :: label
2277 INTEGER(mpi) :: ncon
2278 INTEGER(mpi) :: npar
2279 INTEGER(mpi) :: nrank
2280 INTEGER(mpi) :: inone
2281
2282 REAL(mpd):: rhs
2283 REAL(mpd):: evmax
2284 REAL(mpd):: evmin
2285 INTEGER(mpl):: length
2286 REAL(mpd), DIMENSION(:), ALLOCATABLE :: matConstraintsT
2287 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
2288 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
2289 SAVE
2290 ! ...
2291
2292 IF(ncgb == 0) RETURN ! no constraints
2293
2294 ! product matrix A A^T (A is stored as transposed)
2295 length=mszprd
2296 CALL mpalloc(matconsproduct, length, 'product matrix of constraints (blocks)')
2297 matconsproduct=0.0_mpd
2298 length=ncgb
2299 CALL mpalloc(vecconsresiduals, length, 'residuals of constraints')
2300 CALL mpalloc(vecconssolution, length, 'solution for constraints')
2301 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
2302 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
2303 ! constraint matrix A (A is stored as transposed)
2304 length = mszcon
2305 CALL mpalloc(matconstraintst,length,'transposed matrix of constraints (blocks)')
2306 matconstraintst=0.0_mpd
2307
2308 ! loop over sorted constraints, fill matrices, get rank, inverted product matrix (in groups)
2309 ioffc=0 ! group offset in constraint matrix
2310 ioffp=0 ! group offset in product matrix
2311 nrank=0
2312 DO icgrp=1,ncgrp
2313 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2314 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2315 ncon=ilast+1-ifirst
2316 ipar0=matconsranges(3,ifirst)-1 ! parameter offset
2317 npar=matconsranges(4,ifirst)-ipar0 ! number of parameters
2318 IF (npar <= 0) THEN
2319 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, 0, ' (empty)'
2320 cycle ! skip empty groups/cons.
2321 END IF
2322 DO jcgb=ifirst,ilast
2323 ! index in list
2324 icgb=matconssort(3,jcgb)
2325 ! fill constraint matrix
2326 i=vecconsstart(icgb)
2327 rhs=listconstraints(i )%value ! right hand side
2328 sgm=listconstraints(i+1)%value ! sigma parameter
2329 DO j=i+2,vecconsstart(icgb+1)-1
2330 label=listconstraints(j)%label
2331 factr=listconstraints(j)%value
2332 itgbi=inone(label) ! -> ITGBI= index of parameter label
2333 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2334 IF(ivgb > 0) matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)= &
2335 matconstraintst(int(jcgb-ifirst,mpl)*int(npar,mpl)+ivgb-ipar0+ioffc)+factr ! matrix element
2336 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2337 END DO
2338 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2339 END DO
2340
2341 ! get rank of groups
2342 DO ll=ioffc+1,ioffc+npar
2343 ij=ioffp
2344 DO i=1,ncon
2345 DO j=1,i
2346 ij=ij+1
2347 matconsproduct(ij)=matconsproduct(ij)+ &
2348 matconstraintst(int(i-1,mpl)*int(npar,mpl)+ll)* &
2349 matconstraintst(int(j-1,mpl)*int(npar,mpl)+ll)
2350 END DO
2351 END DO
2352 END DO
2353 ! inversion of product matrix of constraints
2354 CALL sqminv(matconsproduct(ioffp+1:ij),vecconsresiduals(ifirst:ilast),ncon,irank, auxvectord, auxvectori)
2355 IF (icheck > 1 .OR. irank < ncon) THEN
2356 WRITE(*,*) ' Constraint group, #con, rank', icgrp, ncon, irank
2357 IF (irank < ncon) THEN
2358 WRITE(*,*) ' .. rank deficit !! '
2359 WRITE(*,*) ' E.g. fix all parameters and remove all constraints related to label ', &
2361 END IF
2362 END IF
2363 nrank=nrank+irank
2364 ioffc=ioffc+int(npar,mpl)*int(ncon,mpl)
2365 ioffp=ij
2366 END DO
2367
2368 nmiss1=ncgb-nrank
2369
2370 WRITE(*,*) ' '
2371 WRITE(*,*) 'Rank of product matrix of constraints is',nrank, &
2372 ' for',ncgb,' constraint equations'
2373 WRITE(8,*) 'Rank of product matrix of constraints is',nrank, &
2374 ' for',ncgb,' constraint equations'
2375 IF(nrank < ncgb) THEN
2376 WRITE(*,*) 'Warning: insufficient constraint equations!'
2377 WRITE(8,*) 'Warning: insufficient constraint equations!'
2378 IF (iforce == 0) THEN
2379 isubit=1
2380 WRITE(*,*) ' --> enforcing SUBITO mode'
2381 WRITE(8,*) ' --> enforcing SUBITO mode'
2382 END IF
2383 END IF
2384
2385 ! QL decomposition
2386 IF (nfgb < nvgb) THEN
2387 print *
2388 print *, 'QL decomposition of constraints matrix'
2389 ! monitor progress
2390 IF(monpg1 > 0) THEN
2391 WRITE(lunlog,*) 'QL decomposition of constraints matrix'
2393 END IF
2394 IF(icelim < 2) THEN ! True unless unpacked LAPACK
2395 ! QL decomposition
2397 ! loop over parameter blocks
2399 ! check eignevalues of L
2400 CALL qlgete(evmin,evmax)
2401#ifdef LAPACK64
2402 ELSE
2403 CALL lpqldec(matconstraintst,evmin,evmax)
2404#endif
2405 END IF
2406 IF(monpg1 > 0) CALL monend()
2407 print *, ' largest |eigenvalue| of L: ', evmax
2408 print *, ' smallest |eigenvalue| of L: ', evmin
2409 IF (evmin == 0.0_mpd.AND.icheck == 0) THEN
2410 CALL peend(27,'Aborted, singular QL decomposition of constraints matrix')
2411 stop 'FEASMA: stopping due to singular QL decomposition of constraints matrix'
2412 END IF
2413 END IF
2414
2415 CALL mpdealloc(matconstraintst)
2416 CALL mpdealloc(auxvectord)
2417 CALL mpdealloc(auxvectori)
2418
2419 RETURN
2420END SUBROUTINE feasma ! matrix for feasible solution
2421
2429SUBROUTINE feasib(concut,iact)
2430 USE mpmod
2431 USE mpdalc
2432
2433 IMPLICIT NONE
2434 REAL(mpd) :: factr
2435 REAL(mpd) :: sgm
2436 INTEGER(mpi) :: i
2437 INTEGER(mpi) :: icgb
2438 INTEGER(mpi) :: icgrp
2439 INTEGER(mpi) :: iter
2440 INTEGER(mpi) :: itgbi
2441 INTEGER(mpi) :: ivgb
2442 INTEGER(mpi) :: ieblck
2443 INTEGER(mpi) :: isblck
2444 INTEGER(mpi) :: ifirst
2445 INTEGER(mpi) :: ilast
2446 INTEGER(mpi) :: j
2447 INTEGER(mpi) :: jcgb
2448 INTEGER(mpi) :: label
2449 INTEGER(mpi) :: inone
2450 INTEGER(mpi) :: ncon
2451
2452 REAL(mps), INTENT(IN) :: concut
2453 INTEGER(mpi), INTENT(OUT) :: iact
2454
2455 REAL(mpd) :: rhs
2456 REAL(mpd) ::sum1
2457 REAL(mpd) ::sum2
2458 REAL(mpd) ::sum3
2459
2460 REAL(mpd), DIMENSION(:), ALLOCATABLE :: vecCorrections
2461 SAVE
2462
2463 iact=0
2464 IF(ncgb == 0) RETURN ! no constraints
2465
2466 DO iter=1,2
2467 vecconsresiduals=0.0_mpd
2468
2469 ! calculate right constraint equation discrepancies
2470 DO jcgb=1,ncgb
2471 icgb=matconssort(3,jcgb) ! unsorted constraint index
2472 i=vecconsstart(icgb)
2473 rhs=listconstraints(i )%value ! right hand side
2474 sgm=listconstraints(i+1)%value ! sigma parameter
2475 DO j=i+2,vecconsstart(icgb+1)-1
2476 label=listconstraints(j)%label
2477 factr=listconstraints(j)%value
2478 itgbi=inone(label) ! -> ITGBI= index of parameter label
2479 rhs=rhs-factr*globalparameter(itgbi) ! reduce residuum
2480 ENDDO
2481 vecconsresiduals(jcgb)=rhs ! constraint discrepancy
2482 END DO
2483
2484 ! constraint equation discrepancies -------------------------------
2485
2486 sum1=0.0_mpd
2487 sum2=0.0_mpd
2488 sum3=0.0_mpd
2489 DO icgb=1,ncgb
2490 sum1=sum1+vecconsresiduals(icgb)**2
2491 sum2=sum2+abs(vecconsresiduals(icgb))
2492 sum3=max(sum3,abs(vecconsresiduals(icgb)))
2493 END DO
2494 sum1=sqrt(sum1/real(ncgb,mpd))
2495 sum2=sum2/real(ncgb,mpd)
2496
2497 IF(iter == 1.AND.sum1 < concut) RETURN ! do nothing if correction small
2498
2499 IF(iter == 1.AND.ncgb <= 12) THEN
2500 WRITE(*,*) ' '
2501 WRITE(*,*) 'Constraint equation discrepancies:'
2502 WRITE(*,101) (icgb,vecconsresiduals(icgb),icgb=1,ncgb)
2503101 FORMAT(4x,4(i5,g12.4))
2504 WRITE(*,103) concut
2505103 FORMAT(10x,' Cut on rms value is',g8.1)
2506 END IF
2507
2508 IF(iact == 0) THEN
2509 WRITE(*,*) ' '
2510 WRITE(*,*) 'Improve constraints'
2511 END IF
2512 iact=1
2513
2514 WRITE(*,102) iter,sum1,sum2,sum3
2515102 FORMAT(i6,' rms',g12.4,' avrg_abs',g12.4,' max_abs',g12.4)
2516
2517 CALL mpalloc(veccorrections,int(nvgb,mpl),'constraint corrections')
2518 veccorrections=0.0_mpd
2519
2520 ! multiply (group-wise) inverse matrix and constraint vector
2521 isblck=0
2522 DO icgrp=1,ncgrp
2523 ifirst=matconsgroups(1,icgrp) ! first constraint in group
2524 ilast=matconsgroups(1,icgrp+1)-1 ! last constraint in group
2525 ncon=ilast+1-ifirst
2526 ieblck=isblck+(ncon*(ncon+1))/2
2527 CALL dbsvx(matconsproduct(isblck+1:ieblck),vecconsresiduals(ifirst:ilast),vecconssolution(ifirst:ilast),ncon)
2528 isblck=ieblck
2529 END DO
2530
2531 DO jcgb=1,ncgb
2532 icgb=matconssort(3,jcgb) ! unsorted constraint index
2533 i=vecconsstart(icgb)
2534 rhs=listconstraints(i )%value ! right hand side
2535 sgm=listconstraints(i+1)%value ! sigma parameter
2536 DO j=i+2,vecconsstart(icgb+1)-1
2537 label=listconstraints(j)%label
2538 factr=listconstraints(j)%value
2539 itgbi=inone(label) ! -> ITGBI= index of parameter label
2540 ivgb =globalparlabelindex(2,itgbi) ! -> index of variable global parameter
2541 IF(ivgb > 0) THEN
2542 veccorrections(ivgb)=veccorrections(ivgb)+vecconssolution(jcgb)*factr
2543 END IF
2544 ENDDO
2545 END DO
2546
2547 DO i=1,nvgb ! add corrections
2548 itgbi=globalparvartototal(i)
2549 globalparameter(itgbi)=globalparameter(itgbi)+veccorrections(i)
2550 END DO
2551
2552 CALL mpdealloc(veccorrections)
2553
2554 END DO ! iteration 1 and 2
2555
2556END SUBROUTINE feasib ! make parameters feasible
2557
2590SUBROUTINE peread(more)
2591 USE mpmod
2592
2593 IMPLICIT NONE
2594 INTEGER(mpi) :: i
2595 INTEGER(mpi) :: iact
2596 INTEGER(mpi) :: ierrc
2597 INTEGER(mpi) :: ierrf
2598 INTEGER(mpi) :: ioffp
2599 INTEGER(mpi) :: ios
2600 INTEGER(mpi) :: ithr
2601 INTEGER(mpi) :: jfile
2602 INTEGER(mpi) :: jrec
2603 INTEGER(mpi) :: k
2604 INTEGER(mpi) :: kfile
2605 INTEGER(mpi) :: l
2606 INTEGER(mpi) :: lun
2607 INTEGER(mpi) :: mpri
2608 INTEGER(mpi) :: n
2609 INTEGER(mpi) :: nact
2610 INTEGER(mpi) :: nbuf
2611 INTEGER(mpi) :: ndata
2612 INTEGER(mpi) :: noff
2613 INTEGER(mpi) :: noffs
2614 INTEGER(mpi) :: npointer
2615 INTEGER(mpi) :: npri
2616 INTEGER(mpi) :: nr
2617 INTEGER(mpi) :: nrc
2618 INTEGER(mpi) :: nrd
2619 INTEGER(mpi) :: nrpr
2620 INTEGER(mpi) :: nthr
2621 INTEGER(mpi) :: ntot
2622 INTEGER(mpi) :: maxRecordSize
2623 INTEGER(mpi) :: maxRecordFile
2624
2625 INTEGER(mpi), INTENT(OUT) :: more
2626
2627 LOGICAL :: lprint
2628 LOGICAL :: floop
2629 LOGICAL :: eof
2630 REAL(mpd) :: ds0
2631 REAL(mpd) :: ds1
2632 REAL(mpd) :: ds2
2633 REAL(mpd) :: dw
2634 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
2635 CHARACTER (LEN=7) :: cfile
2636 SAVE
2637
2638#ifdef READ_C_FILES
2639 INTERFACE
2640 SUBROUTINE readc(bufferD, bufferF, bufferI, bufferLength, lun, err) BIND(c)
2641 USE iso_c_binding
2642 REAL(c_double), DIMENSION(*), INTENT(OUT) :: bufferD
2643 REAL(c_float), DIMENSION(*), INTENT(OUT) :: bufferF
2644 INTEGER(c_int), DIMENSION(*), INTENT(OUT) :: bufferI
2645 INTEGER(c_int), INTENT(INOUT) :: bufferLength
2646 INTEGER(c_int), INTENT(IN), VALUE :: lun
2647 INTEGER(c_int), INTENT(OUT) :: err
2648 END SUBROUTINE readc
2649 END INTERFACE
2650#endif
2651
2652 DATA lprint/.true./
2653 DATA floop/.true./
2654 DATA npri / 0 /, mpri / 1000 /
2655 ! ...
2656 IF(ifile == 0) THEN ! start/restart
2657 nrec=0
2658 nrecd=0
2659 ntot=0
2660 sumrecords=0
2662 numblocks=0
2665 readbufferinfo=0 ! reset management info
2666 nrpr=1
2667 nthr=mthrdr
2668 nact=0 ! active threads (have something still to read)
2669 DO k=1,nthr
2670 IF (ifile < nfilb) THEN
2671 ifile=ifile+1
2673 readbufferinfo(2,k)=nact
2674 nact=nact+1
2675 END IF
2676 END DO
2677 END IF
2678 npointer=size(readbufferpointer)/nact
2679 ndata=size(readbufferdatai)/nact
2680 more=-1
2681 DO k=1,nthr
2682 iact=readbufferinfo(2,k)
2683 readbufferinfo(4,k)=0 ! reset counter
2684 readbufferinfo(5,k)=iact*ndata ! reset offset
2685 END DO
2686 numblocks=numblocks+1 ! new block
2687
2688 !$OMP PARALLEL &
2689 !$OMP DEFAULT(PRIVATE) &
2690 !$OMP SHARED(readBufferInfo,readBufferPointer,readBufferDataI,readBufferDataD, &
2691 !$OMP readBufferDataF,nPointer,nData,skippedRecords,ndimbuf,NTHR,NFILF,FLOOP, &
2692 !$OMP IFD,KFD,IFILE,NFILB,WFD,XFD,icheck,keepOpen,ireeof,nrderr) NUM_THREADS(NTHR)
2693 ! NUM_THREADS(NTHR) moved to previuos line to make OPARI2 used by scorep-8.4. happy
2694 ithr=1
2695 !$ ITHR=OMP_GET_THREAD_NUM()+1 ! thread number
2696 jfile=readbufferinfo(1,ithr) ! file index
2697 iact =readbufferinfo(2,ithr) ! active thread number
2698 jrec =readbufferinfo(3,ithr) ! records read
2699 ioffp=iact*npointer
2700 noffs=(ithr-1)*ndimbuf ! offset for intermediate float buffer
2701
2702 files: DO WHILE (jfile > 0)
2703 kfile=kfd(2,jfile)
2704 ! open again
2705 IF (keepopen < 1 .AND. readbufferinfo(3,ithr) == 0) THEN
2706 CALL binopn(kfile,ithr,ios)
2707 END IF
2708 records: DO
2709 nbuf=readbufferinfo(4,ithr)+1
2710 noff=readbufferinfo(5,ithr)+2 ! 2 header words per record
2711 nr=ndimbuf
2712 IF(kfile <= nfilf) THEN ! Fortran file
2713 lun=kfile+10
2714 READ(lun,iostat=ierrf) n,(readbufferdataf(noffs+i),i=1,min(n/2,nr)),&
2715 (readbufferdatai(noff+i),i=1,min(n/2,nr))
2716 nr=n/2
2717 ! convert to double
2718 IF (nr <= ndimbuf) THEN
2719 DO i=1,nr
2720 readbufferdatad(noff+i)=real(readbufferdataf(noffs+i),mpr8)
2721 END DO
2722 END IF
2723 ! IF (ierrf < 0) REWIND lun ! end-of-file ! CHK use binrwd()
2724 eof=(ierrf /= 0)
2725 ELSE ! C file
2726 lun=kfile-nfilf
2727 IF (keepopen < 1) lun=ithr
2728#ifdef READ_C_FILES
2729 CALL readc(readbufferdatad(noff+1),readbufferdataf(noffs+1),readbufferdatai(noff+1),nr,lun,ierrc)
2730 n=nr+nr
2731 IF (ierrc > 4) readbufferinfo(6,ithr)=readbufferinfo(6,ithr)+1
2732#else
2733 ierrc=0
2734#endif
2735 eof=(ierrc <= 0.AND.ierrc /= -4) ! allow buffer overruns -> skip record
2736 IF(eof.AND.ierrc < 0) THEN
2737 WRITE(*,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2738 WRITE(8,*) 'Read error for binary Cfile', kfile, 'record', jrec+1, ':', ierrc
2739 IF (icheck <= 0 .AND. ireeof <=0) THEN ! stop unless 'checkinput' mode or 'readerroraseof'
2740 WRITE(cfile,'(I7)') kfile
2741 CALL peend(18,'Aborted, read error(s) for binary file ' // cfile)
2742 stop 'PEREAD: stopping due to read errors (bad record, wrong file type?)'
2743 END IF
2744 IF (kfd(1,jfile) == 1) THEN ! count files with read errors in first loop
2745 !$OMP ATOMIC
2746 nrderr=nrderr+1
2747 END IF
2748 END IF
2749 END IF
2750 IF(eof) EXIT records ! end-of-files or error
2751
2752 jrec=jrec+1
2753 readbufferinfo(3,ithr)=jrec
2754 IF(floop) THEN
2755 xfd(jfile)=max(xfd(jfile),n)
2756 IF(ithr == 1) THEN
2757 CALL hmplnt(1,n)
2758 IF(readbufferdatai(noff+1) /= 0) CALL hmpent(8,real(readbufferdatai(noff+1),mps))
2759 END IF
2760 END IF
2761
2762 IF (nr <= ndimbuf) THEN
2763 readbufferinfo(4,ithr)=nbuf
2764 readbufferinfo(5,ithr)=noff+nr
2765
2766 readbufferpointer(ioffp+nbuf)=noff ! pointer to start of buffer
2767 readbufferdatai(noff )=noff+nr ! pointer to end of buffer
2768 readbufferdatai(noff-1)=jrec ! local record number
2769 readbufferdatad(noff )=real(kfile,mpr8) ! file number
2770 readbufferdatad(noff-1)=real(wfd(kfile),mpr8) ! weight
2771
2772 IF ((noff+nr+2+ndimbuf >= ndata*(iact+1)).OR.(nbuf >= npointer)) EXIT files ! buffer full
2773 ELSE
2774 !$OMP ATOMIC
2776 cycle records
2777 END IF
2778
2779 END DO records
2780
2781 readbufferinfo(1,ithr)=-jfile ! flag eof
2782 IF (keepopen < 1) THEN ! close again
2783 CALL bincls(kfile,ithr)
2784 ELSE ! rewind
2785 CALL binrwd(kfile)
2786 END IF
2787 IF (kfd(1,jfile) == 1) THEN
2788 print *, 'PEREAD: file ', kfile, 'read the first time, found',jrec,' records'
2789 kfd(1,jfile)=-jrec
2790 ELSE
2791 !PRINT *, 'PEREAD: file ', kfile, 'records', jrec, -kfd(1,jfile)
2792 IF (-kfd(1,jfile) /= jrec) THEN
2793 WRITE(cfile,'(I7)') kfile
2794 CALL peend(19,'Aborted, binary file modified (length) ' // cfile)
2795 stop 'PEREAD: file modified (length)'
2796 END IF
2797 END IF
2798 ! take next file
2799 !$OMP CRITICAL
2800 IF (ifile < nfilb) THEN
2801 ifile=ifile+1
2802 jrec=0
2803 readbufferinfo(1,ithr)=ifile
2804 readbufferinfo(3,ithr)=jrec
2805 END IF
2806 !$OMP END CRITICAL
2807 jfile=readbufferinfo(1,ithr)
2808
2809 END DO files
2810 !$OMP END PARALLEL
2811 ! compress pointers
2812 nrd=readbufferinfo(4,1) ! buffers from 1 .thread
2813 DO k=2,nthr
2814 iact =readbufferinfo(2,k)
2815 ioffp=iact*npointer
2816 nbuf=readbufferinfo(4,k)
2817 DO l=1,nbuf
2818 readbufferpointer(nrd+l)=readbufferpointer(ioffp+l)
2819 END DO
2820 nrd=nrd+nbuf
2821 END DO
2822
2823 more=0
2824 DO k=1,nthr
2825 jfile=readbufferinfo(1,k)
2826 IF (jfile > 0) THEN ! no eof yet
2827 readbufferinfo(2,k)=more
2828 more=more+1
2829 ELSE
2830 ! no more files, thread retires
2831 readbufferinfo(1,k)=0
2832 readbufferinfo(2,k)=-1
2833 readbufferinfo(3,k)=0
2835 readbufferinfo(6,k)=0
2836 END IF
2837 END DO
2838 ! record limit ?
2839 IF (mxrec > 0.AND.(ntot+nrd) >= mxrec) THEN
2840 nrd=mxrec-ntot
2841 more=-1
2842 DO k=1,nthr
2843 jfile=readbufferinfo(1,k)
2844 IF (jfile > 0) THEN ! rewind or close files
2845 nrc=readbufferinfo(3,k)
2846 IF (kfd(1,jfile) == 1) kfd(1,jfile)=-nrc
2847 kfile=kfd(2,jfile)
2848 IF (keepopen < 1) THEN ! close again
2849 CALL bincls(kfile,k)
2850 ELSE ! rewind
2851 CALL binrwd(kfile)
2852 END IF
2853 END IF
2854 END DO
2855 END IF
2856
2857 ntot=ntot+nrd
2858 nrec=ntot
2859 numreadbuffer=nrd
2860
2864
2865 DO WHILE (nloopn == 0.AND.ntot >= nrpr)
2866 WRITE(*,*) ' Record ',nrpr
2867 IF (nrpr < 100000) THEN
2868 nrpr=nrpr*10
2869 ELSE
2870 nrpr=nrpr+100000
2871 END IF
2872 END DO
2873
2874 IF (ncache > 0.AND.nloopn <= 1.AND. npri < mpri.AND.mprint > 1) THEN
2875 npri=npri+1
2876 IF (npri == 1) WRITE(*,100)
2877 WRITE(*,101) nrec, nrd, more ,ifile
2878100 FORMAT(/' PeRead records active file' &
2879 /' total block threads number')
2880101 FORMAT(' PeRead',4i10)
2881 END IF
2882
2883 IF (more <= 0) THEN
2884 ifile=0
2885 IF (floop) THEN
2886 ! check for file weights
2887 ds0=0.0_mpd
2888 ds1=0.0_mpd
2889 ds2=0.0_mpd
2890 maxrecordsize=0
2891 maxrecordfile=0
2892 DO k=1,nfilb
2893 IF (xfd(k) > maxrecordsize) THEN
2894 maxrecordsize=xfd(k)
2895 maxrecordfile=k
2896 END IF
2897 dw=real(-kfd(1,k),mpd)
2898 IF (wfd(k) /= 1.0) nfilw=nfilw+1
2899 ds0=ds0+dw
2900 ds1=ds1+dw*real(wfd(k),mpd)
2901 ds2=ds2+dw*real(wfd(k)**2,mpd)
2902 END DO
2903 print *, 'PEREAD: file ', maxrecordfile, 'with max record size ', maxrecordsize
2904 IF (nfilw > 0.AND.ds0 > 0.0_mpd) THEN
2905 ds1=ds1/ds0
2906 ds2=ds2/ds0-ds1*ds1
2907 DO lun=6,lunlog,2
2908 WRITE(lun,177) nfilw,real(ds1,mps),real(ds2,mps)
2909177 FORMAT(/' !!!!!',i4,' weighted binary files', &
2910 /' !!!!! mean, variance of weights =',2g12.4)
2911 END DO
2912 END IF
2913 ! integrate record numbers
2914 DO k=2,nfilb
2915 ifd(k)=ifd(k-1)-kfd(1,k-1)
2916 END DO
2917 ! sort
2918 IF (nthr > 1) CALL sort2k(kfd,nfilb)
2919 IF (skippedrecords > 0) THEN
2920 print *, 'PEREAD skipped records: ', skippedrecords
2921 ndimbuf=maxrecordsize/2 ! adjust buffer size
2922 END IF
2923 END IF
2924 lprint=.false.
2925 floop=.false.
2926 IF (ncache > 0.AND.nloopn <= 1.AND.mprint > 0) &
2928179 FORMAT(/' Read cache usage (#blocks, #records, ', &
2929 'min,max records/block'/17x,i10,i12,2i10)
2930 END IF
2931 RETURN
2932
2933END SUBROUTINE peread
2934
2942SUBROUTINE peprep(mode)
2943 USE mpmod
2944
2945 IMPLICIT NONE
2946
2947 INTEGER(mpi), INTENT(IN) :: mode
2948
2949 INTEGER(mpi) :: ibuf
2950 INTEGER(mpi) :: ichunk
2951 INTEGER(mpi) :: ist
2952 INTEGER(mpi) :: itgbi
2953 INTEGER(mpi) :: j
2954 INTEGER(mpi) :: ja
2955 INTEGER(mpi) :: jb
2956 INTEGER(mpi) :: jsp
2957 INTEGER(mpi) :: nst
2958 INTEGER(mpi), PARAMETER :: maxbad = 100 ! max number of bad records with print out
2959 INTEGER(mpi) :: nbad
2960 INTEGER(mpi) :: nerr
2961 INTEGER(mpi) :: inone
2962
2963 IF (mode > 0) THEN
2964#ifdef __PGIC__
2965 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
2966 ichunk=256
2967#else
2968 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
2969#endif
2970 ! parallelize record loop
2971 !$OMP PARALLEL DO &
2972 !$OMP DEFAULT(PRIVATE) &
2973 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,ICHUNK,iscerr,dscerr) &
2974 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
2975 DO ibuf=1,numreadbuffer ! buffer for current record
2976 ist=readbufferpointer(ibuf)+1
2978 DO ! loop over measurements
2979 CALL isjajb(nst,ist,ja,jb,jsp)
2980 IF(jb == 0) EXIT
2981 DO j=1,ist-jb
2982 readbufferdatai(jb+j)=inone( readbufferdatai(jb+j) ) ! translate to index
2983 END DO
2984 ! scale error ?
2985 IF (iscerr > 0) THEN
2986 IF (jb < ist) THEN
2987 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(1) ! 'global' measurement
2988 ELSE
2989 readbufferdatad(jb) = readbufferdatad(jb) * dscerr(2) ! 'local' measurement
2990 END IF
2991 END IF
2992 END DO
2993 END DO
2994 !$OMP END PARALLEL DO
2995 END IF
2996
2997 !$POMP INST BEGIN(peprep)
2998#ifdef SCOREP_USER_ENABLE
2999 scorep_user_region_by_name_begin("UR_peprep", scorep_user_region_type_common)
3000#endif
3001 IF (mode <= 0) THEN
3002 nbad=0
3003 DO ibuf=1,numreadbuffer ! buffer for current record
3004 CALL pechk(ibuf,nerr)
3005 IF(nerr > 0) THEN
3006 nbad=nbad+1
3007 IF(nbad >= maxbad) EXIT
3008 ELSE
3009 ist=readbufferpointer(ibuf)+1
3011 DO ! loop over measurements
3012 CALL isjajb(nst,ist,ja,jb,jsp)
3013 IF(jb == 0) EXIT
3014 neqn=neqn+1
3015 IF(jb == ist) cycle
3016 negb=negb+1
3017 ndgb=ndgb+(ist-jb)
3018 DO j=1,ist-jb
3019 itgbi=inone( readbufferdatai(jb+j) ) ! generate index
3020 END DO
3021 END DO
3022 END IF
3023 END DO
3024 IF(nbad > 0) THEN
3025 CALL peend(20,'Aborted, bad binary records')
3026 stop 'PEREAD: stopping due to bad records'
3027 END IF
3028 END IF
3029#ifdef SCOREP_USER_ENABLE
3030 scorep_user_region_by_name_end("UR_peprep")
3031#endif
3032 !$POMP INST END(peprep)
3033
3034END SUBROUTINE peprep
3035
3043SUBROUTINE pechk(ibuf, nerr)
3044 USE mpmod
3045
3046 IMPLICIT NONE
3047 INTEGER(mpi) :: i
3048 INTEGER(mpi) :: is
3049 INTEGER(mpi) :: ist
3050 INTEGER(mpi) :: ioff
3051 INTEGER(mpi) :: ja
3052 INTEGER(mpi) :: jb
3053 INTEGER(mpi) :: jsp
3054 INTEGER(mpi) :: nan
3055 INTEGER(mpi) :: nst
3056
3057 INTEGER(mpi), INTENT(IN) :: ibuf
3058 INTEGER(mpi), INTENT(OUT) :: nerr
3059 SAVE
3060 ! ...
3061
3062 ist=readbufferpointer(ibuf)+1
3064 nerr=0
3065 is=ist
3066 jsp=0
3067 outer: DO WHILE(is < nst)
3068 ja=0
3069 jb=0
3070 inner1: DO
3071 is=is+1
3072 IF(is > nst) EXIT outer
3073 IF(readbufferdatai(is) == 0) EXIT inner1 ! found 1. marker
3074 END DO inner1
3075 ja=is
3076 inner2: DO
3077 is=is+1
3078 IF(is > nst) EXIT outer
3079 IF(readbufferdatai(is) == 0) EXIT inner2 ! found 2. marker
3080 END DO inner2
3081 jb=is
3082 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3083 ! special data
3084 jsp=jb ! pointer to special data
3085 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3086 cycle outer
3087 END IF
3088 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3089 is=is+1
3090 END DO
3091 END DO outer
3092 IF(is > nst) THEN
3093 ioff = readbufferpointer(ibuf)
3094 WRITE(*,100) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi)
3095100 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' is broken !!!')
3096 nerr=nerr+1
3097 ENDIF
3098 nan=0
3099 DO i=ist, nst
3100 IF(.NOT.(readbufferdatad(i) <= 0.0_mpr8).AND..NOT.(readbufferdatad(i) > 0.0_mpr8)) nan=nan+1
3101 END DO
3102 IF(nan > 0) THEN
3103 ioff = readbufferpointer(ibuf)
3104 WRITE(*,101) readbufferdatai(ioff-1), int(readbufferdatad(ioff),mpi), nan
3105101 FORMAT(' PEREAD: record ', i8,' in file ',i6, ' contains ', i6, ' NaNs !!!')
3106 nerr= nerr+2
3107 ENDIF
3108
3109END SUBROUTINE pechk
3110
3115SUBROUTINE pepgrp
3116 USE mpmod
3117 USE mpdalc
3118
3119 IMPLICIT NONE
3120
3121 INTEGER(mpi) :: ibuf
3122 INTEGER(mpi) :: ichunk
3123 INTEGER(mpi) :: iproc
3124 INTEGER(mpi) :: ioff
3125 INTEGER(mpi) :: ioffbi
3126 INTEGER(mpi) :: ist
3127 INTEGER(mpi) :: itgbi
3128 INTEGER(mpi) :: j
3129 INTEGER(mpi) :: ja
3130 INTEGER(mpi) :: jb
3131 INTEGER(mpi) :: jsp
3132 INTEGER(mpi) :: nalg
3133 INTEGER(mpi) :: neqna
3134 INTEGER(mpi) :: nnz
3135 INTEGER(mpi) :: nst
3136 INTEGER(mpi) :: nzero
3137 INTEGER(mpi) :: inone
3138 INTEGER(mpl) :: length
3139 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
3140
3141 CALL useone ! make (INONE) usable
3142 globalparheader(-2)=-1 ! set flag to inhibit further updates
3143 ! need back index
3144 IF (mcount > 0) THEN
3145 length=globalparheader(-1)*mthrd
3146 CALL mpalloc(backindexusage,length,'global variable-index array')
3148 END IF
3149 nzero=0
3150#ifdef __PGIC__
3151 ! to prevent "PGF90-F-0000-Internal compiler error. Could not locate uplevel instance for stblock"
3152 ichunk=256
3153#else
3154 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
3155#endif
3156 ! parallelize record loop
3157 !$OMP PARALLEL DO &
3158 !$OMP DEFAULT(PRIVATE) &
3159 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,readBufferDataD,backIndexUsage,globalParHeader,ICHUNK,MCOUNT) &
3160 !$OMP REDUCTION(+:NZERO) &
3161 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
3162 DO ibuf=1,numreadbuffer ! buffer for current record
3163 ist=readbufferpointer(ibuf)+1
3165 IF (mcount > 0) THEN
3166 ! count per record
3167 iproc=0
3168 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
3169 ioffbi=globalparheader(-1)*iproc
3170 nalg=0
3171 ioff=readbufferpointer(ibuf)
3172 DO ! loop over measurements
3173 CALL isjajb(nst,ist,ja,jb,jsp)
3174 IF(jb == 0) EXIT
3175 IF (ist > jb) THEN
3176 DO j=1,ist-jb
3177 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3178 nzero=nzero+1
3179 cycle ! skip 'zero global derivatives' for counting and grouping
3180 END IF
3181 itgbi=inone( readbufferdatai(jb+j) ) ! translate to index
3182 IF (backindexusage(ioffbi+itgbi) == 0) THEN
3183 nalg=nalg+1
3184 readbufferdatai(ioff+nalg)=itgbi
3185 backindexusage(ioffbi+itgbi)=nalg
3186 END IF
3187 END DO
3188 END IF
3189 END DO
3190 ! reset back index
3191 DO j=1,nalg
3192 itgbi=readbufferdatai(ioff+j)
3193 backindexusage(ioffbi+itgbi)=0
3194 END DO
3195 ! sort (record)
3196 CALL sort1k(readbufferdatai(ioff+1),nalg)
3197 readbufferdatai(ioff)=ioff+nalg
3198 ELSE
3199 ! count per equation
3200 nalg=1 ! reserve space for counter 'nnz'
3201 ioff=readbufferpointer(ibuf)
3202 neqna=0 ! number of accepted equations
3203 DO ! loop over measurements
3204 CALL isjajb(nst,ist,ja,jb,jsp)
3205 IF(jb == 0) EXIT
3206 IF (ist > jb) THEN
3207 nnz=0 ! number of non-zero derivatives
3208 DO j=1,ist-jb
3209 IF (readbufferdatad(jb+j) == 0.0_mpd) THEN
3210 nzero=nzero+1
3211 cycle ! skip 'zero global derivatives' for counting and grouping
3212 END IF
3213 nnz=nnz+1
3214 readbufferdatai(ioff+nalg+nnz)=inone( readbufferdatai(jb+j) ) ! translate to index
3215 END DO
3216 IF (nnz == 0) cycle ! nothing for this equation
3217 readbufferdatai(ioff+nalg)=nnz
3218 ! sort (equation)
3219 CALL sort1k(readbufferdatai(ioff+nalg+1),nnz)
3220 nalg=nalg+nnz+1
3221 ! count (accepted) equations
3222 neqna=neqna+1
3223 END IF
3224 END DO
3225 readbufferdatai(ioff)=neqna
3226 END IF
3227 END DO
3228 !$OMP END PARALLEL DO
3229 nzgb=nzgb+nzero
3230
3231 !$POMP INST BEGIN(pepgrp)
3232#ifdef SCOREP_USER_ENABLE
3233 scorep_user_region_by_name_begin("UR_pepgrp", scorep_user_region_type_common)
3234#endif
3235 DO ibuf=1,numreadbuffer ! buffer for current record
3236 ist=readbufferpointer(ibuf)+1
3238 IF (mcount == 0) THEN
3239 ! equation level
3240 DO j=1,nst! loop over measurements
3241 nnz=readbufferdatai(ist)
3242 CALL pargrp(ist+1,ist+nnz)
3243 ist=ist+nnz+1
3244 END DO
3245 ELSE
3246 ! record level, group
3247 CALL pargrp(ist,nst)
3248 ENDIF
3249 END DO
3250 ! free back index
3251 IF (mcount > 0) THEN
3253 END IF
3254#ifdef SCOREP_USER_ENABLE
3255 scorep_user_region_by_name_end("UR_pepgrp")
3256#endif
3257 !$POMP INST END(pepgrp)
3258 globalparheader(-2)=0 ! reset flag to reenable further updates
3259
3260END SUBROUTINE pepgrp
3261
3269SUBROUTINE pargrp(inds,inde)
3270 USE mpmod
3271
3272 IMPLICIT NONE
3273
3274 INTEGER(mpi) :: istart
3275 INTEGER(mpi) :: itgbi
3276 INTEGER(mpi) :: j
3277 INTEGER(mpi) :: jstart
3278 INTEGER(mpi) :: jtgbi
3279 INTEGER(mpi) :: lstart
3280 INTEGER(mpi) :: ltgbi
3281
3282 INTEGER(mpi), INTENT(IN) :: inds
3283 INTEGER(mpi), INTENT(IN) :: inde
3284
3285 IF (inds > inde) RETURN
3286
3287 ltgbi=-1
3288 lstart=-1
3289 ! build up groups
3290 DO j=inds,inde
3291 itgbi=readbufferdatai(j)
3292 globalparlabelcounter(itgbi)=globalparlabelcounter(itgbi)+1 ! count entries
3293 istart=globalparlabelindex(3,itgbi) ! label of group start
3294 IF (istart == 0) THEN ! not yet in group
3295 IF (itgbi /= ltgbi+1) THEN ! start group
3297 ELSE
3298 IF (lstart == 0) THEN ! extend group
3300 ELSE ! start group
3301 globalparlabelindex(3,itgbi)=globalparlabelindex(1,itgbi)
3302 END IF
3303 END IF
3304 END IF
3305 ltgbi=itgbi
3306 lstart=istart
3307 END DO
3308 ! split groups:
3309 ! - start inside group?
3310 itgbi=readbufferdatai(inds)
3311 istart=globalparlabelindex(3,itgbi) ! label of group start
3312 jstart=globalparlabelindex(1,itgbi) ! label of first parameter
3313 IF (istart /= jstart) THEN ! start new group
3314 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3315 globalparlabelindex(3,itgbi) = jstart
3316 itgbi=itgbi+1
3317 IF (itgbi > globalparheader(-1)) EXIT
3318 END DO
3319 END IF
3320 ! - not neigbours anymore
3321 ltgbi=readbufferdatai(inds)
3322 DO j=inds+1,inde
3323 itgbi=readbufferdatai(j)
3324 IF (itgbi /= ltgbi+1) THEN
3325 ! split after ltgbi
3326 lstart=globalparlabelindex(3,ltgbi) ! label of last group start
3327 jtgbi=ltgbi+1 ! new group after ltgbi
3328 jstart=globalparlabelindex(1,jtgbi)
3329 DO WHILE (globalparlabelindex(3,jtgbi) == lstart)
3330 globalparlabelindex(3,jtgbi) = jstart
3331 jtgbi=jtgbi+1
3332 IF (jtgbi > globalparheader(-1)) EXIT
3333 IF (jtgbi == itgbi) jstart=globalparlabelindex(1,jtgbi)
3334 END DO
3335 ! split at itgbi
3336 jtgbi=itgbi
3337 istart=globalparlabelindex(3,jtgbi) ! label of group start
3338 jstart=globalparlabelindex(1,jtgbi) ! label of first parameter
3339 IF (istart /= jstart) THEN ! start new group
3340 DO WHILE (globalparlabelindex(3,jtgbi) == istart)
3341 globalparlabelindex(3,jtgbi) = jstart
3342 jtgbi=jtgbi+1
3343 IF (jtgbi > globalparheader(-1)) EXIT
3344 END DO
3345 END IF
3346 ENDIF
3347 ltgbi=itgbi
3348 END DO
3349 ! - end inside group?
3350 itgbi=readbufferdatai(inde)
3351 IF (itgbi < globalparheader(-1)) THEN
3352 istart=globalparlabelindex(3,itgbi) ! label of group start
3353 itgbi=itgbi+1
3354 jstart=globalparlabelindex(1,itgbi) ! label of new group start
3355 DO WHILE (globalparlabelindex(3,itgbi) == istart)
3356 globalparlabelindex(3,itgbi) = jstart
3357 itgbi=itgbi+1
3358 IF (itgbi > globalparheader(-1)) EXIT
3359 END DO
3360 END IF
3361
3362END SUBROUTINE pargrp
3363
3386SUBROUTINE isjajb(nst,is,ja,jb,jsp)
3387 USE mpmod
3388
3389 IMPLICIT NONE
3390
3391 INTEGER(mpi), INTENT(IN) :: nst
3392 INTEGER(mpi), INTENT(IN OUT) :: is
3393 INTEGER(mpi), INTENT(OUT) :: ja
3394 INTEGER(mpi), INTENT(OUT) :: jb
3395 INTEGER(mpi), INTENT(OUT) :: jsp
3396 SAVE
3397 ! ...
3398
3399 jsp=0
3400 DO
3401 ja=0
3402 jb=0
3403 IF(is >= nst) RETURN
3404 DO
3405 is=is+1
3406 IF(readbufferdatai(is) == 0) EXIT
3407 END DO
3408 ja=is
3409 DO
3410 is=is+1
3411 IF(readbufferdatai(is) == 0) EXIT
3412 END DO
3413 jb=is
3414 IF(ja+1 == jb.AND.readbufferdatad(jb) < 0.0_mpr8) THEN
3415 ! special data
3416 jsp=jb ! pointer to special data
3417 is=is+nint(-readbufferdatad(jb),mpi) ! skip NSP words
3418 cycle
3419 END IF
3420 DO WHILE(readbufferdatai(is+1) /= 0.AND.is < nst)
3421 is=is+1
3422 END DO
3423 EXIT
3424 END DO
3425
3426END SUBROUTINE isjajb
3427
3428
3429!***********************************************************************
3430! LOOPN ...
3436
3437SUBROUTINE loopn
3438 USE mpmod
3439
3440 IMPLICIT NONE
3441 REAL(mpd) :: dsum
3442 REAL(mps) :: elmt
3443 REAL(mpd) :: factrj
3444 REAL(mpd) :: factrk
3445 REAL(mps) :: peakd
3446 REAL(mps) :: peaki
3447 REAL(mps) :: ratae
3448 REAL(mpd) :: rhs
3449 REAL(mps) :: rloop
3450 REAL(mpd) :: sgm
3451 REAL(mps) :: used
3452 REAL(mps) :: usei
3453 REAL(mpd) :: weight
3454 INTEGER(mpi) :: i
3455 INTEGER(mpi) :: ia
3456 INTEGER(mpi) :: ib
3457 INTEGER(mpi) :: ioffb
3458 INTEGER(mpi) :: ipr
3459 INTEGER(mpi) :: itgbi
3460 INTEGER(mpi) :: itgbij
3461 INTEGER(mpi) :: itgbik
3462 INTEGER(mpi) :: ivgb
3463 INTEGER(mpi) :: ivgbij
3464 INTEGER(mpi) :: ivgbik
3465 INTEGER(mpi) :: j
3466 INTEGER(mpi) :: k
3467 INTEGER(mpi) :: lastit
3468 INTEGER(mpi) :: lun
3469 INTEGER(mpi) :: ncrit
3470 INTEGER(mpi) :: ngras
3471 INTEGER(mpi) :: nparl
3472 INTEGER(mpi) :: nr
3473 INTEGER(mpl) :: nrej
3474 INTEGER(mpi) :: inone
3475 INTEGER(mpi) :: ilow
3476 INTEGER(mpi) :: nlow
3477 INTEGER(mpi) :: nzero
3478 LOGICAL :: btest
3479
3480 REAL(mpd):: adder
3481 REAL(mpd)::funref
3482 REAL(mpd)::matij
3483
3484 SAVE
3485 ! ...
3486
3487 ! ----- book and reset ---------------------------------------------
3488 IF(nloopn == 0) THEN ! first call
3489 lastit=-1
3490 iitera=0
3491 END IF
3492
3493 nloopn=nloopn+1 ! increase loop counter
3494 funref=0.0_mpd
3495
3496 IF(nloopn == 1) THEN ! book histograms for 1. iteration
3497 CALL gmpdef(1,4,'Function value in iterations')
3498 IF (metsol == 4 .OR. metsol == 5) THEN ! extend to GMRES, i.e. 6?
3499 CALL gmpdef(2,3,'Number of MINRES steps vs iteration nr')
3500 END IF
3501 CALL hmpdef( 5,0.0,0.0,'Number of degrees of freedom')
3502 CALL hmpdef(11,0.0,0.0,'Number of local parameters')
3503 CALL hmpdef(16,0.0,24.0,'LOG10(cond(band part decomp.)) local fit ')
3504 CALL hmpdef(23,0.0,0.0, 'SQRT of diagonal elements without presigma')
3505 CALL hmpdef(24,0.0,0.0, 'Log10 of off-diagonal elements')
3506 CALL hmpdef(25,0.0,0.0, 'Relative individual pre-sigma')
3507 CALL hmpdef(26,0.0,0.0, 'Relative global pre-sigma')
3508 END IF
3509
3510
3511 CALL hmpdef(3,-prange,prange, & ! book
3512 'Normalized residuals of single (global) measurement')
3513 CALL hmpdef(12,-prange,prange, & ! book
3514 'Normalized residuals of single (local) measurement')
3515 CALL hmpdef(13,-prange,prange, & ! book
3516 'Pulls of single (global) measurement')
3517 CALL hmpdef(14,-prange,prange, & ! book
3518 'Pulls of single (local) measurement')
3519 CALL hmpdef(4,0.0,0.0,'Chi^2/Ndf after local fit')
3520 CALL gmpdef(4,5,'location, dispersion (res.) vs record nr')
3521 CALL gmpdef(5,5,'location, dispersion (pull) vs record nr')
3522
3523 ! WRITE(*,*) 'LOOPN ', NLOOPN, ' executing ICALCM=', ICALCM
3524
3525 ! reset
3526
3527 globalvector=0.0_mpd ! reset rhs vector IGVEC
3529 IF(icalcm == 1) THEN
3530 globalmatd=0.0_mpd
3531 globalmatf=0.
3532 IF (metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) matprecond=0.0_mpd
3533 END IF
3534
3535 IF(nloopn == 2) CALL hmpdef(6,0.0,0.0,'Down-weight fraction')
3536
3537 newite=.false.
3538 IF(iterat /= lastit) THEN ! new iteration
3539 newite=.true.
3540 funref=fvalue
3541 IF(nloopn > 1) THEN
3542 nrej=sum(nrejec)
3543 ! CALL MEND
3544 IF(iterat == 1) THEN
3546 ELSE IF(iterat >= 1) THEN
3547 chicut=sqrt(chicut)
3548 IF(chicut /= 0.0.AND.chicut < 1.5) chicut=1.0
3549 IF(chicut /= 0.0.AND.nrej == 0) chicut=1.0
3550 END IF
3551 END IF
3552 ! WRITE(*,111) ! header line
3553 END IF
3554
3555 nrejec=0 ! reset reject counter
3556 DO k=3,6
3557 writebufferheader(k)=0 ! cache usage
3558 writebufferheader(-k)=0
3559 END DO
3560 ! statistics per binary file
3561 DO i=1,nfilb
3562 jfd(i)=0
3563 cfd(i)=0.0
3564 dfd(i)=0
3565 END DO
3566
3567 IF (imonit /= 0) meashists=0 ! reset monitoring histograms
3568
3569 ! ----- read next data ----------------------------------------------
3570 DO
3571 CALL peread(nr) ! read records
3572 CALL peprep(1) ! prepare records
3574 IF (nr <= 0) EXIT ! next block of events ?
3575 END DO
3576 ! sum up RHS (over threads) once (reduction in LOOPBF: summation for each block)
3577 ioffb=0
3578 DO ipr=2,mthrd
3579 ioffb=ioffb+lenglobalvec
3580 DO k=1,lenglobalvec
3583 END DO
3584 END DO
3585
3586 IF (icalcm == 1) THEN
3587 ! PRINT *, ' cache/w ',(writeBufferHeader(-K),K=3,6),(writeBufferHeader(K),K=3,6)
3588 nparl=writebufferheader(3)
3589 ncrit=writebufferheader(4)
3590 used=real(writebufferheader(-5),mps)/real(writebufferheader(-3),mps)*0.1
3591 usei=real(writebufferheader(5),mps)/real(writebufferheader(3),mps)*0.1
3592 peakd=real(writebufferheader(-6),mps)*0.1
3593 peaki=real(writebufferheader(6),mps)*0.1
3594 WRITE(*,111) nparl,ncrit,usei,used,peaki,peakd
3595111 FORMAT(' Write cache usage (#flush,#overrun,<levels>,', &
3596 'peak(levels))'/2i7,',',4(f6.1,'%'))
3597 ! fill part of MINRES preconditioner matrix from binary files (formerly in mgupdt)
3598 IF (metsol >= 4.AND.metsol < 7) THEN
3599 IF (mbandw == 0) THEN
3600 ! default preconditioner (diagonal)
3601 DO i=1, nvgb
3602 matprecond(i)=matij(i,i)
3603 END DO
3604 ELSE IF (mbandw > 0) THEN
3605 ! band matrix
3606 DO i=1, nvgb
3607 ia=indprecond(i) ! index of diagonal element
3608 DO j=max(1,i-mbandw+1),i
3609 matprecond(ia-i+j)=matij(i,j)
3610 END DO
3611 END DO
3612 END IF
3613 END IF
3614 IF (ichkpg > 0) THEN
3615 ! check parameter groups
3616 CALL ckpgrp
3617 END IF
3618 END IF
3619
3620 ! check entries/counters
3621 nlow=0
3622 ilow=1
3623 nzero=0
3624 DO i=1,nvgb
3625 IF(globalcounter(i) == 0) nzero=nzero+1
3626 IF(globalcounter(i) < mreqena) THEN
3627 nlow=nlow+1
3628 IF(globalcounter(i) < globalcounter(ilow)) ilow=i
3629 END IF
3630 END DO
3631 IF(nlow > 0) THEN
3632 nalow=nalow+nlow
3633 IF(icalcm == 1) nxlow=max(nxlow,nlow) ! for matrix construction ?
3634 itgbi=globalparvartototal(ilow)
3635 print *
3636 print *, " ... warning ..."
3637 print *, " global parameters with too few (< MREQENA) accepted entries: ", nlow
3638 print *, " minimum entries: ", globalcounter(ilow), " for label ", globalparlabelindex(1,itgbi)
3639 print *
3640 END IF
3641 IF(icalcm == 1 .AND. nzero > 0) THEN
3642 ndefec = nzero ! rank defect
3643 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfgb, &
3644 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3645 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfgb, &
3646 '-by-',nfgb,' matrix is ',ndefec,' (should be zero).'
3647 IF (iforce == 0) THEN
3648 isubit=1
3649 WRITE(*,*) ' --> enforcing SUBITO mode'
3650 WRITE(lun,*) ' --> enforcing SUBITO mode'
3651 END IF
3652 END IF
3653
3654 ! ----- after end-of-data add contributions from pre-sigma ---------
3655
3656 IF(nloopn == 1) THEN
3657 ! plot diagonal elements
3658 elmt=0.0
3659 DO i=1,nvgb ! diagonal elements
3660 elmt=real(matij(i,i),mps)
3661 IF(elmt > 0.0) CALL hmpent(23,1.0/sqrt(elmt))
3662 END DO
3663 END IF
3664
3665
3666
3667 ! add pre-sigma contributions to matrix diagonal
3668
3669 ! WRITE(*,*) 'Adding to diagonal ICALCM IND6',ICALCM,IND6
3670
3671 IF(icalcm == 1) THEN
3672 DO ivgb=1,nvgb ! add evtl. pre-sigma
3673 ! WRITE(*,*) 'Index ',IVGB,IVGB,QM(IND6+IVGB)
3674 IF(globalparpreweight(ivgb) /= 0.0) THEN
3675 IF(ivgb > 0) CALL mupdat(ivgb,ivgb,globalparpreweight(ivgb))
3676 END IF
3677 END DO
3678 END IF
3679
3680 CALL hmpwrt(23)
3681 CALL hmpwrt(24)
3682 CALL hmpwrt(25)
3683 CALL hmpwrt(26)
3684
3685
3686 ! add regularization term to F and to rhs --------------------------
3687
3688 ! WRITE(*,*) 'NREGUL ',NREGUL,NLOOPN
3689
3690 IF(nregul /= 0) THEN ! add regularization term to F and to rhs
3691 DO ivgb=1,nvgb
3692 itgbi=globalparvartototal(ivgb) ! global parameter index
3694 adder=globalparpreweight(ivgb)*globalparameter(itgbi)**2
3695 CALL addsums(1, adder, 0, 1.0_mpl)
3696 END DO
3697 END IF
3698
3699
3700 ! ----- add contributions from "measurement" -----------------------
3701
3702
3703 i=1
3704 DO WHILE (i <= lenmeasurements)
3705 rhs=listmeasurements(i )%value ! right hand side
3706 sgm=listmeasurements(i+1)%value ! sigma parameter
3707 i=i+2
3708 weight=0.0
3709 IF(sgm > 0.0) weight=1.0/sgm**2
3710
3711 dsum=-rhs
3712
3713 ! loop over label/factor pairs
3714 ia=i
3715 DO
3716 i=i+1
3717 IF(i > lenmeasurements) EXIT
3718 IF(listmeasurements(i)%label < 0) EXIT
3719 END DO
3720 ib=i-1
3721
3722 DO j=ia,ib
3723 factrj=listmeasurements(j)%value
3724 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3725 IF(itgbij /= 0) THEN
3726 dsum=dsum+factrj*globalparameter(itgbij) ! update residuum
3727 END IF
3728 END DO
3729 DO j=ia,ib
3730 factrj=listmeasurements(j)%value
3731 IF (factrj == 0.0_mpd) cycle ! skip zero factors
3732 itgbij=inone(listmeasurements(j)%label) ! total parameter index
3733 ! add to vector
3734 ivgbij=0
3735 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
3736 IF(ivgbij > 0) THEN
3737 globalvector(ivgbij)=globalvector(ivgbij) -weight*dsum*factrj ! vector
3738 globalcounter(ivgbij)=globalcounter(ivgbij)+1
3739 END IF
3740
3741 IF(icalcm == 1.AND.ivgbij > 0) THEN
3742 DO k=ia,j
3743 factrk=listmeasurements(k)%value
3744 itgbik=inone(listmeasurements(k)%label) ! total parameter index
3745 ! add to matrix
3746 ivgbik=0
3747 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
3748 IF(ivgbij > 0.AND.ivgbik > 0) THEN !
3749 CALL mupdat(ivgbij,ivgbik,weight*factrj*factrk)
3750 END IF
3751 END DO
3752 END IF
3753 END DO
3754
3755 adder=weight*dsum**2
3756 CALL addsums(1, adder, 1, 1.0_mpl)
3757
3758 END DO
3759
3760 ! ----- printout ---------------------------------------------------
3761
3762
3763 ! get accurate sum (Chi^2, (w)NDF)
3765
3766 flines=0.5_mpd*fvalue ! Likelihood function value
3767 rloop=iterat+0.01*nloopn
3768 actfun=real(funref-fvalue,mps)
3769 IF(nloopn == 1) actfun=0.0
3770 ngras=nint(angras,mpi)
3771 ratae=0.0 !!!
3772 IF(delfun /= 0.0) THEN
3773 ratae=min(99.9,actfun/delfun) !!!
3774 ratae=max(-99.9,ratae)
3775 END IF
3776
3777 ! rejects ...
3778
3779 nrej =sum(nrejec)
3780 IF(nloopn == 1) THEN
3781 IF(nrej /= 0) THEN
3782 WRITE(*,*) ' '
3783 WRITE(*,*) 'Data records rejected in initial loop:'
3784 CALL prtrej(6)
3785 END IF
3786 END IF
3787
3788 IF(newite.AND.iterat == 2) THEN
3789 IF(nrecpr /= 0.OR.nrecp2 /= 0) nrecer=nrec3
3790 IF(nrecpr < 0) THEN
3792 END IF
3793 IF(nrecp2 < 0) THEN
3795 END IF
3796 END IF
3797
3798 IF(nloopn <= 2) THEN
3799 IF(nhistp /= 0) THEN
3800 ! CALL HMPRNT(3) ! scaled residual of single measurement
3801 ! CALL HMPRNT(12) ! scaled residual of single measurement
3802 ! CALL HMPRNT(4) ! chi^2/Ndf
3803 END IF
3804 CALL hmpwrt(3)
3805 CALL hmpwrt(12)
3806 CALL hmpwrt(4)
3807 CALL gmpwrt(4) ! location, dispersion (res.) as a function of record nr
3808 IF (nloopn <= lfitnp) THEN
3809 CALL hmpwrt(13)
3810 CALL hmpwrt(14)
3811 CALL gmpwrt(5) ! location, dispersion (pull) as a function of record nr
3812 END IF
3813 END IF
3814 ! IF(NLOOPN.EQ.2.AND.NHISTP.NE.0) CALL HMPRNT(6)
3815 IF(nloopn == 2) CALL hmpwrt(6)
3816 IF(nloopn <= 1) THEN
3817 ! IF(NHISTP.NE.0) CALL HMPRNT(5) ! number of degrees of freedom
3818 ! IF(NHISTP.NE.0) CALL HMPRNT(11) ! Nlocal
3819 CALL hmpwrt(5)
3820 CALL hmpwrt(11)
3821 CALL hmpwrt(16)
3822 END IF
3823
3824 ! local fit: band matrix structure !?
3825 IF (nloopn == 1.AND.nbndr(1)+nbndr(2) > 0) THEN
3826 DO lun=6,8,2
3827 WRITE(lun,*) ' '
3828 WRITE(lun,*) ' === local fits have bordered band matrix structure ==='
3829 IF (nbndr(1) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(1),'number of records (upper/left border)'
3830 IF (nbndr(2) > 0 ) WRITE(lun,101) ' NBNDR',nbndr(2),'number of records (lower/right border)'
3831 WRITE(lun,101) ' NBDRX',nbdrx,'max border size'
3832 WRITE(lun,101) ' NBNDX',nbndx,'max band width'
3833 END DO
3834 END IF
3835
3836 lastit=iterat
3837
3838 ! monitoring of residuals
3839 IF (imonit < 0 .OR. (nloopn == 1 .AND. btest(imonit,0))) CALL monres
3840
3841101 FORMAT(1x,a8,' =',i14,' = ',a)
3842! 101 FORMAT(' LOOPN',I6,' Function value',F22.8,10X,I6,' records')
3843! 102 FORMAT(' incl. constraint penalty',F22.8)
3844! 103 FORMAT(I13,3X,A,G12.4)
3845END SUBROUTINE loopn ! loop with fits
3846
3850
3851SUBROUTINE ploopa(lunp)
3852 USE mpmod
3853
3854 IMPLICIT NONE
3855
3856 INTEGER(mpi), INTENT(IN) :: lunp
3857 ! ..
3858 WRITE(lunp,*) ' '
3859 WRITE(lunp,101) ! header line
3860 WRITE(lunp,102) ! header line
3861101 FORMAT(' it fc',' fcn_value dfcn_exp slpr costh iit st', &
3862 ' ls step cutf',1x,'rejects hhmmss FMS')
3863102 FORMAT(' -- --',' ----------- -------- ---- ----- --- --', &
3864 ' -- ----- ----',1x,'------- ------ ---')
3865 RETURN
3866END SUBROUTINE ploopa ! title for iteration
3867
3871
3872SUBROUTINE ploopb(lunp)
3873 USE mpmod
3874
3875 IMPLICIT NONE
3876 INTEGER(mpi) :: ma
3877 INTEGER :: minut
3878 INTEGER(mpi) :: nfa
3879 INTEGER :: nhour
3880 INTEGER(mpl) :: nrej
3881 INTEGER(mpi) :: nsecnd
3882 REAL(mps) :: ratae
3883 REAL :: rstb
3884 REAL(mps) :: secnd
3885 REAL(mps) :: slopes(3)
3886 REAL(mps) :: steps(3)
3887 REAL, DIMENSION(2) :: ta
3888 REAl etime
3889
3890 INTEGER(mpi), INTENT(IN) :: lunp
3891
3892 CHARACTER (LEN=4):: ccalcm(4)
3893 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3894 SAVE
3895
3896 nrej=sum(nrejec) ! rejects
3897 IF(nrej > 9999999) nrej=9999999
3898 rstb=etime(ta)
3899 deltim=rstb-rstart
3900 CALL sechms(deltim,nhour,minut,secnd) ! time
3901 nsecnd=nint(secnd,mpi)
3902 IF(iterat == 0) THEN
3903 WRITE(lunp,103) iterat,nloopn,fvalue, &
3904 chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3905 ELSE
3906 IF (lsinfo == 10) THEN ! line search skipped
3907 WRITE(lunp,105) iterat,nloopn,fvalue,delfun, &
3908 iitera,istopa,chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3909 ELSE
3910 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3911 ratae=max(-99.9,min(99.9,slopes(2)/slopes(1)))
3912 stepl=steps(2)
3913 WRITE(lunp,104) iterat,nloopn,fvalue,delfun,ratae,angras, &
3914 iitera,istopa,lsinfo,stepl, chicut,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3915 ENDIF
3916 END IF
3917103 FORMAT(i3,i3,e12.5,38x,f5.1, 1x,i7, i3,i2.2,i2.2,a4)
3918104 FORMAT(i3,i3,e12.5,1x,e8.2,f6.3,f6.3,i5,2i3,f6.3,f5.1, &
3919 1x,i7, i3,i2.2,i2.2,a4)
3920105 FORMAT(i3,i3,e12.5,1x,e8.2,12x,i5,i3,9x,f5.1, &
3921 1x,i7, i3,i2.2,i2.2,a4)
3922 RETURN
3923END SUBROUTINE ploopb ! iteration line
3924
3928
3929SUBROUTINE ploopc(lunp)
3930 USE mpmod
3931
3932 IMPLICIT NONE
3933 INTEGER(mpi) :: ma
3934 INTEGER(mpi) :: minut
3935 INTEGER(mpi) :: nfa
3936 INTEGER(mpi) :: nhour
3937 INTEGER(mpl) :: nrej
3938 INTEGER(mpi) :: nsecnd
3939 REAL(mps) :: ratae
3940 REAL :: rstb
3941 REAL(mps) :: secnd
3942 REAL(mps) :: slopes(3)
3943 REAL(mps) :: steps(3)
3944 REAL, DIMENSION(2) :: ta
3945 REAL etime
3946
3947 INTEGER(mpi), INTENT(IN) :: lunp
3948 CHARACTER (LEN=4):: ccalcm(4)
3949 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3950 SAVE
3951
3952 nrej=sum(nrejec) ! rejects
3953 IF(nrej > 9999999) nrej=9999999
3954 rstb=etime(ta)
3955 deltim=rstb-rstart
3956 CALL sechms(deltim,nhour,minut,secnd) ! time
3957 nsecnd=nint(secnd,mpi)
3958 IF (lsinfo == 10) THEN ! line search skipped
3959 WRITE(lunp,104) nloopn,fvalue,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3960 ELSE
3961 CALL ptlopt(nfa,ma,slopes,steps) ! slopes steps
3962 ratae=abs(slopes(2)/slopes(1))
3963 stepl=steps(2)
3964 WRITE(lunp,105) nloopn,fvalue, ratae,lsinfo, &
3965 stepl,nrej,nhour,minut,nsecnd,ccalcm(lcalcm)
3966 END IF
3967104 FORMAT(3x,i3,e12.5,9x, 35x, i7, i3,i2.2,i2.2,a4)
3968105 FORMAT(3x,i3,e12.5,9x, f6.3,14x,i3,f6.3,6x, i7, i3,i2.2,i2.2,a4)
3969 RETURN
3970
3971END SUBROUTINE ploopc ! sub-iteration line
3972
3976
3977SUBROUTINE ploopd(lunp)
3978 USE mpmod
3979 IMPLICIT NONE
3980 INTEGER :: minut
3981 INTEGER :: nhour
3982 INTEGER(mpi) :: nsecnd
3983 REAL :: rstb
3984 REAL(mps) :: secnd
3985 REAL, DIMENSION(2) :: ta
3986 REAL etime
3987
3988 INTEGER(mpi), INTENT(IN) :: lunp
3989 CHARACTER (LEN=4):: ccalcm(4)
3990 DATA ccalcm / ' end',' S', ' F ',' FMS' /
3991 SAVE
3992 rstb=etime(ta)
3993 deltim=rstb-rstart
3994 CALL sechms(deltim,nhour,minut,secnd) ! time
3995 nsecnd=nint(secnd,mpi)
3996
3997 WRITE(lunp,106) nhour,minut,nsecnd,ccalcm(lcalcm)
3998106 FORMAT(69x,i3,i2.2,i2.2,a4)
3999 RETURN
4000END SUBROUTINE ploopd
4001
4003SUBROUTINE explfc(lunit)
4004 USE mpdef
4005 USE mpmod, ONLY: metsol
4006
4007 IMPLICIT NONE
4008 INTEGER(mpi) :: lunit
4009 WRITE(lunit,*) ' '
4010 WRITE(lunit,102) 'Explanation of iteration table'
4011 WRITE(lunit,102) '=============================='
4012 WRITE(lunit,101) 'it', &
4013 'iteration number. Global parameters are improved for it > 0.'
4014 WRITE(lunit,102) 'First function evaluation is called iteraton 0.'
4015 WRITE(lunit,101) 'fc', 'number of function evaluations.'
4016 WRITE(lunit,101) 'fcn_value', 'value of 2 x Likelihood function (LF).'
4017 WRITE(lunit,102) 'The final value is the chi^2 value of the fit and should'
4018 WRITE(lunit,102) 'be about equal to the NDF (see below).'
4019 WRITE(lunit,101) 'dfcn_exp', &
4020 'expected reduction of the value of the Likelihood function (LF)'
4021 WRITE(lunit,101) 'slpr', 'ratio of the actual slope to inital slope.'
4022 WRITE(lunit,101) 'costh', &
4023 'cosine of angle between search direction and -gradient'
4024 IF (metsol == 4) THEN
4025 WRITE(lunit,101) 'iit', &
4026 'number of internal iterations in MINRES algorithm'
4027 WRITE(lunit,101) 'st', 'stop code of MINRES algorithm'
4028 WRITE(lunit,102) '< 0: rhs is very special, with beta2 = 0'
4029 WRITE(lunit,102) '= 0: rhs b = 0, i.e. the exact solution is x = 0'
4030 WRITE(lunit,102) '= 1 requested accuracy achieved, as determined by rtol'
4031 WRITE(lunit,102) '= 2 reasonable accuracy achieved, given eps'
4032 WRITE(lunit,102) '= 3 x has converged to an eigenvector'
4033 WRITE(lunit,102) '= 4 matrix ill-conditioned (Acond has exceeded 0.1/eps)'
4034 WRITE(lunit,102) '= 5 the iteration limit was reached'
4035 WRITE(lunit,102) '= 6 Matrix x vector does not define a symmetric matrix'
4036 WRITE(lunit,102) '= 7 Preconditioner does not define a symmetric matrix'
4037 ELSEIF (metsol == 5) THEN
4038 WRITE(lunit,101) 'iit', &
4039 'number of internal iterations in MINRES-QLP algorithm'
4040 WRITE(lunit,101) 'st', 'stop code of MINRES-QLP algorithm'
4041 WRITE(lunit,102) '= 1: beta_{k+1} < eps, iteration k is the final Lanczos step.'
4042 WRITE(lunit,102) '= 2: beta2 = 0. If M = I, b and x are eigenvectors of A.'
4043 WRITE(lunit,102) '= 3: beta1 = 0. The exact solution is x = 0.'
4044 WRITE(lunit,102) '= 4: A solution to (poss. singular) Ax = b found, given rtol.'
4045 WRITE(lunit,102) '= 5: A solution to (poss. singular) Ax = b found, given eps.'
4046 WRITE(lunit,102) '= 6: Pseudoinverse solution for singular LS problem, given rtol.'
4047 WRITE(lunit,102) '= 7: Pseudoinverse solution for singular LS problem, given eps.'
4048 WRITE(lunit,102) '= 8: The iteration limit was reached.'
4049 WRITE(lunit,102) '= 9: The operator defined by Aprod appears to be unsymmetric.'
4050 WRITE(lunit,102) '=10: The operator defined by Msolve appears to be unsymmetric.'
4051 WRITE(lunit,102) '=11: The operator defined by Msolve appears to be indefinite.'
4052 WRITE(lunit,102) '=12: xnorm has exceeded maxxnorm or will exceed it next iteration.'
4053 WRITE(lunit,102) '=13: Acond has exceeded Acondlim or 0.1/eps.'
4054 WRITE(lunit,102) '=14: Least-squares problem but no converged solution yet.'
4055 WRITE(lunit,102) '=15: A null vector obtained, given rtol.'
4056 ENDIF
4057 WRITE(lunit,101) 'ls', 'line search info'
4058 WRITE(lunit,102) '< 0 recalculate function'
4059 WRITE(lunit,102) '= 0: N or STP lt 0 or step not descending'
4060 WRITE(lunit,102) '= 1: Linesearch convergence conditions reached'
4061 WRITE(lunit,102) '= 2: interval of uncertainty at lower limit'
4062 WRITE(lunit,102) '= 3: max nr of line search calls reached'
4063 WRITE(lunit,102) '= 4: step at the lower bound'
4064 WRITE(lunit,102) '= 5: step at the upper bound'
4065 WRITE(lunit,102) '= 6: rounding error limitation'
4066 WRITE(lunit,101) 'step', &
4067 'the factor for the Newton step during the line search. Usually'
4068 WRITE(lunit,102) &
4069 'a value of 1 gives a sufficient reduction of the LF. Oherwise'
4070 WRITE(lunit,102) 'other step values are tried.'
4071 WRITE(lunit,101) 'cutf', &
4072 'cut factor. Local fits are rejected, if their chi^2 value'
4073 WRITE(lunit,102) &
4074 'is larger than the 3-sigma chi^2 value times the cut factor.'
4075 WRITE(lunit,102) 'A cut factor of 1 is used finally, but initially a larger'
4076 WRITE(lunit,102) 'factor may be used. A value of 0.0 means no cut.'
4077 WRITE(lunit,101) 'rejects', 'total number of rejected local fits.'
4078 WRITE(lunit,101) 'hmmsec', 'the time in hours (h), minutes (mm) and seconds.'
4079 WRITE(lunit,101) 'FMS', 'calculation of Function value, Matrix, Solution.'
4080 WRITE(lunit,*) ' '
4081
4082101 FORMAT(a9,' = ',a)
4083102 FORMAT(13x,a)
4084END SUBROUTINE explfc
4085
4093
4094SUBROUTINE mupdat(i,j,add) !
4095 USE mpmod
4096
4097 IMPLICIT NONE
4098
4099 INTEGER(mpi), INTENT(IN) :: i
4100 INTEGER(mpi), INTENT(IN) :: j
4101 REAL(mpd), INTENT(IN) :: add
4102
4103 INTEGER(mpl):: ijadd
4104 INTEGER(mpl):: ijcsr3
4105 INTEGER(mpl):: ia
4106 INTEGER(mpl):: ja
4107 INTEGER(mpl):: ij
4108 ! ...
4109 IF(i <= 0.OR.j <= 0.OR. add == 0.0_mpd) RETURN
4110 ia=max(i,j) ! larger
4111 ja=min(i,j) ! smaller
4112 ij=0
4113 IF(matsto == 3) THEN
4114 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
4115 ij=ijcsr3(i,j) ! inline code requires same time
4116 IF (ij > 0) globalmatd(ij)=globalmatd(ij)+add
4117 RETURN
4118 ELSE ! sparse symmetric matrix (BSR3)
4119 ! block index
4120 ij=ijcsr3((i-1)/matbsz+1,(j-1)/matbsz+1)
4121 IF (ij > 0) THEN
4122 ! index of first element in block
4123 ij=(ij-1)*matbsz*matbsz+1
4124 ! adjust index for position in block
4125 ij=ij+mod(int(ia-1,mpi),matbsz)*matbsz+mod(int(ja-1,mpi),matbsz)
4126 globalmatd(ij)=globalmatd(ij)+add
4127 ENDIF
4128 RETURN
4129 END IF
4130 ELSE IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4131 ij=ijadd(i,j) ! inline code requires same time
4132 IF (ij == 0) RETURN ! pair is suppressed
4133 IF (ij > 0) THEN
4134 globalmatd(ij)=globalmatd(ij)+add
4135 ELSE
4136 globalmatf(-ij)=globalmatf(-ij)+real(add,mps)
4137 END IF
4138 ELSE ! full or unpacked (block diagonal) symmetric matrix
4139 ! global (ia,ib) to local (row,col) in block
4140 ij=globalrowoffsets(ia)+ja
4141 globalmatd(ij)=globalmatd(ij)+add
4142 END IF
4143 ! MINRES preconditioner
4144 IF(metsol >= 4.AND.metsol < 7.AND.mbandw >= 0) THEN
4145 ij=0 ! no update
4146 IF(ia <= nvgb) THEN ! variable global parameter
4147 IF(mbandw > 0) THEN ! band matrix for Cholesky decomposition
4148 ij=indprecond(ia)-ia+ja
4149 IF(ia > 1.AND.ij <= indprecond(ia-1)) ij=0
4150 ELSE ! default preconditioner (diagonal)
4151 IF(ja == ia) ij=ia
4152 END IF
4153 ELSE ! Lagrange multiplier
4154 ij=offprecond(ia-nvgb)+ja
4155 END IF
4156 ! bad index?
4157 IF(ij < 0.OR.ij > size(matprecond)) THEN
4158 CALL peend(23,'Aborted, bad matrix index')
4159 stop 'mupdat: bad index'
4160 END IF
4161 ! update?
4162 IF(ij /= 0) matprecond(ij)=matprecond(ij)+add
4163 END IF
4164END SUBROUTINE mupdat
4165
4166
4178
4179SUBROUTINE mgupdt(i,j1,j2,il,jl,n,sub)
4180 USE mpmod
4181
4182 IMPLICIT NONE
4183
4184 INTEGER(mpi), INTENT(IN) :: i
4185 INTEGER(mpi), INTENT(IN) :: j1
4186 INTEGER(mpi), INTENT(IN) :: j2
4187 INTEGER(mpi), INTENT(IN) :: il
4188 INTEGER(mpi), INTENT(IN) :: jl
4189 INTEGER(mpi), INTENT(IN) :: n
4190 REAL(mpd), INTENT(IN) :: sub((n*n+n)/2)
4191
4192 INTEGER(mpl):: ij
4193 INTEGER(mpl):: ioff
4194 INTEGER(mpi):: ia
4195 INTEGER(mpi):: ia1
4196 INTEGER(mpi):: ib
4197 INTEGER(mpi):: iblast
4198 INTEGER(mpi):: iblock
4199 INTEGER(mpi):: ijl
4200 INTEGER(mpi):: iprc
4201 INTEGER(mpi):: ir
4202 INTEGER(mpi):: ja
4203 INTEGER(mpi):: jb
4204 INTEGER(mpi):: jblast
4205 INTEGER(mpi):: jblock
4206 INTEGER(mpi):: jc
4207 INTEGER(mpi):: jc1
4208 INTEGER(mpi):: jpg
4209 INTEGER(mpi):: k
4210 INTEGER(mpi):: lr
4211 INTEGER(mpi):: nc
4212
4213 INTEGER(mpl) ijcsr3
4214 ! ...
4215 IF(i <= 0.OR.j1 <= 0.OR.j2 > i) RETURN
4216
4217 IF(matsto == 3) THEN ! sparse symmetric matrix (CSR3, upper triangle)
4218 ja=globalallindexgroups(i) ! first (global) column
4219 jb=globalallindexgroups(i+1)-1 ! last (global) column
4220 ia1=globalallindexgroups(j1) ! first (global) row
4221 ! loop over groups (now in same column)
4222 DO jpg=j1,j2
4223 ia=globalallindexgroups(jpg) ! first (global) row in group
4224 ib=globalallindexgroups(jpg+1)-1 ! last (global) row in group
4225 IF (matbsz < 2) THEN
4226 ! CSR3
4227 ij=ijcsr3(ia,ja)
4228 IF (ij == 0) THEN
4229 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc, matsto
4230 stop
4231 END IF
4232 ioff=ij-ja ! offset
4233 DO ir=ia,ib
4234 jc1=max(ir,ja)
4235 k=il+jc1-ja
4236 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4237 DO jc=jc1,jb
4238 globalmatd(ioff+jc)=globalmatd(ioff+jc)-sub(ijl)
4239 ijl=ijl+k
4240 k=k+1
4241 END DO
4242 ioff=ioff+csr3rowoffsets(ir+1)-csr3rowoffsets(ir)-1
4243 END DO
4244 ELSE
4245 ! BSR3
4246 iblast=-1
4247 jblast=-1
4248 ioff=0
4249 DO ir=ia,ib
4250 iblock=(ir-1)/matbsz+1
4251 jc1=max(ir,ja)
4252 k=il+jc1-ja
4253 ijl=(k*k-k)/2+jl+ir-ia1 ! ISYM index offset (subtrahends matrix)
4254 DO jc=jc1,jb
4255 jblock=(jc-1)/matbsz+1
4256 ! index of first element in (new) block
4257 IF (jblock /= jblast.OR.iblock /= iblast) THEN
4258 ioff=(ijcsr3(iblock,jblock)-1)*matbsz*matbsz+1
4259 iblast=iblock
4260 jblast=jblock
4261 END IF
4262 ! adjust index for position in block
4263 ij=ioff+mod(int(ir-1,mpi),matbsz)+mod(int(jc-1,mpi),matbsz)*matbsz
4264 globalmatd(ij)=globalmatd(ij)-sub(ijl)
4265 ijl=ijl+k
4266 k=k+1
4267 END DO
4268 END DO
4269 END IF
4270 END DO
4271 RETURN
4272 END IF
4273
4274 ! lower triangle
4275 ia=globalallindexgroups(i) ! first (global) row
4276 ib=globalallindexgroups(i+1)-1 ! last (global) row
4277 ja=globalallindexgroups(j1) ! first (global) column
4278 jb=globalallindexgroups(j2+1)-1 ! last (global) column
4279
4280 IF(matsto == 2) THEN ! sparse symmetric matrix (custom)
4281 CALL ijpgrp(i,j1,ij,lr,iprc) ! index of first element of group 'j1'
4282 IF (ij == 0) THEN
4283 print *, ' MGUPDT: ij=0', i,j1,j2,il,jl,ij,lr,iprc,matsto
4284 stop
4285 END IF
4286 k=il
4287 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4288 DO ir=ia,ib
4289 nc=min(ir,jb)-ja ! number of columns -1
4290 IF (jb >= ir) THEN ! diagonal element
4291 globalmatd(ir)=globalmatd(ir)-sub(ijl+jl+nc)
4292 nc=nc-1
4293 END IF
4294 ! off-diagonal elements
4295 IF (iprc == 1) THEN
4296 globalmatd(ij:ij+nc)=globalmatd(ij:ij+nc)-sub(ijl+jl:ijl+jl+nc)
4297 ELSE
4298 globalmatf(ij:ij+nc)=globalmatf(ij:ij+nc)-real(sub(ijl+jl:ijl+jl+nc),mps)
4299 END IF
4300 ij=ij+lr
4301 ijl=ijl+k
4302 k=k+1
4303 END DO
4304 ELSE ! full or unpacked (block diagonal) symmetric matrix
4305 k=il
4306 ijl=(k*k-k)/2 ! ISYM index offset (subtrahends matrix)
4307 DO ir=ia,ib
4308 ! global (ir,0) to local (row,col) in block
4309 ij=globalrowoffsets(ir)
4310 nc=min(ir,jb)-ja ! number of columns -1
4311 globalmatd(ij+ja:ij+ja+nc)=globalmatd(ij+ja:ij+ja+nc)-sub(ijl+jl:ijl+jl+nc)
4312 ijl=ijl+k
4313 k=k+1
4314 END DO
4315 END IF
4316
4317END SUBROUTINE mgupdt
4318
4319
4346
4347SUBROUTINE loopbf(nrej,numfil,naccf,chi2f,ndff)
4348 USE mpmod
4349
4350 IMPLICIT NONE
4351 REAL(mpd) :: cauchy
4352 REAL(mps) :: chichi
4353 REAL(mps) :: chlimt
4354 REAL(mps) :: chndf
4355 REAL(mpd) :: chuber
4356 REAL(mpd) :: down
4357 REAL(mpd) :: pull
4358 REAL(mpd) :: r1
4359 REAL(mpd) :: r2
4360 REAL(mps) :: rec
4361 REAL(mpd) :: rerr
4362 REAL(mpd) :: resid
4363 REAL(mps) :: resing
4364 REAL(mpd) :: resmax
4365 REAL(mpd) :: rmeas
4366 REAL(mpd) :: rmloc
4367 REAL(mpd) :: suwt
4368 REAL(mps) :: used
4369 REAL(mpd) :: wght
4370 REAL(mps) :: chindl
4371 INTEGER(mpi) :: i
4372 INTEGER(mpi) :: ia
4373 INTEGER(mpi) :: ib
4374 INTEGER(mpi) :: ibuf
4375 INTEGER(mpi) :: ichunk
4376 INTEGER(mpl) :: icmn
4377 INTEGER(mpl) :: icost
4378 INTEGER(mpi) :: id
4379 INTEGER(mpi) :: idiag
4380 INTEGER(mpi) :: ieq
4381 INTEGER(mpi) :: iext
4382 INTEGER(mpi) :: ij
4383 INTEGER(mpi) :: ije
4384 INTEGER(mpi) :: ijn
4385 INTEGER(mpi) :: ik
4386 INTEGER(mpi) :: ike
4387 INTEGER(mpi) :: il
4388 INTEGER(mpi) :: im
4389 INTEGER(mpi) :: imeas
4390 INTEGER(mpi) :: in
4391 INTEGER(mpi) :: inv
4392 INTEGER(mpi) :: ioffb
4393 INTEGER(mpi) :: ioffc
4394 INTEGER(mpi) :: ioffd
4395 INTEGER(mpi) :: ioffe
4396 INTEGER(mpi) :: ioffi
4397 INTEGER(mpi) :: ioffq
4398 INTEGER(mpi) :: iprc
4399 INTEGER(mpi) :: iprcnx
4400 INTEGER(mpi) :: iprdbg
4401 INTEGER(mpi) :: iproc
4402 INTEGER(mpi) :: irbin
4403 INTEGER(mpi) :: isize
4404 INTEGER(mpi) :: ist
4405 INTEGER(mpi) :: iter
4406 INTEGER(mpi) :: itgbi
4407 INTEGER(mpi) :: ivgbj
4408 INTEGER(mpi) :: ivgbk
4409 INTEGER(mpi) :: ivpgrp
4410 INTEGER(mpi) :: j
4411 INTEGER(mpi) :: j1
4412 INTEGER(mpi) :: ja
4413 INTEGER(mpi) :: jb
4414 INTEGER(mpi) :: jk
4415 INTEGER(mpi) :: jl
4416 INTEGER(mpi) :: jl1
4417 INTEGER(mpi) :: jn
4418 INTEGER(mpi) :: jnx
4419 INTEGER(mpi) :: joffd
4420 INTEGER(mpi) :: joffi
4421 INTEGER(mpi) :: jproc
4422 INTEGER(mpi) :: jrc
4423 INTEGER(mpi) :: jsp
4424 INTEGER(mpi) :: k
4425 INTEGER(mpi) :: kbdr
4426 INTEGER(mpi) :: kbdrx
4427 INTEGER(mpi) :: kbnd
4428 INTEGER(mpi) :: kfl
4429 INTEGER(mpi) :: kx
4430 INTEGER(mpi) :: lvpgrp
4431 INTEGER(mpi) :: mbdr
4432 INTEGER(mpi) :: mbnd
4433 INTEGER(mpi) :: mside
4434 INTEGER(mpi) :: nalc
4435 INTEGER(mpi) :: nalg
4436 INTEGER(mpi) :: nan
4437 INTEGER(mpi) :: nb
4438 INTEGER(mpi) :: ndf
4439 INTEGER(mpi) :: ndown
4440 INTEGER(mpi) :: neq
4441 INTEGER(mpi) :: nfred
4442 INTEGER(mpi) :: nfrei
4443 INTEGER(mpi) :: ngg
4444 INTEGER(mpi) :: nprdbg
4445 INTEGER(mpi) :: nrank
4446 INTEGER(mpl) :: nrc
4447 INTEGER(mpi) :: nst
4448 INTEGER(mpi) :: nter
4449 INTEGER(mpi) :: nweig
4450 INTEGER(mpi) :: ngrp
4451 INTEGER(mpi) :: npar
4452
4453 INTEGER(mpl), INTENT(IN OUT) :: nrej(6)
4454 INTEGER(mpi), INTENT(IN) :: numfil
4455 INTEGER(mpi), INTENT(IN OUT) :: naccf(numfil)
4456 REAL(mps), INTENT(IN OUT) :: chi2f(numfil)
4457 INTEGER(mpi), INTENT(IN OUT) :: ndff(numfil)
4458
4459 REAL(mps) :: cndl10
4460 REAL(mpd) :: dchi2
4461 REAL(mpd) :: dvar
4462 REAL(mpd) :: dw1
4463 REAL(mpd) :: dw2
4464 REAL(mpd) :: evdmin
4465 REAL(mpd) :: evdmax
4466 REAL(mpd) :: summ
4467 INTEGER(mpi) :: ijprec
4468
4469 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
4470
4471 LOGICAL:: lprnt
4472 LOGICAL::lhist
4473
4474 CHARACTER (LEN=3):: chast
4475 DATA chuber/1.345_mpd/ ! constant for Huber down-weighting
4476 DATA cauchy/2.3849_mpd/ ! constant for Cauchy down-weighting
4477 SAVE chuber,cauchy
4478 ! ...
4479
4480 ichunk=min((numreadbuffer+mthrd-1)/mthrd/32+1,256)
4481 ! reset header, 3 words per thread:
4482 ! number of entries, offset to data, indices
4485 nprdbg=0
4486 iprdbg=-1
4487
4488 ! parallelize record loop
4489 ! private copy of NREJ,.. for each thread, combined at end, init with 0.
4490 !$OMP PARALLEL DO &
4491 !$OMP DEFAULT(PRIVATE) &
4492 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI, &
4493 !$OMP readBufferDataD,writeBufferHeader,writeBufferInfo, &
4494 !$OMP writeBufferData,writeBufferIndices,writeBufferUpdates,globalVector,globalCounter, &
4495 !$OMP globalParameter,globalParLabelIndex,globalIndexUsage,backIndexUsage, &
4496 !$OMP measBins,numMeas,measIndex,measRes,measHists,globalAllParToGroup,globalAllIndexGroups, &
4497 !$OMP localCorrections,localEquations,ifd, &
4498 !$OMP NAGB,NVGB,NAGBN,ICALCM,ICHUNK,NLOOPN,NRECER,NPRDBG,IPRDBG, &
4499 !$OMP NEWITE,CHICUT,LHUBER,CHUBER,ITERAT,NRECPR,MTHRD,NSPC,NAEQN, &
4500 !$OMP DWCUT,CHHUGE,NRECP2,CAUCHY,LFITNP,LFITBB,IMONIT,IMONMD,MONPG1,LUNLOG,MDEBUG,CNDLMX) &
4501 !$OMP REDUCTION(+:NREJ,NBNDR,NACCF,CHI2F,NDFF) &
4502 !$OMP REDUCTION(MAX:NBNDX,NBDRX) &
4503 !$OMP REDUCTION(MIN:NREC3) &
4504 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
4505 DO ibuf=1,numreadbuffer ! buffer for current record
4506 jrc=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
4507 kfl=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
4508 nrc=ifd(kfl)+jrc ! global record number
4509 dw1=real(readbufferdatad(readbufferpointer(ibuf)-1),mpd) ! weight
4510 dw2=sqrt(dw1)
4511
4512 iproc=0
4513 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
4514 ioffb=nagb*iproc ! offset 'f'.
4515 ioffc=nagbn*iproc ! offset 'c'.
4516 ioffe=nvgb*iproc ! offset 'e'
4517 ioffd=writebufferheader(-1)*iproc+writebufferinfo(2,iproc+1) ! offset data
4518 ioffi=writebufferheader(1)*iproc+writebufferinfo(3,iproc+1)+3 ! offset indices
4519 ioffq=naeqn*iproc ! offset equations (measurements)
4520 ! ----- reset ------------------------------------------------------
4521 lprnt=.false.
4522 lhist=(iproc == 0)
4523 rec=real(nrc,mps) ! floating point value
4524 IF(nloopn == 1.AND.mod(nrc,100000_mpl) == 0) THEN
4525 WRITE(*,*) 'Record',nrc,' ... still reading'
4526 IF(monpg1>0) WRITE(lunlog,*) 'Record',nrc,' ... still reading'
4527 END IF
4528
4529 ! printout/debug only for one thread at a time
4530
4531
4532 ! flag for record printout -----------------------------------------
4533
4534 lprnt=.false.
4535 IF(newite.AND.(iterat == 1.OR.iterat == 3)) THEN
4536 IF(nrc == nrecpr) lprnt=.true.
4537 IF(nrc == nrecp2) lprnt=.true.
4538 IF(nrc == nrecer) lprnt=.true.
4539 END IF
4540 IF (lprnt)THEN
4541 !$OMP ATOMIC
4542 nprdbg=nprdbg+1 ! number of threads with debug
4543 IF (nprdbg == 1) iprdbg=iproc ! first thread with debug
4544 IF (iproc /= iprdbg) lprnt=.false.
4545 ! print *, ' LPRNT ', NRC, NPRDBG, IPRDBG, IPROC, LPRNT
4546 END IF
4547 IF(lprnt) THEN
4548 WRITE(1,*) ' '
4549 WRITE(1,*) '------------------ Loop',nloopn, &
4550 ': Printout for record',nrc,iproc
4551 WRITE(1,*) ' '
4552 END IF
4553
4554 ! ----- print data -------------------------------------------------
4555
4556 IF(lprnt) THEN
4557 imeas=0 ! local derivatives
4558 ist=readbufferpointer(ibuf)+1
4560 DO ! loop over measurements
4561 CALL isjajb(nst,ist,ja,jb,jsp)
4562 IF(ja == 0) EXIT
4563 IF(imeas == 0) WRITE(1,1121)
4564 imeas=imeas+1
4565 WRITE(1,1122) imeas,readbufferdatad(ja),readbufferdatad(jb), &
4566 (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
4567 END DO
45681121 FORMAT(/'Measured value and local derivatives'/ &
4569 ' i measured std_dev index...derivative ...')
45701122 FORMAT(i3,2g12.4,3(i3,g12.4)/(27x,3(i3,g12.4)))
4571
4572 imeas=0 ! global derivatives
4573 ist=readbufferpointer(ibuf)+1
4575 DO ! loop over measurements
4576 CALL isjajb(nst,ist,ja,jb,jsp)
4577 IF(ja == 0) EXIT
4578 IF(imeas == 0) WRITE(1,1123)
4579 imeas=imeas+1
4580 IF (jb < ist) THEN
4581 IF(ist-jb > 2) THEN
4582 WRITE(1,1124) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4583 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4584 ELSE
4585 WRITE(1,1125) imeas,(globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
4586 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
4587 END IF
4588 END IF
4589 END DO
45901123 FORMAT(/'Global derivatives'/ &
4591 ' i label gindex vindex derivative ...')
45921124 FORMAT(i3,2(i9,i7,i7,g12.4)/(3x,2(i9,i7,i7,g12.4)))
45931125 FORMAT(i3,2(i9,i7,i7,g12.4))
4594 END IF
4595
4596 ! ----- first loop -------------------------------------------------
4597 ! ------ prepare local fit ------
4598 ! count local and global derivates
4599 ! subtract actual alignment parameters from the measured data
4600
4601 IF(lprnt) THEN
4602 WRITE(1,*) ' '
4603 WRITE(1,*) 'Data corrections using values of global parameters'
4604 WRITE(1,*) '=================================================='
4605 WRITE(1,101)
4606 END IF
4607 nalg=0 ! count number of global derivatives
4608 nalc=0 ! count number of local derivatives
4609 neq=0 ! count number of equations
4610
4611 ist=readbufferpointer(ibuf)+1
4613 DO ! loop over measurements
4614 CALL isjajb(nst,ist,ja,jb,jsp)
4615 IF(ja == 0) EXIT
4616 rmeas=real(readbufferdatad(ja),mpd) ! data
4617 neq=neq+1 ! count equation
4618 localequations(1,ioffq+neq)=ja
4619 localequations(2,ioffq+neq)=jb
4620 localequations(3,ioffq+neq)=ist
4621 ! subtract global ... from measured value
4622 DO j=1,ist-jb ! global parameter loop
4623 itgbi=readbufferdatai(jb+j) ! global parameter label
4624 rmeas=rmeas-real(readbufferdatad(jb+j),mpd)*globalparameter(itgbi) ! subtract !!! reversed
4625 IF (icalcm == 1) THEN
4626 ij=globalparlabelindex(2,itgbi) ! -> index of variable global parameter
4627 IF(ij > 0) THEN
4628 ijn=backindexusage(ioffe+ij) ! get index of index
4629 IF(ijn == 0) THEN ! not yet included
4630 nalg=nalg+1 ! count
4631 globalindexusage(ioffc+nalg)=ij ! store global index
4632 backindexusage(ioffe+ij)=nalg ! store back index
4633 END IF
4634 END IF
4635 END IF
4636 END DO
4637 IF(lprnt) THEN
4638 IF (jb < ist) WRITE(1,102) neq,readbufferdatad(ja),rmeas,readbufferdatad(jb)
4639 END IF
4640 readbufferdatad(ja)=real(rmeas,mpr8) ! global contribution subtracted
4641 DO j=1,jb-ja-1 ! local parameter loop
4642 ij=readbufferdatai(ja+j)
4643 nalc=max(nalc,ij) ! number of local parameters
4644 END DO
4645 END DO
4646101 FORMAT(' index measvalue corrvalue sigma')
4647102 FORMAT(i6,2x,2g12.4,' +-',g12.4)
4648
4649 IF(nalc <= 0) GO TO 90
4650
4651 ngg=(nalg*nalg+nalg)/2
4652 ngrp=0
4653 IF (icalcm == 1) THEN
4654 localglobalmatrix(:nalg*nalc)=0.0_mpd ! reset global-local matrix
4655 localglobalmap(:nalg*nalc)=0 ! reset global-local map
4656 ! store parameter group indices
4657 CALL sort1k(globalindexusage(ioffc+1),nalg) ! sort global par.
4658 lvpgrp=-1
4659 npar=0
4660 DO k=1,nalg
4661 iext=globalindexusage(ioffc+k)
4662 backindexusage(ioffe+iext)=k ! update back index
4663 ivpgrp=globalallpartogroup(iext) ! group
4664 IF (ivpgrp /= lvpgrp) THEN
4665 ngrp=ngrp+1
4666 writebufferindices(ioffi+ngrp)=ivpgrp ! global par group indices
4667 lvpgrp=ivpgrp
4668 npar=npar+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4669 END IF
4670 END DO
4671 ! check NPAR==NALG
4672 IF (npar /= nalg) THEN
4673 print *, ' mismatch of number of global parameters ', nrc, nalg, npar, ngrp
4674 print *, globalindexusage(ioffc+1:ioffc+nalg)
4675 print *, writebufferindices(ioffi+1:ioffi+ngrp)
4676 j=0
4677 DO k=1,ngrp
4678 ivpgrp=writebufferindices(ioffi+k)
4679 j=j+globalallindexgroups(ivpgrp+1)-globalallindexgroups(ivpgrp)
4680 IF (globalallpartogroup(globalindexusage(ioffc+j)) /= ivpgrp) &
4681 print *, ' bad group ', k, j, ivpgrp, globalindexusage(ioffc+j)
4682 END DO
4683 CALL peend(35,'Aborted, mismatch of number of global parameters')
4684 stop ' mismatch of number of global parameters '
4685 ENDIF
4686 ! index header
4687 writebufferindices(ioffi-2)=jrc ! record number in file
4688 writebufferindices(ioffi-1)=nalg ! number of global parameters
4689 writebufferindices(ioffi )=ngrp ! number of global par groups
4690 DO k=1,ngg
4691 writebufferupdates(ioffd+k)=0.0_mpd ! reset global-global matrix
4692 END DO
4693 END IF
4694 ! ----- iteration start and check ---------------------------------
4695
4696 nter=1 ! first loop without down-weighting
4697 IF(nloopn /= 1.AND.lhuber /= 0) nter=lhuber
4698 localcorrections(ioffq+1:ioffq+neq) = 0._mpd
4699
4700 ! check matrix for bordered band structure (MBDR+MBND+1 <= NALC)
4701 mbnd=-1
4702 mbdr=nalc
4703 mside=-1 ! side (1: upper/left border, 2: lower/right border)
4704 DO i=1, 2*nalc
4705 ibandh(i)=0
4706 END DO
4707 idiag=1
4708
4709 iter=0
4710 resmax=0.0
4711 DO WHILE(iter < nter) ! outlier suppresssion iteration loop
4712 iter=iter+1
4713 resmax=0.0
4714 IF(lprnt) THEN
4715 WRITE(1,*) ' '
4716 WRITE(1,*) 'Outlier-suppression iteration',iter,' of',nter
4717 WRITE(1,*) '=========================================='
4718 WRITE(1,*) ' '
4719 imeas=0
4720 END IF
4721
4722 ! ----- second loop ------------------------------------------------
4723 ! accumulate normal equations for local fit and determine solution
4724 DO i=1,nalc
4725 blvec(i)=0.0_mpd ! reset vector
4726 END DO
4727 DO i=1,(nalc*nalc+nalc)/2 ! GF: FIXME - not really, local parameter number...
4728 clmat(i)=0.0_mpd ! (p)reset matrix
4729 END DO
4730 ndown=0
4731 nweig=0
4732 cndl10=0.
4733 DO ieq=1,neq! loop over measurements
4734 ja=localequations(1,ioffq+ieq)
4735 jb=localequations(2,ioffq+ieq)
4736 rmeas=real(readbufferdatad(ja),mpd) ! data
4737 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4738 wght =1.0_mpd/rerr**2 ! weight from error
4739 nweig=nweig+1
4740 resid=rmeas-localcorrections(ioffq+ieq) ! subtract previous fit
4741 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4742 IF(iter <= 3) THEN
4743 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4744 wght=wght*chuber*rerr/abs(resid)
4745 ndown=ndown+1
4746 END IF
4747 ELSE ! Cauchy
4748 wght=wght/(1.0+(resid/rerr/cauchy)**2)
4749 END IF
4750 END IF
4751
4752 IF(lprnt.AND.iter /= 1.AND.nter /= 1) THEN
4753 chast=' '
4754 IF(abs(resid) > chuber*rerr) chast='* '
4755 IF(abs(resid) > 3.0*rerr) chast='** '
4756 IF(abs(resid) > 6.0*rerr) chast='***'
4757 IF(imeas == 0) WRITE(1,*) 'Second loop: accumulate'
4758 IF(imeas == 0) WRITE(1,103)
4759 imeas=imeas+1
4760 down=1.0/sqrt(wght)
4761 r1=resid/rerr
4762 r2=resid/down
4763 WRITE(1,104) imeas,rmeas,resid,rerr,r1,chast,r2
4764 END IF
4765103 FORMAT(' index corrvalue residuum sigma', &
4766 ' nresid cnresid')
4767104 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4768
4769 DO j=1,jb-ja-1 ! normal equations, local parameter loop
4770 ij=readbufferdatai(ja+j) ! local parameter index J
4771 blvec(ij)=blvec(ij)+wght*rmeas*real(readbufferdatad(ja+j),mpd)
4772 DO k=1,j
4773 ik=readbufferdatai(ja+k) ! local parameter index K
4774 jk=(ij*ij-ij)/2+ik ! index in symmetric matrix
4775 clmat(jk)=clmat(jk) & ! force double precision
4776 +wght*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)
4777 ! check for band matrix substructure
4778 IF (iter == 1) THEN
4779 id=iabs(ij-ik)+1
4780 im=min(ij,ik) ! upper/left border
4781 ibandh(id)=max(ibandh(id),im)
4782 im=min(nalc+1-ij,nalc+1-ik) ! lower/rght border (mirrored)
4783 ibandh(nalc+id)=max(ibandh(nalc+id),im)
4784 END IF
4785 END DO
4786 END DO
4787 END DO
4788 ! for non trivial fits check for bordered band matrix structure
4789 IF (iter == 1.AND.nalc > 5.AND.lfitbb > 0) THEN
4790 kx=-1
4791 kbdrx=0
4792 icmn=int(nalc,mpl)**3 ! cost (*6) should improve by at least factor 2
4793 ! upper/left border ?
4794 kbdr=0
4795 DO k=nalc,2,-1
4796 kbnd=k-2
4797 kbdr=max(kbdr,ibandh(k))
4798 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4799 IF (icost < icmn) THEN
4800 icmn=icost
4801 kx=k
4802 kbdrx=kbdr
4803 mside=1
4804 END IF
4805 END DO
4806 IF (kx < 0) THEN
4807 ! lower/right border instead?
4808 kbdr=0
4809 DO k=nalc,2,-1
4810 kbnd=k-2
4811 kbdr=max(kbdr,ibandh(k+nalc))
4812 icost=6*int(nalc-kbdr,mpl)*int(kbnd+kbdr+1,mpl)**2+2*int(kbdr,mpl)**3
4813 IF (icost < icmn) THEN
4814 icmn=icost
4815 kx=k
4816 kbdrx=kbdr
4817 mside=2
4818 END IF
4819 END DO
4820 END IF
4821 IF (kx > 0) THEN
4822 mbnd=kx-2
4823 mbdr=kbdrx
4824 END IF
4825 END IF
4826
4827 IF (mbnd >= 0) THEN
4828 ! fast solution for border banded matrix (inverse for ICALCM>0)
4829 IF (nloopn == 1) THEN
4830 nbndr(mside)=nbndr(mside)+1
4831 nbdrx=max(nbdrx,mbdr)
4832 nbndx=max(nbndx,mbnd)
4833 END IF
4834
4835 inv=0
4836 IF (nloopn <= lfitnp.AND.iter == 1) inv=1 ! band part of inverse (for pulls)
4837 IF (icalcm == 1.OR.lprnt) inv=2 ! complete inverse
4838 IF (mside == 1) THEN
4839 CALL sqmibb(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4840 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4841 ELSE
4842 CALL sqmibb2(clmat,blvec,nalc,mbdr,mbnd,inv,nrank, &
4843 vbnd,vbdr,aux,vbk,vzru,scdiag,scflag,evdmin,evdmax)
4844 ENDIF
4845 ! log10(condition of band part)
4846 IF (evdmin > 0.0_mpl) cndl10=log10(real(evdmax/evdmin,mps))
4847 IF (lhist.AND.nloopn == 1) CALL hmpent(16,cndl10)
4848 ELSE
4849 ! full inversion and solution
4850 inv=2
4851 CALL sqminv(clmat,blvec,nalc,nrank,scdiag,scflag)
4852 END IF
4853 ! check for NaNs
4854 nan=0
4855 DO k=1, nalc
4856 IF ((.NOT.(blvec(k) <= 0.0_mpd)).AND. (.NOT.(blvec(k) > 0.0_mpd))) nan=nan+1
4857 END DO
4858
4859 IF(lprnt) THEN
4860 WRITE(1,*) ' '
4861 WRITE(1,*) 'Parameter determination:',nalc,' parameters,', ' rank=',nrank
4862 WRITE(1,*) '-----------------------'
4863 IF(ndown /= 0) WRITE(1,*) ' ',ndown,' data down-weighted'
4864 WRITE(1,*) ' '
4865 END IF
4866
4867 ! ----- third loop -------------------------------------------------
4868 ! calculate single residuals remaining after local fit and chi^2
4869
4870 summ=0.0_mpd
4871 suwt=0.0
4872 imeas=0
4873 DO ieq=1,neq! loop over measurements
4874 ja=localequations(1,ioffq+ieq)
4875 jb=localequations(2,ioffq+ieq)
4876 ist=localequations(3,ioffq+ieq)
4877 rmeas=real(readbufferdatad(ja),mpd) ! data (global contrib. subtracted)
4878 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
4879 wght =1.0_mpd/rerr**2 ! weight from error
4880 rmloc=0.0 ! local fit result reset
4881 DO j=1,jb-ja-1 ! local parameter loop
4882 ij=readbufferdatai(ja+j)
4883 rmloc=rmloc+real(readbufferdatad(ja+j),mpd)*blvec(ij) ! local fit result
4884 END DO
4885 localcorrections(ioffq+ieq)=rmloc ! save local fit result
4886 rmeas=rmeas-rmloc ! reduced to residual
4887
4888 ! calculate pulls? (needs covariance matrix)
4889 IF(iter == 1.AND.inv > 0.AND.nloopn <= lfitnp) THEN
4890 dvar=0.0_mpd
4891 DO j=1,jb-ja-1
4892 ij=readbufferdatai(ja+j)
4893 jk=(ij*ij-ij)/2 ! index in symmetric matrix, row offset
4894 ! off diagonal (symmetric)
4895 DO k=1,j-1
4896 ik=readbufferdatai(ja+k)
4897 dvar=dvar+clmat(jk+ik)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+k),mpd)*2.0_mpd
4898 END DO
4899 ! diagonal
4900 dvar=dvar+clmat(jk+ij)*real(readbufferdatad(ja+j),mpd)*real(readbufferdatad(ja+j),mpd)
4901 END DO
4902 ! some variance left to define a pull?
4903 IF (0.999999_mpd/wght > dvar) THEN
4904 pull=rmeas/sqrt(1.0_mpd/wght-dvar)
4905 IF (lhist) THEN
4906 IF (jb < ist) THEN
4907 CALL hmpent(13,real(pull,mps)) ! histogram pull
4908 CALL gmpms(5,rec,real(pull,mps))
4909 ELSE
4910 CALL hmpent(14,real(pull,mps)) ! histogram pull
4911 END IF
4912 END IF
4913 ! monitoring
4914 IF (imonit /= 0) THEN
4915 IF (jb < ist) THEN
4916 ij=readbufferdatai(jb+1) ! group by first global label
4917 if (imonmd == 0) THEN
4918 irbin=min(measbins,max(1,int(pull*rerr/measres(ij)/measbinsize+0.5*real(measbins,mpd))))
4919 ELSE
4920 irbin=min(measbins,max(1,int(pull/measbinsize+0.5*real(measbins,mpd))))
4921 ENDIF
4922 irbin=irbin+measbins*(measindex(ij)-1+nummeas*iproc)
4923 meashists(irbin)=meashists(irbin)+1
4924 ENDIF
4925 ENDIF
4926 END IF
4927 END IF
4928
4929 IF(iter == 1.AND.jb < ist.AND.lhist) &
4930 CALL gmpms(4,rec,real(rmeas/rerr,mps)) ! residual (with global deriv.)
4931
4932 dchi2=wght*rmeas*rmeas
4933 ! DCHIT=DCHI2
4934 resid=rmeas
4935 IF(nloopn /= 1.AND.iter /= 1.AND.lhuber /= 0) THEN
4936 IF(iter <= 3) THEN
4937 IF(abs(resid) > chuber*rerr) THEN ! down-weighting
4938 wght=wght*chuber*rerr/abs(resid)
4939 dchi2=2.0*chuber*(abs(resid)/rerr-0.5*chuber)
4940 END IF
4941 ELSE
4942 wght=wght/(1.0_mpd+(resid/rerr/cauchy)**2)
4943 dchi2=log(1.0_mpd+(resid/rerr/cauchy)**2)*cauchy**2
4944 END IF
4945 END IF
4946
4947 down=1.0/sqrt(wght)
4948
4949 ! SUWT=SUWT+DCHI2/DCHIT
4950 suwt=suwt+rerr/down
4951 IF(lprnt) THEN
4952 chast=' '
4953 IF(abs(resid) > chuber*rerr) chast='* '
4954 IF(abs(resid) > 3.0*rerr) chast='** '
4955 IF(abs(resid) > 6.0*rerr) chast='***'
4956 IF(imeas == 0) WRITE(1,*) 'Third loop: single residuals'
4957 IF(imeas == 0) WRITE(1,105)
4958 imeas=imeas+1
4959 r1=resid/rerr
4960 r2=resid/down
4961 IF(resid < 0.0) r1=-r1
4962 IF(resid < 0.0) r2=-r2
4963 WRITE(1,106) imeas,readbufferdatad(ja),rmeas,rerr,r1,chast,r2
4964 END IF
4965105 FORMAT(' index corrvalue residuum sigma', &
4966 ' nresid cnresid')
4967106 FORMAT(i6,2x,2g12.4,' +-',g12.4,f7.2,1x,a3,f8.2)
4968
4969 IF(iter == nter) THEN
4970 readbufferdatad(ja)=real(rmeas,mpr8) ! store remaining residual
4971 resmax=max(resmax,abs(rmeas)/rerr)
4972 END IF
4973
4974 IF(iter == 1.AND.lhist) THEN
4975 IF (jb < ist) THEN
4976 CALL hmpent( 3,real(rmeas/rerr,mps)) ! histogram norm residual
4977 ELSE
4978 CALL hmpent(12,real(rmeas/rerr,mps)) ! histogram norm residual
4979 END IF
4980 END IF
4981 summ=summ+dchi2 ! accumulate chi-square sum
4982 END DO
4983
4984 ndf=neq-nrank
4985 resing=(real(nweig,mps)-real(suwt,mps))/real(nweig,mps)
4986 IF (lhist) THEN
4987 IF(iter == 1) CALL hmpent( 5,real(ndf,mps)) ! histogram Ndf
4988 IF(iter == 1) CALL hmpent(11,real(nalc,mps)) ! histogram Nlocal
4989 IF(nloopn == 2.AND.iter == nter) CALL hmpent(6,resing)
4990 END IF
4991 IF(lprnt) THEN
4992 WRITE(1,*) ' '
4993 WRITE(1,*) 'Chi^2=',summ,' at',ndf,' degrees of freedom: ', &
4994 '3-sigma limit is',chindl(3,ndf)*real(ndf,mps)
4995 WRITE(1,*) suwt,' is sum of factors, compared to',nweig, &
4996 ' Downweight fraction:',resing
4997 END IF
4998 IF(nan > 0) THEN
4999 nrej(1)=nrej(1)+1 ! count cases
5000 IF (nrec3 == huge(nrec3)) nrec3=nrc
5001 IF(lprnt) THEN
5002 WRITE(1,*) ' NaNs ', nalc, nrank, nan
5003 WRITE(1,*) ' ---> rejected!'
5004 END IF
5005 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-1 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5006 GO TO 90
5007 END IF
5008 IF(nrank /= nalc) THEN
5009 nrej(2)=nrej(2)+1 ! count cases
5010 IF (nrec3 == huge(nrec3)) nrec3=nrc
5011 IF(lprnt) THEN
5012 WRITE(1,*) ' rank deficit', nalc, nrank
5013 WRITE(1,*) ' ---> rejected!'
5014 END IF
5015 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-2 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5016 GO TO 90
5017 END IF
5018 IF(cndl10 > cndlmx) THEN
5019 nrej(3)=nrej(3)+1 ! count cases
5020 IF (nrec3 == huge(nrec3)) nrec3=nrc
5021 IF(lprnt) THEN
5022 WRITE(1,*) ' too large condition(band part) ', nalc, nrank, cndl10
5023 WRITE(1,*) ' ---> rejected!'
5024 END IF
5025 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-3 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5026 GO TO 90
5027 END IF
5028 IF(ndf <= 0) THEN
5029 nrej(4)=nrej(4)+1 ! count cases
5030 IF(lprnt) THEN
5031 WRITE(1,*) ' Ndf<=0', nalc, nrank, ndf
5032 WRITE(1,*) ' ---> rejected!'
5033 END IF
5034 IF (mdebug < 0.AND.nloopn == 1) print *, ' bad local fit-4 ', kfl,jrc,nrc,mside,neq,nalc,nrank,nan,cndl10
5035 GO TO 90
5036 END IF
5037
5038 chndf=real(summ/real(ndf,mpd),mps)
5039
5040 IF(iter == 1.AND.lhist) CALL hmpent(4,chndf) ! histogram chi^2/Ndf
5041 END DO ! outlier iteration loop
5042
5043 ! ----- reject eventually ------------------------------------------
5044
5045 IF(newite.AND.iterat == 2) THEN ! find record with largest Chi^2/Ndf
5046 IF(nrecp2 < 0.AND.chndf > writebufferdata(2,iproc+1)) THEN
5047 writebufferdata(2,iproc+1)=chndf
5048 writebufferinfo(8,iproc+1)=jrc
5049 writebufferinfo(9,iproc+1)=kfl
5050 END IF
5051 END IF
5052
5053 chichi=chindl(3,ndf)*real(ndf,mps)
5054 ! GF IF(SUMM.GT.50.0*CHICHI) THEN ! huge
5055 ! CHK CHICUT<0: NO cut (1st iteration)
5056 IF(chicut >= 0.0) THEN
5057 IF(summ > chhuge*chichi) THEN ! huge
5058 nrej(5)=nrej(5)+1 ! count cases with huge chi^2
5059 IF(lprnt) THEN
5060 WRITE(1,*) ' ---> rejected!'
5061 END IF
5062 GO TO 90
5063 END IF
5064
5065 IF(chicut > 0.0) THEN
5066 chlimt=chicut*chichi
5067 ! WRITE(*,*) 'chi^2 ',SUMM,CHLIMT,CHICUT,CHINDL(3,NDF),NDF
5068 IF(summ > chlimt) THEN
5069 IF(lprnt) THEN
5070 WRITE(1,*) ' ---> rejected!'
5071 END IF
5072 ! add to FVALUE
5073 dchi2=chlimt ! total contribution limit
5074 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5075 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5076 GO TO 90
5077 END IF
5078 END IF
5079 END IF
5080
5081 IF(lhuber > 1.AND.dwcut /= 0.0.AND.resing > dwcut) THEN
5082 ! add to FVALUE
5083 dchi2=summ ! total contribution
5084 CALL addsums(iproc+1, dchi2, ndf, dw1) ! add total contribution
5085 nrej(6)=nrej(6)+1 ! count cases with large chi^2
5086 ! WRITE(*,*) 'Downweight fraction cut ',RESING,DWCUT,SUMM
5087 IF(lprnt) THEN
5088 WRITE(1,*) ' ---> rejected!'
5089 END IF
5090 GO TO 90
5091 END IF
5092
5093 IF(newite.AND.iterat == 2) THEN ! find record with largest residual
5094 IF(nrecpr < 0.AND.resmax > writebufferdata(1,iproc+1)) THEN
5095 writebufferdata(1,iproc+1)=real(resmax,mps)
5096 writebufferinfo(6,iproc+1)=jrc
5097 writebufferinfo(7,iproc+1)=kfl
5098 END IF
5099 END IF
5100 ! 'track quality' per binary file: accepted records
5101 naccf(kfl)=naccf(kfl)+1
5102 ndff(kfl) =ndff(kfl) +ndf
5103 chi2f(kfl)=chi2f(kfl)+chndf
5104
5105 ! ----- fourth loop ------------------------------------------------
5106 ! update of global matrix and vector according to the "Millepede"
5107 ! principle, from the global/local information
5108
5109 summ=0.0_mpd
5110 DO ieq=1,neq! loop over measurements
5111 ja=localequations(1,ioffq+ieq)
5112 jb=localequations(2,ioffq+ieq)
5113 ist=localequations(3,ioffq+ieq)
5114 rmeas=real(readbufferdatad(ja),mpd) ! data residual
5115 rerr =real(readbufferdatad(jb),mpd) ! ... and the error
5116 wght =1.0_mpd/rerr**2 ! weight from measurement error
5117 dchi2=wght*rmeas*rmeas ! least-square contribution
5118
5119 IF(nloopn /= 1.AND.lhuber /= 0) THEN ! check residual
5120 resid=abs(rmeas)
5121 IF(resid > chuber*rerr) THEN
5122 wght=wght*chuber*rerr/resid ! down-weighting
5123 dchi2=2.0*chuber*(resid/rerr-0.5*chuber) ! modified contribution
5124 END IF
5125 END IF
5126 ! sum up
5127 summ=summ+dchi2
5128
5129 ! global-global matrix contribution: add directly to gg-matrix
5130
5131 DO j=1,ist-jb
5132 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5133 IF (readbufferdatad(jb+j) == 0.0_mpd) cycle ! skip zero global derivatives
5134 IF(ivgbj > 0) THEN
5135 globalvector(ioffb+ivgbj)=globalvector(ioffb+ivgbj) &
5136 +dw1*wght*rmeas*real(readbufferdatad(jb+j),mpd) ! vector !!! reverse
5137 globalcounter(ioffb+ivgbj)=globalcounter(ioffb+ivgbj)+1
5138 IF(icalcm == 1) THEN
5139 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5140 DO k=1,j
5142 IF(ivgbk > 0) THEN
5143 ike=backindexusage(ioffe+ivgbk) ! get index of index, non-zero
5144 ia=max(ije,ike) ! larger
5145 ib=min(ije,ike) ! smaller
5146 ij=ib+(ia*ia-ia)/2
5147 writebufferupdates(ioffd+ij)=writebufferupdates(ioffd+ij) &
5148 -dw1*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(jb+k),mpd)
5149 END IF
5150 END DO
5151 END IF
5152 END IF
5153 END DO
5154
5155 ! normal equations - rectangular matrix for global/local pars
5156 ! global-local matrix contribution: accumulate rectangular matrix
5157 IF (icalcm /= 1) cycle
5158 DO j=1,ist-jb
5159 ivgbj=globalparlabelindex(2,readbufferdatai(jb+j)) ! -> index of variable global parameter
5160 IF(ivgbj > 0) THEN
5161 ije=backindexusage(ioffe+ivgbj) ! get index of index, non-zero
5162 DO k=1,jb-ja-1
5163 ik=readbufferdatai(ja+k) ! local index
5164 jk=ik+(ije-1)*nalc ! matrix index
5166 dw2*wght*real(readbufferdatad(jb+j),mpd)*real(readbufferdatad(ja+k),mpd)
5168 END DO
5169 END IF
5170 END DO
5171 END DO
5172 ! add to total objective function
5173 CALL addsums(iproc+1, summ, ndf, dw1)
5174
5175 ! ----- final matrix update ----------------------------------------
5176 ! update global matrices and vectors
5177 IF(icalcm /= 1) GO TO 90 ! matrix update
5178 ! (inverse local matrix) * (rectang. matrix) -> CORM
5179 ! T
5180 ! resulting symmetrix matrix = G * Gamma^{-1} * G
5181
5182 ! check sparsity of localGlobalMatrix (with par. groups)
5183 isize=nalc+nalg+1 ! row/clolumn offsets
5184 ! check rows
5185 k=0 ! offset
5186 DO i=1, nalg
5187 localglobalstructure(i)=isize
5188 DO j=1, nalc
5189 IF (localglobalmap(k+j) > 0) THEN
5190 localglobalstructure(isize+1)=j ! column
5191 localglobalstructure(isize+2)=k+j ! index
5192 isize=isize+2
5193 ENDIF
5194 END DO
5195 k=k+nalc
5196 END DO
5197 ! <50% non-zero elements?
5198 IF (isize-localglobalstructure(1) < nalc*nalg) THEN
5199 ! check columns (too)
5200 DO j=1, nalc
5201 localglobalstructure(nalg+j)=isize
5202 k=0 ! offset
5203 DO i=1, nalg
5204 IF (localglobalmap(k+j) > 0) THEN
5205 localglobalstructure(isize+1)=i ! row
5206 localglobalstructure(isize+2)=k+j ! index
5207 isize=isize+2
5208 ENDIF
5209 k=k+nalc
5210 END DO
5211 END DO
5212 localglobalstructure(nalg+nalc+1)=isize
5214 ELSE
5215 CALL dbavat(clmat,localglobalmatrix,writebufferupdates(ioffd+1),nalc,nalg,1)
5216 END IF
5217 ! (rectang. matrix) * (local param vector) -> CORV
5218 ! resulting vector = G * q (q = local parameter)
5219 ! CALL DBGAX(DQ(IGLMA/2+1),BLVEC,DQ(ICORV/2+1),NALG,NALC) ! not done
5220 ! the vector update is not done, because after local fit it is zero!
5221
5222 ! update cache status
5223 writebufferinfo(1,iproc+1)=writebufferinfo(1,iproc+1)+1
5224 writebufferinfo(2,iproc+1)=writebufferinfo(2,iproc+1)+ngg
5225 writebufferinfo(3,iproc+1)=writebufferinfo(3,iproc+1)+ngrp+3
5226 ! check free space
5227 nfred=writebufferheader(-1)-writebufferinfo(2,iproc+1)-writebufferheader(-2)
5229 IF (nfred < 0.OR.nfrei < 0) THEN ! need to flush
5230 nb=writebufferinfo(1,iproc+1)
5231 joffd=writebufferheader(-1)*iproc ! offset data
5232 joffi=writebufferheader(1)*iproc+3 ! offset indices
5233 used=real(writebufferinfo(2,iproc+1),mps)/real(writebufferheader(-1),mps)
5234 writebufferinfo(4,iproc+1)=writebufferinfo(4,iproc+1) +nint(1000.0*used,mpi)
5235 used=real(writebufferinfo(3,iproc+1),mps)/real(writebufferheader(1),mps)
5236 writebufferinfo(5,iproc+1)=writebufferinfo(5,iproc+1) +nint(1000.0*used,mpi)
5237 !$OMP CRITICAL
5240
5241 DO ib=1,nb
5242 nalg=writebufferindices(joffi-1)
5243 il=1 ! row in update matrix
5244 DO in=1,writebufferindices(joffi)
5245 i=writebufferindices(joffi+in)
5246 j=writebufferindices(joffi+1) ! 1. group
5247 iprc=ijprec(i,j) ! group pair precision
5248 jl=1 ! col in update matrix
5249 ! start (rows) for continous groups
5250 j1=j
5251 jl1=jl
5252 ! other groups for row
5253 DO jn=2,in
5255 jnx=writebufferindices(joffi+jn) ! next group
5256 iprcnx=ijprec(i,jnx) ! group pair precision
5257 ! end of continous groups?
5258 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5259 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5260 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5261 ! restart continous groups
5262 j1=jnx ! new 1. column
5263 jl1=jl
5264 iprc=iprcnx
5265 END IF
5266 j=jnx ! last group
5267 END DO
5268 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5269 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5271 END DO
5272 joffd=joffd+(il*il-il)/2
5273 joffi=joffi+writebufferindices(joffi)+3
5274 END DO
5275 !$OMP END CRITICAL
5276 ! reset counter, pointers
5277 DO k=1,3
5278 writebufferinfo(k,iproc+1)=0
5279 END DO
5280 END IF
5281
528290 IF(lprnt) THEN
5283 WRITE(1,*) ' '
5284 WRITE(1,*) '------------------ End of printout for record',nrc
5285 WRITE(1,*) ' '
5286 END IF
5287
5288 DO i=1,nalg ! reset global index array
5289 iext=globalindexusage(ioffc+i)
5290 backindexusage(ioffe+iext)=0
5291 END DO
5292
5293 END DO
5294 !$OMP END PARALLEL DO
5295
5296 IF (icalcm == 1) THEN
5297 ! flush remaining matrices
5298 DO k=1,mthrd ! update statistics
5300 used=real(writebufferinfo(2,k),mps)/real(writebufferheader(-1),mps)
5301 writebufferinfo(4,k)=writebufferinfo(4,k)+nint(1000.0*used,mpi)
5304 writebufferinfo(4,k)=0
5306 used=real(writebufferinfo(3,k),mps)/real(writebufferheader(1),mps)
5307 writebufferinfo(5,k)=writebufferinfo(5,k)+nint(1000.0*used,mpi)
5310 writebufferinfo(5,k)=0
5311 END DO
5312
5313 !$OMP PARALLEL &
5314 !$OMP DEFAULT(PRIVATE) &
5315 !$OMP SHARED(writeBufferHeader,writeBufferInfo,writeBufferIndices,writeBufferUpdates,MTHRD) &
5316 !$OMP SHARED(globalAllParToGroup,globalAllIndexGroups,nspc)
5317 iproc=0
5318 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5319 DO jproc=0,mthrd-1
5320 nb=writebufferinfo(1,jproc+1)
5321 ! print *, ' flush end ', JPROC, NRC, NB
5322 joffd=writebufferheader(-1)*jproc ! offset data
5323 joffi=writebufferheader(1)*jproc+3 ! offset indices
5324 DO ib=1,nb
5325 ! print *, ' buf end ', JPROC,IB,writeBufferIndices(JOFFI-2),writeBufferIndices(JOFFI)
5326 nalg=writebufferindices(joffi-1)
5327 il=1 ! row in update matrix
5328 DO in=1,writebufferindices(joffi)
5329 i=writebufferindices(joffi+in)
5330 !$ IF (MOD(I,MTHRD).EQ.IPROC) THEN
5331 j=writebufferindices(joffi+1) ! 1. group
5332 iprc=ijprec(i,j) ! group pair precision
5333 jl=1 ! col in update matrix
5334 ! start (rows) for continous groups
5335 j1=j
5336 jl1=jl
5337 ! other groups for row
5338 DO jn=2,in
5340 jnx=writebufferindices(joffi+jn) ! next group
5341 iprcnx=ijprec(i,jnx) ! group pair precision
5342 ! end of continous groups?
5343 IF (.NOT.((jnx == j+1).AND.(iprc == iprcnx))) THEN
5344 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! matrix update
5345 !print *, ' update ', ib,i,j1,j,il,jl1,0,iprc,jnx,iprcnx
5346 ! restart continous groups
5347 j1=jnx ! new 1. column
5348 jl1=jl
5349 iprc=iprcnx
5350 END IF
5351 j=jnx ! last group
5352 END DO
5353 CALL mgupdt(i,j1,j,il,jl1,nalg,writebufferupdates(joffd+1)) ! final matrix update
5354 !print *, '.update ', ib, i,j1,j,il,jl1,1,iprc
5355 !$ END IF
5357 END DO
5358 joffd=joffd+(il*il-il)/2
5359 joffi=joffi+writebufferindices(joffi)+3
5360 END DO
5361 END DO
5362 !$OMP END PARALLEL
5363 END IF
5364
5365 IF(newite.AND.iterat == 2) THEN ! get worst records (for printrecord -1 -1)
5366 IF (nrecpr < 0) THEN
5367 DO k=1,mthrd
5368 IF (writebufferdata(1,k) > value1) THEN
5371 END IF
5372 END DO
5373 END IF
5374 IF (nrecp2 < 0) THEN
5375 DO k=1,mthrd
5376 IF (writebufferdata(2,k) > value2) THEN
5379 END IF
5380 END DO
5381 END IF
5382 END IF
5383
5384END SUBROUTINE loopbf
5385
5386!***********************************************************************
5387
5390SUBROUTINE prtrej(lun)
5391 USE mpmod
5392
5393 IMPLICIT NONE
5394 INTEGER(mpi), INTENT(IN) :: lun
5395
5396 IF (nrejec(1)>0) WRITE(lun,*) nrejec(1), ' (local solution contains NaNs)'
5397 IF (nrejec(2)>0) WRITE(lun,*) nrejec(2), ' (local matrix with rank deficit)'
5398 IF (nrejec(3)>0) WRITE(lun,*) nrejec(3), ' (local matrix with ill condition)'
5399 IF (nrejec(4)>0) WRITE(lun,*) nrejec(4), ' (local fit with Ndf=0)'
5400 IF (nrejec(5)>0) WRITE(lun,*) nrejec(5), ' (local fit with huge Chi2(Ndf))'
5401 IF (nrejec(6)>0) WRITE(lun,*) nrejec(6), ' (local fit with large Chi2(Ndf))'
5402
5403END SUBROUTINE prtrej
5404
5405!***********************************************************************
5406
5419SUBROUTINE prtglo
5420 USE mpmod
5421
5422 IMPLICIT NONE
5423 REAL(mps):: dpa
5424 REAL(mps):: err
5425 REAL(mps):: gcor
5426 INTEGER(mpi) :: i
5427 INTEGER(mpi) :: icom
5428 INTEGER(mpl) :: icount
5429 INTEGER(mpi) :: ie
5430 INTEGER(mpi) :: iev
5431 INTEGER(mpi) :: ij
5432 INTEGER(mpi) :: imin
5433 INTEGER(mpi) :: iprlim
5434 INTEGER(mpi) :: isub
5435 INTEGER(mpi) :: itgbi
5436 INTEGER(mpi) :: itgbl
5437 INTEGER(mpi) :: ivgbi
5438 INTEGER(mpi) :: j
5439 INTEGER(mpi) :: label
5440 INTEGER(mpi) :: lup
5441 REAL(mps):: par
5442 LOGICAL :: lowstat
5443
5444 REAL(mpd):: diag
5445 REAL(mpd)::gmati
5446 REAL(mpd)::gcor2
5447 INTEGER(mpi) :: labele(3)
5448 REAL(mps):: compnt(3)
5449 SAVE
5450 ! ...
5451
5452 lup=09
5453 CALL mvopen(lup,'millepede.res')
5454
5455 WRITE(*,*) ' '
5456 WRITE(*,*) ' Result of fit for global parameters'
5457 WRITE(*,*) ' ==================================='
5458 WRITE(*,*) ' '
5459
5460 WRITE(*,101)
5461
5462 WRITE(lup,*) 'Parameter ! first 3 elements per line are', &
5463 ' significant (if used as input)'
5464
5465
5466 iprlim=10
5467 DO itgbi=1,ntgb ! all parameter variables
5468 itgbl=globalparlabelindex(1,itgbi)
5469 ivgbi=globalparlabelindex(2,itgbi)
5470 icom=globalparcomments(itgbi) ! comment
5471 IF (icom > 0) WRITE(lup,113) listcomments(icom)%text
5472 par=real(globalparameter(itgbi),mps) ! initial value
5473 icount=0 ! counts
5474 lowstat = .false.
5475 IF(ivgbi > 0) THEN
5476 icount=globalcounter(ivgbi) ! used in last iteration
5477 lowstat = (icount < mreqena) ! too few accepted entries
5478 dpa=real(globalparameter(itgbi)-globalparstart(itgbi),mps) ! difference
5479 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5480 gmati=globalmatd(globalrowoffsets(ivgbi)+ivgbi)
5481 err=sqrt(abs(real(gmati,mps)))
5482 IF(gmati < 0.0_mpd) err=-err
5483 diag=workspacediag(ivgbi)
5484 gcor=-1.0
5485 IF(gmati*diag > 0.0_mpd) THEN ! global correlation
5486 gcor2=1.0_mpd-1.0_mpd/(gmati*diag)
5487 IF(gcor2 >= 0.0_mpd.AND.gcor2 <= 1.0_mpd) gcor=real(sqrt(gcor2),mps)
5488 END IF
5489 END IF
5490 END IF
5491 IF(ipcntr > 1) icount=globalparlabelcounter(itgbi) ! from binary files
5492 IF(lowstat) icount=-(icount+1) ! flag 'lowstat' with icount < 0
5493 IF(ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5494 IF(itgbi <= iprlim) THEN
5495 IF(ivgbi <= 0) THEN
5496 WRITE(* ,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5497 ELSE
5498 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5499 IF (igcorr == 0) THEN
5500 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5501 ELSE
5502 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5503 END IF
5504 ELSE
5505 WRITE(*,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5506 END IF
5507 END IF
5508 ELSE IF(itgbi == iprlim+1) THEN
5509 WRITE(* ,*) '... (further printout suppressed, but see log file)'
5510 END IF
5511
5512 ! file output
5513 IF(ivgbi <= 0) THEN
5514 IF (ipcntr /= 0) THEN
5515 WRITE(lup,110) itgbl,par,real(globalparpresigma(itgbi),mps),icount
5516 ELSE
5517 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps)
5518 END IF
5519 ELSE
5520 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
5521 IF (ipcntr /= 0) THEN
5522 WRITE(lup,112) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,icount
5523 ELSE IF (igcorr /= 0) THEN
5524 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err,gcor
5525 ELSE
5526 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,err
5527 END IF
5528 ELSE
5529 IF (ipcntr /= 0) THEN
5530 WRITE(lup,111) itgbl,par,real(globalparpresigma(itgbi),mps),dpa,icount
5531 ELSE
5532 WRITE(lup,102) itgbl,par,real(globalparpresigma(itgbi),mps),dpa
5533 END IF
5534 END IF
5535 END IF
5536 END DO
5537 rewind lup
5538 CLOSE(unit=lup)
5539
5540 IF(metsol == 2) THEN ! diagonalisation: write eigenvectors
5541 CALL mvopen(lup,'millepede.eve')
5542 imin=1
5543 DO i=nagb,1,-1
5544 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
5545 imin=i ! index of smallest pos. eigenvalue
5546 EXIT
5547 ENDIF
5548 END DO
5549 iev=0
5550
5551 DO isub=0,min(15,imin-1)
5552 IF(isub < 10) THEN
5553 i=imin-isub
5554 ELSE
5555 i=isub-9
5556 END IF
5557
5558 ! DO I=IMIN,MAX(1,IMIN-9),-1 ! backward loop, up to 10 vectors
5559 WRITE(*,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5560 WRITE(lup,*) 'Eigenvector ',i,' with eigenvalue',workspaceeigenvalues(i)
5561 DO j=1,nagb
5562 ij=j+(i-1)*nagb ! index with eigenvector array
5563 IF(j <= nvgb) THEN
5564 itgbi=globalparvartototal(j)
5565 label=globalparlabelindex(1,itgbi)
5566 ELSE
5567 label=nvgb-j ! label negative for constraints
5568 END IF
5569 iev=iev+1
5570 labele(iev)=label
5571 compnt(iev)=real(workspaceeigenvectors(ij),mps) ! component
5572 IF(iev == 3) THEN
5573 WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5574 iev=0
5575 END IF
5576 END DO
5577 IF(iev /= 0) WRITE(lup,103) (labele(ie),compnt(ie),ie=1,iev)
5578 iev=0
5579 WRITE(lup,*) ' '
5580 END DO
5581 CLOSE(unit=lup)
5582
5583 END IF
5584
5585101 FORMAT(1x,' label parameter presigma differ', &
5586 ' error'/ 1x,'-----------',4x,4('-------------'))
5587102 FORMAT(i10,2x,4g14.5,f8.3)
5588103 FORMAT(3(i11,f11.7,2x))
5589110 FORMAT(i10,2x,2g14.5,28x,i12)
5590111 FORMAT(i10,2x,3g14.5,14x,i12)
5591112 FORMAT(i10,2x,4g14.5,i12)
5592113 FORMAT('!',a)
5593END SUBROUTINE prtglo ! print final log file
5594
5595!***********************************************************************
5596
5606SUBROUTINE prtstat
5607 USE mpmod
5608 USE mpdalc
5609
5610 IMPLICIT NONE
5611 REAL(mps):: par
5612 REAL(mps):: presig
5613 INTEGER(mpi) :: icom
5614 INTEGER(mpl) :: icount
5615 INTEGER(mpi) :: ifrst
5616 INTEGER(mpi) :: ilast
5617 INTEGER(mpi) :: inext
5618 INTEGER(mpi) :: itgbi
5619 INTEGER(mpi) :: itgbl
5620 INTEGER(mpi) :: itpgrp
5621 INTEGER(mpi) :: ivgbi
5622 INTEGER(mpi) :: lup
5623 INTEGER(mpi) :: icgrp
5624 INTEGER(mpi) :: ipgrp
5625 INTEGER(mpi) :: j
5626 INTEGER(mpi) :: jpgrp
5627 INTEGER(mpi) :: k
5628 INTEGER(mpi) :: label1
5629 INTEGER(mpi) :: label2
5630 INTEGER(mpi) :: ncon
5631 INTEGER(mpi) :: npair
5632 INTEGER(mpi) :: nstep
5633 CHARACTER :: c1
5634
5635 INTEGER(mpl):: length
5636
5637 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
5638
5639 INTERFACE ! needed for assumed-shape dummy arguments
5640 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
5641 USE mpdef
5642 INTEGER(mpi), INTENT(IN) :: ipgrp
5643 INTEGER(mpi), INTENT(OUT) :: npair
5644 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
5645 END SUBROUTINE ggbmap
5646 END INTERFACE
5647
5648 SAVE
5649 ! ...
5650
5651 lup=09
5652 CALL mvopen(lup,'millepede.res')
5653 WRITE(lup,*) '*** Results of checking input only, no solution performed ***'
5654 WRITE(lup,*) '! === global parameters ==='
5655 WRITE(lup,*) '! fixed-1: by pre-sigma, -2: by entries cut, -3: by iterated entries cut'
5656 IF (ipcntr < 0) THEN
5657 WRITE(lup,*) '! Label Value Pre-sigma SkippedEntries Cons. group Status '
5658 ELSE
5659 WRITE(lup,*) '! Label Value Pre-sigma Entries Cons. group Status '
5660 END IF
5661 !iprlim=10
5662 DO itgbi=1,ntgb ! all parameter variables
5663 itgbl=globalparlabelindex(1,itgbi)
5664 ivgbi=globalparlabelindex(2,itgbi)
5665 icom=globalparcomments(itgbi) ! comment
5666 IF (icom > 0) WRITE(lup,117) listcomments(icom)%text
5667 c1=' '
5668 IF (globalparlabelindex(3,itgbi) == itgbl) c1='>'
5669 par=real(globalparameter(itgbi),mps) ! initial value
5670 presig=real(globalparpresigma(itgbi),mps) ! initial presigma
5671 icount=globalparlabelcounter(itgbi) ! from binary files
5672 IF (ipcntr < 0) icount=globalparlabelzeros(itgbi) ! 'zero derivatives' from binary files
5673 icgrp=globalparcons(itgbi) ! constraints group
5674
5675 IF (ivgbi <= 0) THEN
5676 ! not used
5677 IF (ivgbi == -4) THEN
5678 WRITE(lup,116) c1,itgbl,par,presig,icount,icgrp
5679 ELSE
5680 WRITE(lup,110) c1,itgbl,par,presig,icount,icgrp,ivgbi
5681 END IF
5682 ELSE
5683 ! variable
5684 WRITE(lup,111) c1,itgbl,par,presig,icount,icgrp
5685 END IF
5686 END DO
5687 ! appearance statistics
5688 IF (icheck > 1) THEN
5689 WRITE(lup,*) '!.'
5690 WRITE(lup,*) '!.Appearance statistics '
5691 WRITE(lup,*) '!. Label First file and record Last file and record #files #paired-par'
5692 DO itgbi=1,ntgb
5693 itpgrp=globalparlabelindex(4,itgbi)
5694 IF (itpgrp > 0) THEN
5695 WRITE(lup,112) globalparlabelindex(1,itgbi), (appearancecounter(itgbi*5+k), k=-4,0), paircounter(itpgrp)
5696 ELSE ! 'empty' parameter
5697 WRITE(lup,112) globalparlabelindex(1,itgbi)
5698 END IF
5699 END DO
5700 END IF
5701 IF (ncgrp > 0) THEN
5702 WRITE(lup,*) '* === constraint groups ==='
5703 IF (icheck == 1) THEN
5704 WRITE(lup,*) '* Group #Cons. Entries First label Last label'
5705 ELSE
5706 WRITE(lup,*) '* Group #Cons. Entries First label Last label Paired label range'
5707 length=ntpgrp+ncgrp
5708 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
5709 END IF
5710 DO icgrp=1, ncgrp
5711 IF (matconsgroups(2,icgrp) <= matconsgroups(3,icgrp)) THEN
5712 label1=globalparlabelindex(1,globalparvartototal(matconsgroups(2,icgrp))) ! first label
5713 label2=globalparlabelindex(1,globalparvartototal(matconsgroups(3,icgrp))) ! last label
5714 ELSE ! empty group/cons.
5715 label1=0
5716 label2=0
5717 END IF
5718 ncon=matconsgroups(1,icgrp+1)-matconsgroups(1,icgrp)
5719 WRITE(lup,113) icgrp, ncon,vecconsgroupcounts(icgrp),label1,label2
5720 IF (icheck > 1 .AND. label1 > 0) THEN
5721 ipgrp=globalparlabelindex(4,globalparvartototal(matconsgroups(2,icgrp))) ! first par. group
5722 ! get paired parameter groups
5723 CALL ggbmap(ntpgrp+icgrp,npair,vecpairedpargroups)
5724 vecpairedpargroups(npair+1)=0
5725 ifrst=0
5726 nstep=1
5727 DO j=1, npair
5728 jpgrp=vecpairedpargroups(j)
5729 inext=globaltotindexgroups(1,jpgrp)
5730 DO k=1,globaltotindexgroups(2,jpgrp)
5731 ! end of continous region ?
5732 IF (ifrst /= 0.AND.inext /= (ilast+nstep)) THEN
5733 label1=globalparlabelindex(1,ifrst)
5734 label2=globalparlabelindex(1,ilast)
5735 WRITE(lup,114) label1, label2
5736 ifrst=0
5737 END IF
5738 ! skip 'self-correlations'
5739 IF (globalparcons(inext) /= icgrp) THEN
5740 IF (ifrst == 0) ifrst=inext
5741 ilast=inext
5742 END IF
5743 inext=inext+1
5744 nstep=1
5745 END DO
5746 ! skip 'empty' parameter
5747 IF (jpgrp == vecpairedpargroups(j+1)-1) THEN
5748 nstep=globaltotindexgroups(1,vecpairedpargroups(j+1)) &
5749 -(globaltotindexgroups(1,jpgrp)+globaltotindexgroups(2,jpgrp)-1)
5750 END IF
5751 END DO
5752 IF (ifrst /= 0) THEN
5753 label1=globalparlabelindex(1,ifrst)
5754 label2=globalparlabelindex(1,ilast)
5755 WRITE(lup,114) label1, label2
5756 END IF
5757 END IF
5758 END DO
5759 IF (icheck > 1) THEN
5760 WRITE(lup,*) '*.'
5761 WRITE(lup,*) '*.Appearance statistics '
5762 WRITE(lup,*) '*. Group First file and record Last file and record #files'
5763 DO icgrp=1, ncgrp
5764 WRITE(lup,115) icgrp, (appearancecounter((ntgb+icgrp)*5+k), k=-4,0)
5765 END DO
5766 END IF
5767 END IF
5768
5769 rewind lup
5770 CLOSE(unit=lup)
5771
5772110 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' fixed',i2)
5773111 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' variable')
5774112 FORMAT(' !.',i10,6i11)
5775113 FORMAT(' * ',i6,i8,3i12)
5776114 FORMAT(' *:',48x,i12,' ..',i12)
5777115 FORMAT(' *.',i10,5i11)
5778116 FORMAT(' !',a1,i10,2x,2g14.5,2i12,' redundant')
5779117 FORMAT(' !!',a)
5780END SUBROUTINE prtstat ! print input statistics
5781
5782
5796
5797SUBROUTINE avprds(n,l,x,is,ie,b)
5798 USE mpmod
5799
5800 IMPLICIT NONE
5801 INTEGER(mpi) :: i
5802 INTEGER(mpi) :: ia
5803 INTEGER(mpi) :: ia2
5804 INTEGER(mpi) :: ib
5805 INTEGER(mpi) :: ib2
5806 INTEGER(mpi) :: in
5807 INTEGER(mpi) :: ipg
5808 INTEGER(mpi) :: iproc
5809 INTEGER(mpi) :: ir
5810 INTEGER(mpi) :: j
5811 INTEGER(mpi) :: ja
5812 INTEGER(mpi) :: ja2
5813 INTEGER(mpi) :: jb
5814 INTEGER(mpi) :: jb2
5815 INTEGER(mpi) :: jn
5816 INTEGER(mpi) :: lj
5817
5818 INTEGER(mpi), INTENT(IN) :: n
5819 INTEGER(mpl), INTENT(IN) :: l
5820 REAL(mpd), INTENT(IN) :: x(n)
5821 INTEGER(mpi), INTENT(IN) :: is
5822 INTEGER(mpi), INTENT(IN) :: ie
5823 REAL(mpd), INTENT(OUT) :: b(n)
5824 INTEGER(mpl) :: k
5825 INTEGER(mpl) :: kk
5826 INTEGER(mpl) :: ku
5827 INTEGER(mpl) :: ll
5828 INTEGER(mpl) :: indij
5829 INTEGER(mpl) :: indid
5830 INTEGER(mpl) :: ij
5831 INTEGER(mpi) :: ichunk
5832 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
5833 SAVE
5834 ! ...
5835
5836 ichunk=min((n+mthrd-1)/mthrd/8+1,128)
5837 IF(matsto /= 2) THEN
5838 ! full or unpacked (block diagonal) symmetric matrix
5839 ! parallelize row loop
5840 ! private copy of B(N) for each thread, combined at end, init with 0.
5841 ! slot of 128 'I' for next idle thread
5842 !$OMP PARALLEL DO &
5843 !$OMP PRIVATE(J,IJ) &
5844 !$OMP SCHEDULE(DYNAMIC,ichunk)
5845 DO i=1,n
5846 ij=globalrowoffsets(i+l)+l
5847 DO j=is,min(i,ie)
5848 b(i)=b(i)+globalmatd(ij+j)*x(j)
5849 END DO
5850 END DO
5851 !$OMP END PARALLEL DO
5852
5853 !$OMP PARALLEL DO &
5854 !$OMP PRIVATE(J,IJ) &
5855 !$OMP REDUCTION(+:B) &
5856 !$OMP SCHEDULE(DYNAMIC,ichunk)
5857 DO i=is,ie
5858 ij=globalrowoffsets(i+l)+l
5859 DO j=1,i-1
5860 b(j)=b(j)+globalmatd(ij+j)*x(i)
5861 END DO
5862 END DO
5863 !$OMP END PARALLEL DO
5864 ELSE
5865 ! sparse, compressed matrix
5866 IF(sparsematrixoffsets(2,1) /= n) THEN
5867 CALL peend(24,'Aborted, vector/matrix size mismatch')
5868 stop 'AVPRDS: mismatched vector and matrix'
5869 END IF
5870 ! parallelize row (group) loop
5871 ! slot of 1024 'I' for next idle thread
5872 !$OMP PARALLEL DO &
5873 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
5874 !$OMP PRIVATE(IA,IB,IN,JA,JB,IA2,IB2,JA2,JB2) &
5875 !$OMP REDUCTION(+:B) &
5876 !$OMP SCHEDULE(DYNAMIC,ichunk)
5877 DO ipg=1,napgrp
5878 iproc=0
5879 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
5880 ! row group
5881 ia=globalallindexgroups(ipg) ! first (global) row
5882 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
5883 in=ib-ia+1 ! number of rows
5884 ! overlap
5885 ia2=max(ia,is)
5886 ib2=min(ib,ie)
5887 ! diagonal elements
5888 IF (ia2 <= ib2) b(ia2:ib2)=b(ia2:ib2)+globalmatd(ia2:ib2)*x(ia2:ib2)
5889 ! off-diagonals double precision
5890 ir=ipg
5891 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5892 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5893 ku=sparsematrixoffsets(1,ir+1)-kk
5894 indid=kk
5895 indij=ll
5896 IF (ku > 0) THEN
5897 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5898 DO i=ia,ib
5899 IF (i <= ie.AND.i >= is) THEN
5900 DO k=1,ku
5901 j=sparsematrixcolumns(indid+k)
5902 b(j)=b(j)+globalmatd(indij+k)*x(i)
5903 END DO
5904 END IF
5905 DO k=1,ku
5906 j=sparsematrixcolumns(indid+k)
5907 IF (j <= ie.AND.j >= is) THEN
5908 b(i)=b(i)+globalmatd(indij+k)*x(j)
5909 END IF
5910 END DO
5911 indij=indij+ku
5912 END DO
5913 ELSE
5914 ! regions of continous column groups
5915 DO k=2,ku-2,2
5916 j=sparsematrixcolumns(indid+k) ! first group
5917 ja=globalallindexgroups(j) ! first (global) column
5918 lj=sparsematrixcolumns(indid+k-1) ! region offset
5919 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5920 jb=ja+jn-1 ! last (global) column
5921 ja2=max(ja,is)
5922 jb2=min(jb,ie)
5923 IF (ja2 <= jb2) THEN
5924 lj=1 ! index (in group region)
5925 DO i=ia,ib
5926 b(i)=b(i)+dot_product(globalmatd(indij+lj+ja2-ja:indij+lj+jb2-ja),x(ja2:jb2))
5927 lj=lj+jn
5928 END DO
5929 END IF
5930 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5931 lj=1
5932 DO j=ja,jb
5933 b(j)=b(j)+dot_product(globalmatd(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),x(ia2:ib2))
5934 lj=lj+1
5935 END DO
5936 END IF
5937 indij=indij+in*jn
5938 END DO
5939 END IF
5940 END IF
5941 ! mixed precision
5942 IF (nspc > 1) THEN
5943 ir=ipg+napgrp+1 ! off-diagonals single precision
5944 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
5945 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
5946 ku=sparsematrixoffsets(1,ir+1)-kk
5947 indid=kk
5948 indij=ll
5949 IF (ku == 0) cycle
5950 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
5951 DO i=ia,ib
5952 IF (i <= ie.AND.i >= is) THEN
5953 DO k=1,ku
5954 j=sparsematrixcolumns(indid+k)
5955 b(j)=b(j)+globalmatf(indij+k)*x(i)
5956 END DO
5957 END IF
5958 DO k=1,ku
5959 j=sparsematrixcolumns(indid+k)
5960 IF (j <= ie.AND.j >= is) THEN
5961 b(i)=b(i)+globalmatf(indij+k)*x(j)
5962 END IF
5963 END DO
5964 indij=indij+ku
5965 END DO
5966 ELSE
5967 ! regions of continous column groups
5968 DO k=2,ku-2,2
5969 j=sparsematrixcolumns(indid+k) ! first group
5970 ja=globalallindexgroups(j) ! first (global) column
5971 lj=sparsematrixcolumns(indid+k-1) ! region offset
5972 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
5973 jb=ja+jn-1 ! last (global) column
5974 ja2=max(ja,is)
5975 jb2=min(jb,ie)
5976 IF (ja2 <= jb2) THEN
5977 lj=1 ! index (in group region)
5978 DO i=ia,ib
5979 b(i)=b(i)+dot_product(real(globalmatf(indij+lj+ja2-ja:indij+lj+jb2-ja),mpd),x(ja2:jb2))
5980 lj=lj+jn
5981 END DO
5982 END IF
5983 IF (mextnd == 0.AND.ia2 <= ib2) THEN
5984 lj=1
5985 DO j=ja,jb
5986 b(j)=b(j)+dot_product(real(globalmatf(indij+lj+jn*(ia2-ia):indij+lj+jn*(ib2-ia):jn),mpd),x(ia2:ib2))
5987 lj=lj+1
5988 END DO
5989 END IF
5990 indij=indij+in*jn
5991 END DO
5992 END IF
5993 END IF
5994 END DO
5995 ENDIF
5996
5997END SUBROUTINE avprds
5998
6010
6011SUBROUTINE avprd0(n,l,x,b)
6012 USE mpmod
6013
6014 IMPLICIT NONE
6015 INTEGER(mpi) :: i
6016 INTEGER(mpi) :: ia
6017 INTEGER(mpi) :: ib
6018 INTEGER(mpi) :: in
6019 INTEGER(mpi) :: ipg
6020 INTEGER(mpi) :: iproc
6021 INTEGER(mpi) :: ir
6022 INTEGER(mpi) :: j
6023 INTEGER(mpi) :: ja
6024 INTEGER(mpi) :: jb
6025 INTEGER(mpi) :: jn
6026 INTEGER(mpi) :: lj
6027
6028 INTEGER(mpi), INTENT(IN) :: n
6029 INTEGER(mpl), INTENT(IN) :: l
6030 REAL(mpd), INTENT(IN) :: x(n)
6031 REAL(mpd), INTENT(OUT) :: b(n)
6032 INTEGER(mpl) :: k
6033 INTEGER(mpl) :: kk
6034 INTEGER(mpl) :: ku
6035 INTEGER(mpl) :: ll
6036 INTEGER(mpl) :: indij
6037 INTEGER(mpl) :: indid
6038 INTEGER(mpl) :: ij
6039 INTEGER(mpi) :: ichunk
6040 !$ INTEGER(mpi) OMP_GET_THREAD_NUM
6041 SAVE
6042 ! ...
6043 !$ DO i=1,n
6044 !$ b(i)=0.0_mpd ! reset 'global' B()
6045 !$ END DO
6046 ichunk=min((n+mthrd-1)/mthrd/8+1,1024)
6047 IF(matsto /= 2) THEN
6048 ! full or unpacked (block diagonal) symmetric matrix
6049 ! parallelize row loop
6050 ! private copy of B(N) for each thread, combined at end, init with 0.
6051 ! slot of 1024 'I' for next idle thread
6052 !$OMP PARALLEL DO &
6053 !$OMP PRIVATE(J,IJ) &
6054 !$OMP REDUCTION(+:B) &
6055 !$OMP SCHEDULE(DYNAMIC,ichunk)
6056 DO i=1,n
6057 ij=globalrowoffsets(i+l)+l
6058 b(i)=globalmatd(ij+i)*x(i)
6059 DO j=1,i-1
6060 b(j)=b(j)+globalmatd(ij+j)*x(i)
6061 b(i)=b(i)+globalmatd(ij+j)*x(j)
6062 END DO
6063 END DO
6064 !$OMP END PARALLEL DO
6065 ELSE
6066 ! sparse, compressed matrix
6067 IF(sparsematrixoffsets(2,1) /= n) THEN
6068 CALL peend(24,'Aborted, vector/matrix size mismatch')
6069 stop 'AVPRD0: mismatched vector and matrix'
6070 END IF
6071 ! parallelize row (group) loop
6072 ! slot of 1024 'I' for next idle thread
6073 !$OMP PARALLEL DO &
6074 !$OMP PRIVATE(I,IR,K,KK,LL,KU,INDID,INDIJ,J,JN,LJ) &
6075 !$OMP PRIVATE(IA,IB,IN,JA,JB) &
6076 !$OMP REDUCTION(+:B) &
6077 !$OMP SCHEDULE(DYNAMIC,ichunk)
6078 DO ipg=1,napgrp
6079 iproc=0
6080 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
6081 ! row group
6082 ia=globalallindexgroups(ipg) ! first (global) row
6083 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6084 in=ib-ia+1 ! number of rows
6085 !
6086 ! diagonal elements
6087 b(ia:ib)=globalmatd(ia:ib)*x(ia:ib)
6088 ! off-diagonals double precision
6089 ir=ipg
6090 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6091 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6092 ku=sparsematrixoffsets(1,ir+1)-kk
6093 indid=kk
6094 indij=ll
6095 IF (ku > 0) THEN
6096 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6097 DO i=ia,ib
6098 DO k=1,ku
6099 j=sparsematrixcolumns(indid+k)
6100 b(j)=b(j)+globalmatd(indij+k)*x(i)
6101 b(i)=b(i)+globalmatd(indij+k)*x(j)
6102 END DO
6103 indij=indij+ku
6104 END DO
6105 ELSE
6106 ! regions of continous column groups
6107 DO k=2,ku-2,2
6108 j=sparsematrixcolumns(indid+k) ! first group
6109 ja=globalallindexgroups(j) ! first (global) column
6110 lj=sparsematrixcolumns(indid+k-1) ! region offset
6111 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6112 jb=ja+jn-1 ! last (global) column
6113 lj=1 ! index (in group region)
6114 DO i=ia,ib
6115 b(i)=b(i)+dot_product(globalmatd(indij+lj:indij+lj+jn-1),x(ja:jb))
6116 lj=lj+jn
6117 END DO
6118 IF (mextnd == 0) THEN
6119 lj=1
6120 DO j=ja,jb
6121 b(j)=b(j)+dot_product(globalmatd(indij+lj:indij+jn*in:jn),x(ia:ib))
6122 lj=lj+1
6123 END DO
6124 END IF
6125 indij=indij+in*jn
6126 END DO
6127 END IF
6128 END IF
6129 ! mixed precision
6130 IF (nspc > 1) THEN
6131 ir=ipg+napgrp+1 ! off-diagonals single precision
6132 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6133 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6134 ku=sparsematrixoffsets(1,ir+1)-kk
6135 indid=kk
6136 indij=ll
6137 IF (ku == 0) cycle
6138 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6139 DO i=ia,ib
6140 DO k=1,ku
6141 j=sparsematrixcolumns(indid+k)
6142 b(j)=b(j)+real(globalmatf(indij+k),mpd)*x(i)
6143 b(i)=b(i)+real(globalmatf(indij+k),mpd)*x(j)
6144 END DO
6145 indij=indij+ku
6146 END DO
6147 ELSE
6148 ! regions of continous column groups
6149 DO k=2,ku-2,2
6150 j=sparsematrixcolumns(indid+k) ! first group
6151 ja=globalallindexgroups(j) ! first (global) column
6152 lj=sparsematrixcolumns(indid+k-1) ! region offset
6153 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6154 jb=ja+jn-1 ! last (global) column
6155 lj=1 ! index (in group region)
6156 DO i=ia,ib
6157 b(i)=b(i)+dot_product(real(globalmatf(indij+lj:indij+lj+jn-1),mpd),x(ja:jb))
6158 lj=lj+jn
6159 END DO
6160 IF (mextnd == 0) THEN
6161 lj=1
6162 DO j=ja,jb
6163 b(j)=b(j)+dot_product(real(globalmatf(indij+lj:indij+jn*in:jn),mpd),x(ia:ib))
6164 lj=lj+1
6165 END DO
6166 END IF
6167 indij=indij+in*jn
6168 END DO
6169 END IF
6170 END IF
6171 END DO
6172 ENDIF
6173
6174END SUBROUTINE avprd0
6175
6176
6179SUBROUTINE anasps
6180 USE mpmod
6181
6182 IMPLICIT NONE
6183 INTEGER(mpi) :: ia
6184 INTEGER(mpi) :: ib
6185 INTEGER(mpi) :: ipg
6186 INTEGER(mpi) :: ir
6187 INTEGER(mpi) :: ispc
6188 INTEGER(mpi) :: lj
6189 REAL(mps) :: avg
6190
6191
6192 INTEGER(mpl) :: in
6193 INTEGER(mpl) :: jn
6194 INTEGER(mpl) :: k
6195 INTEGER(mpl) :: kk
6196 INTEGER(mpl) :: ku
6197 INTEGER(mpl) :: ll
6198 INTEGER(mpl) :: indid
6199 INTEGER(mpl), DIMENSION(12) :: icount
6200 SAVE
6201
6202 ! require sparse storage
6203 IF(matsto /= 2) RETURN
6204 ! reset
6205 icount=0
6206 icount(4)=huge(icount(4))
6207 icount(7)=huge(icount(7))
6208 icount(10)=huge(icount(10))
6209 ! loop over precisions
6210 DO ispc=1,nspc
6211 ! loop over row groups
6212 DO ipg=1,napgrp
6213 ! row group
6214 ia=globalallindexgroups(ipg) ! first (global) row
6215 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6216 in=ib-ia+1 ! number of rows
6217
6218 ir=ipg+(ispc-1)*(napgrp+1)
6219 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6220 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6221 ku=sparsematrixoffsets(1,ir+1)-kk
6222 indid=kk
6223 IF (ku == 0) cycle
6224 IF (sparsematrixcolumns(indid+1) /= 0) THEN ! no compression
6225 icount(1)=icount(1)+in
6226 icount(2)=icount(2)+in*ku
6227 ELSE
6228 ! regions of continous column groups
6229 DO k=2,ku-2,2
6230 lj=sparsematrixcolumns(indid+k-1) ! region offset
6231 jn=sparsematrixcolumns(indid+k+1)-lj ! number of columns
6232 icount(3)=icount(3)+1 ! block (region) counter
6233 icount(4)=min(icount(4),jn) ! min number of columns per block (region)
6234 icount(5)=icount(5)+jn ! sum number of columns per block (region)
6235 icount(6)=max(icount(6),jn) ! max number of columns per block (region)
6236 icount(7)=min(icount(7),in) ! min number of rows per block (region)
6237 icount(8)=icount(8)+in ! sum number of rows per block (region)
6238 icount(9)=max(icount(9),in) ! max number of rows per block (region)
6239 icount(10)=min(icount(10),in*jn) ! min number of elements per block (region)
6240 icount(11)=icount(11)+in*jn ! sum number of elements per block (region)
6241 icount(12)=max(icount(12),in*jn) ! max number of elements per block (region)
6242 END DO
6243 END IF
6244 END DO
6245 END DO
6246
6247 WRITE(*,*) "analysis of sparsity structure"
6248 IF (icount(1) > 0) THEN
6249 WRITE(*,101) "rows without compression/blocks ", icount(1)
6250 WRITE(*,101) " contained elements ", icount(2)
6251 ENDIF
6252 WRITE(*,101) "number of block matrices ", icount(3)
6253 avg=real(icount(5),mps)/real(icount(3),mps)
6254 WRITE(*,101) "number of columns (min,mean,max) ", icount(4), avg, icount(6)
6255 avg=real(icount(8),mps)/real(icount(3),mps)
6256 WRITE(*,101) "number of rows (min,mean,max) ", icount(7), avg, icount(9)
6257 avg=real(icount(11),mps)/real(icount(3),mps)
6258 WRITE(*,101) "number of elements (min,mean,max) ", icount(10), avg, icount(12)
6259101 FORMAT(2x,a34,i10,f10.3,i10)
6260
6261END SUBROUTINE anasps
6262
6272
6273SUBROUTINE avprod(n,x,b)
6274 USE mpmod
6275
6276 IMPLICIT NONE
6277
6278 INTEGER(mpi), INTENT(IN) :: n
6279 REAL(mpd), INTENT(IN) :: x(n)
6280 REAL(mpd), INTENT(OUT) :: b(n)
6281
6282 SAVE
6283 ! ...
6284 IF(n > nagb) THEN
6285 CALL peend(24,'Aborted, vector/matrix size mismatch')
6286 stop 'AVPROD: mismatched vector and matrix'
6287 END IF
6288 ! input to AVPRD0
6289 vecxav(1:n)=x
6290 vecxav(n+1:nagb)=0.0_mpd
6291 !use elimination for constraints ?
6292 IF(n < nagb) CALL qlmlq(vecxav,1,.false.) ! Q*x
6293 ! calclulate vecBav=globalMat*vecXav
6294 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
6295 !use elimination for constraints ?
6296 IF(n < nagb) CALL qlmlq(vecbav,1,.true.) ! Q^t*x
6297 ! output from AVPRD0
6298 b=vecbav(1:n)
6299
6300END SUBROUTINE avprod
6301
6302
6312
6313SUBROUTINE ijpgrp(itema,itemb,ij,lr,iprc)
6314 USE mpmod
6315
6316 IMPLICIT NONE
6317 INTEGER(mpi) :: ispc
6318 INTEGER(mpi) :: item1
6319 INTEGER(mpi) :: item2
6320 INTEGER(mpi) :: itemc
6321 INTEGER(mpi) :: jtem
6322 INTEGER(mpi) :: jtemn
6323 INTEGER(mpi) :: np
6324
6325 INTEGER(mpi), INTENT(IN) :: itema
6326 INTEGER(mpi), INTENT(IN) :: itemb
6327 INTEGER(mpl), INTENT(OUT) :: ij
6328 INTEGER(mpi), INTENT(OUT) :: lr
6329 INTEGER(mpi), INTENT(OUT) :: iprc
6330
6331 INTEGER(mpl) :: k
6332 INTEGER(mpl) :: kk
6333 INTEGER(mpl) :: kl
6334 INTEGER(mpl) :: ku
6335 INTEGER(mpl) :: ll
6336 ! ...
6337 ij=0
6338 lr=0
6339 iprc=0
6340 item1=max(itema,itemb) ! larger index
6341 item2=min(itema,itemb) ! smaller index
6342 IF(item2 <= 0.OR.item1 > napgrp) RETURN
6343 np=globalallindexgroups(item1+1)-globalallindexgroups(item1) ! size of group item1
6344 ! loop over precisions
6345 outer: DO ispc=1,nspc
6346 kk=sparsematrixoffsets(1,item1) ! offset (column lists)
6347 ll=sparsematrixoffsets(2,item1) ! offset (matrix)
6348 kl=1
6349 ku=sparsematrixoffsets(1,item1+1)-kk
6350 item1=item1+napgrp+1
6351 iprc=ispc
6352 IF (sparsematrixcolumns(kk+1) == 0) THEN ! compression ?
6353 ! compressed (list of continous regions of parameter groups (pairs of offset and 1. group index)
6354 kl=2
6355 ku=ku-2
6356 IF(ku < kl) cycle outer ! not found
6357 DO
6358 k=2*((kl+ku)/4) ! binary search
6359 jtem=sparsematrixcolumns(kk+k) ! first column (group) of region
6360 jtemn=sparsematrixcolumns(kk+k+2) ! first column (group) after region
6361 IF(item2 >= jtem.AND.item2 < jtemn) THEN
6362 ! length of region
6363 lr=sparsematrixcolumns(kk+k+1)-sparsematrixcolumns(kk+k-1)
6364 IF (globalallindexgroups(item2)-globalallindexgroups(jtem) >= lr) cycle outer ! outside region
6365 EXIT ! found
6366 END IF
6367 IF(item2 < jtem) THEN
6368 ku=k-2
6369 ELSE IF(item2 >= jtemn) THEN
6370 kl=k+2
6371 END IF
6372 IF(kl <= ku) cycle
6373 cycle outer ! not found
6374 END DO
6375 ! group offset in row
6376 ij=sparsematrixcolumns(kk+k-1)
6377 ! absolute offset
6378 ij=ll+ij*np+globalallindexgroups(item2)-globalallindexgroups(jtem)+1
6379
6380 ELSE
6381 ! simple column list
6382 itemc=globalallindexgroups(item2) ! first (col) index of group
6383 lr=int(ku,mpi) ! number of columns
6384 IF(ku < kl) cycle outer ! not found
6385 DO
6386 k=(kl+ku)/2 ! binary search
6387 jtem=sparsematrixcolumns(kk+k)
6388 IF(itemc == jtem) EXIT ! found
6389 IF(itemc < jtem) THEN
6390 ku=k-1
6391 ELSE IF(itemc > jtem) THEN
6392 kl=k+1
6393 END IF
6394 IF(kl <= ku) cycle
6395 cycle outer ! not found
6396 END DO
6397 ij=ll+k
6398
6399 END IF
6400 RETURN
6401 END DO outer
6402
6403END SUBROUTINE ijpgrp
6404
6410
6411FUNCTION ijprec(itema,itemb)
6412 USE mpmod
6413
6414 IMPLICIT NONE
6415
6416 INTEGER(mpi) :: lr
6417 INTEGER(mpl) :: ij
6418
6419 INTEGER(mpi), INTENT(IN) :: itema
6420 INTEGER(mpi), INTENT(IN) :: itemb
6421 INTEGER(mpi) :: ijprec
6422
6423 ! ...
6424 ijprec=1
6425 IF (matsto == 2.AND.nspc > 1) THEN ! sparse storage with mixed precision
6426 ! check groups
6427 CALL ijpgrp(itema,itemb,ij,lr,ijprec)
6428 END IF
6429
6430END FUNCTION ijprec
6431
6439
6440FUNCTION ijadd(itema,itemb) ! index using "d" and "z"
6441 USE mpmod
6442
6443 IMPLICIT NONE
6444
6445 INTEGER(mpi) :: item1
6446 INTEGER(mpi) :: item2
6447 INTEGER(mpi) :: ipg1
6448 INTEGER(mpi) :: ipg2
6449 INTEGER(mpi) :: lr
6450 INTEGER(mpi) :: iprc
6451
6452 INTEGER(mpi), INTENT(IN) :: itema
6453 INTEGER(mpi), INTENT(IN) :: itemb
6454
6455 INTEGER(mpl) :: ijadd
6456 INTEGER(mpl) :: ij
6457 ! ...
6458 ijadd=0
6459 item1=max(itema,itemb) ! larger index
6460 item2=min(itema,itemb) ! smaller index
6461 !print *, ' ijadd ', item1, item2
6462 IF(item2 <= 0.OR.item1 > nagb) RETURN
6463 IF(item1 == item2) THEN ! diagonal element
6464 ijadd=item1
6465 RETURN
6466 END IF
6467 ! ! off-diagonal element
6468 ! get parameter groups
6469 ipg1=globalallpartogroup(item1)
6470 ipg2=globalallpartogroup(item2)
6471 ! get offset for groups
6472 CALL ijpgrp(ipg1,ipg2,ij,lr,iprc)
6473 IF (ij == 0) RETURN
6474 ! add offset inside groups
6475 ijadd=ij+(item2-globalallindexgroups(ipg2))+(item1-globalallindexgroups(ipg1))*lr
6476 ! reduced precision?
6477 IF (iprc > 1) ijadd=-ijadd
6478
6479END FUNCTION ijadd
6480
6488
6489FUNCTION ijcsr3(itema,itemb) ! index using "d" and "z"
6490 USE mpmod
6491
6492 IMPLICIT NONE
6493
6494 INTEGER(mpi) :: item1
6495 INTEGER(mpi) :: item2
6496 INTEGER(mpi) :: jtem
6497
6498 INTEGER(mpi), INTENT(IN) :: itema
6499 INTEGER(mpi), INTENT(IN) :: itemb
6500
6501 INTEGER(mpl) :: ijcsr3
6502 INTEGER(mpl) :: kk
6503 INTEGER(mpl) :: ks
6504 INTEGER(mpl) :: ke
6505
6506 ! ...
6507 ijcsr3=0
6508 item1=max(itema,itemb) ! larger index
6509 item2=min(itema,itemb) ! smaller index
6510 !print *, ' ijadd ', item1, item2
6511 IF(item2 <= 0.OR.item1 > nagb) RETURN
6512 ! start of column list for row
6513 ks=csr3rowoffsets(item2)
6514 ! end of column list for row
6515 ke=csr3rowoffsets(item2+1)-1
6516 ! binary search
6517 IF(ke < ks) THEN
6518 ! empty list
6519 print *, ' IJCSR3 empty list ', item1, item2, ks, ke
6520 CALL peend(23,'Aborted, bad matrix index')
6521 stop 'ijcsr3: empty list'
6522 ENDIF
6523 DO
6524 kk=(ks+ke)/2 ! center of rgion
6525 jtem=int(csr3columnlist(kk),mpi)
6526 IF(item1 == jtem) EXIT ! found
6527 IF(item1 < jtem) THEN
6528 ke=kk-1
6529 ELSE
6530 ks=kk+1
6531 END IF
6532 IF(ks <= ke) cycle
6533 ! not found
6534 print *, ' IJCSR3 not found ', item1, item2, ks, ke
6535 CALL peend(23,'Aborted, bad matrix index')
6536 stop 'ijcsr3: not found'
6537 END DO
6538 ijcsr3=kk
6539END FUNCTION ijcsr3
6540
6546
6547FUNCTION matij(itema,itemb)
6548 USE mpmod
6549
6550 IMPLICIT NONE
6551
6552 INTEGER(mpi) :: item1
6553 INTEGER(mpi) :: item2
6554 INTEGER(mpl) :: i
6555 INTEGER(mpl) :: j
6556 INTEGER(mpl) :: ij
6557 INTEGER(mpl) :: ijadd
6558 INTEGER(mpl) :: ijcsr3
6559
6560 INTEGER(mpi), INTENT(IN) :: itema
6561 INTEGER(mpi), INTENT(IN) :: itemb
6562
6563 REAL(mpd) :: matij
6564 ! ...
6565 matij=0.0_mpd
6566 item1=max(itema,itemb) ! larger index
6567 item2=min(itema,itemb) ! smaller index
6568 IF(item2 <= 0.OR.item1 > nagb) RETURN
6569
6570 i=item1
6571 j=item2
6572
6573 IF(matsto < 2) THEN ! full or unpacked (block diagonal) symmetric matrix
6574 ij=globalrowoffsets(i)+j
6575 matij=globalmatd(ij)
6576 ELSE IF(matsto ==2) THEN ! sparse symmetric matrix (custom)
6577 ij=ijadd(item1,item2) ! inline code requires same time
6578 IF(ij > 0) THEN
6579 matij=globalmatd(ij)
6580 ELSE IF (ij < 0) THEN
6581 matij=real(globalmatf(-ij),mpd)
6582 END IF
6583 ELSE ! sparse symmetric matrix (CSR3)
6584 IF(matbsz < 2) THEN ! sparse symmetric matrix (CSR3)
6585 ij=ijcsr3(item1,item2) ! inline code requires same time
6586 IF(ij > 0) matij=globalmatd(ij)
6587 ELSE ! sparse symmetric matrix (BSR3)
6588 ! block index
6589 ij=ijcsr3((item1-1)/matbsz+1,(item2-1)/matbsz+1)
6590 IF (ij > 0) THEN
6591 ! index of first element in block
6592 ij=(ij-1)*matbsz*matbsz+1
6593 ! adjust index for position in block
6594 ij=ij+mod(item1-1,matbsz)*matbsz+mod(item2-1,matbsz)
6595 matij=globalmatd(ij)
6596 ENDIF
6597 END IF
6598 END IF
6599
6600END FUNCTION matij
6601
6604
6605SUBROUTINE mhalf2
6606 USE mpmod
6607
6608 IMPLICIT NONE
6609 INTEGER(mpi) :: i
6610 INTEGER(mpi) :: ia
6611 INTEGER(mpi) :: ib
6612 INTEGER(mpi) :: ichunk
6613 INTEGER(mpi) :: in
6614 INTEGER(mpi) :: ipg
6615 INTEGER(mpi) :: ir
6616 INTEGER(mpi) :: ispc
6617 INTEGER(mpi) :: j
6618 INTEGER(mpi) :: ja
6619 INTEGER(mpi) :: jb
6620 INTEGER(mpi) :: jn
6621 INTEGER(mpi) :: lj
6622
6623 INTEGER(mpl) :: ij
6624 INTEGER(mpl) :: ijadd
6625 INTEGER(mpl) :: k
6626 INTEGER(mpl) :: kk
6627 INTEGER(mpl) :: ku
6628 INTEGER(mpl) :: ll
6629 ! ...
6630
6631 ichunk=min((napgrp+mthrd-1)/mthrd/8+1,1024)
6632
6633 DO ispc=1,nspc
6634 ! parallelize row loop
6635 ! slot of 1024 'I' for next idle thread
6636 !$OMP PARALLEL DO &
6637 !$OMP PRIVATE(I,IR,K,KK,LL,KU,IJ,J,LJ) &
6638 !$OMP PRIVATE(IA,IB,IN,JA,JB,JN) &
6639 !$OMP SCHEDULE(DYNAMIC,ichunk)
6640 DO ipg=1,napgrp
6641 ! row group
6642 ia=globalallindexgroups(ipg) ! first (global) row
6643 ib=globalallindexgroups(ipg+1)-1 ! last (global) row
6644 in=ib-ia+1 ! number of rows
6645 !
6646 ir=ipg+(ispc-1)*(napgrp+1)
6647 kk=sparsematrixoffsets(1,ir) ! offset in 'd' (column lists)
6648 ll=sparsematrixoffsets(2,ir) ! offset in 'j' (matrix)
6649 ku=sparsematrixoffsets(1,ir+1)-kk
6650 ! regions of continous column groups
6651 DO k=2,ku-2,2
6652 j=sparsematrixcolumns(kk+k) ! first group
6653 ja=globalallindexgroups(j) ! first (global) column
6654 lj=sparsematrixcolumns(kk+k-1) ! region offset
6655 jn=sparsematrixcolumns(kk+k+1)-lj ! number of columns
6656 jb=ja+jn-1 ! last (global) column
6657 ! skip first half
6658 IF (sparsematrixcolumns(kk+k+2) <= ipg) THEN
6659 ll=ll+in*jn
6660 cycle
6661 END IF
6662 ! at diagonal or in second half
6663 DO i=ia,ib ! loop over rows
6664 DO j=ja,jb ! loop over columns
6665 ll=ll+1
6666 IF (j > i) THEN
6667 ij=ijadd(i,j)
6668 IF (ispc==1) THEN
6669 globalmatd(ll)=globalmatd(ij)
6670 ELSE
6671 globalmatf(ll)=globalmatf(-ij)
6672 END IF
6673 END IF
6674 END DO
6675 END DO
6676 END DO
6677 END DO
6678 !$OMP END PARALLEL DO
6679 END DO
6680
6681END SUBROUTINE mhalf2
6682
6691
6692SUBROUTINE sechms(deltat,nhour,minut,secnd)
6693 USE mpdef
6694
6695 IMPLICIT NONE
6696 REAL(mps), INTENT(IN) :: deltat
6697 INTEGER(mpi), INTENT(OUT) :: minut
6698 INTEGER(mpi), INTENT(OUT):: nhour
6699 REAL(mps), INTENT(OUT):: secnd
6700 INTEGER(mpi) :: nsecd
6701 ! DELTAT = time in sec -> NHOUR,MINUT,SECND
6702 ! ...
6703 nsecd=nint(deltat,mpi) ! -> integer
6704 nhour=nsecd/3600
6705 minut=nsecd/60-60*nhour
6706 secnd=deltat-60*(minut+60*nhour)
6707END SUBROUTINE sechms
6708
6736
6737INTEGER(mpi) FUNCTION inone(item) ! translate 1-D identifier to nrs
6738 USE mpmod
6739 USE mpdalc
6740
6741 IMPLICIT NONE
6742 INTEGER(mpi), INTENT(IN) :: item
6743 INTEGER(mpi) :: j
6744 INTEGER(mpi) :: k
6745 INTEGER(mpi) :: iprime
6746 INTEGER(mpl) :: length
6747 INTEGER(mpl), PARAMETER :: four = 4
6748
6749 inone=0
6750 !print *, ' INONE ', item
6751 IF(item <= 0) RETURN
6752 IF(globalparheader(-1) == 0) THEN
6753 length=128 ! initial number
6754 CALL mpalloc(globalparlabelindex,four,length,'INONE: label & index')
6755 CALL mpalloc(globalparlabelcounter,length,'INONE: counter') ! updated in pargrp
6756 CALL mpalloc(globalparhashtable,2*length,'INONE: hash pointer')
6758 globalparheader(-0)=int(length,mpi) ! length of labels/indices
6759 globalparheader(-1)=0 ! number of stored items
6760 globalparheader(-2)=0 ! =0 during build-up
6761 globalparheader(-3)=int(length,mpi) ! next number
6762 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number
6763 globalparheader(-5)=0 ! number of overflows
6764 globalparheader(-6)=0 ! nr of variable parameters
6765 globalparheader(-8)=0 ! number of sorted items
6766 END IF
6767 outer: DO
6768 j=1+mod(item,globalparheader(-4))+globalparheader(-0)
6769 inner: DO ! normal case: find item
6770 k=j
6772 IF(j == 0) EXIT inner ! unused hash code
6773 IF(item == globalparlabelindex(1,j)) EXIT outer ! found
6774 END DO inner
6775 ! not found
6776 IF(globalparheader(-1) == globalparheader(-0).OR.globalparheader(-2) /= 0) THEN
6777 globalparheader(-5)=globalparheader(-5)+1 ! overflow
6778 j=0
6779 RETURN
6780 END IF
6781 globalparheader(-1)=globalparheader(-1)+1 ! increase number of elements
6783 j=globalparheader(-1)
6784 globalparhashtable(k)=j ! hash index
6785 globalparlabelindex(1,j)=item ! add new item
6786 globalparlabelindex(2,j)=0 ! reset index (for variable par.)
6787 globalparlabelindex(3,j)=0 ! reset group info (first label)
6788 globalparlabelindex(4,j)=0 ! reset group info (group index)
6789 globalparlabelcounter(j)=0 ! reset (long) counter
6790 IF(globalparheader(-1) /= globalparheader(-0)) EXIT outer
6791 ! update with larger dimension and redefine index
6793 CALL upone
6794 IF (lvllog > 1) WRITE(lunlog,*) 'INONE: array increased to', &
6795 globalparheader(-3),' words'
6796 END DO outer
6797
6798 ! counting now in pargrp
6799 !IF(globalParHeader(-2) == 0) THEN
6800 ! globalParLabelIndex(2,j)=globalParLabelIndex(2,j)+1 ! increase counter
6801 ! globalParHeader(-7)=globalParHeader(-7)+1
6802 !END IF
6803 inone=j
6804END FUNCTION inone
6805
6807SUBROUTINE upone
6808 USE mpmod
6809 USE mpdalc
6810
6811 IMPLICIT NONE
6812 INTEGER(mpi) :: i
6813 INTEGER(mpi) :: j
6814 INTEGER(mpi) :: k
6815 INTEGER(mpi) :: iprime
6816 INTEGER(mpi) :: nused
6817 LOGICAL :: finalUpdate
6818 INTEGER(mpl) :: oldLength
6819 INTEGER(mpl) :: newLength
6820 INTEGER(mpl), PARAMETER :: four = 4
6821 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArr
6822 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: tempVec
6823 SAVE
6824 ! ...
6825 finalupdate=(globalparheader(-3) == globalparheader(-1))
6826 IF(finalupdate) THEN ! final (cleanup) call
6827 IF (globalparheader(-1) > globalparheader(-8)) THEN
6830 END IF
6831 END IF
6832 ! save old LabelIndex
6833 nused = globalparheader(-1)
6834 oldlength = globalparheader(-0)
6835 CALL mpalloc(temparr,four,oldlength,'INONE: temp array')
6836 temparr(:,1:nused)=globalparlabelindex(:,1:nused)
6837 CALL mpalloc(tempvec,oldlength,'INONE: temp vector')
6838 tempvec(1:nused)=globalparlabelcounter(1:nused)
6842 ! create new LabelIndex
6843 newlength = globalparheader(-3)
6844 CALL mpalloc(globalparlabelindex,four,newlength,'INONE: label & index')
6845 CALL mpalloc(globalparlabelcounter,newlength,'INONE: counter')
6846 CALL mpalloc(globalparhashtable,2*newlength,'INONE: hash pointer')
6848 globalparlabelindex(:,1:nused) = temparr(:,1:nused) ! copy back saved content
6849 globalparlabelcounter(1:nused) = tempvec(1:nused) ! copy back saved content
6850 CALL mpdealloc(tempvec)
6851 CALL mpdealloc(temparr)
6852 globalparheader(-0)=int(newlength,mpi) ! length of labels/indices
6854 globalparheader(-4)=iprime(globalparheader(-0)) ! prime number < LNDA
6855 ! redefine hash
6856 outer: DO i=1,globalparheader(-1)
6858 inner: DO
6859 k=j
6861 IF(j == 0) EXIT inner ! unused hash code
6862 IF(j == i) cycle outer ! found
6863 ENDDO inner
6865 END DO outer
6866 IF(.NOT.finalupdate) RETURN
6867
6868 globalparheader(-2)=1 ! set flag to inhibit further updates
6869 IF (lvllog > 1) THEN
6870 WRITE(lunlog,*) ' '
6871 WRITE(lunlog,*) 'INONE: array reduced to',newlength,' words'
6872 WRITE(lunlog,*) 'INONE:',globalparheader(-1),' items stored.'
6873 END IF
6874END SUBROUTINE upone ! update, redefine
6875
6877SUBROUTINE useone
6878 USE mpmod
6879
6880 IMPLICIT NONE
6881 INTEGER(mpi) :: i
6882 INTEGER(mpi) :: j
6883 INTEGER(mpi) :: k
6884 SAVE
6885 ! ...
6886 IF (globalparheader(-1) > globalparheader(-8)) THEN
6888 ! redefine hash
6890 outer: DO i=1,globalparheader(-1)
6892 inner: DO
6893 k=j
6895 IF(j == 0) EXIT inner ! unused hash code
6896 IF(j == i) cycle outer ! found
6897 ENDDO inner
6899 END DO outer
6901 END IF
6902END SUBROUTINE useone ! make usable
6903
6908
6909INTEGER(mpi) FUNCTION iprime(n)
6910 USE mpdef
6911
6912 IMPLICIT NONE
6913 INTEGER(mpi), INTENT(IN) :: n
6914 INTEGER(mpi) :: nprime
6915 INTEGER(mpi) :: nsqrt
6916 INTEGER(mpi) :: i
6917 ! ...
6918 SAVE
6919 nprime=n ! max number
6920 IF(mod(nprime,2) == 0) nprime=nprime+1 ! ... odd number
6921 outer: DO
6922 nprime=nprime-2 ! next lower odd number
6923 nsqrt=int(sqrt(real(nprime,mps)),mpi)
6924 DO i=3,nsqrt,2 !
6925 IF(i*(nprime/i) == nprime) cycle outer ! test prime number
6926 END DO
6927 EXIT outer ! found
6928 END DO outer
6929 iprime=nprime
6930END FUNCTION iprime
6931
6941SUBROUTINE loop1
6942 USE mpmod
6943 USE mpdalc
6944
6945 IMPLICIT NONE
6946 INTEGER(mpi) :: i
6947 INTEGER(mpi) :: idum
6948 INTEGER(mpi) :: in
6949 INTEGER(mpi) :: indab
6950 INTEGER(mpi) :: itgbi
6951 INTEGER(mpi) :: itgbl
6952 INTEGER(mpi) :: ivgbi
6953 INTEGER(mpi) :: j
6954 INTEGER(mpi) :: jgrp
6955 INTEGER(mpi) :: lgrp
6956 INTEGER(mpi) :: mqi
6957 INTEGER(mpi) :: nc31
6958 INTEGER(mpi) :: nr
6959 INTEGER(mpi) :: nwrd
6960 INTEGER(mpi) :: inone
6961 REAL(mpd) :: param
6962 REAL(mpd) :: presg
6963 REAL(mpd) :: prewt
6964
6965 INTEGER(mpl) :: length
6966 INTEGER(mpl) :: rows
6967 SAVE
6968 ! ...
6969 WRITE(lunlog,*) ' '
6970 WRITE(lunlog,*) 'LOOP1: starting'
6971 CALL mstart('LOOP1')
6972
6973 ! add labels from parameter, constraints, measurements, comments -------------
6974 DO i=1, lenparameters
6975 idum=inone(listparameters(i)%label)
6976 END DO
6977 DO i=1, lenpresigmas
6978 idum=inone(listpresigmas(i)%label)
6979 END DO
6980 DO i=1, lenconstraints
6981 idum=inone(listconstraints(i)%label)
6982 END DO
6983 DO i=1, lenmeasurements
6984 idum=inone(listmeasurements(i)%label)
6985 END DO
6986 DO i=1, lencomments
6987 idum=inone(listcomments(i)%label)
6988 END DO
6989
6990 IF(globalparheader(-1) /= 0) THEN
6991 WRITE(lunlog,*) 'LOOP1:',globalparheader(-1), ' labels from txt data stored'
6992 END IF
6993 WRITE(lunlog,*) 'LOOP1: reading data files'
6994
6995 neqn=0 ! number of equations
6996 negb=0 ! number of equations with global parameters
6997 ndgb=0 ! number of global derivatives
6998 nzgb=0 ! number of zero global derivatives
6999 DO
7000 DO j=1,globalparheader(-1)
7001 globalparlabelindex(2,j)=0 ! reset count
7002 END DO
7003
7004 CALL hmpldf(1,'Number of words/record in binary file')
7005 CALL hmpdef(8,0.0,60.0,'not_stored data per record')
7006 ! define read buffer
7007 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7008 nwrd=nc31+1
7009 IF(ndimbuf > nwrd) THEN
7010 CALL peend(20,'Aborted, bad binary records')
7011 stop 'LOOP1: length of binary record exceeds cache size, wrong file type?'
7012 END IF
7013 length=nwrd*mthrdr
7014 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7015 nwrd=nc31*10+2+ndimbuf
7016 length=nwrd*mthrdr
7017 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7018 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7019 ! to read (old) float binary files
7020 length=(ndimbuf+2)*mthrdr
7021 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7022
7023 ! read all data files and add all labels to global labels table ----
7024 IF(mprint /= 0) THEN
7025 WRITE(*,*) 'Read all binary data files:'
7026 END IF
7027
7028 DO
7029 CALL peread(nr) ! read records
7030 IF (skippedrecords == 0) THEN
7031 CALL peprep(0) ! prepare records
7032 CALL pepgrp ! update parameter group info
7033 END IF
7034 IF(nr <= 0) EXIT ! end of data?
7035 END DO
7036 ! release read buffer
7041 IF (skippedrecords == 0) THEN
7042 EXIT
7043 ELSE
7044 WRITE(lunlog,*) 'LOOP1: reading data files again'
7045 END IF
7046 END DO
7047
7048 IF(nhistp /= 0) THEN
7049 CALL hmprnt(1)
7050 CALL hmprnt(8)
7051 END IF
7052 CALL hmpwrt(1)
7053 CALL hmpwrt(8)
7054 ntgb = globalparheader(-1) ! total number of labels/parameters
7055 IF (ntgb == 0) THEN
7056 CALL peend(21,'Aborted, no labels/parameters defined')
7057 stop 'LOOP1: no labels/parameters defined'
7058 END IF
7059 CALL upone ! finalize the global label table
7060
7061 WRITE(lunlog,*) 'LOOP1:',ntgb, &
7062 ' is total number NTGB of labels/parameters'
7063 ! histogram number of entries per label ----------------------------
7064 CALL hmpldf(2,'Number of entries per label')
7065 DO j=1,ntgb
7066 CALL hmplnt(2,globalparlabelindex(2,j))
7067 END DO
7068 IF(nhistp /= 0) CALL hmprnt(2) ! print histogram
7069 CALL hmpwrt(2) ! write to his file
7070
7071 ! three subarrays for all global parameters ------------------------
7072 length=ntgb
7073 CALL mpalloc(globalparameter,length,'global parameters')
7074 globalparameter=0.0_mpd
7075 CALL mpalloc(globalparpresigma,length,'pre-sigmas') ! presigmas
7077 CALL mpalloc(globalparstart,length,'global parameters at start')
7079 CALL mpalloc(globalparcopy,length,'copy of global parameters')
7080 CALL mpalloc(globalparcons,length,'global parameter constraints')
7082 CALL mpalloc(globalparcomments,length,'global parameter comments')
7084
7085 DO i=1,lenparameters ! parameter start values
7086 param=listparameters(i)%value
7087 in=inone(listparameters(i)%label)
7088 IF(in /= 0) THEN
7089 globalparameter(in)=param
7090 globalparstart(in)=param
7091 ENDIF
7092 END DO
7093
7094 DO i=1, lencomments
7095 in=inone(listcomments(i)%label)
7096 IF(in /= 0) globalparcomments(in)=i
7097 END DO
7098
7099 npresg=0
7100 DO i=1,lenpresigmas ! pre-sigma values
7101 presg=listpresigmas(i)%value
7102 in=inone(listpresigmas(i)%label)
7103 IF(in /= 0) THEN
7104 IF(presg > 0.0) npresg=npresg+1 ! FIXME: check if enough 'entries'?
7105 globalparpresigma(in)=presg ! insert pre-sigma 0 or > 0
7106 END IF
7107 END DO
7108 WRITE(lunlog,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7109 WRITE(*,*) 'LOOP1:',npresg,' is number of pre-sigmas'
7110 IF(npresg == 0) WRITE(*,*) 'Warning: no pre-sigmas defined'
7111
7112 ! build constraint groups, check for redundancy constrints
7113 CALL grpcon
7114
7115 ! determine flag variable (active) or fixed (inactive) -------------
7116
7117 indab=0
7118 DO i=1,ntgb
7119 IF (globalparpresigma(i) < 0.0) THEN
7120 globalparlabelindex(2,i)=-1 ! fixed (pre-sigma), not used in matrix (not active)
7121 ELSE IF(globalparlabelcounter(i) < mreqenf) THEN
7122 globalparlabelindex(2,i)=-2 ! fixed (entries cut), not used in matrix (not active)
7123 ELSE IF (globalparcons(i) < 0) THEN
7124 globalparlabelindex(2,i)=-4 ! fixed (redundant), not used in matrix (not active)
7125 ELSE
7126 indab=indab+1
7127 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7128 END IF
7129 END DO
7130 globalparheader(-6)=indab ! counted variable
7131 nvgb=indab ! nr of variable parameters
7132 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7133 IF(iteren > mreqenf) THEN
7134 IF (mcount == 0) THEN
7135 CALL loop1i ! iterate entries cut
7136 ELSE
7137 WRITE(lunlog,*) 'LOOP1: counting records, NO iteration of entries cut !'
7138 iteren=0
7139 END IF
7140 END IF
7141
7142 ! --- check for parameter groups
7143 CALL hmpdef(15,0.0,120.0,'Number of parameters per group')
7144 ntpgrp=0
7145 DO j=1,ntgb
7146 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7147 ! new group?
7149 globalparlabelindex(4,j)=ntpgrp ! relation total index -> group
7150 END DO
7151 ! check variable parameters
7152 nvpgrp=0
7153 lgrp=-1
7154 DO j=1,ntgb
7155 IF (globalparlabelindex(2,j) <= 0) cycle ! skip fixed parameter
7156 ! new group ?
7157 IF (globalparlabelindex(4,j) /= lgrp) nvpgrp=nvpgrp+1
7158 lgrp=globalparlabelindex(4,j)
7159 END DO
7160 length=ntpgrp; rows=2
7161 CALL mpalloc(globaltotindexgroups,rows,length,'parameter groups, 1. index and size')
7163 ! fill
7164 lgrp=-1
7165 DO j=1,ntgb
7166 IF (globalparlabelindex(3,j) == 0) cycle ! skip empty parameter
7167 jgrp=globalparlabelindex(4,j)
7168 IF (jgrp /= lgrp) globaltotindexgroups(1,jgrp)=j ! first (total) index
7169 globaltotindexgroups(2,jgrp)=globaltotindexgroups(2,jgrp)+1 ! (total) size
7170 lgrp=jgrp
7171 END DO
7172 DO j=1,ntpgrp
7173 CALL hmpent(15,real(globaltotindexgroups(2,j),mps))
7174 END DO
7175 IF(nhistp /= 0) CALL hmprnt(15) ! print histogram
7176 CALL hmpwrt(15) ! write to his file
7177 WRITE(lunlog,*) 'LOOP1:',ntpgrp, &
7178 ' is total number NTPGRP of label/parameter groups'
7179 !print *, ' globalTotIndexGroups ', globalTotIndexGroups
7180
7181 ! translation table of length NVGB of total global indices ---------
7182 length=nvgb
7183 CALL mpalloc(globalparvartototal,length,'translation table var -> total')
7184 indab=0
7185 DO i=1,ntgb
7186 IF(globalparlabelindex(2,i) > 0) THEN
7187 indab=indab+1
7188 globalparvartototal(indab)=i
7189 END IF
7190 END DO
7191
7192 ! regularization ---------------------------------------------------
7193 CALL mpalloc(globalparpreweight,length,'pre-sigmas weights') ! presigma weights
7194 WRITE(*,112) ' Default pre-sigma =',regpre, &
7195 ' (if no individual pre-sigma defined)'
7196 WRITE(*,*) 'Pre-sigma factor is',regula
7197
7198 IF(nregul == 0) THEN
7199 WRITE(*,*) 'No regularization will be done'
7200 ELSE
7201 WRITE(*,*) 'Regularization will be done, using factor',regula
7202 END IF
7203112 FORMAT(a,e9.2,a)
7204 IF (nvgb <= 0) THEN
7205 CALL peend(22,'Aborted, no variable global parameters')
7206 stop '... no variable global parameters'
7207 ENDIF
7208
7209 DO ivgbi=1,nvgb ! IVGBI = index of variable global parameter
7210 itgbi=globalparvartototal(ivgbi) ! ITGBI = global parameter index
7211 presg=globalparpresigma(itgbi) ! get pre-sigma
7212 prewt=0.0 ! pre-weight
7213 IF(presg > 0.0) THEN
7214 prewt=1.0/presg**2 ! 1/presigma^2
7215 ELSE IF(presg == 0.0.AND.regpre > 0.0) THEN
7216 prewt=1.0/real(regpre**2,mpd) ! default 1/presigma^2
7217 END IF
7218 globalparpreweight(ivgbi)=regula*prewt ! weight = factor / presigma^2
7219 END DO
7220
7221 ! WRITE(*,*) 'GlPa_index GlPa_label array1 array6'
7222 DO i=1,ntgb
7223 itgbl=globalparlabelindex(1,i)
7224 ivgbi=globalparlabelindex(2,i)
7225 IF(ivgbi > 0) THEN
7226 ! WRITE(*,111) I,ITGBL,QM(IND1+I),QM(IND6+IVGBI)
7227 ELSE
7228 ! WRITE(*,111) I,ITGBL,QM(IND1+I)
7229 END IF
7230 END DO
7231 ! 111 FORMAT(I5,I10,F10.5,E12.4)
7232 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7233 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7234 ! To avoid INT(mpi) overflows in diagonalization
7235 IF (metsol == 2.AND.nvgb >= 46340) THEN
7236 metsol=1
7237 WRITE(*,101) 'Too many variable parameters for diagonalization, fallback is inversion'
7238 END IF
7239
7240 ! print overview over important numbers ----------------------------
7241
7242 nrecal=nrec
7243 IF(mprint /= 0) THEN
7244 WRITE(*,*) ' '
7245 WRITE(*,101) ' NREC',nrec,'number of records'
7246 IF (nrecd > 0) WRITE(*,101) ' NRECD',nrec,'number of records containing doubles'
7247 WRITE(*,101) ' NEQN',neqn,'number of equations (measurements)'
7248 WRITE(*,101) ' NEGB',negb,'number of equations with global parameters'
7249 WRITE(*,101) ' NDGB',ndgb,'number of global derivatives'
7250 IF (nzgb > 0) THEN
7251 WRITE(*,101) ' NZGB',nzgb,'number of zero global der. (ignored in entry counts)'
7252 ENDIF
7253 IF (mcount == 0) THEN
7254 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7255 ELSE
7256 WRITE(*,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7257 ENDIF
7258 IF(iteren > mreqenf) &
7259 WRITE(*,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7260 WRITE(*,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7261 IF (mreqpe > 1) WRITE(*,101) &
7262 'MREQPE',mreqpe,'required number of pair entries'
7263 IF (msngpe >= 1) WRITE(*,101) &
7264 'MSNGPE',msngpe,'max pair entries single prec. storage'
7265 WRITE(*,101) 'NTGB',ntgb,'total number of parameters'
7266 WRITE(*,101) 'NVGB',nvgb,'number of variable parameters'
7267 IF(mprint > 1) THEN
7268 WRITE(*,*) ' '
7269 WRITE(*,*) 'Global parameter labels:'
7270 mqi=ntgb
7271 IF(mqi <= 100) THEN
7272 WRITE(*,*) (globalparlabelindex(2,i),i=1,mqi)
7273 ELSE
7274 WRITE(*,*) (globalparlabelindex(2,i),i=1,30)
7275 WRITE(*,*) ' ...'
7276 mqi=((mqi-20)/20)*20+1
7277 WRITE(*,*) (globalparlabelindex(2,i),i=mqi,ntgb)
7278 END IF
7279 END IF
7280 WRITE(*,*) ' '
7281 WRITE(*,*) ' '
7282 END IF
7283 WRITE(8,*) ' '
7284 WRITE(8,101) ' NREC',nrec,'number of records'
7285 IF (nrecd > 0) WRITE(8,101) ' NRECD',nrec,'number of records containing doubles'
7286 WRITE(8,101) ' NEQN',neqn,'number of equations (measurements)'
7287 WRITE(8,101) ' NEGB',negb,'number of equations with global parameters'
7288 WRITE(8,101) ' NDGB',ndgb,'number of global derivatives'
7289 IF (mcount == 0) THEN
7290 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (eqns in binary files)'
7291 ELSE
7292 WRITE(8,101) 'MREQENF',mreqenf,'required number of entries (recs in binary files)'
7293 ENDIF
7294 IF(iteren > mreqenf) &
7295 WRITE(8,101) 'ITEREN',iteren,'iterate cut for parameters with less entries'
7296 WRITE(8,101) 'MREQENA',mreqena,'required number of entries (from accepted fits)'
7297
7298 WRITE(lunlog,*) 'LOOP1: ending'
7299 WRITE(lunlog,*) ' '
7300 CALL mend
7301
7302101 FORMAT(1x,a8,' =',i14,' = ',a)
7303END SUBROUTINE loop1
7304
7312SUBROUTINE loop1i
7313 USE mpmod
7314 USE mpdalc
7315
7316 IMPLICIT NONE
7317 INTEGER(mpi) :: i
7318 INTEGER(mpi) :: ibuf
7319 INTEGER(mpi) :: ij
7320 INTEGER(mpi) :: indab
7321 INTEGER(mpi) :: ist
7322 INTEGER(mpi) :: j
7323 INTEGER(mpi) :: ja
7324 INTEGER(mpi) :: jb
7325 INTEGER(mpi) :: jsp
7326 INTEGER(mpi) :: nc31
7327 INTEGER(mpi) :: nr
7328 INTEGER(mpi) :: nlow
7329 INTEGER(mpi) :: nst
7330 INTEGER(mpi) :: nwrd
7331
7332 INTEGER(mpl) :: length
7333 INTEGER(mpl), DIMENSION(:), ALLOCATABLE :: newCounter
7334 SAVE
7335
7336 ! ...
7337 WRITE(lunlog,*) ' '
7338 WRITE(lunlog,*) 'LOOP1: iterating'
7339 WRITE(*,*) ' '
7340 WRITE(*,*) 'LOOP1: iterating'
7341
7342 length=ntgb
7343 CALL mpalloc(newcounter,length,'new entries counter')
7344 newcounter=0
7345
7346 ! define read buffer
7347 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7348 nwrd=nc31+1
7349 length=nwrd*mthrdr
7350 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7351 nwrd=nc31*10+2+ndimbuf
7352 length=nwrd*mthrdr
7353 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7354 CALL mpalloc(readbufferdatad,length,'read buffer, double')
7355 ! to read (old) float binary files
7356 length=(ndimbuf+2)*mthrdr
7357 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7358
7359 DO
7360 CALL peread(nr) ! read records
7361 CALL peprep(1) ! prepare records
7362 DO ibuf=1,numreadbuffer ! buffer for current record
7363 ist=readbufferpointer(ibuf)+1
7365 nwrd=nst-ist+1
7366 DO ! loop over measurements
7367 CALL isjajb(nst,ist,ja,jb,jsp)
7368 IF(ja == 0.AND.jb == 0) EXIT
7369 IF(ja /= 0) THEN
7370 nlow=0
7371 DO j=1,ist-jb
7372 ij=readbufferdatai(jb+j) ! index of global parameter
7373 ij=globalparlabelindex(2,ij) ! change to variable parameter
7374 IF(ij == -2) nlow=nlow+1 ! fixed by entries cut
7375 END DO
7376 IF(nlow == 0) THEN
7377 DO j=1,ist-jb
7378 ij=readbufferdatai(jb+j) ! index of global parameter
7379 newcounter(ij)=newcounter(ij)+1 ! count again
7380 END DO
7381 ENDIF
7382 END IF
7383 END DO
7384 ! end-of-event
7385 END DO
7386 IF(nr <= 0) EXIT ! end of data?
7387 END DO
7388
7389 ! release read buffer
7394
7395 indab=0
7396 DO i=1,ntgb
7397 IF(globalparlabelindex(2,i) > 0) THEN
7398 IF(newcounter(i) >= mreqenf .OR. globalparlabelcounter(i) >= iteren) THEN
7399 indab=indab+1
7400 globalparlabelindex(2,i)=indab ! variable, used in matrix (active)
7401 ELSE
7402 globalparlabelindex(2,i)=-3 ! fixed (iterated entries cut), not used in matrix (not active)
7403 END IF
7404 END IF
7405 END DO
7406 globalparheader(-6)=indab ! counted variable
7407 nvgb=indab ! nr of variable parameters
7408 WRITE(lunlog,*) 'LOOP1:',nvgb, ' is number NVGB of variable parameters'
7409 CALL mpdealloc(newcounter)
7410
7411END SUBROUTINE loop1i
7412
7423
7424SUBROUTINE loop2
7425 USE mpmod
7426 USE mpdalc
7427
7428 IMPLICIT NONE
7429 REAL(mps) :: chin2
7430 REAL(mps) :: chin3
7431 REAL(mps) :: cpr
7432 REAL(mps) :: fsum
7433 REAL(mps) :: gbc
7434 REAL(mps) :: gbu
7435 INTEGER(mpi) :: i
7436 INTEGER(mpi) :: ia
7437 INTEGER(mpi) :: ib
7438 INTEGER(mpi) :: ibuf
7439 INTEGER(mpi) :: icblst
7440 INTEGER(mpi) :: icboff
7441 INTEGER(mpi) :: icgb
7442 INTEGER(mpi) :: icgrp
7443 INTEGER(mpi) :: icount
7444 INTEGER(mpi) :: iext
7445 INTEGER(mpi) :: ihis
7446 INTEGER(mpi) :: ij
7447 INTEGER(mpi) :: ij1
7448 INTEGER(mpi) :: ijn
7449 INTEGER(mpi) :: ioff
7450 INTEGER(mpi) :: ipoff
7451 INTEGER(mpi) :: iproc
7452 INTEGER(mpi) :: irecmm
7453 INTEGER(mpi) :: ist
7454 INTEGER(mpi) :: itgbi
7455 INTEGER(mpi) :: itgbij
7456 INTEGER(mpi) :: itgbik
7457 INTEGER(mpi) :: ivgbij
7458 INTEGER(mpi) :: ivgbik
7459 INTEGER(mpi) :: ivpgrp
7460 INTEGER(mpi) :: j
7461 INTEGER(mpi) :: ja
7462 INTEGER(mpi) :: jb
7463 INTEGER(mpi) :: jcgrp
7464 INTEGER(mpi) :: jext
7465 INTEGER(mpi) :: jcgb
7466 INTEGER(mpi) :: jrec
7467 INTEGER(mpi) :: jsp
7468 INTEGER(mpi) :: joff
7469 INTEGER(mpi) :: k
7470 INTEGER(mpi) :: kcgrp
7471 INTEGER(mpi) :: kfile
7472 INTEGER(mpi) :: l
7473 INTEGER(mpi) :: label
7474 INTEGER(mpi) :: labelf
7475 INTEGER(mpi) :: labell
7476 INTEGER(mpi) :: lvpgrp
7477 INTEGER(mpi) :: lu
7478 INTEGER(mpi) :: lun
7479 INTEGER(mpi) :: maeqnf
7480 INTEGER(mpi) :: nall
7481 INTEGER(mpi) :: naeqna
7482 INTEGER(mpi) :: naeqnf
7483 INTEGER(mpi) :: naeqng
7484 INTEGER(mpi) :: npdblk
7485 INTEGER(mpi) :: nc31
7486 INTEGER(mpi) :: ncachd
7487 INTEGER(mpi) :: ncachi
7488 INTEGER(mpi) :: ncachr
7489 INTEGER(mpi) :: ncon
7490 INTEGER(mpi) :: nda
7491 INTEGER(mpi) :: ndf
7492 INTEGER(mpi) :: ndfmax
7493 INTEGER(mpi) :: nfixed
7494 INTEGER(mpi) :: nggd
7495 INTEGER(mpi) :: nggi
7496 INTEGER(mpi) :: nmatmo
7497 INTEGER(mpi) :: noff
7498 INTEGER(mpi) :: npair
7499 INTEGER(mpi) :: npar
7500 INTEGER(mpi) :: nparmx
7501 INTEGER(mpi) :: nr
7502 INTEGER(mpi) :: nrece
7503 INTEGER(mpi) :: nrecf
7504 INTEGER(mpi) :: nrecmm
7505 INTEGER(mpi) :: nst
7506 INTEGER(mpi) :: nwrd
7507 INTEGER(mpi) :: inone
7508 INTEGER(mpi) :: inc
7509 REAL(mps) :: wgh
7510 REAL(mps) :: wolfc3
7511 REAL(mps) :: wrec
7512 REAL(mps) :: chindl
7513
7514 REAL(mpd)::dstat(3)
7515 REAL(mpd)::rerr
7516 INTEGER(mpl):: nblock
7517 INTEGER(mpl):: nbwrds
7518 INTEGER(mpl):: noff8
7519 INTEGER(mpl):: ndimbi
7520 INTEGER(mpl):: ndimsa(4)
7521 INTEGER(mpl):: ndgn
7522 INTEGER(mpl):: nnzero
7523 INTEGER(mpl):: matsiz(2)
7524 INTEGER(mpl):: matwords
7525 INTEGER(mpl):: mbwrds
7526 INTEGER(mpl):: length
7527 INTEGER(mpl):: rows
7528 INTEGER(mpl):: cols
7529 INTEGER(mpl), PARAMETER :: two=2
7530 INTEGER(mpi) :: maxGlobalPar = 0
7531 INTEGER(mpi) :: maxLocalPar = 0
7532 INTEGER(mpi) :: maxEquations = 0
7533
7534 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupList
7535 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecConsGroupIndex
7536 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecPairedParGroups
7537 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: vecBlockCounts
7538
7539 INTERFACE ! needed for assumed-shape dummy arguments
7540 SUBROUTINE ndbits(npgrp,ndims,nsparr,ihst)
7541 USE mpdef
7542 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7543 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7544 INTEGER(mpl), DIMENSION(:,:), INTENT(OUT) :: nsparr
7545 INTEGER(mpi), INTENT(IN) :: ihst
7546 END SUBROUTINE ndbits
7547 SUBROUTINE ckbits(npgrp,ndims)
7548 USE mpdef
7549 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7550 INTEGER(mpl), DIMENSION(4), INTENT(OUT) :: ndims
7551 END SUBROUTINE ckbits
7552 SUBROUTINE spbits(npgrp,nsparr,nsparc)
7553 USE mpdef
7554 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7555 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
7556 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: nsparc
7557 END SUBROUTINE spbits
7558 SUBROUTINE gpbmap(ngroup,npgrp,npair)
7559 USE mpdef
7560 INTEGER(mpi), INTENT(IN) :: ngroup
7561 INTEGER(mpi), DIMENSION(:,:), INTENT(IN) :: npgrp
7562 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npair
7563 END SUBROUTINE gpbmap
7564 SUBROUTINE ggbmap(ipgrp,npair,npgrp)
7565 USE mpdef
7566 INTEGER(mpi), INTENT(IN) :: ipgrp
7567 INTEGER(mpi), INTENT(OUT) :: npair
7568 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: npgrp
7569 END SUBROUTINE ggbmap
7570 SUBROUTINE pbsbits(npgrp,ibsize,nnzero,nblock,nbkrow)
7571 USE mpdef
7572 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7573 INTEGER(mpi), INTENT(IN) :: ibsize
7574 INTEGER(mpl), INTENT(OUT) :: nnzero
7575 INTEGER(mpl), INTENT(OUT) :: nblock
7576 INTEGER(mpi), DIMENSION(:),INTENT(OUT) :: nbkrow
7577 END SUBROUTINE pbsbits
7578 SUBROUTINE pblbits(npgrp,ibsize,nsparr,nsparc)
7579 USE mpdef
7580 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7581 INTEGER(mpi), INTENT(IN) :: ibsize
7582 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7583 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7584 END SUBROUTINE pblbits
7585 SUBROUTINE prbits(npgrp,nsparr)
7586 USE mpdef
7587 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7588 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparr
7589 END SUBROUTINE prbits
7590 SUBROUTINE pcbits(npgrp,nsparr,nsparc)
7591 USE mpdef
7592 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
7593 INTEGER(mpl), DIMENSION(:), INTENT(IN) :: nsparr
7594 INTEGER(mpl), DIMENSION(:), INTENT(OUT) :: nsparc
7595 END SUBROUTINE pcbits
7596 END INTERFACE
7597
7598 SAVE
7599
7600 !$ INTEGER(mpi) :: OMP_GET_THREAD_NUM
7601
7602 ! ...
7603 WRITE(lunlog,*) ' '
7604 WRITE(lunlog,*) 'LOOP2: starting'
7605 CALL mstart('LOOP2')
7606
7607 ! two subarrays to get the global parameter indices, used in an event
7608 length=nvgb
7609 CALL mpalloc(globalindexusage,length,'global index')
7610 CALL mpalloc(backindexusage,length,'back index')
7612 CALL mpalloc(globalindexranges,length,'global index ranges')
7614
7615 length=ntgb
7616 CALL mpalloc(globalparlabelzeros,length,'global label with zero der. counters')
7618
7619 ! prepare constraints - determine number of constraints NCGB
7620 ! - sort and split into blocks
7621 ! - update globalIndexRanges
7622 CALL prpcon
7623
7624 IF (metsol == 3.AND.icelim <= 0) THEN
7625 ! decomposition: enforce elimination
7626 icelim=1
7627 WRITE(lunlog,*) ' Elimination for constraints enforced for solution by decomposition!'
7628 END IF
7629 IF (metsol == 9.AND.icelim > 0) THEN
7630 ! sparsePARDISO: enforce multipliers
7631 icelim=0
7632 WRITE(lunlog,*) ' Lagrange multipliers enforced for solution by sparsePARDISO!'
7633 END IF
7634 IF (matsto > 0.AND.icelim > 1) THEN
7635 ! decomposition: enforce elimination
7636 icelim=1
7637 WRITE(lunlog,*) ' Elimination for constraints with mpqldec enforced (LAPACK only for unpacked storage)!'
7638 END IF
7639 IF (icelim > 0) THEN ! elimination
7640 nagb=nvgb ! total number of parameters
7641 napgrp=nvpgrp ! total number of parameter groups
7642 nfgb=nvgb-ncgb ! number of fit parameters
7643 nprecond(1)=0 ! number of constraints for preconditioner
7644 nprecond(2)=nfgb ! matrix size for preconditioner
7645 nprecond(3)=0 ! number of constraint blocks for preconditioner
7646 ELSE ! Lagrange multipliers
7647 nagb=nvgb+ncgb ! total number of parameters
7648 napgrp=nvpgrp+ncgb ! total number of parameter groups
7649 nfgb=nagb ! number of fit parameters
7650 nprecond(1)=ncgb ! number of constraints for preconditioner
7651 nprecond(2)=nvgb ! matrix size for preconditioner
7652 nprecond(3)=ncblck ! number of constraint blocks for preconditioner
7653 ENDIF
7654 noff8=int(nagb,mpl)*int(nagb-1,mpl)/2
7655
7656 ! all (variable) parameter groups
7657 length=napgrp+1
7658 CALL mpalloc(globalallindexgroups,length,'all parameter groups, 1. index')
7660 ivpgrp=0
7661 lvpgrp=-1
7662 DO i=1,ntgb
7663 ij=globalparlabelindex(2,i)
7664 IF (ij <= 0) cycle ! variable ?
7665 IF (globalparlabelindex(4,i) /= lvpgrp) THEN
7666 ivpgrp=ivpgrp+1
7667 globalallindexgroups(ivpgrp)=ij ! first index
7668 lvpgrp=globalparlabelindex(4,i)
7669 END IF
7670 END DO
7671 ! Lagrange multipliers
7672 IF (napgrp > nvpgrp) THEN
7673 DO jcgb=1, ncgb
7674 ivpgrp=ivpgrp+1
7675 globalallindexgroups(ivpgrp)=nvgb+jcgb
7676 END DO
7677 END IF
7679 ! from all (variable) parameters to group
7680 length=nagb
7681 CALL mpalloc(globalallpartogroup,length,'translation table all (var) par -> group')
7683 DO i=1,napgrp
7686 END DO
7687 END DO
7688 IF (icheck > 2) THEN
7689 print *
7690 print *, ' Variable parameter groups ', nvpgrp
7691 DO i=1,nvpgrp
7693 k=globalparlabelindex(4,itgbi) ! (total) group index
7695 globalparlabelindex(1,itgbi)
7696 END DO
7697 print *
7698 END IF
7699
7700 ! read all data files and add all variable index pairs -------------
7701
7702 IF (icheck > 1) CALL clbmap(ntpgrp+ncgrp)
7703
7704 IF(matsto == 2) THEN
7705 ! MINRES, sparse storage
7706 CALL clbits(napgrp,mreqpe,mhispe,msngpe,mextnd,ndimbi,nspc) ! get dimension for bit storage, encoding, precision info
7707 END IF
7708 IF(matsto == 3) THEN
7709 ! PARDISO, upper triangle (parameter groups) incl. rectangular part (constraints)
7710 CALL plbits(nvpgrp,nvgb,ncgb,ndimbi) ! get dimension for bit storage, global parameters and constraints
7711 END IF
7712
7713 IF (imonit /= 0) THEN
7714 length=ntgb
7715 CALL mpalloc(measindex,length,'measurement counter/index')
7716 measindex=0
7717 CALL mpalloc(measres,length,'measurement resolution')
7718 measres=0.0_mps
7719 lunmon=9
7720 CALL mvopen(lunmon,'millepede.mon')
7721 ENDIF
7722
7723 ! for checking appearance
7724 IF (icheck > 1) THEN
7725 length=5*(ntgb+ncgrp)
7726 CALL mpalloc(appearancecounter,length,'appearance statistics')
7728 length=ntgb
7729 CALL mpalloc(paircounter,length,'pair statistics')
7730 paircounter=0
7731 END IF
7732
7733 ! checking constraint goups
7734 IF (icheck > 0.AND. ncgrp > 0) THEN
7735 length=ncgrp
7736 CALL mpalloc(vecconsgroupcounts,length,'counter for constraint groups')
7738 CALL mpalloc(vecconsgrouplist,length,'constraint group list')
7739 CALL mpalloc(vecconsgroupindex,length,'constraint group index')
7740 vecconsgroupindex=0
7741 END IF
7742
7743 ! reading events===reading events===reading events===reading events=
7744 nrece =0 ! 'empty' records (no variable global parameters)
7745 nrecf =0 ! records with fixed global parameters
7746 naeqng=0 ! count number of equations (with global der.)
7747 naeqnf=0 ! count number of equations ( " , fixed)
7748 naeqna=0 ! all
7749 WRITE(lunlog,*) 'LOOP2: start event reading'
7750 ! monitoring for sparse matrix?
7751 irecmm=0
7752 IF (matsto == 2.AND.matmon /= 0) THEN
7753 nmatmo=0
7754 IF (matmon > 0) THEN
7755 nrecmm=matmon
7756 ELSE
7757 nrecmm=1
7758 END IF
7759 END IF
7760 DO k=1,3
7761 dstat(k)=0.0_mpd
7762 END DO
7763 ! define read buffer
7764 nc31=ncache/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
7765 nwrd=nc31+1
7766 length=nwrd*mthrdr
7767 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
7768 nwrd=nc31*10+2+ndimbuf
7769 length=nwrd*mthrdr
7770 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
7771 CALL mpalloc(readbufferdatad,length,'read buffer, real')
7772 ! to read (old) float binary files
7773 length=(ndimbuf+2)*mthrdr
7774 CALL mpalloc(readbufferdataf,length,'read buffer, float')
7775
7776 DO
7777 CALL peread(nr) ! read records
7778 CALL peprep(1) ! prepare records
7779 ioff=0
7780 DO ibuf=1,numreadbuffer ! buffer for current record
7781 jrec=readbufferdatai(readbufferpointer(ibuf)-1) ! record number in file
7782 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7783 nrec=ifd(kfile)+jrec ! global record number
7784 ! Printout for DEBUG
7785 IF(nrec <= mdebug) THEN
7786 nda=0
7787 wrec =real(readbufferdatad(readbufferpointer(ibuf)-1),mps) ! weight
7788 WRITE(*,*) ' '
7789 WRITE(*,*) 'Record number ',nrec,' from file ',kfile
7790 IF (wgh /= 1.0) WRITE(*,*) ' weight ',wrec
7791 ist=readbufferpointer(ibuf)+1
7793 DO ! loop over measurements
7794 CALL isjajb(nst,ist,ja,jb,jsp)
7795 IF(ja == 0) EXIT
7796 nda=nda+1
7797 IF(nda > mdebg2) THEN
7798 IF(nda == mdebg2+1) WRITE(*,*) '... and more data'
7799 cycle
7800 END IF
7801 WRITE(*,*) ' '
7802 WRITE(*,*) nda, ' Measured value =',readbufferdatad(ja),' +- ',readbufferdatad(jb)
7803 WRITE(*,*) 'Local derivatives:'
7804 WRITE(*,107) (readbufferdatai(ja+j),readbufferdatad(ja+j),j=1,jb-ja-1)
7805107 FORMAT(6(i3,g12.4))
7806 IF (jb < ist) THEN
7807 WRITE(*,*) 'Global derivatives:'
7808 WRITE(*,108) (globalparlabelindex(1,readbufferdatai(jb+j)),readbufferdatai(jb+j), &
7809 globalparlabelindex(2,readbufferdatai(jb+j)),readbufferdatad(jb+j),j=1,ist-jb)
7810108 FORMAT(3i11,g12.4)
7811 END IF
7812 IF(nda == 1) THEN
7813 WRITE(*,*) 'total_par_label __label__ var_par_index derivative'
7814 END IF
7815 END DO
7816 WRITE(*,*) ' '
7817 END IF
7818
7819 nagbn =0 ! count number of global derivatives
7820 nalcn =0 ! count number of local derivatives
7821 naeqn =0 ! count number of equations
7822 icgrp =0 ! count constraint groups
7823 maeqnf=naeqnf
7824 ist=readbufferpointer(ibuf)+1
7826 nwrd=nst-ist+1
7827 DO ! loop over measurements
7828 CALL isjajb(nst,ist,ja,jb,jsp)
7829 IF(ja == 0.AND.jb == 0) EXIT
7830 naeqn=naeqn+1
7831 naeqna=naeqna+1
7832 IF(ja /= 0) THEN
7833 IF (ist > jb) THEN
7834 naeqng=naeqng+1
7835 ! monitoring, group measurements, sum up entries and errors
7836 IF (imonit /= 0) THEN
7837 rerr =real(readbufferdatad(jb),mpd) ! the error
7838 ij=readbufferdatai(jb+1) ! index of first global parameter, used to group measurements
7839 measindex(ij)=measindex(ij)+1
7840 measres(ij)=measres(ij)+rerr
7841 END IF
7842 END IF
7843 nfixed=0
7844 DO j=1,ist-jb
7845 ij=readbufferdatai(jb+j) ! index of global parameter
7846 IF (nzgb > 0) THEN
7847 ! count zero global derivatives
7848 IF (readbufferdatad(jb+j) == 0.0_mpl) globalparlabelzeros(ij)=globalparlabelzeros(ij)+1
7849 END IF
7850 ! check appearance
7851 IF (icheck > 1) THEN
7852 joff = 5*(ij-1)
7853 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7854 IF (appearancecounter(joff+1) == 0) THEN
7855 appearancecounter(joff+1) = kfile
7856 appearancecounter(joff+2) = jrec ! (local) record number
7857 END IF
7858 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=appearancecounter(joff+5)+1
7859 appearancecounter(joff+3) = kfile
7860 appearancecounter(joff+4) = jrec ! (local) record number
7861 ! count pairs
7862 DO k=1,j
7864 END DO
7865 jcgrp=globalparcons(ij)
7866 ! correlate constraint groups with 'other' parameter groups
7867 DO k=1,j
7868 kcgrp=globalparcons(readbufferdatai(jb+k))
7869 IF (kcgrp == jcgrp) cycle
7870 IF (jcgrp > 0) CALL inbmap(ntpgrp+jcgrp,globalparlabelindex(4,readbufferdatai(jb+k)))
7871 IF (kcgrp > 0) CALL inbmap(ntpgrp+kcgrp,globalparlabelindex(4,ij))
7872 END DO
7873 END IF
7874 ! check constraint groups
7875 IF (icheck > 0.AND.ncgrp > 0) THEN
7876 k=globalparcons(ij) ! constraint group
7877 IF (k > 0) THEN
7878 icount=naeqn
7879 IF (mcount > 0) icount=1 ! count records
7880 IF (vecconsgroupindex(k) == 0) THEN
7881 ! add to list
7882 icgrp=icgrp+1
7883 vecconsgrouplist(icgrp)=k
7884 ! check appearance
7885 IF (icheck > 1) THEN
7886 joff = 5*(ntgb+k-1)
7887 kfile=nint(readbufferdatad(readbufferpointer(ibuf)),mpi) ! file
7888 IF (appearancecounter(joff+1) == 0) THEN
7889 appearancecounter(joff+1) = kfile
7890 appearancecounter(joff+2) = jrec ! (local) record number
7891 END IF
7892 IF (appearancecounter(joff+3) /= kfile) appearancecounter(joff+5)=&
7893 appearancecounter(joff+5)+1
7894 appearancecounter(joff+3) = kfile
7895 appearancecounter(joff+4) = jrec ! (local) record number
7896 END IF
7897 END IF
7898 IF (vecconsgroupindex(k) < icount) THEN
7899 ! count
7900 vecconsgroupindex(k)=icount
7902 END IF
7903 END IF
7904 END IF
7905
7906 ij=globalparlabelindex(2,ij) ! change to variable parameter
7907 IF(ij > 0) THEN
7908 ijn=backindexusage(ij) ! get index of index
7909 IF(ijn == 0) THEN ! not yet included
7910 nagbn=nagbn+1 ! count
7911 globalindexusage(nagbn)=ij ! store variable index
7912 backindexusage(ij)=nagbn ! store back index
7913 END IF
7914 ELSE
7915 nfixed=nfixed+1
7916 END IF
7917 END DO
7918 IF (nfixed > 0) naeqnf=naeqnf+1
7919 END IF
7920
7921 IF(ja /= 0.AND.jb /= 0) THEN
7922 DO j=1,jb-ja-1 ! local parameters
7923 ij=readbufferdatai(ja+j)
7924 nalcn=max(nalcn,ij)
7925 END DO
7926 END IF
7927 END DO
7928
7929 ! end-of-event
7930 IF (naeqnf > maeqnf) nrecf=nrecf+1
7931 irecmm=irecmm+1
7932 ! end-of-event-end-of-event-end-of-event-end-of-event-end-of-event-e
7933
7934 maxglobalpar=max(nagbn,maxglobalpar) ! maximum number of global parameters
7935 maxlocalpar=max(nalcn,maxlocalpar) ! maximum number of local parameters
7936 maxequations=max(naeqn,maxequations) ! maximum number of equations
7937
7938 ! sample statistics for caching
7939 dstat(1)=dstat(1)+real((nwrd+2)*2,mpd) ! record size
7940 dstat(2)=dstat(2)+real(nagbn+2,mpd) ! indices,
7941 dstat(3)=dstat(3)+real(nagbn*nagbn+nagbn,mpd) ! data for MUPDAT
7942
7943 ! clear constraint groups index
7944 DO k=1, icgrp
7945 vecconsgroupindex(vecconsgrouplist(k))=0
7946 END DO
7947
7948 CALL sort1k(globalindexusage,nagbn) ! sort global par.
7949
7950 IF (nagbn == 0) THEN
7951 nrece=nrece+1
7952 ELSE
7953 ! update parameter range
7956 ENDIF
7957
7958 ! overwrite read buffer with lists of global labels
7959 ioff=ioff+1
7960 readbufferpointer(ibuf)=ioff
7961 readbufferdatai(ioff)=ioff+nagbn
7962 joff=ioff
7963 lvpgrp=-1
7964 DO i=1,nagbn ! reset global index array, store parameter groups
7965 iext=globalindexusage(i)
7966 backindexusage(iext)=0
7967 ivpgrp=globalallpartogroup(iext)
7968 !ivpgrp=iext
7969 IF (ivpgrp /= lvpgrp) THEN
7970 joff=joff+1
7971 readbufferdatai(joff)=ivpgrp
7972 lvpgrp=ivpgrp
7973 END IF
7974 END DO
7975 readbufferdatai(ioff)=joff
7976 ioff=joff
7977
7978 END DO
7979 ioff=0
7980
7981 IF (matsto == 3) THEN
7982 !$OMP PARALLEL &
7983 !$OMP DEFAULT(PRIVATE) &
7984 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
7985 iproc=0
7986 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
7987 DO ibuf=1,numreadbuffer
7988 ist=readbufferpointer(ibuf)+1
7990 DO i=ist,nst ! store all combinations
7991 iext=readbufferdatai(i) ! variable global index
7992 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct column per thread
7993 DO l=i,nst
7994 jext=readbufferdatai(l)
7995 CALL inbits(iext,jext,1) ! save space
7996 END DO
7997 !$ ENDIF
7998 END DO
7999 END DO
8000 !$OMP END PARALLEL
8001 END IF
8002 IF (matsto == 2) THEN
8003 !$OMP PARALLEL &
8004 !$OMP DEFAULT(PRIVATE) &
8005 !$OMP SHARED(numReadBuffer,readBufferPointer,readBufferDataI,MTHRD)
8006 iproc=0
8007 !$ IPROC=OMP_GET_THREAD_NUM() ! thread number
8008 DO ibuf=1,numreadbuffer
8009 ist=readbufferpointer(ibuf)+1
8011 DO i=ist,nst ! store all combinations
8012 iext=readbufferdatai(i) ! variable global index
8013 !$ IF (MOD(IEXT,MTHRD).EQ.IPROC) THEN ! distinct rows per thread
8014 DO l=ist,i
8015 jext=readbufferdatai(l)
8016 CALL inbits(iext,jext,1) ! save space
8017 END DO
8018 !$ ENDIF
8019 END DO
8020 END DO
8021 !$OMP END PARALLEL
8022 ! monitoring
8023 IF (matmon /= 0.AND. &
8024 (irecmm >= nrecmm.OR.irecmm == mxrec)) THEN
8025 IF (nmatmo == 0) THEN
8026 WRITE(*,*)
8027 WRITE(*,*) 'Monitoring of sparse matrix construction'
8028 WRITE(*,*) ' records ........ off-diagonal elements ', &
8029 '....... compression memory'
8030 WRITE(*,*) ' non-zero used(double) used', &
8031 '(float) [%] [GB]'
8032 END IF
8033 nmatmo=nmatmo+1
8034 CALL ckbits(globalallindexgroups,ndimsa)
8035 gbc=1.0e-9*real((mpi*ndimsa(2)+mpd*ndimsa(3)+mps*ndimsa(4))/mpi*(bit_size(1_mpi)/8),mps) ! GB compressed
8036 gbu=1.0e-9*real(((mpi+mpd)*(ndimsa(3)+ndimsa(4)))/mpi*(bit_size(1_mpi)/8),mps) ! GB uncompressed
8037 cpr=100.0*gbc/gbu
8038 WRITE(*,1177) irecmm,ndimsa(1),ndimsa(3),ndimsa(4),cpr,gbc
80391177 FORMAT(i9,3i13,f10.2,f11.6)
8040 DO WHILE(irecmm >= nrecmm)
8041 IF (matmon > 0) THEN
8042 nrecmm=nrecmm+matmon
8043 ELSE
8044 nrecmm=nrecmm*2
8045 END IF
8046 END DO
8047 END IF
8048
8049 END IF
8050
8051 IF (nr <= 0) EXIT ! next block of events ?
8052 END DO
8053 ! release read buffer
8058
8059 WRITE(lunlog,*) 'LOOP2: event reading ended - end of data'
8060 DO k=1,3
8061 dstat(k)=dstat(k)/real(nrec,mpd)
8062 END DO
8063 ! end=of=data=end=of=data=end=of=data=end=of=data=end=of=data=end=of
8064
8065 IF (icheck > 0.AND. ncgrp > 0) THEN
8066 CALL mpdealloc(vecconsgroupindex)
8067 CALL mpdealloc(vecconsgrouplist)
8068 END IF
8069
8070 IF (icheck > 1) THEN
8072 END IF
8073 IF (icheck > 3) THEN
8074 length=ntpgrp+ncgrp
8075 CALL mpalloc(vecpairedpargroups,length,'paired global parameter groups (I)')
8076 print *
8077 print *, ' Total parameter groups pairs', ntpgrp
8078 DO i=1,ntpgrp
8079 itgbi=globaltotindexgroups(1,i)
8080 CALL ggbmap(i,npair,vecpairedpargroups)
8081 k=globalparlabelindex(4,itgbi) ! (total) group index
8082 print *, i, itgbi, globalparlabelindex(1,itgbi), npair, ':', vecpairedpargroups(:npair)
8083 END DO
8084 print *
8085 END IF
8086
8087 ! check constraints
8088 IF(matsto == 2) THEN
8089
8090 ! constraints and index pairs with Lagrange multiplier
8091 inc=max(mreqpe, msngpe+1) ! keep constraints in double precision
8092
8093 ! loop over (sorted) constraints
8094 DO jcgb=1,ncgb
8095 icgb=matconssort(3,jcgb) ! unsorted constraint index
8096 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8097 label=listconstraints(i)%label
8098 itgbi=inone(label)
8099 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8100 IF(ij > 0 .AND. nagb > nvgb) THEN
8102 END IF
8103 END DO
8104 END DO
8105 END IF
8106 IF(matsto == 3) THEN
8107 ! loop over (sorted) constraints
8108 DO jcgb=1,ncgb
8109 icgb=matconssort(3,jcgb) ! unsorted constraint index
8110 DO i=vecconsstart(icgb)+2,vecconsstart(icgb+1)-1
8111 label=listconstraints(i)%label
8112 itgbi=inone(label)
8113 ij=globalparlabelindex(2,itgbi) ! change to variable parameter
8114 IF(ij > 0.AND.listconstraints(i)%value /= 0.0_mpd) THEN
8115 ! non-zero coefficient
8116 CALL irbits(ij,jcgb)
8117 END IF
8118 END DO
8119 END DO
8120 END IF
8121
8122 ! check measurements
8123 IF(matsto == 2 .OR. matsto == 3) THEN
8124 ! measurements - determine index-pairs
8125
8126 i=1
8127 DO WHILE (i <= lenmeasurements)
8128 i=i+2
8129 ! loop over label/factor pairs
8130 ia=i
8131 DO
8132 i=i+1
8133 IF(i > lenmeasurements) EXIT
8134 IF(listmeasurements(i)%label < 0) EXIT
8135 END DO
8136 ib=i-1
8137
8138 DO j=ia,ib
8139 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8140 ! first index
8141 ivgbij=0
8142 IF(itgbij /= 0) ivgbij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8143 DO k=ia,j
8144 itgbik=inone(listmeasurements(k)%label) ! total parameter index
8145 ! second index
8146 ivgbik=0
8147 IF(itgbik /= 0) ivgbik=globalparlabelindex(2,itgbik) ! -> index of variable global parameter
8148 IF(ivgbij > 0.AND.ivgbik > 0) THEN
8150 IF (mprint > 1) WRITE(*,*) 'add index pair ',ivgbij,ivgbik
8151 END IF
8152 END DO
8153 END DO
8154
8155 END DO
8156 ELSE
8157 ! more checks for block diagonal structure
8158 ! loop over measurements
8159 i=1
8160 DO WHILE (i <= lenmeasurements)
8161 i=i+2
8162 ! loop over label/factor pairs
8163 ia=i
8164 DO
8165 i=i+1
8166 IF(i > lenmeasurements) EXIT
8167 IF(listmeasurements(i)%label < 0) EXIT
8168 END DO
8169 ib=i-1
8170 ij1=nvgb
8171 ijn=1
8172 DO j=ia,ib
8173 itgbij=inone(listmeasurements(j)%label) ! total parameter index
8174 ! first index
8175 ij=0
8176 IF(itgbij /= 0) ij=globalparlabelindex(2,itgbij) ! -> index of variable global parameter
8177 IF (ij > 0) THEN
8178 ij1=min(ij1,ij)
8179 ijn=max(ijn,ij)
8180 END IF
8181 END DO
8182 globalindexranges(ij1)=max(globalindexranges(ij1),ijn)
8183 END DO
8184
8185 END IF
8186
8187 nummeas=0 ! number of measurement groups
8188 IF (imonit /= 0) THEN
8189 DO i=1,ntgb
8190 IF (measindex(i) > 0) THEN
8192 measres(i) = measres(i)/real(measindex(i),mpd)
8193 measindex(i) = nummeas
8194 END IF
8195 END DO
8196 length=nummeas*mthrd*measbins
8197 CALL mpalloc(meashists,length,'measurement counter')
8198 END IF
8199
8200 ! check for block diagonal structure, count blocks
8201 npblck=0
8202 l=0
8203 DO i=1,nvgb
8204 IF (i > l) npblck=npblck+1
8205 l=max(l,globalindexranges(i))
8206 globalindexranges(i)=npblck ! block number
8207 END DO
8208
8209 length=npblck+1; rows=2
8210 ! parameter blocks
8211 CALL mpalloc(matparblockoffsets,rows,length,'global parameter blocks (I)')
8213 CALL mpalloc(vecparblockconoffsets,length,'global parameter blocks (I)')
8215 ! fill matParBlocks
8216 l=0
8217 DO i=1,nvgb
8218 IF (globalindexranges(i) > l) THEN
8219 l=globalindexranges(i) ! block number
8220 matparblockoffsets(1,l)=i-1 ! block offset
8221 END IF
8222 END DO
8224 nparmx=0
8225 DO i=1,npblck
8226 rows=matparblockoffsets(1,i+1)-matparblockoffsets(1,i)
8227 nparmx=max(nparmx,int(rows,mpi))
8228 END DO
8229
8230 ! connect constraint blocks
8231 DO i=1,ncblck
8232 ia=matconsblocks(2,i) ! first parameter in constraint block
8233 IF (ia > matconsblocks(3,i)) cycle
8234 ib=globalindexranges(ia) ! parameter block number
8235 matparblockoffsets(2,ib+1)=i
8236 END DO
8237
8238 ! use diagonal block matrix storage?
8239 IF (npblck > 1) THEN
8240 IF (icheck > 0) THEN
8241 WRITE(*,*)
8242 DO i=1,npblck
8243 ia=matparblockoffsets(1,i)
8244 ib=matparblockoffsets(1,i+1)
8245 ja=matparblockoffsets(2,i)
8246 jb=matparblockoffsets(2,i+1)
8249 WRITE(*,*) ' Parameter block', i, ib-ia, jb-ja, labelf, labell
8250 ENDDO
8251 ENDIF
8252 WRITE(lunlog,*)
8253 WRITE(lunlog,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8254 WRITE(*,*)
8255 WRITE(*,*) 'Detected', npblck, '(disjoint) parameter blocks, max size ', nparmx
8256 IF ((metsol == 1.OR.metsol == 3.OR.metsol>=7).AND.nagb == nvgb) THEN
8257 WRITE(*,*) 'Using block diagonal storage mode'
8258 ELSE
8259 ! keep single block = full matrix
8260 DO i=1,2
8262 END DO
8263 npblck=1
8264 DO i=1,nvgb
8266 END DO
8267 END IF
8268 END IF
8269
8270 ! print numbers ----------------------------------------------------
8271
8272 IF (nagb >= 65536) THEN
8273 noff=int(noff8/1000,mpi)
8274 ELSE
8275 noff=int(noff8,mpi)
8276 END IF
8277 ndgn=0
8278 matwords=0
8279 IF(matsto == 2) THEN
8280 ihis=0
8281 IF (mhispe > 0) THEN
8282 ihis=15
8283 CALL hmpdef(ihis,0.0,real(mhispe,mps), 'NDBITS: #off-diagonal elements')
8284 END IF
8285 length=(napgrp+1)*nspc
8286 CALL mpalloc(sparsematrixoffsets,two,length, 'sparse matrix row offsets')
8288 ndgn=ndimsa(3)+ndimsa(4) ! actual number of off-diagonal elements
8289 matwords=ndimsa(2)+length*4 ! size of sparsity structure
8290
8291 IF (mhispe > 0) THEN
8292 IF (nhistp /= 0) CALL hmprnt(ihis)
8293 CALL hmpwrt(ihis)
8294 END IF
8295 END IF
8296 IF (matsto == 3) THEN
8297 length=nagb+1
8298 CALL mpalloc(csr3rowoffsets,length, 'sparse matrix row offsets (CSR3)')
8299 IF (mpdbsz > 1) THEN
8300 ! BSR3, check (for optimal) block size
8301 mbwrds=0
8302 DO i=1,mpdbsz
8303 npdblk=(nagb-1)/ipdbsz(i)+1
8304 length=int(npdblk,mpl)
8305 CALL mpalloc(vecblockcounts,length, 'sparse matrix row offsets (CSR3)')
8306 CALL pbsbits(globalallindexgroups,ipdbsz(i),nnzero,nblock,vecblockcounts)
8307 nbwrds=2*int(nblock,mpl)*int(ipdbsz(i)*ipdbsz(i)+1,mpl) ! number of words needed
8308 IF ((i == 1).OR.(nbwrds < mbwrds)) THEN
8309 matbsz=ipdbsz(i)
8310 mbwrds=nbwrds
8311 csr3rowoffsets(1)=1
8312 DO k=1,npdblk
8313 csr3rowoffsets(k+1)=csr3rowoffsets(k)+vecblockcounts(k)
8314 END DO
8315 END IF
8316 CALL mpdealloc(vecblockcounts)
8317 END DO
8318 ELSE
8319 ! CSR3
8321 !csr3RowOffsets(nvgb+2:)=csr3RowOffsets(nvgb+1) ! Lagrange multipliers (empty)
8322 END IF
8323 END IF
8324
8325 nagbn=maxglobalpar ! max number of global parameters in one event
8326 nalcn=maxlocalpar ! max number of local parameters in one event
8327 naeqn=maxequations ! max number of equations in one event
8330 ! matrices for event matrices
8331 ! split up cache
8332 IF (fcache(2) == 0.0) THEN ! from data (DSTAT)
8333 fcache(1)=real(dstat(1),mps)*fcache(1) ! leave some part free for fluctuations
8334 fcache(2)=real(dstat(2),mps)
8335 fcache(3)=real(dstat(3),mps)
8336 END IF
8337 fsum=fcache(1)+fcache(2)+fcache(3)
8338 DO k=1,3
8339 fcache(k)=fcache(k)/fsum
8340 END DO
8341 ncachr=nint(real(ncache,mps)*fcache(1),mpi) ! read cache
8342 ! define read buffer
8343 nc31=ncachr/(31*mthrdr) ! split read cache 1 : 10 : 10*2 for pointers, ints, floats
8344 nwrd=nc31+1
8345 length=nwrd*mthrdr
8346 CALL mpalloc(readbufferpointer,length,'read buffer, pointer')
8347 nwrd=nc31*10+2+ndimbuf
8348 length=nwrd*mthrdr
8349 CALL mpalloc(readbufferdatai,length,'read buffer, integer')
8350 CALL mpalloc(readbufferdatad,length,'read buffer, real')
8351 ! to read (old) float binary files
8352 length=(ndimbuf+2)*mthrdr
8353 CALL mpalloc(readbufferdataf,length,'read buffer, float')
8354
8355 ncachi=nint(real(ncache,mps)*fcache(2),mpi) ! index cache
8356 ncachd=ncache-ncachr-ncachi ! data cache
8357 nggd=(nagbn*nagbn+nagbn)/2+ncachd/(2*mthrd) ! number of double
8358 nggi=2+nagbn+ncachi/mthrd ! number of ints
8359 length=nagbn*mthrd
8360 CALL mpalloc(globalindexusage,length, 'global parameters (dim =max/event)')
8361 length=nvgb*mthrd
8362 CALL mpalloc(backindexusage,length,'global variable-index array')
8364 length=nagbn*nalcn
8365 CALL mpalloc(localglobalmatrix,length,'local/global matrix, content')
8366 CALL mpalloc(localglobalmap,length,'local/global matrix, map (counts)')
8367 length=2*nagbn*nalcn+nagbn+nalcn+1
8368 CALL mpalloc(localglobalstructure,length,'local/global matrix, (sparsity) structure')
8369 length=nggd*mthrd
8370 CALL mpalloc(writebufferupdates,length,'symmetric update matrices')
8371 writebufferheader(-1)=nggd ! number of words per thread
8372 writebufferheader(-2)=(nagbn*nagbn+nagbn)/2 ! min free (double) words
8373 length=nggi*mthrd
8374 CALL mpalloc(writebufferindices,length,'symmetric update matrix indices')
8375 rows=9; cols=mthrd
8376 CALL mpalloc(writebufferinfo,rows,cols,'write buffer status (I)')
8377 rows=2; cols=mthrd
8378 CALL mpalloc(writebufferdata,rows,cols,'write buffer status (F)')
8379 writebufferheader(1)=nggi ! number of words per thread
8380 writebufferheader(2)=nagbn+3 ! min free words
8381
8382 ! print all relevant dimension parameters
8383
8384 DO lu=6,8,2 ! unit 6 and 8
8385
8386 WRITE(lu,*) ' '
8387 WRITE(lu,101) 'NTGB',ntgb,'total number of parameters'
8388 WRITE(lu,102) '(all parameters, appearing in binary files)'
8389 WRITE(lu,101) 'NVGB',nvgb,'number of variable parameters'
8390 WRITE(lu,102) '(appearing in fit matrix/vectors)'
8391 WRITE(lu,101) 'NAGB',nagb,'number of all parameters'
8392 WRITE(lu,102) '(including Lagrange multiplier or reduced)'
8393 WRITE(lu,101) 'NTPGRP',ntpgrp,'total number of parameter groups'
8394 WRITE(lu,101) 'NVPGRP',nvpgrp,'number of variable parameter groups'
8395 WRITE(lu,101) 'NFGB',nfgb,'number of fit parameters'
8396 IF(metsol >= 4.AND. metsol <7) THEN ! band matrix as MINRES preconditioner
8397 WRITE(lu,101) 'MBANDW',mbandw,'band width of preconditioner matrix'
8398 WRITE(lu,102) '(if <0, no preconditioner matrix)'
8399 END IF
8400 IF (nagb >= 65536) THEN
8401 WRITE(lu,101) 'NOFF/K',noff,'max number of off-diagonal elements'
8402 ELSE
8403 WRITE(lu,101) 'NOFF',noff,'max number of off-diagonal elements'
8404 END IF
8405 IF(ndgn /= 0) THEN
8406 IF (nagb >= 65536) THEN
8407 WRITE(lu,101) 'NDGN/K',ndgn/1000,'actual number of off-diagonal elements'
8408 ELSE
8409 WRITE(lu,101) 'NDGN',ndgn,'actual number of off-diagonal elements'
8410 ENDIF
8411 ENDIF
8412 WRITE(lu,101) 'NCGB',ncgb,'number of constraints'
8413 WRITE(lu,101) 'NAGBN',nagbn,'max number of global parameters in an event'
8414 WRITE(lu,101) 'NALCN',nalcn,'max number of local parameters in an event'
8415 WRITE(lu,101) 'NAEQN',naeqn,'max number of equations in an event'
8416 IF (mprint > 1) THEN
8417 WRITE(lu,101) 'NAEQNA',naeqna,'number of equations'
8418 WRITE(lu,101) 'NAEQNG',naeqng, &
8419 'number of equations with global parameters'
8420 WRITE(lu,101) 'NAEQNF',naeqnf, &
8421 'number of equations with fixed global parameters'
8422 WRITE(lu,101) 'NRECF',nrecf, &
8423 'number of records with fixed global parameters'
8424 END IF
8425 IF (nrece > 0) THEN
8426 WRITE(lu,101) 'NRECE',nrece, &
8427 'number of records without variable parameters'
8428 END IF
8429 IF (ncache > 0) THEN
8430 WRITE(lu,101) 'NCACHE',ncache,'number of words for caching'
8431 WRITE(lu,111) (fcache(k)*100.0,k=1,3)
8432111 FORMAT(22x,'cache splitting ',3(f6.1,' %'))
8433 END IF
8434 WRITE(lu,*) ' '
8435
8436 WRITE(lu,*) ' '
8437 WRITE(lu,*) 'Solution method and matrix-storage mode:'
8438 IF(metsol == 1) THEN
8439 WRITE(lu,*) ' METSOL = 1: matrix inversion'
8440 ELSE IF(metsol == 2) THEN
8441 WRITE(lu,*) ' METSOL = 2: diagonalization'
8442 ELSE IF(metsol == 3) THEN
8443 WRITE(lu,*) ' METSOL = 3: decomposition'
8444 ELSE IF(metsol == 4) THEN
8445 WRITE(lu,*) ' METSOL = 4: MINRES (rtol', mrestl,')'
8446 ELSE IF(metsol == 5) THEN
8447 WRITE(lu,*) ' METSOL = 5: MINRES-QLP (rtol', mrestl,')'
8448 ELSE IF(metsol == 6) THEN
8449 WRITE(lu,*) ' METSOL = 6: GMRES'
8450#ifdef LAPACK64
8451 ELSE IF(metsol == 7) THEN
8452 WRITE(lu,*) ' METSOL = 7: LAPACK factorization'
8453 ELSE IF(metsol == 8) THEN
8454 WRITE(lu,*) ' METSOL = 8: LAPACK factorization'
8455#ifdef PARDISO
8456 ELSE IF(metsol == 9) THEN
8457 WRITE(lu,*) ' METSOL = 9: Intel oneMKL PARDISO'
8458#endif
8459#endif
8460 END IF
8461 WRITE(lu,*) ' with',mitera,' iterations'
8462 IF(matsto == 0) THEN
8463 WRITE(lu,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
8464 ELSE IF(matsto == 1) THEN
8465 WRITE(lu,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
8466 ELSE IF(matsto == 2) THEN
8467 WRITE(lu,*) ' MATSTO = 2: sparse matrix (custom)'
8468 ELSE IF(matsto == 3) THEN
8469 IF (matbsz < 2) THEN
8470 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
8471 ELSE
8472 WRITE(lu,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
8473 WRITE(lu,*) ' block size', matbsz
8474 END IF
8475 END IF
8476 IF(npblck > 1) THEN
8477 WRITE(lu,*) ' block diagonal with', npblck, ' blocks'
8478 END IF
8479 IF(mextnd>0) WRITE(lu,*) ' with extended storage'
8480 IF(dflim /= 0.0) THEN
8481 WRITE(lu,103) 'Convergence assumed, if expected dF <',dflim
8482 END IF
8483 IF(ncgb > 0) THEN
8484 IF(nfgb < nvgb) THEN
8485 IF (icelim > 1) THEN
8486 WRITE(lu,*) 'Constraints handled by elimination with LAPACK'
8487 ELSE
8488 WRITE(lu,*) 'Constraints handled by elimination'
8489 END IF
8490 ELSE
8491 WRITE(lu,*) 'Constraints handled by Lagrange multipliers'
8492 ENDIF
8493 END IF
8494
8495 END DO ! print loop
8496
8497 IF(nalcn == 0) THEN
8498 CALL peend(28,'Aborted, no local parameters')
8499 stop 'LOOP2: stopping due to missing local parameters'
8500 END IF
8501
8502 ! Wolfe conditions
8503
8504 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8505 IF(wolfc1 == 0.0) wolfc1=1.0e-4
8506 IF(wolfc2 == 0.0) wolfc2=0.9
8507 IF(0.0 < wolfc1.AND.wolfc1 < wolfc2.AND.wolfc2 < 1.0) GO TO 32
8508 IF(wolfc1 <= 0.0) wolfc1=1.0e-4
8509 IF(wolfc2 >= 1.0) wolfc2=0.9
8510 IF(wolfc1 > wolfc2) THEN ! exchange
8511 wolfc3=wolfc1
8513 wolfc2=wolfc3
8514 ELSE
8515 wolfc1=1.0e-4
8516 wolfc2=0.9
8517 END IF
8518 WRITE(*,105) wolfc1,wolfc2
8519 WRITE(lun,105) wolfc1,wolfc2
8520105 FORMAT(' Constants C1, C2 for Wolfe conditions:',g12.4,', ',g12.4)
8521
8522 ! prepare matrix and gradient storage ------------------------------
852332 matsiz=0 ! number of words for double, single precision storage
8524 IF (matsto == 3) THEN ! sparse matrix (CSR3, BSR3)
8525 npdblk=(nagb-1)/matbsz+1 ! number of row blocks
8526 length=csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
8527 matsiz(1)=length*int(matbsz*matbsz,mpl)
8528 matwords=(length+nagb+1)*2 ! size of sparsity structure
8529 CALL mpalloc(csr3columnlist,length,'sparse matrix column list (CSR3)')
8530 IF (matbsz > 1) THEN
8532 ELSE
8534 END IF
8535 ELSE IF (matsto == 2) THEN ! sparse matrix (custom)
8536 matsiz(1)=ndimsa(3)+nagb
8537 matsiz(2)=ndimsa(4)
8538 CALL mpalloc(sparsematrixcolumns,ndimsa(2),'sparse matrix column list')
8540 CALL anasps ! analyze sparsity structure
8541 ELSE ! full or unpacked matrix, optional block diagonal
8542 length=nagb
8543 CALL mpalloc(globalrowoffsets,length,'global row offsets (full or unpacked (block) storage)')
8544 ! loop over blocks (multiple blocks only with elimination !)
8546 DO i=1,npblck
8547 ipoff=matparblockoffsets(1,i)
8548 icboff=matparblockoffsets(2,i) ! constraint block offset
8549 icblst=matparblockoffsets(2,i+1) ! constraint block offset
8550 npar=matparblockoffsets(1,i+1)-ipoff ! size of block (number of parameters)
8551 IF (icblst > icboff) THEN
8552 ncon=matconsblocks(1,icblst+1)-matconsblocks(1,icboff+1) ! number of constraints in (parameter) block
8553 ELSE
8554 ncon=0
8555 ENDIF
8557 nall = npar; IF (icelim <= 0) nall=npar+ncon ! add Lagrange multipliers
8558 DO k=1,nall
8559 globalrowoffsets(ipoff+k)=matsiz(1)-ipoff
8560 IF (matsto == 1) THEN
8561 matsiz(1)=matsiz(1)+k ! full ('triangular')
8562 ELSE
8563 matsiz(1)=matsiz(1)+nall ! unpacked ('quadratic')
8564 END IF
8565 END DO
8566 END DO
8567 END IF
8568 matwords=matwords+matsiz(1)*2+matsiz(2) ! #words for matrix storage
8569
8570 CALL feasma ! prepare constraint matrices
8571
8572 IF (icheck <= 0) CALL vmprep(matsiz) ! prepare matrix and gradient storage
8573 WRITE(*,*) ' '
8574 IF (matwords < 250000) THEN
8575 WRITE(*,*) 'Size of global matrix: < 1 MB'
8576 ELSE
8577 WRITE(*,*) 'Size of global matrix:',int(real(matwords,mps)*4.0e-6,mpi),' MB'
8578 ENDIF
8579 ! print chi^2 cut tables
8580
8581 ndfmax=naeqn-1
8582 WRITE(lunlog,*) ' '
8583 WRITE(lunlog,*) ' Cut values of Chi^2/Ndf and Chi2,'
8584 WRITE(lunlog,*) ' corresponding to 2 and 3 standard deviations'
8585 WRITE(lunlog,*) ' Ndf Chi^2/Ndf(2) Chi^2(2) ', &
8586 ' Chi^2/Ndf(3) Chi^2(3)'
8587 ndf=0
8588 DO
8589 IF(ndf > naeqn) EXIT
8590 IF(ndf < 10) THEN
8591 ndf=ndf+1
8592 ELSE IF(ndf < 20) THEN
8593 ndf=ndf+2
8594 ELSE IF(ndf < 100) THEN
8595 ndf=ndf+5
8596 ELSE IF(ndf < 200) THEN
8597 ndf=ndf+10
8598 ELSE
8599 EXIT
8600 END IF
8601 chin2=chindl(2,ndf)
8602 chin3=chindl(3,ndf)
8603 WRITE(lunlog,106) ndf,chin2,chin2*real(ndf,mps),chin3, chin3*real(ndf,mps)
8604 END DO
8605
8606 WRITE(lunlog,*) 'LOOP2: ending'
8607 WRITE(lunlog,*) ' '
8608 ! warnings from check input mode
8609 IF (icheck > 0) THEN
8610 IF (ncgbe /= 0) THEN
8611 WRITE(*,199) ' '
8612 WRITE(*,199) ' '
8613 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8614 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8615 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8616 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8617 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8618 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8619 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8620 WRITE(*,199) ' '
8621 WRITE(*,*) ' Number of empty constraints =',abs(ncgbe), ', should be 0'
8622 WRITE(*,*) ' => please check constraint definition, mille data'
8623 WRITE(*,199) ' '
8624 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
8625 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
8626 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
8627 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
8628 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
8629 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
8630 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
8631 WRITE(*,199) ' '
8632 END IF
8633 END IF
8634 CALL mend
8635101 FORMAT(1x,a8,' =',i14,' = ',a)
8636102 FORMAT(22x,a)
8637103 FORMAT(1x,a,g12.4)
8638106 FORMAT(i6,2(3x,f9.3,f12.1,3x))
8639199 FORMAT(7x,a)
8640END SUBROUTINE loop2
8641
8646SUBROUTINE monres
8647 USE mpmod
8648 USE mpdalc
8649
8650 IMPLICIT NONE
8651 INTEGER(mpi) :: i
8652 INTEGER(mpi) :: ij
8653 INTEGER(mpi) :: imed
8654 INTEGER(mpi) :: j
8655 INTEGER(mpi) :: k
8656 INTEGER(mpi) :: nent
8657 INTEGER(mpi), DIMENSION(measBins) :: isuml ! location
8658 INTEGER(mpi), DIMENSION(measBins) :: isums ! scale
8659 REAL(mps) :: amed
8660 REAL(mps) :: amad
8661
8662 INTEGER(mpl) :: ioff
8663 LOGICAL :: lfirst
8664 SAVE
8665 DATA lfirst /.true./
8666
8667 ! combine data from threads
8668 ioff=0
8669 DO i=2,mthrd
8670 ioff=ioff+measbins*nummeas
8671 DO j=1,measbins*nummeas
8672 meashists(j)=meashists(j)+meashists(ioff+j)
8673 END DO
8674 END DO
8675
8676 IF (lfirst) THEN
8677 IF (imonmd == 0) THEN
8678 WRITE(lunmon,'(A)') '*** Normalized residuals grouped by first global label (per local fit cycle) ***'
8679 ELSE
8680 WRITE(lunmon,'(A)') '*** Pulls grouped by first global label (per local fit cycle) ***'
8681 ENDIF
8682 WRITE(lunmon,'(A)') '! LFC Label Entries Median RMS(MAD) <error>'
8683 lfirst=.false.
8684 END IF
8685
8686 !$POMP INST BEGIN(monres)
8687#ifdef SCOREP_USER_ENABLE
8688 scorep_user_region_by_name_begin("UR_monres", scorep_user_region_type_common)
8689#endif
8690 ! analyze histograms
8691 ioff=0
8692 DO i=1,ntgb
8693 IF (measindex(i) > 0) THEN
8694 isuml=0
8695 ! sum up content
8696 isuml(1)=meashists(ioff+1)
8697 DO j=2,measbins
8698 isuml(j)=isuml(j-1)+meashists(ioff+j)
8699 END DO
8700 nent=isuml(measbins)
8701 IF (nent > 0) THEN
8702 ! get median (for location)
8703 DO j=2,measbins
8704 IF (2*isuml(j) > nent) EXIT
8705 END DO
8706 imed=j
8707 amed=real(j,mps)
8708 IF (isuml(j) > isuml(j-1)) amed=amed+real(nent-2*isuml(j-1),mps)/real(2*isuml(j)-2*isuml(j-1),mps)
8709 amed=real(measbinsize,mps)*(amed-real(measbins/2,mps))
8710 ! sum up differences
8711 isums = 0
8712 DO j=imed,measbins
8713 k=j-imed+1
8714 isums(k)=isums(k)+meashists(ioff+j)
8715 END DO
8716 DO j=imed-1,1,-1
8717 k=imed-j
8718 isums(k)=isums(k)+meashists(ioff+j)
8719 END DO
8720 DO j=2, measbins
8721 isums(j)=isums(j)+isums(j-1)
8722 END DO
8723 ! get median (for scale)
8724 DO j=2,measbins
8725 IF (2*isums(j) > nent) EXIT
8726 END DO
8727 amad=real(j-1,mps)
8728 IF (isums(j) > isums(j-1)) amad=amad+real(nent-2*isums(j-1),mps)/real(2*isums(j)-2*isums(j-1),mps)
8729 amad=real(measbinsize,mps)*amad
8730 ELSE
8731 amed=0.0
8732 amad=0.0
8733 END IF
8734 ij=globalparlabelindex(1,i)
8735 WRITE(lunmon,110) nloopn, ij, nent, amed, amad*1.4826, real(measres(i),mps)
8736 !
8737 ioff=ioff+measbins
8738 END IF
8739 END DO
8740#ifdef SCOREP_USER_ENABLE
8741 scorep_user_region_by_name_end("UR_monres")
8742#endif
8743 !$POMP INST END(monres)
8744
8745110 FORMAT(i5,2i10,3g14.5)
8746END SUBROUTINE monres
8747
8748
8752
8753SUBROUTINE vmprep(msize)
8754 USE mpmod
8755 USE mpdalc
8756
8757 IMPLICIT NONE
8758 INTEGER(mpi) :: i
8759 INTEGER(mpi) :: ib
8760 INTEGER(mpi) :: ioff
8761 INTEGER(mpi) :: ipar0
8762 INTEGER(mpi) :: ncon
8763 INTEGER(mpi) :: npar
8764 INTEGER(mpi) :: nextra
8765#ifdef LAPACK64
8766 INTEGER :: nbopt, nboptx, ILAENV
8767#endif
8768 !
8769 INTEGER(mpl), INTENT(IN) :: msize(2)
8770
8771 INTEGER(mpl) :: length
8772 INTEGER(mpl) :: nwrdpc
8773 INTEGER(mpl), PARAMETER :: three = 3
8774
8775 SAVE
8776 ! ...
8777 ! Vector/matrix storage
8778 length=nagb*mthrd
8779 CALL mpalloc(globalvector,length,'rhs vector') ! double precision vector
8780 CALL mpalloc(globalcounter,length,'rhs counter') ! integer vector
8782 length=naeqn*mthrd
8783 CALL mpalloc(localcorrections,length,'residual vector of one record')
8784 CALL mpalloc(localequations,three,length,'mesurements indices (ISJAJB) of one record')
8785 length=nalcn*nalcn
8786 CALL mpalloc(aux,length,' local fit scratch array: aux')
8787 CALL mpalloc(vbnd,length,' local fit scratch array: vbnd')
8788 CALL mpalloc(vbdr,length,' local fit scratch array: vbdr')
8789 length=((nalcn+1)*nalcn)/2
8790 CALL mpalloc(clmat,length,' local fit matrix: clmat')
8791 CALL mpalloc(vbk,length,' local fit scratch array: vbk')
8792 length=nalcn
8793 CALL mpalloc(blvec,length,' local fit vector: blvec')
8794 CALL mpalloc(vzru,length,' local fit scratch array: vzru')
8795 CALL mpalloc(scdiag,length,' local fit scratch array: scdiag')
8796 CALL mpalloc(scflag,length,' local fit scratch array: scflag')
8797 CALL mpalloc(ibandh,2*length,' local fit band width hist.: ibandh')
8798
8799 CALL mpalloc(globalmatd,msize(1),'global matrix (D)' )
8800 CALL mpalloc(globalmatf,msize(2),'global matrix (F)')
8801
8802 mszpcc=0
8803 IF(metsol >= 4.AND.metsol < 7.AND. mbandw >= 0) THEN ! GMRES/MINRES algorithms
8804 ! array space is:
8805 ! variable-width band matrix or diagonal matrix for parameters
8806 ! followed by symmetric matrix for constraints
8807 ! followed by rectangular matrix for constraints
8808 nwrdpc=0
8809 ncon=nagb-nvgb ! number of Lagrange multipliers
8810 ! constraint block info
8811 length=4*ncblck; IF(ncon == 0) length=0
8812 CALL mpalloc(blockprecond,length,'preconditioner: constraint blocks')
8813 length=ncon
8814 CALL mpalloc(offprecond,length,'preconditioner: constraint offsets')
8815 !END IF
8816 ! variable-width band matrix ?
8817 IF(mbandw > 0) THEN
8818 length=nagb
8819 CALL mpalloc(indprecond,length,'pointer-array variable-band matrix')
8820 nwrdpc=nwrdpc+length
8821 DO i=1,min(mbandw,nvgb)
8822 indprecond(i)=(i*i+i)/2 ! increasing number
8823 END DO
8824 DO i=min(mbandw,nvgb)+1,nvgb
8825 indprecond(i)=indprecond(i-1)+mbandw ! fixed band width
8826 END DO
8827 DO i=nvgb+1,nagb ! reset
8828 indprecond(i)=0
8829 END DO
8830 END IF
8831 ! symmetric part
8832 length=(ncon*ncon+ncon)/2
8833 ! add 'band' part
8834 IF(mbandw > 0) THEN ! variable-width band matrix
8835 length=length+indprecond(nvgb)
8836 ELSE ! default preconditioner (diagonal)
8837 length=length+nvgb
8838 END IF
8839 ! add rectangular part (compressed, constraint blocks)
8840 IF(ncon > 0) THEN
8841 ioff=0
8842 ! extra space (for forward solution in EQUDEC)
8843 nextra=max(0,mbandw-1)
8844 DO ib=1,ncblck
8845 ! first constraint in block
8846 blockprecond(ioff+1)=matconsblocks(1,ib)
8847 ! last constraint in block
8848 blockprecond(ioff+2)=matconsblocks(1,ib+1)-1
8849 ! parameter offset
8850 ipar0=matconsblocks(2,ib)-1
8851 blockprecond(ioff+3)=ipar0
8852 ! number of parameters (-> columns)
8853 npar=matconsblocks(3,ib)-ipar0
8854 blockprecond(ioff+4)=npar+nextra
8855 DO i=blockprecond(ioff+1),blockprecond(ioff+2)
8856 offprecond(i)=length-ipar0
8857 length=length+npar+nextra
8858 mszpcc=mszpcc+npar+nextra
8859 END DO
8860 ioff=ioff+4
8861 END DO
8862 ELSE
8863 IF(mbandw == 0) length=length+1 ! for valid precons argument matPreCond((ncon*ncon+ncon)/2+nvgb+1)
8864 END IF
8865 ! allocate
8866 IF(mbandw > 0) THEN
8867 CALL mpalloc(matprecond,length,'variable-band preconditioner matrix')
8868 ELSE
8869 CALL mpalloc(matprecond,length,'default preconditioner matrix')
8870 END IF
8871 nwrdpc=nwrdpc+2*length
8872 IF (nwrdpc > 250000) THEN
8873 WRITE(*,*)
8874 WRITE(*,*) 'Size of preconditioner matrix:',int(real(nwrdpc,mps)*4.0e-6,mpi),' MB'
8875 END IF
8876
8877 END IF
8878
8879
8880 length=nagb
8881 CALL mpalloc(globalcorrections,length,'corrections') ! double prec corrections
8882
8883 length=nagb
8884 CALL mpalloc(workspaced,length,'auxiliary array (D1)') ! double aux 1
8885 CALL mpalloc(workspacelinesearch,length,'auxiliary array (D2)') ! double aux 2
8886 CALL mpalloc(workspacei, length,'auxiliary array (I)') ! int aux 1
8887
8888 IF(metsol == 1) THEN
8889 CALL mpalloc(workspacediag,length,'diagonal of global matrix)') ! double aux 1
8890 CALL mpalloc(workspacerow,length,'(pivot) row of global matrix)')
8891 ! CALL MEGARR('t D',2*NAGB,'auxiliary array') ! double aux 8
8892 END IF
8893
8894 IF(metsol == 2) THEN
8895 IF(nagb>46300) THEN
8896 CALL peend(23,'Aborted, bad matrix index (will exceed 32bit)')
8897 stop 'vmprep: bad index (matrix to large for diagonalization)'
8898 END IF
8899 CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8900 CALL mpalloc(workspacediagonalization,length,'auxiliary array (D3)') ! double aux 3
8901 CALL mpalloc(workspaceeigenvalues,length,'auxiliary array (D6)') ! double aux 6
8902 length=nagb*nagb
8903 CALL mpalloc(workspaceeigenvectors,length,'(rotation) matrix U') ! rotation matrix
8904 END IF
8905
8906 IF(metsol >= 4.AND.metsol < 7) THEN
8907 CALL mpalloc(vecxav,length,'vector X (AVPROD)') ! double aux 1
8908 CALL mpalloc(vecbav,length,'vector B (AVPROD)') ! double aux 1
8909 END IF
8910
8911#ifdef LAPACK64
8912 IF(metsol == 7) THEN
8913 IF(nagb > nvgb) CALL mpalloc(lapackipiv, length,'IPIV for DSPTRG (L)') ! pivot indices for DSPTRF
8914 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8915 END IF
8916 IF(metsol == 8) THEN
8917 IF(nagb > nvgb) THEN
8918 CALL mpalloc(lapackipiv, length,'LAPACK IPIV (L)')
8919 nbopt = ilaenv( 1_mpl, 'DSYTRF', 'U', int(nagb,mpl), int(nagb,mpl), -1_mpl, -1_mpl ) ! optimal block size
8920 print *
8921 print *, 'LAPACK optimal block size for DSYTRF:', nbopt
8922 lplwrk=length*int(nbopt,mpl)
8923 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8924 ELSE IF(nfgb < nvgb.AND.icelim > 1) THEN
8925 ! elimination of constraints with LAPACK
8926 lplwrk=1
8927 DO i=1,npblck
8928 npar=matparblockoffsets(1,i+1)-matparblockoffsets(1,i) ! number of parameters in block
8929 ncon=vecparblockconoffsets(i+1)-vecparblockconoffsets(i) ! number of constraints in block
8930 nbopt = ilaenv( 1_mpl, 'DORMQL', 'RN', int(npar,mpl), int(npar,mpl), int(ncon,mpl), int(npar,mpl) ) ! optimal buffer size
8931 IF (int(npar,mpl)*int(nbopt,mpl) > lplwrk) THEN
8932 lplwrk=int(npar,mpl)*int(nbopt,mpl)
8933 nboptx=nbopt
8934 END IF
8935 END DO
8936 print *
8937 print *, 'LAPACK optimal block size for DORMQL:', nboptx
8938 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (D)')
8939 END IF
8940 IF(ilperr == 1) CALL mpalloc(workspacediag,length,'diagonal of global matrix') ! double aux 1
8941 END IF
8942#endif
8943
8944END SUBROUTINE vmprep
8945
8949
8950SUBROUTINE minver
8951 USE mpmod
8952
8953 IMPLICIT NONE
8954 INTEGER(mpi) :: i
8955 INTEGER(mpi) :: ib
8956 INTEGER(mpi) :: icoff
8957 INTEGER(mpi) :: ipoff
8958 INTEGER(mpi) :: j
8959 INTEGER(mpi) :: lun
8960 INTEGER(mpi) :: ncon
8961 INTEGER(mpi) :: nfit
8962 INTEGER(mpi) :: npar
8963 INTEGER(mpi) :: nrank
8964 INTEGER(mpl) :: imoff
8965 INTEGER(mpl) :: ioff1
8966 REAL(mpd) :: matij
8967
8968 EXTERNAL avprds
8969
8970 SAVE
8971 ! ...
8972 lun=lunlog ! log file
8973
8974 IF(icalcm == 1) THEN
8975 ! save diagonal (for global correlation)
8976 DO i=1,nagb
8977 workspacediag(i)=matij(i,i)
8978 END DO
8979 ! use elimination for constraints ?
8980 IF(nfgb < nvgb) THEN
8981 ! monitor progress
8982 IF(monpg1 > 0) THEN
8983 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
8985 END IF
8986 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
8987 IF(monpg1 > 0) CALL monend()
8988 END IF
8989 END IF
8990
8991 ! loop over blocks (multiple blocks only with elimination !)
8992 DO ib=1,npblck
8993 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
8994 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
8995 icoff=vecparblockconoffsets(ib) ! constraint offset for block
8996 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
8997 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
8998 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
8999 ! use elimination for constraints ?
9000 IF(nfit < npar) THEN
9001 CALL qlsetb(ib)
9002 ! solve L^t*y=d by backward substitution
9004 ! transform, reduce rhs
9005 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9006 ! correction from eliminated part
9007 DO i=1,nfit
9008 DO j=1,ncon
9009 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9011 END DO
9012 END DO
9013 END IF
9014
9015 IF(icalcm == 1) THEN
9016 ! monitor progress
9017 IF(monpg1 > 0) THEN
9018 WRITE(lunlog,*) 'Inversion of global matrix (A->A^-1)'
9020 END IF
9021 ! invert and solve
9022 CALL sqminl(globalmatd(imoff+1:), globalcorrections(ipoff+1:),nfit,nrank, &
9024 IF(monpg1 > 0) CALL monend()
9025 IF(nfit /= nrank) THEN
9026 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
9027 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9028 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
9029 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9030 IF (iforce == 0 .AND. isubit == 0) THEN
9031 isubit=1
9032 WRITE(*,*) ' --> enforcing SUBITO mode'
9033 WRITE(lun,*) ' --> enforcing SUBITO mode'
9034 END IF
9035 ELSE IF(ndefec == 0) THEN
9036 IF(npblck == 1) THEN
9037 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9038 ELSE
9039 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9040 END IF
9041 END IF
9042 ndefec=ndefec+nfit-nrank ! rank defect
9043
9044 ELSE ! multiply gradient by inverse matrix
9045 workspaced(:nfit)=globalcorrections(ipoff+1:ipoff+nfit)
9046 CALL dbsvxl(globalmatd(imoff+1:),workspaced,globalcorrections(ipoff+1:),nfit)
9047 END IF
9048
9049 !use elimination for constraints ?
9050 IF(nfit < npar) THEN
9051 ! extend, transform back solution
9052 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9053 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9054 END IF
9055 END DO
9056
9057END SUBROUTINE minver
9058
9062
9063SUBROUTINE mchdec
9064 USE mpmod
9065
9066 IMPLICIT NONE
9067 INTEGER(mpi) :: i
9068 INTEGER(mpi) :: ib
9069 INTEGER(mpi) :: icoff
9070 INTEGER(mpi) :: ipoff
9071 INTEGER(mpi) :: j
9072 INTEGER(mpi) :: lun
9073 INTEGER(mpi) :: ncon
9074 INTEGER(mpi) :: nfit
9075 INTEGER(mpi) :: npar
9076 INTEGER(mpi) :: nrank
9077 INTEGER(mpl) :: imoff
9078 INTEGER(mpl) :: ioff1
9079
9080 REAL(mpd) :: evmax
9081 REAL(mpd) :: evmin
9082
9083 EXTERNAL avprds
9084
9085 SAVE
9086 ! ...
9087 lun=lunlog ! log file
9088
9089 IF(icalcm == 1) THEN
9090 ! use elimination for constraints ?
9091 ! monitor progress
9092 IF(monpg1 > 0) THEN
9093 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9095 END IF
9096 IF(nfgb < nvgb) CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9097 IF(monpg1 > 0) CALL monend()
9098 END IF
9099
9100 ! loop over blocks (multiple blocks only with elimination !)
9101 DO ib=1,npblck
9102 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9103 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9104 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9105 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9106 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9107 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9108 ! use elimination for constraints ?
9109 IF(nfit < npar) THEN
9110 CALL qlsetb(ib)
9111 ! solve L^t*y=d by backward substitution
9113 ! transform, reduce rhs
9114 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9115 ! correction from eliminated part
9116 DO i=1,nfit
9117 DO j=1,ncon
9118 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9120 END DO
9121 END DO
9122 END IF
9123
9124 IF(icalcm == 1) THEN
9125 ! monitor progress
9126 IF(monpg1 > 0) THEN
9127 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9129 END IF
9130 ! decompose and solve
9131 CALL chdec2(globalmatd(imoff+1:),nfit,nrank,evmax,evmin,monpg1)
9132 IF(monpg1 > 0) CALL monend()
9133 IF(nfit /= nrank) THEN
9134 WRITE(*,*) 'Warning: the rank defect of the symmetric',nfit, &
9135 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9136 WRITE(lun,*) 'Warning: the rank defect of the symmetric',nfit, &
9137 '-by-',nfit,' matrix is ',nfit-nrank,' (should be zero).'
9138 IF (iforce == 0 .AND. isubit == 0) THEN
9139 isubit=1
9140 WRITE(*,*) ' --> enforcing SUBITO mode'
9141 WRITE(lun,*) ' --> enforcing SUBITO mode'
9142 END IF
9143 ELSE IF(ndefec == 0) THEN
9144 IF(npblck == 1) THEN
9145 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9146 ELSE
9147 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9148 END IF
9149 WRITE(lun,*) ' largest diagonal element (LDLt)', evmax
9150 WRITE(lun,*) ' smallest diagonal element (LDLt)', evmin
9151 END IF
9152 ndefec=ndefec+nfit-nrank ! rank defect
9153
9154 END IF
9155 ! backward/forward substitution
9156 CALL chslv2(globalmatd(imoff+1:),globalcorrections(ipoff+1:),nfit)
9157
9158 !use elimination for constraints ?
9159 IF(nfit < npar) THEN
9160 ! extend, transform back solution
9161 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9162 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9163 END IF
9164 END DO
9165
9166END SUBROUTINE mchdec
9167
9168#ifdef LAPACK64
9169
9174
9175SUBROUTINE mdptrf
9176 USE mpmod
9177
9178 IMPLICIT NONE
9179 INTEGER(mpi) :: i
9180 INTEGER(mpi) :: ib
9181 INTEGER(mpi) :: icoff
9182 INTEGER(mpi) :: ipoff
9183 INTEGER(mpi) :: j
9184 INTEGER(mpi) :: lun
9185 INTEGER(mpi) :: ncon
9186 INTEGER(mpi) :: nfit
9187 INTEGER(mpi) :: npar
9188 INTEGER(mpl) :: imoff
9189 INTEGER(mpl) :: ioff1
9190 INTEGER(mpi) :: infolp
9191 REAL(mpd) :: matij
9192
9193 EXTERNAL avprds
9194
9195 SAVE
9196 ! ...
9197 lun=lunlog ! log file
9198
9199 IF(icalcm == 1) THEN
9200 IF(ilperr == 1) THEN
9201 ! save diagonal (for global correlation)
9202 DO i=1,nagb
9203 workspacediag(i)=matij(i,i)
9204 END DO
9205 END IF
9206 ! use elimination for constraints ?
9207 IF(nfgb < nvgb) THEN
9208 ! monitor progress
9209 IF(monpg1 > 0) THEN
9210 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9212 END IF
9213 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9214 IF(monpg1 > 0) CALL monend()
9215 END IF
9216 END IF
9217
9218 ! loop over blocks (multiple blocks only with elimination !)
9219 DO ib=1,npblck
9220 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9221 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9222 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9223 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9224 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9225 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9226 ! use elimination for constraints ?
9227 IF(nfit < npar) THEN
9228 CALL qlsetb(ib)
9229 ! solve L^t*y=d by backward substitution
9231 ! transform, reduce rhs
9232 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9233 ! correction from eliminated part
9234 DO i=1,nfit
9235 DO j=1,ncon
9236 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9238 END DO
9239 END DO
9240 END IF
9241
9242 IF(icalcm == 1) THEN
9243 ! multipliers?
9244 IF (nfit > npar) THEN
9245 ! monitor progress
9246 IF(monpg1 > 0) THEN
9247 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9249 END IF
9250 !$POMP INST BEGIN(dsptrf)
9251#ifdef SCOREP_USER_ENABLE
9252 scorep_user_region_by_name_begin("UR_dsptrf", scorep_user_region_type_common)
9253#endif
9254 CALL dsptrf('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),infolp)
9255#ifdef SCOREP_USER_ENABLE
9256 scorep_user_region_by_name_end("UR_dsptrf")
9257#endif
9258 !$POMP INST END(dsptrf)
9259 IF(monpg1 > 0) CALL monend()
9260 ELSE
9261 ! monitor progress
9262 IF(monpg1 > 0) THEN
9263 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9265 END IF
9266 !$POMP INST BEGIN(dpptrf)
9267#ifdef SCOREP_USER_ENABLE
9268 scorep_user_region_by_name_begin("UR_dpptrf", scorep_user_region_type_common)
9269#endif
9270 CALL dpptrf('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
9271#ifdef SCOREP_USER_ENABLE
9272 scorep_user_region_by_name_end("UR_dpptrf")
9273#endif
9274 !$POMP INST END(dpptrf)
9275 IF(monpg1 > 0) CALL monend()
9276 ENDIF
9277 ! check result
9278 IF(infolp==0) THEN
9279 IF(npblck == 1) THEN
9280 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9281 ELSE
9282 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9283 END IF
9284 ELSE
9285 ndefec=ndefec+1 ! (lower limit of) rank defect
9286 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9287 '-by-',nfit,' failed at index ', infolp
9288 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9289 '-by-',nfit,' failed at index ', infolp
9290 CALL peend(29,'Aborted, factorization of global matrix failed')
9291 stop 'mdptrf: bad matrix'
9292 END IF
9293 END IF
9294 ! backward/forward substitution
9295 ! multipliers?
9296 IF (nfit > npar) THEN
9297 CALL dsptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),lapackipiv(ipoff+1:),&
9298 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9299 IF(infolp /= 0) print *, ' DSPTRS failed: ', infolp
9300 ELSE
9301 CALL dpptrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),&
9302 globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9303 IF(infolp /= 0) print *, ' DPPTRS failed: ', infolp
9304 ENDIF
9305
9306 !use elimination for constraints ?
9307 IF(nfit < npar) THEN
9308 ! extend, transform back solution
9309 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9310 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9311 END IF
9312 END DO
9313
9314END SUBROUTINE mdptrf
9315
9321
9322SUBROUTINE mdutrf
9323 USE mpmod
9324
9325 IMPLICIT NONE
9326 INTEGER(mpi) :: i
9327 INTEGER(mpi) :: ib
9328 INTEGER(mpi) :: icoff
9329 INTEGER(mpi) :: ipoff
9330 INTEGER(mpi) :: j
9331 INTEGER(mpi) :: lun
9332 INTEGER(mpi) :: ncon
9333 INTEGER(mpi) :: nfit
9334 INTEGER(mpi) :: npar
9335 INTEGER(mpl) :: imoff
9336 INTEGER(mpl) :: ioff1
9337 INTEGER(mpl) :: iloff
9338 INTEGER(mpi) :: infolp
9339
9340 REAL(mpd) :: matij
9341
9342 EXTERNAL avprds
9343
9344 SAVE
9345 ! ...
9346 lun=lunlog ! log file
9347
9348 IF(icalcm == 1) THEN
9349 IF(ilperr == 1) THEN
9350 ! save diagonal (for global correlation)
9351 DO i=1,nagb
9352 workspacediag(i)=matij(i,i)
9353 END DO
9354 END IF
9355 ! use elimination for constraints ?
9356 IF(nfgb < nvgb) THEN
9357 ! monitor progress
9358 IF(monpg1 > 0) THEN
9359 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9361 END IF
9362 IF (icelim > 1) THEN
9363 CALL lpavat(.true.)
9364 ELSE
9365 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9366 END IF
9367 IF(monpg1 > 0) CALL monend()
9368 END IF
9369 END IF
9370
9371 ! loop over blocks (multiple blocks only with elimination !)
9372 iloff=0 ! offset of L in lapackQL
9373 DO ib=1,npblck
9374 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9375 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9376 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9377 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9378 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9379 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
9380 ! use elimination for constraints ?
9381 IF(nfit < npar) THEN
9382 IF (icelim > 1) THEN
9383 ! solve L^t*y=d by backward substitution
9384 vecconssolution(1:ncon)=vecconsresiduals(icoff+1:icoff+ncon)
9385 CALL dtrtrs('L','T','N',int(ncon,mpl),1_mpl,lapackql(iloff+npar-ncon+1:),int(npar,mpl),&
9386 vecconssolution,int(ncon,mpl),infolp)
9387 IF(infolp /= 0) print *, ' DTRTRS failed: ', infolp
9388 ! transform, reduce rhs, Q^t*b
9389 CALL dormql('L','T',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9390 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9391 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9392 ELSE
9393 CALL qlsetb(ib)
9394 ! solve L^t*y=d by backward substitution
9396 ! transform, reduce rhs
9397 CALL qlmlq(globalcorrections(ipoff+1:),1,.true.) ! Q^t*b
9398 END IF
9399 ! correction from eliminated part
9400 DO i=1,nfit
9401 DO j=1,ncon
9402 ioff1=globalrowoffsets(nfit+j+ipoff)+i+ipoff ! local (nfit+j,i)
9404 END DO
9405 END DO
9406 END IF
9407
9408 IF(icalcm == 1) THEN
9409 ! multipliers?
9410 IF (nfit > npar) THEN
9411 ! monitor progress
9412 IF(monpg1 > 0) THEN
9413 WRITE(lunlog,*) 'Factorization of global matrix (A->L*D*L^t)'
9415 END IF
9416 !$POMP INST BEGIN(dsytrf)
9417#ifdef SCOREP_USER_ENABLE
9418 scorep_user_region_by_name_begin("UR_dsytrf", scorep_user_region_type_common)
9419#endif
9420 CALL dsytrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
9421 lapackipiv(ipoff+1:),lapackwork,lplwrk,infolp)
9422#ifdef SCOREP_USER_ENABLE
9423 scorep_user_region_by_name_end("UR_dsytrf")
9424#endif
9425 !$POMP INST END(dsytrf)
9426 IF(monpg1 > 0) CALL monend()
9427 ELSE
9428 ! monitor progress
9429 IF(monpg1 > 0) THEN
9430 WRITE(lunlog,*) 'Factorization of global matrix (A->L*L^t)'
9432 END IF
9433 !$POMP INST BEGIN(dpotrf)
9434#ifdef SCOREP_USER_ENABLE
9435 scorep_user_region_by_name_begin("UR_dpotrf", scorep_user_region_type_common)
9436#endif
9437 CALL dpotrf('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
9438#ifdef SCOREP_USER_ENABLE
9439 scorep_user_region_by_name_end("UR_dpotrf")
9440#endif
9441 !$POMP INST END(dpotrf)
9442 IF(monpg1 > 0) CALL monend()
9443 ENDIF
9444 ! check result
9445 IF(infolp==0) THEN
9446 IF(npblck == 1) THEN
9447 WRITE(lun,*) 'No rank defect of the symmetric matrix'
9448 ELSE
9449 WRITE(lun,*) 'No rank defect of the symmetric block', ib, ' of size', npar
9450 END IF
9451 ELSE
9452 ndefec=ndefec+1 ! (lower limit of) rank defect
9453 WRITE(*,*) 'Warning: factorization of the symmetric',nfit, &
9454 '-by-',nfit,' failed at index ', infolp
9455 WRITE(lun,*) 'Warning: factorization of the symmetric',nfit, &
9456 '-by-',nfit,' failed at index ', infolp
9457 CALL peend(29,'Aborted, factorization of global matrix failed')
9458 stop 'mdutrf: bad matrix'
9459 END IF
9460 END IF
9461 ! backward/forward substitution
9462 ! multipliers?
9463 IF (nfit > npar) THEN
9464 CALL dsytrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(nfit,mpl),&
9465 lapackipiv(ipoff+1:),globalcorrections(ipoff+1:),int(nfit,mpl),infolp)
9466 IF(infolp /= 0) print *, ' DSYTRS failed: ', infolp
9467 ELSE
9468 CALL dpotrs('U',int(nfit,mpl),1_mpl,globalmatd(imoff+1:),int(npar,mpl),&
9469 globalcorrections(ipoff+1:),int(npar,mpl),infolp)
9470 IF(infolp /= 0) print *, ' DPOTRS failed: ', infolp
9471 ENDIF
9472
9473 !use elimination for constraints ?
9474 IF(nfit < npar) THEN
9475 IF (icelim > 1) THEN
9476 ! correction from eliminated part
9477 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9478 ! extend, transform back solution, Q*x
9479 CALL dormql('L','N',int(npar,mpl),1_mpl,int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9480 lapacktau(icoff+1:),globalcorrections(ipoff+1:),int(npar,mpl),lapackwork,lplwrk,infolp)
9481 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9482 ELSE
9483 ! extend, transform back solution
9484 globalcorrections(nfit+1+ipoff:npar+ipoff)=vecconssolution(1:ncon)
9485 CALL qlmlq(globalcorrections(ipoff+1:),1,.false.) ! Q*x
9486 END IF
9487 END IF
9488 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9489 END DO
9490
9491END SUBROUTINE mdutrf
9492
9503SUBROUTINE lpqldec(a,emin,emax)
9504 USE mpmod
9505 USE mpdalc
9506
9507 IMPLICIT NONE
9508 INTEGER(mpi) :: ib
9509 INTEGER(mpi) :: icb
9510 INTEGER(mpi) :: icboff
9511 INTEGER(mpi) :: icblst
9512 INTEGER(mpi) :: icoff
9513 INTEGER(mpi) :: icfrst
9514 INTEGER(mpi) :: iclast
9515 INTEGER(mpi) :: ipfrst
9516 INTEGER(mpi) :: iplast
9517 INTEGER(mpi) :: ipoff
9518 INTEGER(mpi) :: i
9519 INTEGER(mpi) :: j
9520 INTEGER(mpi) :: ncon
9521 INTEGER(mpi) :: npar
9522 INTEGER(mpi) :: npb
9523 INTEGER(mpl) :: imoff
9524 INTEGER(mpl) :: iloff
9525 INTEGER(mpi) :: infolp
9526 INTEGER :: nbopt, ILAENV
9527
9528 REAL(mpd), INTENT(IN) :: a(mszcon)
9529 REAL(mpd), INTENT(OUT) :: emin
9530 REAL(mpd), INTENT(OUT) :: emax
9531 SAVE
9532
9533 print *
9534 ! loop over blocks (multiple blocks only with elimination !)
9535 iloff=0 ! size of unpacked constraint matrix
9536 DO ib=1,npblck
9537 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9538 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9539 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9540 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9541 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9542 END DO
9543 ! allocate
9544 CALL mpalloc(lapackql, iloff, 'LAPACK QL (QL decomp.) ')
9545 lapackql=0.
9546 iloff=ncgb
9547 CALL mpalloc(lapacktau, iloff, 'LAPACK TAU (QL decomp.) ')
9548 ! fill
9549 iloff=0 ! offset of unpacked constraint matrix block
9550 imoff=0 ! offset of packed constraint matrix block
9551 DO ib=1,npblck
9552 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9553 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9554 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9555 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9556 IF(ncon <= 0) cycle
9557 ! block with constraints
9558 icboff=matparblockoffsets(2,ib) ! constraint block offset
9559 icblst=matparblockoffsets(2,ib+1) ! constraint block offset
9560 DO icb=icboff+1,icboff+icblst
9561 icfrst=matconsblocks(1,icb) ! first constraint in block
9562 iclast=matconsblocks(1,icb+1)-1 ! last constraint in block
9563 DO j=icfrst,iclast
9564 ipfrst=matconsranges(3,j)-ipoff ! first (rel.) parameter
9565 iplast=matconsranges(4,j)-ipoff ! last (rel.) parameters
9566 npb=iplast-ipfrst+1
9567 lapackql(iloff+ipfrst:iloff+iplast)=a(imoff+1:imoff+npb)
9568 imoff=imoff+npb
9569 iloff=iloff+npar
9570 END DO
9571 END DO
9572 END DO
9573 ! decompose
9574 iloff=0 ! offset of unpacked constraint matrix block
9575 emax=-1.
9576 emin=1.
9577 DO ib=1,npblck
9578 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9579 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9580 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9581 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9582 IF(ncon <= 0) cycle
9583 ! block with constraints
9584 nbopt = ilaenv( 1_mpl, 'DGEQLF', '', int(npar,mpl), int(ncon,mpl), int(npar,mpl), -1_mpl ) ! optimal block size
9585 print *, 'LAPACK optimal block size for DGEQLF:', nbopt
9586 lplwrk=int(ncon,mpl)*int(nbopt,mpl)
9587 CALL mpalloc(lapackwork, lplwrk,'LAPACK WORK array (d)')
9588 !$POMP INST BEGIN(dgeqlf)
9589#ifdef SCOREP_USER_ENABLE
9590 scorep_user_region_by_name_begin("UR_dgeqlf", scorep_user_region_type_common)
9591#endif
9592 CALL dgeqlf(int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),int(npar,mpl),&
9593 lapacktau(icoff+1:),lapackwork,lplwrk,infolp)
9594 IF(infolp /= 0) print *, ' DGEQLF failed: ', infolp
9595#ifdef SCOREP_USER_ENABLE
9596 scorep_user_region_by_name_end("UR_dgeqlf")
9597#endif
9598 !$POMP INST END(dgeqlf)
9599 CALL mpdealloc(lapackwork)
9600 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9601 ! get min/max diaginal element of L
9602 imoff=iloff
9603 IF(emax < emin) THEN
9604 emax=lapackql(imoff)
9605 emin=emax
9606 END IF
9607 DO i=1,ncon
9608 IF (abs(emax) < abs(lapackql(imoff))) emax=lapackql(imoff)
9609 IF (abs(emin) > abs(lapackql(imoff))) emin=lapackql(imoff)
9610 imoff=imoff-npar-1
9611 END DO
9612 END DO
9613 print *
9614END SUBROUTINE lpqldec
9615
9625SUBROUTINE lpavat(t)
9626 USE mpmod
9627
9628 IMPLICIT NONE
9629 INTEGER(mpi) :: i
9630 INTEGER(mpi) :: ib
9631 INTEGER(mpi) :: icoff
9632 INTEGER(mpi) :: ipoff
9633 INTEGER(mpi) :: j
9634 INTEGER(mpi) :: ncon
9635 INTEGER(mpi) :: npar
9636 INTEGER(mpl) :: imoff
9637 INTEGER(mpl) :: iloff
9638 INTEGER(mpi) :: infolp
9639 CHARACTER (LEN=1) :: transr, transl
9640
9641 LOGICAL, INTENT(IN) :: t
9642 SAVE
9643
9644 IF (t) THEN ! Q^t*A*Q
9645 transr='N'
9646 transl='T'
9647 ELSE ! Q*A*Q^t
9648 transr='T'
9649 transl='N'
9650 ENDIF
9651
9652 ! loop over blocks (multiple blocks only with elimination !)
9653 iloff=0 ! offset of L in lapackQL
9654 DO ib=1,npblck
9655 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
9656 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
9657 icoff=vecparblockconoffsets(ib) ! constraint offset for block
9658 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
9659 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
9660 IF(ncon <= 0 ) cycle
9661
9662 !$POMP INST BEGIN(dormql)
9663#ifdef SCOREP_USER_ENABLE
9664 scorep_user_region_by_name_begin("UR_dormql", scorep_user_region_type_common)
9665#endif
9666 ! expand matrix (copy lower to upper triangle)
9667 ! parallelize row loop
9668 ! slot of 32 'I' for next idle thread
9669 !$OMP PARALLEL DO &
9670 !$OMP PRIVATE(J) &
9671 !$OMP SCHEDULE(DYNAMIC,32)
9672 DO i=ipoff+1,ipoff+npar
9673 DO j=ipoff+1,i-1
9675 ENDDO
9676 ENDDO
9677 ! A*Q
9678 CALL dormql('R',transr,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9679 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9680 lapackwork,lplwrk,infolp)
9681 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9682 ! Q^t*(A*Q)
9683 CALL dormql('L',transl,int(npar,mpl),int(npar,mpl),int(ncon,mpl),lapackql(iloff+1:),&
9684 int(npar,mpl),lapacktau(icoff+1:),globalmatd(imoff+1:),int(npar,mpl),&
9685 lapackwork,lplwrk,infolp)
9686 IF(infolp /= 0) print *, ' DORMQL failed: ', infolp
9687#ifdef SCOREP_USER_ENABLE
9688 scorep_user_region_by_name_end("UR_dormql")
9689#endif
9690 !$POMP INST END(dormql)
9691
9692 iloff=iloff+int(npar,mpl)*int(ncon,mpl)
9693 END DO
9694
9695END SUBROUTINE lpavat
9696
9697#ifdef PARDISO
9698include 'mkl_pardiso.f90'
9699!===============================================================================
9700! Copyright 2004-2022 Intel Corporation.
9701!
9702! This software and the related documents are Intel copyrighted materials, and
9703! your use of them is governed by the express license under which they were
9704! provided to you (License). Unless the License provides otherwise, you may not
9705! use, modify, copy, publish, distribute, disclose or transmit this software or
9706! the related documents without Intel's prior written permission.
9707!
9708! This software and the related documents are provided as is, with no express
9709! or implied warranties, other than those that are expressly stated in the
9710! License.
9711!===============================================================================
9712!
9713! Content : Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO Fortran-90
9714! use case
9715!
9716!*******************************************************************************
9717
9722SUBROUTINE mspardiso
9723 USE mkl_pardiso
9724 USE mpmod
9725 USE mpdalc
9726 IMPLICIT NONE
9727
9728 !.. Internal solver memory pointer
9729 TYPE(mkl_pardiso_handle) :: pt(64) ! Handle to internal data structure
9730 !.. All other variables
9731 INTEGER(mpl), PARAMETER :: maxfct =1 ! Max. number of factors with identical sparsity structure kept in memory
9732 INTEGER(mpl), PARAMETER :: mnum = 1 ! Actual factor to use
9733 INTEGER(mpl), PARAMETER :: nrhs = 1 ! Number of right hand sides
9734
9735 INTEGER(mpl) :: mtype ! Matrix type (symmetric, pos. def.: 2, indef.: -2)
9736 INTEGER(mpl) :: phase ! Solver phase(s) to be executed
9737 INTEGER(mpl) :: error ! Error code
9738 INTEGER(mpl) :: msglvl ! Message level
9739
9740 INTEGER(mpi) :: i
9741 INTEGER(mpl) :: ij
9742 INTEGER(mpl) :: idum(1)
9743 INTEGER(mpi) :: lun
9744 INTEGER(mpl) :: length
9745 INTEGER(mpi) :: nfill
9746 INTEGER(mpi) :: npdblk
9747 REAL(mpd) :: adum(1)
9748 REAL(mpd) :: ddum(1)
9749
9750 INTEGER(mpl) :: iparm(64)
9751 REAL(mpd), ALLOCATABLE :: b( : ) ! Right hand side (of equations system)
9752 REAL(mpd), ALLOCATABLE :: x( : ) ! Solution (of equations system)
9753 SAVE
9754
9755 lun=lunlog ! log file
9756
9757 error = 0 ! initialize error flag
9758 msglvl = ipddbg ! print statistical information
9759 npdblk=(nfgb-1)/matbsz+1 ! number of row blocks
9760
9761 IF(icalcm == 1) THEN
9762 mtype = 2 ! positive definite symmetric matrix
9763 IF (nfgb > nvgb) mtype = -2 ! indefinte symmetric matrix (Lagrange multipliers)
9764
9765 !$POMP INST BEGIN(mspd00)
9766#ifdef SCOREP_USER_ENABLE
9767 scorep_user_region_by_name_begin("UR_mspd00", scorep_user_region_type_common)
9768#endif
9769 WRITE(*,*)
9770 WRITE(*,*) 'MSPARDISO: number of non-zero elements = ', csr3rowoffsets(npdblk+1)-csr3rowoffsets(1)
9771 ! fill up last block?
9772 nfill = npdblk*matbsz-nfgb
9773 IF (nfill > 0) THEN
9774 WRITE(*,*) 'MSPARDISO: number of rows to fill up = ', nfill
9775 ! end of last block
9776 ij = (csr3rowoffsets(npdblk+1)-csr3rowoffsets(1))*int(matbsz,mpl)*int(matbsz,mpl)
9777 DO i=1,nfill
9778 globalmatd(ij) = 1.0_mpd
9779 ij = ij-matbsz-1 ! back one row and one column in last block
9780 END DO
9781 END IF
9782
9783 ! close previous PARADISO run
9784 IF (ipdmem > 0) THEN
9785 !.. Termination and release of memory
9786 phase = -1 ! release internal memory
9787 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), adum, idum, idum, &
9788 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9789 IF (error /= 0) THEN
9790 WRITE(lun,*) 'The following ERROR was detected: ', error
9791 WRITE(*,'(A,2I10)') ' PARDISO release failed (phase, error): ', phase, error
9792 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9793 CALL peend(40,'Aborted, other error: PARDISO release')
9794 stop 'MSPARDISO: stopping due to error in PARDISO release'
9795 END IF
9796 ipdmem=0
9797 END IF
9798
9799 !..
9800 !.. Set up PARDISO control parameter
9801 !..
9802 iparm=0 ! using defaults
9803 iparm(2) = 2 ! fill-in reordering from METIS
9804 iparm(10) = 8 ! perturb the pivot elements with 1E-8
9805 iparm(18) = -1 ! Output: number of nonzeros in the factor LU
9806 iparm(19) = -1 ! Output: Mflops for LU factorization
9807 iparm(21) = 1 ! pivoting for symmetric indefinite matrices
9808 DO i=1, lenpardiso
9809 iparm(listpardiso(i)%label)=listpardiso(i)%ivalue
9810 END DO
9811 IF (iparm(1) == 0) WRITE(lun,*) 'PARDISO using defaults '
9812 IF (iparm(43) /= 0) THEN
9813 WRITE(lun,*) 'PARDISO: computation of the diagonal of inverse matrix not implemented !'
9814 iparm(43) = 0 ! no computation of the diagonal of inverse matrix
9815 END IF
9816
9817 ! necessary for the FIRST call of the PARDISO solver.
9818 DO i = 1, 64
9819 pt(i)%DUMMY = 0
9820 END DO
9821#ifdef SCOREP_USER_ENABLE
9822 scorep_user_region_by_name_end("UR_mspd00")
9823#endif
9824 !$POMP INST END(mspd00)
9825 END IF
9826
9827 IF(icalcm == 1) THEN
9828 ! monitor progress
9829 IF(monpg1 > 0) THEN
9830 WRITE(lunlog,*) 'Decomposition of global matrix (A->L*D*L^t)'
9832 END IF
9833 ! decompose and solve
9834 !.. Reordering and Symbolic Factorization, This step also allocates
9835 ! all memory that is necessary for the factorization
9836 !$POMP INST BEGIN(mspd11)
9837#ifdef SCOREP_USER_ENABLE
9838 scorep_user_region_by_name_begin("UR_mspd11", scorep_user_region_type_common)
9839#endif
9840 phase = 11 ! only reordering and symbolic factorization
9841 IF (matbsz > 1) THEN
9842 iparm(1) = 1 ! non default setting
9843 iparm(37) = matbsz ! using BSR3 instead of CSR3
9844 END IF
9845 IF (ipddbg > 0) THEN
9846 DO i=1,64
9847 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9848 END DO
9849 END IF
9850 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9851 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9852#ifdef SCOREP_USER_ENABLE
9853 scorep_user_region_by_name_end("UR_mspd11")
9854#endif
9855 !$POMP INST END(mspd11)
9856 WRITE(lun,*) 'PARDISO reordering completed ... '
9857 WRITE(lun,*) 'PARDISO peak memory required (KB)', iparm(15)
9858 IF (ipddbg > 0) THEN
9859 DO i=1,64
9860 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9861 END DO
9862 END IF
9863 IF (error /= 0) THEN
9864 WRITE(lun,*) 'The following ERROR was detected: ', error
9865 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9866 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9867 CALL peend(40,'Aborted, other error: PARDISO reordering')
9868 stop 'MSPARDISO: stopping due to error in PARDISO reordering'
9869 END IF
9870 IF (iparm(60) == 0) THEN
9871 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(17) ! in core
9872 ELSE
9873 ipdmem=ipdmem+max(iparm(15),iparm(16))+iparm(63) ! out of core
9874 END IF
9875 WRITE(lun,*) 'Size (KB) of allocated memory = ',ipdmem
9876 WRITE(lun,*) 'Number of nonzeros in factors = ',iparm(18)
9877 WRITE(lun,*) 'Number of factorization MFLOPS = ',iparm(19)
9878
9879 !.. Factorization.
9880 !$POMP INST BEGIN(mspd22)
9881#ifdef SCOREP_USER_ENABLE
9882 scorep_user_region_by_name_begin("UR_mspd22", scorep_user_region_type_common)
9883#endif
9884 phase = 22 ! only factorization
9885 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9886 idum, nrhs, iparm, msglvl, ddum, ddum, error)
9887#ifdef SCOREP_USER_ENABLE
9888 scorep_user_region_by_name_end("UR_mspd22")
9889#endif
9890 !$POMP INST END(mspd22)
9891 WRITE(lun,*) 'PARDISO factorization completed ... '
9892 IF (ipddbg > 0) THEN
9893 DO i=1,64
9894 WRITE(lun,*) ' iparm(',i,') =', iparm(i)
9895 END DO
9896 END IF
9897 IF (error /= 0) THEN
9898 WRITE(lun,*) 'The following ERROR was detected: ', error
9899 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9900 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9901 CALL peend(40,'Aborted, other error: PARDISO factorization')
9902 stop 'MSPARDISO: stopping due to error in PARDISO factorization'
9903 ENDIF
9904 IF (mtype < 0) THEN
9905 IF (iparm(14) > 0) &
9906 WRITE(lun,*) 'Number of perturbed pivots = ',iparm(14)
9907 WRITE(lun,*) 'Number of positive eigenvalues = ',iparm(22)-nfill
9908 WRITE(lun,*) 'Number of negative eigenvalues = ',iparm(23)
9909 ELSE IF (iparm(30) > 0) THEN
9910 WRITE(lun,*) 'Equation with bad pivot (<=0.) = ',iparm(30)
9911 END IF
9912
9913 IF (monpg1 > 0) CALL monend()
9914 END IF
9915
9916 ! backward/forward substitution
9917 !.. Back substitution and iterative refinement
9918 length=nfgb+nfill
9919 CALL mpalloc(b,length,' PARDISO r.h.s')
9920 CALL mpalloc(x,length,' PARDISO solution')
9922 !$POMP INST BEGIN(mspd33)
9923#ifdef SCOREP_USER_ENABLE
9924 scorep_user_region_by_name_begin("UR_mspd33", scorep_user_region_type_common)
9925#endif
9926 iparm(6) = 0 ! don't update r.h.s. with solution
9927 phase = 33 ! only solving
9928 CALL pardiso_64(pt, maxfct, mnum, mtype, phase, int(npdblk,mpl), globalmatd, csr3rowoffsets, csr3columnlist, &
9929 idum, nrhs, iparm, msglvl, b, x, error)
9930#ifdef SCOREP_USER_ENABLE
9931 scorep_user_region_by_name_end("UR_mspd33")
9932#endif
9933 !$POMP INST END(mspd33)
9935 CALL mpdealloc(x)
9936 CALL mpdealloc(b)
9937 WRITE(lun,*) 'PARDISO solve completed ... '
9938 IF (error /= 0) THEN
9939 WRITE(lun,*) 'The following ERROR was detected: ', error
9940 WRITE(*,'(A,2I10)') ' PARDISO decomposition failed (phase, error): ', phase, error
9941 IF (ipddbg == 0) WRITE(*,*) ' rerun with "debugPARDISO" for more info'
9942 CALL peend(40,'Aborted, other error: PARDISO solve')
9943 stop 'MSPARDISO: stopping due to error in PARDISO solve'
9944 ENDIF
9945
9946END SUBROUTINE mspardiso
9947#endif
9948#endif
9949
9951SUBROUTINE mdiags
9952 USE mpmod
9953
9954 IMPLICIT NONE
9955 REAL(mps) :: evalue
9956 INTEGER(mpi) :: i
9957 INTEGER(mpi) :: iast
9958 INTEGER(mpi) :: idia
9959 INTEGER(mpi) :: imin
9960 INTEGER(mpl) :: ioff1
9961 INTEGER(mpi) :: j
9962 INTEGER(mpi) :: last
9963 INTEGER(mpi) :: lun
9964 INTEGER(mpi) :: nmax
9965 INTEGER(mpi) :: nmin
9966 INTEGER(mpi) :: ntop
9967 REAL(mpd) :: matij
9968 !
9969 EXTERNAL avprds
9970
9971 SAVE
9972 ! ...
9973
9974 lun=lunlog ! log file
9975
9976 ! save diagonal (for global correlation)
9977 IF(icalcm == 1) THEN
9978 DO i=1,nagb
9979 workspacediag(i)=matij(i,i)
9980 END DO
9981 ENDIF
9982
9983 !use elimination for constraints ?
9984 IF(nfgb < nvgb) THEN
9985 IF(icalcm == 1) THEN
9986 ! monitor progress
9987 IF(monpg1 > 0) THEN
9988 WRITE(lunlog,*) 'Shrinkage of global matrix (A->Q^t*A*Q)'
9990 END IF
9991 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.true.) ! Q^t*A*Q
9992 IF(monpg1 > 0) CALL monend()
9993 ENDIF
9994 ! solve L^t*y=d by backward substitution
9996 ! transform, reduce rhs
9997 CALL qlmlq(globalcorrections,1,.true.) ! Q^t*b
9998 ! correction from eliminated part
9999 DO i=1,nfgb
10000 DO j=1,ncgb
10001 ioff1=globalrowoffsets(nfgb+j)+i ! global (nfit+j,i)
10003 END DO
10004 END DO
10005 END IF
10006
10007 IF(icalcm == 1) THEN
10008 ! eigenvalues eigenvectors symm_input
10009 workspaceeigenvalues=0.0_mpd
10012
10013 ! histogram of positive eigenvalues
10014
10015 nmax=int(1.0+log10(real(workspaceeigenvalues(1),mps)),mpi) ! > log of largest eigenvalue
10016 imin=1
10017 DO i=nfgb,1,-1
10018 IF(workspaceeigenvalues(i) > 0.0_mpd) THEN
10019 imin=i ! index of smallest pos. eigenvalue
10020 EXIT
10021 END IF
10022 END DO
10023 nmin=int(log10(real(workspaceeigenvalues(imin),mps)),mpi) ! log of smallest pos. eigenvalue
10024 ntop=nmin+6
10025 DO WHILE(ntop < nmax)
10026 ntop=ntop+3
10027 END DO
10028
10029 CALL hmpdef(7,real(nmin,mps),real(ntop,mps), 'log10 of positive eigenvalues')
10030 DO idia=1,nfgb
10031 IF(workspaceeigenvalues(idia) > 0.0_mpd) THEN ! positive
10032 evalue=log10(real(workspaceeigenvalues(idia),mps))
10033 CALL hmpent(7,evalue)
10034 END IF
10035 END DO
10036 IF(nhistp /= 0) CALL hmprnt(7)
10037 CALL hmpwrt(7)
10038
10039 iast=max(1,imin-60)
10040 CALL gmpdef(3,2,'low-value end of eigenvalues')
10041 DO i=iast,nfgb
10042 evalue=real(workspaceeigenvalues(i),mps)
10043 CALL gmpxy(3,real(i,mps),evalue)
10044 END DO
10045 IF(nhistp /= 0) CALL gmprnt(3)
10046 CALL gmpwrt(3)
10047
10048 DO i=1,nfgb
10049 workspacediagonalization(i)=0.0_mpd
10050 IF(workspaceeigenvalues(i) /= 0.0_mpd) THEN
10051 workspacediagonalization(i)=max(0.0_mpd,log10(abs(workspaceeigenvalues(i)))+3.0_mpd)
10053 END IF
10054 END DO
10055 last=min(nfgb,nvgb)
10056 WRITE(lun,*) ' '
10057 WRITE(lun,*) 'The first (largest) eigenvalues ...'
10058 WRITE(lun,102) (workspaceeigenvalues(i),i=1,min(20,nagb))
10059 WRITE(lun,*) ' '
10060 WRITE(lun,*) 'The last eigenvalues ... up to',last
10061 WRITE(lun,102) (workspaceeigenvalues(i),i=max(1,last-19),last)
10062 WRITE(lun,*) ' '
10063 IF(nagb > nvgb) THEN
10064 WRITE(lun,*) 'The eigenvalues from',nvgb+1,' to',nagb
10065 WRITE(lun,102) (workspaceeigenvalues(i),i=nvgb+1,nagb)
10066 WRITE(lun,*) ' '
10067 ENDIF
10068 WRITE(lun,*) 'Log10 + 3 of ',nfgb,' eigenvalues in decreasing', ' order'
10069 WRITE(lun,*) '(for Eigenvalue < 0.001 the value 0.0 is shown)'
10070 WRITE(lun,101) (workspacediagonalization(i),i=1,nfgb)
10071 IF(workspacediagonalization(nfgb) < 0) WRITE(lun,*) 'Negative values are ', &
10072 'printed for negative eigenvalues'
10074 WRITE(lun,*) ' '
10075 WRITE(lun,*) last,' significances: insignificant if ', &
10076 'compatible with N(0,1)'
10077 WRITE(lun,101) (workspacediagonalization(i),i=1,last)
10078
10079
10080101 FORMAT(10f7.1)
10081102 FORMAT(5e14.6)
10082
10083 END IF
10084
10085 ! solution ---------------------------------------------------------
10087 ! eigenvalues eigenvectors
10089
10090 !use elimination for constraints ?
10091 IF(nfgb < nvgb) THEN
10092 ! extend, transform back solution
10094 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10095 END IF
10096
10097END SUBROUTINE mdiags
10098
10100SUBROUTINE zdiags
10101 USE mpmod
10102
10103 IMPLICIT NONE
10104 INTEGER(mpi) :: i
10105 INTEGER(mpl) :: ioff1
10106 INTEGER(mpl) :: ioff2
10107 INTEGER(mpi) :: j
10108
10109 ! eigenvalue eigenvectors cov.matrix
10111
10112 !use elimination for constraints ?
10113 IF(nfgb < nvgb) THEN
10114 ! extend, transform eigenvectors
10115 ioff1=nfgb*nfgb
10116 ioff2=nfgb*nvgb
10117 workspaceeigenvectors(ioff2+1:)=0.0_mpd
10118 DO i=nfgb,1,-1
10119 ioff1=ioff1-nfgb
10120 ioff2=ioff2-nvgb
10121 DO j=nfgb,1,-1
10123 END DO
10124 workspaceeigenvectors(ioff2+nfgb+1:ioff2+nvgb)=0.0_mpd
10125 END DO
10126 CALL qlmlq(workspaceeigenvectors,nvgb,.false.) ! Q*U
10127 END IF
10128
10129END SUBROUTINE zdiags
10130
10136
10137SUBROUTINE mminrs
10138 USE mpmod
10139 USE minresmodule, ONLY: minres
10140
10141 IMPLICIT NONE
10142 INTEGER(mpi) :: istop
10143 INTEGER(mpi) :: itn
10144 INTEGER(mpi) :: itnlim
10145 INTEGER(mpi) :: lun
10146 INTEGER(mpi) :: nout
10147 INTEGER(mpi) :: nrkd
10148 INTEGER(mpi) :: nrkd2
10149
10150 REAL(mpd) :: shift
10151 REAL(mpd) :: rtol
10152 REAL(mpd) :: anorm
10153 REAL(mpd) :: acond
10154 REAL(mpd) :: arnorm
10155 REAL(mpd) :: rnorm
10156 REAL(mpd) :: ynorm
10157 LOGICAL :: checka
10158 EXTERNAL avprds, avprod, mvsolv, mcsolv
10159 SAVE
10160 ! ...
10161 lun=lunlog ! log file
10162
10163 nout=lun
10164 itnlim=2000 ! iteration limit
10165 shift =0.0_mpd ! not used
10166 rtol = mrestl ! from steering
10167 checka=.false.
10168
10170 !use elimination for constraints ?
10171 IF(nfgb < nvgb) THEN
10172 ! solve L^t*y=d by backward substitution
10174 ! input to AVPRD0
10175 vecxav(1:nfgb)=0.0_mpd
10177 CALL qlmlq(vecxav,1,.false.) ! Q*x
10178 ! calclulate vecBav=globalMat*vecXav
10179 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10180 ! correction from eliminated part
10182 ! transform, reduce rhs
10183 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10184 END IF
10185
10186 IF(mbandw == 0) THEN ! default preconditioner
10187 IF(icalcm == 1) THEN
10188 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10189 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10190 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10192 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10193 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10194 IF(monpg1 > 0) CALL monend()
10195 END IF
10196 CALL minres(nfgb, avprod, mcsolv, workspaced, shift, checka ,.true. , &
10197 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10198 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10199 IF(icalcm == 1) THEN
10200 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10201 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10202 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10204 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10205 IF(monpg1 > 0) CALL monend()
10206 END IF
10207 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.true. , &
10208 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10209 ELSE
10210 CALL minres(nfgb, avprod, mvsolv, workspaced, shift, checka ,.false. , &
10211 globalcorrections, itnlim, nout, rtol, istop, itn, anorm, acond, rnorm, arnorm, ynorm)
10212 END IF
10213
10214 !use elimination for constraints ?
10215 IF(nfgb < nvgb) THEN
10216 ! extend, transform back solution
10218 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10219 END IF
10220
10221 iitera=itn
10222 istopa=istop
10223 mnrsit=mnrsit+itn
10224
10225 IF (istopa == 0) print *, 'MINRES: istop=0, exact solution x=0.'
10226
10227END SUBROUTINE mminrs
10228
10234
10235SUBROUTINE mminrsqlp
10236 USE mpmod
10237 USE minresqlpmodule, ONLY: minresqlp
10238
10239 IMPLICIT NONE
10240 INTEGER(mpi) :: istop
10241 INTEGER(mpi) :: itn
10242 INTEGER(mpi) :: itnlim
10243 INTEGER(mpi) :: lun
10244 INTEGER(mpi) :: nout
10245 INTEGER(mpi) :: nrkd
10246 INTEGER(mpi) :: nrkd2
10247
10248 REAL(mpd) :: rtol
10249 REAL(mpd) :: mxxnrm
10250 REAL(mpd) :: trcond
10251
10252 EXTERNAL avprds, avprod, mvsolv, mcsolv
10253 SAVE
10254 ! ...
10255 lun=lunlog ! log file
10256
10257 nout=lun
10258 itnlim=2000 ! iteration limit
10259 rtol = mrestl ! from steering
10260 mxxnrm = real(nagb,mpd)/sqrt(epsilon(mxxnrm))
10261 IF(mrmode == 1) THEN
10262 trcond = 1.0_mpd/epsilon(trcond) ! only QR
10263 ELSE IF(mrmode == 2) THEN
10264 trcond = 1.0_mpd ! only QLP
10265 ELSE
10266 trcond = mrtcnd ! QR followed by QLP
10267 END IF
10268
10270 !use elimination for constraints ?
10271 IF(nfgb < nvgb) THEN
10272 ! solve L^t*y=d by backward substitution
10274 ! input to AVPRD0
10275 vecxav(1:nfgb)=0.0_mpd
10277 CALL qlmlq(vecxav,1,.false.) ! Q*x
10278 ! calclulate vecBav=globalMat*vecXav
10279 CALL avprd0(nagb,0_mpl,vecxav,vecbav)
10280 ! correction from eliminated part
10282 ! transform, reduce rhs
10283 CALL qlmlq(workspaced,1,.true.) ! Q^t*b
10284 END IF
10285
10286 IF(mbandw == 0) THEN ! default preconditioner
10287 IF(icalcm == 1) THEN
10288 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,1,.true.) ! transform preconditioner matrix
10289 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10290 WRITE(lun,*) 'MMINRS: PRECONS started', nprecond(2), nprecond(1)
10292 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),nrkd)
10293 WRITE(lun,*) 'MMINRS: PRECONS ended ', nrkd
10294 IF(monpg1 > 0) CALL monend()
10295 END IF
10296 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mcsolv, nout=nout, &
10297 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10298 x=globalcorrections, istop=istop, itn=itn)
10299 ELSE IF(mbandw > 0) THEN ! band matrix preconditioner
10300 IF(icalcm == 1) THEN
10301 IF(nfgb < nvgb) CALL qlpssq(avprds,matprecond,mbandw,.true.) ! transform preconditioner matrix
10302 IF(monpg1 > 0) CALL monini(lunlog,monpg1,monpg2)
10303 WRITE(lun,*) 'MMINRS: EQUDECS started', nprecond(2), nprecond(1)
10305 WRITE(lun,*) 'MMINRS: EQUDECS ended ', nrkd, nrkd2
10306 IF(monpg1 > 0) CALL monend()
10307 END IF
10308
10309 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, msolve=mvsolv, nout=nout, &
10310 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10311 x=globalcorrections, istop=istop, itn=itn)
10312 ELSE
10313 CALL minresqlp( n=nfgb, aprod=avprod, b=workspaced, nout=nout, &
10314 itnlim=itnlim, rtol=rtol, maxxnorm=mxxnrm, trancond=trcond, &
10315 x=globalcorrections, istop=istop, itn=itn)
10316 END IF
10317
10318 !use elimination for constraints ?
10319 IF(nfgb < nvgb) THEN
10320 ! extend, transform back solution
10322 CALL qlmlq(globalcorrections,1,.false.) ! Q*x
10323 END IF
10324
10325 iitera=itn
10326 istopa=istop
10327 mnrsit=mnrsit+itn
10328
10329 IF (istopa == 3) print *, 'MINRES: istop=0, exact solution x=0.'
10330
10331END SUBROUTINE mminrsqlp
10332
10340
10341SUBROUTINE mcsolv(n,x,y) ! solve M*y = x
10342 USE mpmod
10343
10344 IMPLICIT NONE
10345 INTEGER(mpi),INTENT(IN) :: n
10346 REAL(mpd), INTENT(IN) :: x(n)
10347 REAL(mpd), INTENT(OUT) :: y(n)
10348 SAVE
10349 ! ...
10351 matprecond(1+nvgb+(nprecond(1)*(nprecond(1)+1))/2),blockprecond,matprecond(1+nvgb),y,x)
10352END SUBROUTINE mcsolv
10353
10361
10362SUBROUTINE mvsolv(n,x,y) ! solve M*y = x
10363 USE mpmod
10364
10365 IMPLICIT NONE
10366
10367 INTEGER(mpi), INTENT(IN) :: n
10368 REAL(mpd), INTENT(IN) :: x(n)
10369 REAL(mpd), INTENT(OUT) :: y(n)
10370
10371 SAVE
10372 ! ...
10373 y=x ! copy to output vector
10374
10376END SUBROUTINE mvsolv
10377
10378
10379
10380!***********************************************************************
10381
10394
10395SUBROUTINE xloopn !
10396 USE mpmod
10397
10398 IMPLICIT NONE
10399 REAL(mps) :: catio
10400 REAL(mps) :: concu2
10401 REAL(mps) :: concut
10402 REAL, DIMENSION(2) :: ta
10403 REAL etime
10404 INTEGER(mpi) :: i
10405 INTEGER(mpi) :: iact
10406 INTEGER(mpi) :: iagain
10407 INTEGER(mpi) :: idx
10408 INTEGER(mpi) :: info
10409 INTEGER(mpi) :: ib
10410 INTEGER(mpi) :: ipoff
10411 INTEGER(mpi) :: icoff
10412 INTEGER(mpl) :: ioff
10413 INTEGER(mpi) :: itgbi
10414 INTEGER(mpi) :: ivgbi
10415 INTEGER(mpi) :: jcalcm
10416 INTEGER(mpi) :: k
10417 INTEGER(mpi) :: labelg
10418 INTEGER(mpi) :: litera
10419 INTEGER(mpl) :: lrej
10420 INTEGER(mpi) :: lun
10421 INTEGER(mpi) :: lunp
10422 INTEGER(mpi) :: minf
10423 INTEGER(mpi) :: mrati
10424 INTEGER(mpi) :: nan
10425 INTEGER(mpi) :: ncon
10426 INTEGER(mpi) :: nfaci
10427 INTEGER(mpi) :: nloopsol
10428 INTEGER(mpi) :: npar
10429 INTEGER(mpi) :: nrati
10430 INTEGER(mpl) :: nrej
10431 INTEGER(mpi) :: nsol
10432 INTEGER(mpi) :: inone
10433#ifdef LAPACK64
10434 INTEGER(mpi) :: infolp
10435 INTEGER(mpi) :: nfit
10436 INTEGER(mpl) :: imoff
10437#endif
10438
10439 REAL(mpd) :: stp
10440 REAL(mpd) :: dratio
10441 REAL(mpd) :: dwmean
10442 REAL(mpd) :: db
10443 REAL(mpd) :: db1
10444 REAL(mpd) :: db2
10445 REAL(mpd) :: dbdot
10446 REAL(mpd) :: dbsig
10447 LOGICAL :: btest
10448 LOGICAL :: warner
10449 LOGICAL :: warners
10450 LOGICAL :: warnerss
10451 LOGICAL :: warners3
10452 LOGICAL :: lsflag
10453 CHARACTER (LEN=7) :: cratio
10454 CHARACTER (LEN=7) :: cfacin
10455 CHARACTER (LEN=7) :: crjrat
10456 EXTERNAL avprds
10457 SAVE
10458 ! ...
10459
10460 ! Printout of algorithm for solution and important parameters ------
10461
10462 lun=lunlog ! log file
10463
10464 DO lunp=6,lunlog,lunlog-6
10465 WRITE(lunp,*) ' '
10466 WRITE(lunp,*) 'Solution algorithm: '
10467 WRITE(lunp,121) '=================================================== '
10468
10469 IF(metsol == 1) THEN
10470 WRITE(lunp,121) 'solution method:','matrix inversion'
10471 ELSE IF(metsol == 2) THEN
10472 WRITE(lunp,121) 'solution method:','diagonalization'
10473 ELSE IF(metsol == 3) THEN
10474 WRITE(lunp,121) 'solution method:','decomposition'
10475 ELSE IF(metsol == 4) THEN
10476 WRITE(lunp,121) 'solution method:', 'minres (Paige/Saunders)'
10477 ELSE IF(metsol == 5) THEN
10478 WRITE(lunp,121) 'solution method:', 'minres-qlp (Choi/Paige/Saunders)'
10479 IF(mrmode == 1) THEN
10480 WRITE(lunp,121) ' ', ' using QR factorization' ! only QR
10481 ELSE IF(mrmode == 2) THEN
10482 WRITE(lunp,121) ' ', ' using QLP factorization' ! only QLP
10483 ELSE
10484 WRITE(lunp,121) ' ', ' using QR and QLP factorization' ! QR followed by QLP
10485 WRITE(lunp,123) 'transition condition', mrtcnd
10486 END IF
10487 ELSE IF(metsol == 6) THEN
10488 WRITE(lunp,121) 'solution method:', &
10489 'gmres (generalized minimzation of residuals)'
10490#ifdef LAPACK64
10491 ELSE IF(metsol == 7) THEN
10492 IF (nagb > nvgb) THEN
10493 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSPTRF)'
10494 ELSE
10495 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPPTRF)'
10496 ENDIF
10497 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10498 ELSE IF(metsol == 8) THEN
10499 IF (nagb > nvgb) THEN
10500 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DSYTRF)'
10501 ELSE
10502 WRITE(lunp,121) 'solution method:', 'LAPACK factorization (DPOTRF)'
10503 ENDIF
10504 IF(ilperr == 1) WRITE(lunp,121) ' ', 'with error calculation (D??TRI)'
10505#ifdef PARDISO
10506 ELSE IF(metsol == 9) THEN
10507 IF (matbsz < 2) THEN
10508 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (CSR3))'
10509 ELSE
10510 WRITE(lunp,121) 'solution method:', 'Intel oneMKL PARDISO (sparse matrix (BSR3))'
10511 ENDIF
10512#endif
10513#endif
10514 END IF
10515 WRITE(lunp,123) 'convergence limit at Delta F=',dflim
10516 WRITE(lunp,122) 'maximum number of iterations=',mitera
10517 matrit=min(matrit,mitera)
10518 IF(matrit > 1) THEN
10519 WRITE(lunp,122) 'matrix recalculation up to ',matrit, '. iteration'
10520 END IF
10521 IF(metsol >= 4.AND.metsol < 7) THEN
10522 IF(matsto == 1) THEN
10523 WRITE(lunp,121) 'matrix storage:','full'
10524 ELSE IF(matsto == 2) THEN
10525 WRITE(lunp,121) 'matrix storage:','sparse'
10526 END IF
10527 WRITE(lunp,122) 'pre-con band-width parameter=',mbandw
10528 IF(mbandw == 0) THEN
10529 WRITE(lunp,121) 'pre-conditioning:','default'
10530 ELSE IF(mbandw < 0) THEN
10531 WRITE(lunp,121) 'pre-conditioning:','none!'
10532 ELSE IF(mbandw > 0) THEN
10533 IF(lprecm > 0) THEN
10534 WRITE(lunp,121) 'pre-conditioning=','skyline-matrix (rank preserving)'
10535 ELSE
10536 WRITE(lunp,121) 'pre-conditioning=','band-matrix'
10537 ENDIF
10538 END IF
10539 END IF
10540 IF(regpre == 0.0_mpd.AND.npresg == 0) THEN
10541 WRITE(lunp,121) 'using pre-sigmas:','no'
10542 ELSE
10543 ! FIXME: NPRESG contains parameters that failed the 'entries' cut...
10544 WRITE(lunp,124) 'pre-sigmas defined for', &
10545 REAL(100*npresg,mps)/REAL(nvgb,mps),' % of variable parameters'
10546 WRITE(lunp,123) 'default pre-sigma=',regpre
10547 END IF
10548 IF(nregul == 0) THEN
10549 WRITE(lunp,121) 'regularization:','no'
10550 ELSE
10551 WRITE(lunp,121) 'regularization:','yes'
10552 WRITE(lunp,123) 'regularization factor=',regula
10553 END IF
10554
10555 IF(chicut /= 0.0) THEN
10556 WRITE(lunp,121) 'Chi square cut equiv 3 st.dev applied'
10557 WRITE(lunp,123) '... in first iteration with factor',chicut
10558 WRITE(lunp,123) '... in second iteration with factor',chirem
10559 WRITE(lunp,121) ' (reduced by sqrt in next iterations)'
10560 END IF
10561 IF(iscerr > 0) THEN
10562 WRITE(lunp,121) 'Scaling of measurement errors applied'
10563 WRITE(lunp,123) '... factor for "global" measuements',dscerr(1)
10564 WRITE(lunp,123) '... factor for "local" measuements',dscerr(2)
10565 END IF
10566 IF(lhuber /= 0) THEN
10567 WRITE(lunp,122) 'Down-weighting of outliers in', lhuber,' iterations'
10568 WRITE(lunp,123) 'Cut on downweight fraction',dwcut
10569 END IF
10570
10571
10572121 FORMAT(1x,a40,3x,a)
10573122 FORMAT(1x,a40,3x,i0,a)
10574123 FORMAT(1x,a40,2x,e9.2)
10575124 FORMAT(1x,a40,3x,f5.1,a)
10576 END DO
10577
10578 ! initialization of iterations -------------------------------------
10579
10580 iitera=0
10581 nsol =0 ! counter for solutions
10582 info =0
10583 lsinfo=0
10584 stp =0.0_mpd
10585 stepl =real(stp,mps)
10586 concut=1.0e-12 ! initial constraint accuracy
10587 concu2=1.0e-06 ! constraint accuracy
10588 icalcm=1 ! require matrix calculation
10589 iterat=0 ! iteration counter
10590 iterat=-1
10591 litera=-2
10592 nloopsol=0 ! (new) solution from this nloopn
10593 nrej=0 ! reset number of rejects
10594 IF(metsol == 1) THEN
10595 wolfc2=0.5 ! not accurate
10596 minf=1
10597 ELSE IF(metsol == 2) THEN
10598 wolfc2=0.5 ! not acurate
10599 minf=2
10600 ELSE IF(metsol == 3) THEN
10601 wolfc2=0.5 ! not acurate
10602 minf=1
10603 ELSE IF(metsol == 4) THEN
10604 wolfc2=0.1 ! accurate
10605 minf=3
10606 ELSE IF(metsol == 5) THEN
10607 wolfc2=0.1 ! accurate
10608 minf=3
10609 ELSE IF(metsol == 6) THEN
10610 wolfc2=0.1 ! accurate
10611 minf=3
10612 ELSE
10613 wolfc2=0.5 ! not accurate
10614 minf=1
10615 END IF
10616
10617 ! check initial feasibility of constraint equations ----------------
10618
10619 WRITE(*,*) ' '
10620 IF(nofeas == 0) THEN ! make parameter feasible
10621 WRITE(lunlog,*) 'Checking feasibility of parameters:'
10622 WRITE(*,*) 'Checking feasibility of parameters:'
10623 CALL feasib(concut,iact) ! check feasibility
10624 IF(iact /= 0) THEN ! done ...
10625 WRITE(*,102) concut
10626 WRITE(*,*) ' parameters are made feasible'
10627 WRITE(lunlog,102) concut
10628 WRITE(lunlog,*) ' parameters are made feasible'
10629 ELSE ! ... was OK
10630 WRITE(*,*) ' parameters are feasible (i.e. satisfy constraints)'
10631 WRITE(lunlog,*) ' parameters are feasible (i.e. satisfy constraints)'
10632 END IF
10633 concut=concu2 ! cut for constraint check
10634 END IF
10635 iact=1 ! set flag for new data loop
10636 nofeas=0 ! set check-feasibility flag
10637
10638 WRITE(*,*) ' '
10639 WRITE(*,*)'Reading files and accumulating vectors/matrices ...'
10640 WRITE(*,*) ' '
10641 IF(monpg1>0) THEN
10642 WRITE(lunlog,*)
10643 WRITE(lunlog,*)'Reading files and accumulating vectors/matrices ...'
10644 WRITE(lunlog,*)
10645 END IF
10646
10647 rstart=etime(ta)
10648 iterat=-1
10649 litera= 0
10650 jcalcm=-1
10651 iagain= 0
10652
10653 icalcm=1
10654
10655 ! Block 1: data loop with vector (and matrix) calculation ----------
10656
10657 DO
10658 IF(iterat >= 0) THEN
10659 lcalcm=jcalcm+3 ! mode (1..4) of last loop
10660 IF(jcalcm+1 /= 0) THEN
10661 IF(iterat == 0) THEN
10662 CALL ploopa(6) ! header
10663 CALL ploopb(6)
10664 CALL ploopa(lunlog) ! iteration line
10665 CALL ploopb(lunlog)
10666 iterat=1
10667 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10668 ELSE
10669 IF(iterat /= litera) THEN
10670 CALL ploopb(6)
10671 ! CALL PLOOPA(LUNLOG)
10672 CALL ploopb(lunlog)
10673 litera=iterat
10674 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,delfun) ! fcn-value (with expected)
10675 IF(metsol == 4 .OR. metsol == 5) THEN ! extend to 6, i.e. GMRES?
10676 CALL gmpxy(2,real(iterat,mps),real(iitera,mps)) ! MINRES iterations
10677 END IF
10678 ELSE
10679 CALL ploopc(6) ! sub-iteration line
10680 CALL ploopc(lunlog)
10681 CALL gmpxyd(1,real(nloopn,mps),real(fvalue,mps),0.5,0.) ! fcn-value graph (no Delta)
10682 END IF
10683 END IF
10684 ELSE
10685 CALL ploopd(6) ! solution line
10686 CALL ploopd(lunlog)
10687 END IF
10688 rstart=etime(ta)
10689 ! CHK
10690 IF (iabs(jcalcm) <= 1) THEN
10691 idx=jcalcm+4
10692 times(idx )=(times(idx )*times(idx+3)+deltim) /(times(idx+3)+1.0)
10693 times(idx+3)= times(idx+3)+1.0
10694 END IF
10695 END IF
10696 jcalcm=icalcm
10697
10698 IF(icalcm >= 0) THEN ! ICALCM = +1 & 0
10699 CALL loopn ! data loop
10700 CALL addcst ! constraints
10701 lrej=nrej
10702 nrej=sum(nrejec) ! total number of rejects
10703 IF(3*nrej > nrecal) THEN
10704 WRITE(*,*) ' '
10705 WRITE(*,*) 'Data records rejected in previous loop: '
10706 CALL prtrej(6)
10707 WRITE(*,*) 'Too many rejects (>33.3%) - stop'
10708 CALL peend(26,'Aborted, too many rejects')
10709 stop
10710 END IF
10711 ! fill second half (j>i) of global matrix for extended storage, experimental
10712 IF (icalcm == 1.AND.mextnd > 0) CALL mhalf2()
10713 END IF
10714 ! Block 2: new iteration with calculation of solution --------------
10715 IF(abs(icalcm) == 1) THEN ! ICALCM = +1 & -1
10716 DO i=1,nagb
10717 globalcorrections(i)=globalvector(i) ! copy rhs
10718 END DO
10719 DO i=1,nvgb
10720 itgbi=globalparvartototal(i)
10721 workspacelinesearch(i)=globalparameter(itgbi) ! copy X for line search
10722 END DO
10723
10724 iterat=iterat+1 ! increase iteration count
10725 IF(metsol == 1) THEN
10726 CALL minver ! inversion
10727 ELSE IF(metsol == 2) THEN
10728 CALL mdiags ! diagonalization
10729 ELSE IF(metsol == 3) THEN
10730 CALL mchdec ! decomposition
10731 ELSE IF(metsol == 4) THEN
10732 CALL mminrs ! MINRES
10733 ELSE IF(metsol == 5) THEN
10734 CALL mminrsqlp ! MINRES-QLP
10735 ELSE IF(metsol == 6) THEN
10736 WRITE(*,*) '... reserved for GMRES (not yet!)'
10737 CALL mminrs ! GMRES not yet
10738#ifdef LAPACK64
10739 ELSE IF(metsol == 7) THEN
10740 CALL mdptrf ! LAPACK (packed storage)
10741 ELSE IF(metsol == 8) THEN
10742 CALL mdutrf ! LAPACK (unpacked storage)
10743#ifdef PARDISO
10744 ELSE IF(metsol == 9) THEN
10745 CALL mspardiso ! Intel oneMKL PARDISO (sparse matrix (CSR3, upper triangle))
10746#endif
10747#endif
10748 END IF
10749 nloopsol=nloopn ! (new) solution for this nloopn
10750
10751 ! check feasibility and evtl. make step vector feasible
10752
10753 DO i=1,nvgb
10754 itgbi=globalparvartototal(i)
10755 globalparcopy(itgbi)=globalparameter(itgbi) ! save
10756 globalparameter(itgbi)=globalparameter(itgbi)+globalcorrections(i) ! update
10757 END DO
10758 CALL feasib(concut,iact) ! improve constraints
10759 concut=concu2 ! new cut for constraint check
10760 DO i=1,nvgb
10761 itgbi=globalparvartototal(i)
10762 globalcorrections(i)=globalparameter(itgbi)-globalparcopy(itgbi) ! feasible stp
10763 globalparameter(itgbi)=globalparcopy(itgbi) ! restore
10764 END DO
10765
10768 db2=dbdot(nvgb,globalvector,globalvector)
10769 delfun=real(db,mps)
10770 angras=real(db/sqrt(db1*db2),mps)
10771 dbsig=16.0_mpd*sqrt(max(db1,db2))*epsilon(db) ! significant change
10772
10773 ! do line search for this iteration/solution ?
10774 ! lsearch >2: all, =2: all with (next) chicut =1., =1: last, <1: none
10775 lsflag=(lsearch > 2 .OR. (lsearch == 2 .AND. chicut < 2.25) .OR. &
10776 (lsearch == 1 .AND. chicut < 2.25 .AND. (delfun <= dflim .OR. iterat >= mitera)))
10777 lsflag=lsflag .AND. (db > dbsig) ! require significant change
10778 IF (lsflag) THEN
10779 ! initialize line search based on slopes and prepare next
10780 CALL ptldef(wolfc2, 10.0, minf,10)
10781 IF(metsol == 1) THEN
10782 wolfc2=0.5 ! not accurate
10783 minf=3
10784 ELSE IF(metsol == 2) THEN
10785 wolfc2=0.5 ! not acurate
10786 minf=3
10787 ELSE IF(metsol == 3) THEN
10788 wolfc2=0.5 ! not acurate
10789 minf=3
10790 ELSE IF(metsol == 4) THEN
10791 wolfc2=0.1 ! accurate
10792 minf=4
10793 ELSE IF(metsol == 5) THEN
10794 wolfc2=0.1 ! accurate
10795 minf=4
10796 ELSE IF(metsol == 6) THEN
10797 wolfc2=0.1 ! accurate
10798 minf=4
10799 ELSE
10800 wolfc2=0.5 ! not accurate
10801 minf=3
10802 END IF
10803 ENDIF
10804
10805 ! change significantly negative ?
10806 IF(db <= -dbsig) THEN
10807 WRITE(*,*) 'Function not decreasing:',db
10808 IF(db > -1.0e-3_mpd) THEN ! 100311, VB/CK: allow some margin for numerics
10809 iagain=iagain+1
10810 IF (iagain <= 1) THEN
10811 WRITE(*,*) '... again matrix calculation'
10812 icalcm=1
10813 cycle
10814 ELSE
10815 WRITE(*,*) '... aborting iterations'
10816 GO TO 90
10817 END IF
10818 ELSE
10819 WRITE(*,*) '... stopping iterations'
10820 iagain=-1
10821 GO TO 90
10822 END IF
10823 ELSE
10824 iagain=0
10825 END IF
10826 icalcm=0 ! switch
10827 ENDIF
10828 ! Block 3: line searching ------------------------------------------
10829
10830 IF(icalcm+2 == 0) EXIT
10831 IF (lsflag) THEN
10832 CALL ptline(nvgb,workspacelinesearch, & ! current parameter values
10833 flines, & ! chi^2 function value
10834 globalvector, & ! gradient
10835 globalcorrections, & ! step vector stp
10836 stp, & ! returned step factor
10837 info) ! returned information
10838 ! WRITE(*,*) 'PTLINE returns INFO, STP=',INFO, STP
10839 ELSE ! skip line search
10840 info=10
10841 stepl=1.0
10842 IF (nloopn == nloopsol) THEN ! new solution: update corrections
10844 ENDIF
10845 ENDIF
10846 lsinfo=info
10847
10848 stepl=real(stp,mps)
10849 nan=0
10850 DO i=1,nvgb
10851 itgbi=globalparvartototal(i)
10852 IF ((.NOT.(workspacelinesearch(i) <= 0.0_mpd)).AND. &
10853 (.NOT.(workspacelinesearch(i) > 0.0_mpd))) nan=nan+1
10854 globalparameter(itgbi)=workspacelinesearch(i) ! current parameter values
10855 END DO
10856
10857 IF (nan > 0) THEN
10858 WRITE(*,*) 'Result vector containes ', nan,' NaNs - stop'
10859 CALL peend(25,'Aborted, result vector contains NaNs')
10860 stop
10861 END IF
10862
10863 ! subito exit, if required -----------------------------------------
10864
10865 IF(isubit /= 0) THEN ! subito
10866 WRITE(*,*) 'Subito! Exit after first step.'
10867 GO TO 90
10868 END IF
10869
10870 IF(info == 0) THEN
10871 WRITE(*,*) 'INFO=0 should not happen (line search input err)'
10872 IF (iagain <= 0) THEN
10873 icalcm=1
10874 cycle
10875 ENDIF
10876 END IF
10877 IF(info < 0 .OR. nloopn == nloopsol) cycle
10878 ! Block 4: line search convergence ---------------------------------
10879
10880 CALL ptlprt(lunlog)
10881 CALL feasib(concut,iact) ! check constraints
10882 IF(iact /= 0.OR.chicut > 1.0) THEN
10883 icalcm=-1
10884 IF(iterat < matrit) icalcm=+1
10885 cycle ! iterate
10886 END IF
10887 IF(delfun <= dflim) GO TO 90 ! convergence
10888 IF(iterat >= mitera) GO TO 90 ! ending
10889 icalcm=-1
10890 IF(iterat < matrit) icalcm=+1
10891 cycle ! next iteration
10892
10893 ! Block 5: iteration ending ----------------------------------------
10894
1089590 icalcm=-2
10896 END DO
10897 IF(sum(nrejec) /= 0) THEN
10898 WRITE(*,*) ' '
10899 WRITE(*,*) 'Data records rejected in last loop: '
10900 CALL prtrej(6)
10901 END IF
10902
10903 ! monitoring of residuals
10904 IF (imonit > 0 .AND. btest(imonit,1)) CALL monres
10905 IF (lunmon > 0) CLOSE(unit=lunmon)
10906
10907 ! construct inverse from diagonalization
10908 IF(metsol == 2) CALL zdiags
10909
10910 IF(ALLOCATED(workspacediag)) THEN ! provide parameter errors?
10911#ifdef LAPACK64
10912 IF (metsol == 7.OR.metsol == 8) THEN
10913 ! inverse from factorization
10914 ! loop over blocks (multiple blocks only with elimination !)
10915 DO ib=1,npblck
10916 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10917 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10918 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10919 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10920 imoff=globalrowoffsets(ipoff+1)+ipoff ! block offset in global matrix
10921 nfit=npar+ncon; IF (icelim > 0) nfit=npar-ncon ! number of fit parameters in block
10922 IF (nfit > npar) THEN
10923 ! monitor progress
10924 IF(monpg1 > 0) THEN
10925 WRITE(lunlog,*) 'Inverse of global matrix from LDLt factorization'
10927 END IF
10928 IF (matsto == 1) THEN
10929 !$POMP INST BEGIN(dsptri)
10930#ifdef SCOREP_USER_ENABLE
10931 scorep_user_region_by_name_begin("UR_dsptri", scorep_user_region_type_common)
10932#endif
10933 CALL dsptri('U',int(nfit,mpl),globalmatd(imoff+1:),lapackipiv(ipoff+1:),workspaced,infolp)
10934 IF(infolp /= 0) print *, ' DSPTRI failed: ', infolp
10935#ifdef SCOREP_USER_ENABLE
10936 scorep_user_region_by_name_end("UR_dsptri")
10937#endif
10938 !$POMP INST END(dsptri)
10939 IF(monpg1 > 0) CALL monend()
10940 ELSE
10941 !$POMP INST BEGIN(dsytri)
10942#ifdef SCOREP_USER_ENABLE
10943 scorep_user_region_by_name_begin("UR_dsytri", scorep_user_region_type_common)
10944#endif
10945 CALL dsytri('U',int(nfit,mpl),globalmatd(imoff+1:),int(nfit,mpl),&
10946 lapackipiv(ipoff+1:),workspaced,infolp)
10947 IF(infolp /= 0) print *, ' DSYTRI failed: ', infolp
10948#ifdef SCOREP_USER_ENABLE
10949 scorep_user_region_by_name_end("UR_dsytri")
10950#endif
10951 !$POMP INST END(dsytri)
10952 IF(monpg1 > 0) CALL monend()
10953 END IF
10954 ELSE
10955 IF(monpg1 > 0) THEN
10956 WRITE(lunlog,*) 'Inverse of global matrix from LLt factorization'
10958 END IF
10959 IF (matsto == 1) THEN
10960 !$POMP INST BEGIN(dpptri)
10961#ifdef SCOREP_USER_ENABLE
10962 scorep_user_region_by_name_begin("UR_dpptri", scorep_user_region_type_common)
10963#endif
10964 CALL dpptri('U',int(nfit,mpl),globalmatd(imoff+1:),infolp)
10965 IF(infolp /= 0) print *, ' DPPTRI failed: ', infolp
10966#ifdef SCOREP_USER_ENABLE
10967 scorep_user_region_by_name_end("UR_dpptri")
10968#endif
10969 !$POMP INST END(dpptri)
10970 ELSE
10971 !$POMP INST BEGIN(dpotri)
10972#ifdef SCOREP_USER_ENABLE
10973 scorep_user_region_by_name_begin("UR_dpotri", scorep_user_region_type_common)
10974#endif
10975 CALL dpotri('U',int(nfit,mpl),globalmatd(imoff+1:),int(npar,mpl),infolp)
10976 IF(infolp /= 0) print *, ' DPOTRI failed: ', infolp
10977#ifdef SCOREP_USER_ENABLE
10978 scorep_user_region_by_name_end("UR_dpotri")
10979#endif
10980 !$POMP INST END(dpotri)
10981 END IF
10982 IF(monpg1 > 0) CALL monend()
10983 END IF
10984 END DO
10985 END IF
10986#endif
10987 !use elimination for constraints ?
10988 IF(nfgb < nvgb) THEN
10989 ! extend, transform matrix
10990 ! loop over blocks
10991 DO ib=1,npblck
10992 ipoff=matparblockoffsets(1,ib) ! parameter offset for block
10993 npar=matparblockoffsets(1,ib+1)-ipoff ! number of parameters in block
10994 icoff=vecparblockconoffsets(ib) ! constraint offset for block
10995 ncon=vecparblockconoffsets(ib+1)-icoff ! number of constraints in block
10996 DO i=npar-ncon+1,npar
10997 ioff=globalrowoffsets(i+ipoff)+ipoff
10998 globalmatd(ioff+1:ioff+i)=0.0_mpd
10999 END DO
11000 END DO
11001 ! monitor progress
11002 IF(monpg1 > 0) THEN
11003 WRITE(lunlog,*) 'Expansion of global matrix (A->Q*A*Q^t)'
11005 END IF
11006 IF(icelim < 2) THEN
11007 CALL qlssq(avprds,globalmatd,size(globalmatd,kind=mpl),globalrowoffsets,.false.) ! Q*A*Q^t
11008#ifdef LAPACK64
11009 ELSE ! unpack storage, use LAPACK
11010 CALL lpavat(.false.)
11011#endif
11012 END IF
11013 IF(monpg1 > 0) CALL monend()
11014 END IF
11015 END IF
11016
11017 dwmean=sumndf/real(ndfsum,mpd)
11018 dratio=fvalue/dwmean/real(ndfsum-nfgb,mpd)
11019 catio=real(dratio,mps)
11020 IF(nloopn /= 1.AND.lhuber /= 0) THEN
11021 catio=catio/0.9326 ! correction Huber downweighting (in global chi2)
11022 END IF
11023 mrati=nint(100.0*catio,mpi)
11024
11025 DO lunp=6,lunlog,lunlog-6
11026 WRITE(lunp,*) ' '
11027 IF (nfilw <= 0) THEN
11028 WRITE(lunp,*) 'Sum(Chi^2)/Sum(Ndf) =',fvalue
11029 WRITE(lunp,*) ' / (',ndfsum,'-',nfgb,')'
11030 WRITE(lunp,*) ' =',dratio
11031 ELSE
11032 WRITE(lunp,*) 'Sum(W*Chi^2)/Sum(Ndf)/<W> =',fvalue
11033 WRITE(lunp,*) ' / (',ndfsum,'-', nfgb,')'
11034 WRITE(lunp,*) ' /',dwmean
11035 WRITE(lunp,*) ' =',dratio
11036 END IF
11037 WRITE(lunp,*) ' '
11038 IF(nloopn /= 1.AND.lhuber /= 0) WRITE(lunp,*) &
11039 ' with correction for down-weighting ',catio
11040 END DO
11041 nrej=sum(nrejec) ! total number of rejects
11042
11043 ! ... the end with exit code ???????????????????????????????????????
11044
11045 ! WRITE(*,199) ! write exit code
11046 ! + '-----------------------------------------------------------'
11047 ! IF(ITEXIT.EQ.0) WRITE(*,199)
11048 ! + 'Exit code = 0: Convergence reached'
11049 ! IF(ITEXIT.EQ.1) WRITE(*,199)
11050 ! + 'Exit code = 1: No improvement in last iteration'
11051 ! IF(ITEXIT.EQ.2) WRITE(*,199)
11052 ! + 'Exit code = 2: Maximum number of iterations reached'
11053 ! IF(ITEXIT.EQ.3) WRITE(*,199)
11054 ! + 'Exit code = 3: Failure'
11055 ! WRITE(*,199)
11056 ! + '-----------------------------------------------------------'
11057 ! WRITE(*,199) ' '
11058
11059
11060 nrati=nint(10000.0*real(nrej,mps)/real(nrecal,mps),mpi)
11061 WRITE(crjrat,197) 0.01_mpd*real(nrati,mpd)
11062 nfaci=nint(100.0*sqrt(catio),mpi)
11063
11064 WRITE(cratio,197) 0.01_mpd*real(mrati,mpd)
11065 WRITE(cfacin,197) 0.01_mpd*real(nfaci,mpd)
11066
11067 warner=.false. ! warnings
11068 IF(mrati < 90.OR.mrati > 110) warner=.true.
11069 IF(nrati > 100) warner=.true.
11070 IF(ncgbe /= 0) warner=.true.
11071 warners = .false. ! severe warnings
11072 IF(nalow /= 0) warners=.true.
11073 warnerss = .false. ! more severe warnings
11074 IF(nmiss1 /= 0) warnerss=.true.
11075 IF(iagain /= 0) warnerss=.true.
11076 IF(ndefec /= 0) warnerss=.true.
11077 IF(ndefpg /= 0) warnerss=.true.
11078 warners3 = .false. ! more severe warnings
11079 IF(nrderr /= 0) warners3=.true.
11080
11081 IF(warner.OR.warners.OR.warnerss.Or.warners3) THEN
11082 WRITE(*,199) ' '
11083 WRITE(*,199) ' '
11084 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
11085 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
11086 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
11087 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
11088 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
11089 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
11090 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
11091
11092 IF(mrati < 90.OR.mrati > 110) THEN
11093 WRITE(*,199) ' '
11094 WRITE(*,*) ' Chi^2/Ndf = ',cratio, ' (should be close to 1)'
11095 WRITE(*,*) ' => multiply all input standard ', &
11096 'deviations by factor',cfacin
11097 END IF
11098
11099 IF(nrati > 100) THEN
11100 WRITE(*,199) ' '
11101 WRITE(*,*) ' Fraction of rejects =',crjrat,' %', &
11102 ' (should be far below 1 %)'
11103 WRITE(*,*) ' => please provide correct mille data'
11104 CALL chkrej ! check (and print) rejection details
11105 END IF
11106
11107 IF(iagain /= 0) THEN
11108 WRITE(*,199) ' '
11109 WRITE(*,*) ' Matrix not positiv definite '// &
11110 '(function not decreasing)'
11111 WRITE(*,*) ' => please provide correct mille data'
11112 END IF
11113
11114 IF(ndefec /= 0) THEN
11115 WRITE(*,199) ' '
11116 WRITE(*,*) ' Rank defect =',ndefec, &
11117 ' for global matrix, should be 0'
11118 WRITE(*,*) ' => please provide correct mille data'
11119 END IF
11120
11121 IF(ndefpg /= 0) THEN
11122 WRITE(*,199) ' '
11123 WRITE(*,*) ' Rank defect for',ndefpg, &
11124 ' parameter groups, should be 0'
11125 WRITE(*,*) ' => please provide correct mille data'
11126 END IF
11127
11128 IF(nmiss1 /= 0) THEN
11129 WRITE(*,199) ' '
11130 WRITE(*,*) ' Rank defect =',nmiss1, &
11131 ' for constraint equations, should be 0'
11132 WRITE(*,*) ' => please correct constraint definition'
11133 END IF
11134
11135 IF(ncgbe /= 0) THEN
11136 WRITE(*,199) ' '
11137 WRITE(*,*) ' Number of empty constraints =',ncgbe, ', should be 0'
11138 WRITE(*,*) ' => please check constraint definition, mille data'
11139 END IF
11140
11141 IF(nxlow /= 0) THEN
11142 WRITE(*,199) ' '
11143 WRITE(*,*) ' Possible rank defects =',nxlow, ' for global matrix'
11144 WRITE(*,*) ' (too few accepted entries)'
11145 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11146 END IF
11147
11148 IF(nalow /= 0) THEN
11149 WRITE(*,199) ' '
11150 WRITE(*,*) ' Possible bad elements =',nalow, ' in global vector'
11151 WRITE(*,*) ' (toos few accepted entries)'
11152 IF(ipcntr > 0) WRITE(*,*) ' (indicated in millepede.res by counts<0)'
11153 WRITE(*,*) ' => please check mille data and ENTRIES cut'
11154 END IF
11155
11156 IF(nrderr /= 0) THEN
11157 WRITE(*,199) ' '
11158 WRITE(*,*) ' Binary file(s) with read errors =',nrderr, ' (treated as EOF)'
11159 WRITE(*,*) ' => please check mille data'
11160 END IF
11161
11162 WRITE(*,199) ' '
11163 WRITE(*,199) 'WarningWarningWarningWarningWarningWarningWarningWarningWar'
11164 WRITE(*,199) 'arningWarningWarningWarningWarningWarningWarningWarningWarn'
11165 WRITE(*,199) 'rningWarningWarningWarningWarningWarningWarningWarningWarni'
11166 WRITE(*,199) 'ningWarningWarningWarningWarningWarningWarningWarningWarnin'
11167 WRITE(*,199) 'ingWarningWarningWarningWarningWarningWarningWarningWarning'
11168 WRITE(*,199) 'ngWarningWarningWarningWarningWarningWarningWarningWarningW'
11169 WRITE(*,199) 'gWarningWarningWarningWarningWarningWarningWarningWarningWa'
11170 WRITE(*,199) ' '
11171
11172 ENDIF
11173
11174 CALL mend ! modul ending
11175
11176 ! ------------------------------------------------------------------
11177
11178 IF(metsol == 1) THEN
11179
11180 ELSE IF(metsol == 2) THEN
11181 ! CALL zdiags moved up (before qlssq)
11182 ELSE IF(metsol == 3) THEN
11183 ! decomposition - nothing foreseen yet
11184 ELSE IF(metsol == 4 .OR. metsol == 5) THEN
11185 ! errors and correlations from MINRES
11186 DO k=1,mnrsel
11187 labelg=lbmnrs(k)
11188 IF(labelg == 0) cycle
11189 itgbi=inone(labelg)
11190 ivgbi=0
11191 IF(itgbi /= 0) ivgbi=globalparlabelindex(2,itgbi)
11192 IF(ivgbi < 0) ivgbi=0
11193 IF(ivgbi == 0) cycle
11194 ! determine error and global correlation for parameter IVGBI
11195 IF (metsol == 4) THEN
11196 CALL solglo(ivgbi)
11197 ELSE
11198 CALL solgloqlp(ivgbi)
11199 ENDIF
11200 END DO
11201
11202 ELSE IF(metsol == 6) THEN
11203
11204#ifdef LAPACK64
11205 ELSE IF(metsol == 7) THEN
11206 ! LAPACK - nothing foreseen yet
11207#endif
11208 END IF
11209
11210 CALL prtglo ! print result
11211
11212 IF (warners3) THEN
11213 CALL peend(4,'Ended with severe warnings (bad binary file(s))')
11214 ELSE IF (warnerss) THEN
11215 CALL peend(3,'Ended with severe warnings (bad global matrix)')
11216 ELSE IF (warners) THEN
11217 CALL peend(2,'Ended with severe warnings (insufficient measurements)')
11218 ELSE IF (warner) THEN
11219 CALL peend(1,'Ended with warnings (bad measurements)')
11220 ELSE
11221 CALL peend(0,'Ended normally')
11222 END IF
11223
11224102 FORMAT(' Call FEASIB with cut=',g10.3)
11225 ! 103 FORMAT(1X,A,G12.4)
11226197 FORMAT(f7.2)
11227199 FORMAT(7x,a)
11228END SUBROUTINE xloopn ! standard solution
11229
11230
11235
11236SUBROUTINE chkrej
11237 USE mpmod
11238 USE mpdalc
11239
11240 IMPLICIT NONE
11241 INTEGER(mpi) :: i
11242 INTEGER(mpi) :: kfl
11243 INTEGER(mpi) :: kmin
11244 INTEGER(mpi) :: kmax
11245 INTEGER(mpi) :: nrc
11246 INTEGER(mpl) :: nrej
11247
11248 REAL(mps) :: fmax
11249 REAL(mps) :: fmin
11250 REAL(mps) :: frac
11251
11252 REAL(mpd) :: sumallw
11253 REAL(mpd) :: sumrejw
11254
11255 sumallw=0.; sumrejw=0.;
11256 kmin=0; kmax=0;
11257 fmax=-1.; fmin=2;
11258
11259 DO i=1,nfilb
11260 kfl=kfd(2,i)
11261 nrc=-kfd(1,i)
11262 IF (nrc > 0) THEN
11263 nrej=nrc-jfd(kfl)
11264 sumallw=sumallw+real(nrc,mpd)*wfd(kfl)
11265 sumrejw=sumrejw+real(nrej,mpd)*wfd(kfl)
11266 frac=real(nrej,mps)/real(nrc,mps)
11267 IF (frac > fmax) THEN
11268 kmax=kfl
11269 fmax=frac
11270 END IF
11271 IF (frac < fmin) THEN
11272 kmin=kfl
11273 fmin=frac
11274 END IF
11275 END IF
11276 END DO
11277 IF (nfilw > 0) &
11278 WRITE(*,"(' Weighted fraction =',F8.2,' %')") 100.*sumrejw/sumallw
11279 IF (nfilb > 1) THEN
11280 WRITE(*,"(' File with max. fraction ',I6,' :',F8.2,' %')") kmax, 100.*fmax
11281 WRITE(*,"(' File with min. fraction ',I6,' :',F8.2,' %')") kmin, 100.*fmin
11282 END IF
11283
11284END SUBROUTINE chkrej
11285
11299
11300SUBROUTINE filetc
11301 USE mpmod
11302 USE mpdalc
11303
11304 IMPLICIT NONE
11305 INTEGER(mpi) :: i
11306 INTEGER(mpi) :: ia
11307 INTEGER(mpi) :: iargc
11308 INTEGER(mpi) :: ib
11309 INTEGER(mpi) :: ie
11310 INTEGER(mpi) :: ierrf
11311 INTEGER(mpi) :: ieq
11312 INTEGER(mpi) :: ifilb
11313 INTEGER(mpi) :: ioff
11314 INTEGER(mpi) :: iopt
11315 INTEGER(mpi) :: ios
11316 INTEGER(mpi) :: iosum
11317 INTEGER(mpi) :: it
11318 INTEGER(mpi) :: k
11319 INTEGER(mpi) :: mat
11320 INTEGER(mpi) :: nab
11321 INTEGER(mpi) :: nline
11322 INTEGER(mpi) :: npat
11323 INTEGER(mpi) :: ntext
11324 INTEGER(mpi) :: nu
11325 INTEGER(mpi) :: nuf
11326 INTEGER(mpi) :: nums
11327 INTEGER(mpi) :: nufile
11328 INTEGER(mpi) :: lenfileInfo
11329 INTEGER(mpi) :: lenFileNames
11330 INTEGER(mpi) :: matint
11331 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: vecfileInfo
11332 INTEGER(mpi), DIMENSION(:,:), ALLOCATABLE :: tempArray
11333 INTEGER(mpl) :: rows
11334 INTEGER(mpl) :: cols
11335 INTEGER(mpl) :: newcols
11336 INTEGER(mpl) :: length
11337
11338 CHARACTER (LEN=1024) :: text
11339 CHARACTER (LEN=1024) :: fname
11340 CHARACTER (LEN=14) :: bite(3)
11341 CHARACTER (LEN=32) :: keystx
11342 INTEGER(mpi), PARAMETER :: mnum=100
11343 REAL(mpd) :: dnum(mnum)
11344
11345#ifdef READ_C_FILES
11346 INTERFACE
11347 SUBROUTINE initc(nfiles) BIND(c)
11348 USE iso_c_binding
11349 INTEGER(c_int), INTENT(IN), VALUE :: nfiles
11350 END SUBROUTINE initc
11351 END INTERFACE
11352#endif
11353
11354 SAVE
11355 DATA bite/'C_binary','text ','Fortran_binary'/
11356 ! ...
11357 CALL mstart('FILETC/X')
11358
11359 nuf=1 ! C binary is default
11360 DO i=1,8
11361 times(i)=0.0
11362 END DO
11363
11364 ! read command line options ----------------------------------------
11365
11366 filnam=' ' ! print command line options and find steering file
11367 DO i=1,iargc()
11368 IF(i == 1) THEN
11369 WRITE(*,*) ' '
11370 WRITE(*,*) 'Command line options: '
11371 WRITE(*,*) '--------------------- '
11372 END IF
11373 CALL getarg(i,text) ! get I.th text from command line
11374 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11375 WRITE(*,101) i,text(1:nab) ! echo print
11376 IF(text(ia:ia) /= '-') THEN
11377 nu=nufile(text(ia:ib)) ! inquire on file existence
11378 IF(nu == 2) THEN ! existing text file
11379 IF(filnam /= ' ') THEN
11380 WRITE(*,*) 'Second text file in command line - stop'
11381 CALL peend(12,'Aborted, second text file in command line')
11382 stop
11383 ELSE
11384 filnam=text
11385 END IF
11386 ELSE
11387 WRITE(*,*) 'Open error for file:',text(ia:ib),' - stop'
11388 CALL peend(16,'Aborted, open error for file')
11389 IF(text(ia:ia) /= '/') THEN
11390 CALL getenv('PWD',text)
11391 CALL rltext(text,ia,ib,nab)
11392 WRITE(*,*) 'PWD:',text(ia:ib)
11393 END IF
11394 stop
11395 END IF
11396 ELSE
11397 IF(index(text(ia:ib),'b') /= 0) THEN
11398 mdebug=3 ! debug flag
11399 WRITE(*,*) 'Debugging requested'
11400 END IF
11401 it=index(text(ia:ib),'t')
11402 IF(it /= 0) THEN
11403 ictest=1 ! internal test files
11404 ieq=index(text(ia+it:ib),'=')+it
11405 IF (it /= ieq) THEN
11406 IF (index(text(ia+ieq:ib),'SL0' ) /= 0) ictest=2
11407 IF (index(text(ia+ieq:ib),'SLE' ) /= 0) ictest=3
11408 IF (index(text(ia+ieq:ib),'BP' ) /= 0) ictest=4
11409 IF (index(text(ia+ieq:ib),'BRLF') /= 0) ictest=5
11410 IF (index(text(ia+ieq:ib),'BRLC') /= 0) ictest=6
11411 END IF
11412 END IF
11413 IF(index(text(ia:ib),'s') /= 0) isubit=1 ! like "subito"
11414 IF(index(text(ia:ib),'f') /= 0) iforce=1 ! like "force"
11415 IF(index(text(ia:ib),'c') /= 0) icheck=1 ! like "checkinput"
11416 IF(index(text(ia:ib),'C') /= 0) icheck=2 ! like "checkinput 2"
11417 END IF
11418 IF(i == iargc()) WRITE(*,*) '--------------------- '
11419 END DO
11420
11421
11422 ! create test files for option -t ----------------------------------
11423
11424 IF(ictest >= 1) THEN
11425 WRITE(*,*) ' '
11426 IF (ictest == 1) THEN
11427 CALL mptest ! 'wire chamber'
11428 ELSE
11429 CALL mptst2(ictest-2) ! 'silicon tracker'
11430 END IF
11431 IF(filnam == ' ') filnam='mp2str.txt'
11432 WRITE(*,*) ' '
11433 END IF
11434
11435 ! check default steering file with file-name "steerfile" -----------
11436
11437 IF(filnam == ' ') THEN ! check default steering file
11438 text='steerfile'
11439 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11440 nu=nufile(text(ia:ib)) ! inquire on file existence and type
11441 IF(nu > 0) THEN
11442 filnam=text
11443 ELSE
11444 CALL peend(10,'Aborted, no steering file')
11445 stop 'in FILETC: no steering file. .'
11446 END IF
11447 END IF
11448
11449
11450 ! open, read steering file:
11451 ! end
11452 ! fortranfiles
11453 ! cfiles
11454
11455
11456 CALL rltext(filnam,ia,ib,nfnam) ! return indices for non-blank area
11457 WRITE(*,*) ' '
11458 WRITE(*,*) 'Listing of steering file: ',filnam(1:nfnam)
11459 WRITE(*,*) '-------------------------'
11460 OPEN(10,file=filnam(1:nfnam),iostat=ios)
11461 IF(ios /= 0) THEN
11462 WRITE(*,*) 'Open error for steering file - stop'
11463 CALL peend(11,'Aborted, open error for steering file')
11464 IF(filnam(1:1) /= '/') THEN
11465 CALL getenv('PWD',text)
11466 CALL rltext(text,ia,ib,nab)
11467 WRITE(*,*) 'PWD:',text(ia:ib)
11468 END IF
11469 stop
11470 END IF
11471 ifile =0
11472 nfiles=0
11473
11474 lenfileinfo=2
11475 lenfilenames=0
11476 rows=6; cols=lenfileinfo
11477 CALL mpalloc(vecfileinfo,rows,cols,'file info from steering')
11478 nline=0
11479 DO
11480 READ(10,102,iostat=ierrf) text ! read steering file
11481 IF (ierrf < 0) EXIT ! eof
11482 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
11483 nline=nline+1
11484 IF(nline <= 50) THEN ! print up to 50 lines
11485 WRITE(*,101) nline,text(1:nab)
11486 IF(nline == 50) WRITE(*,*) ' ...'
11487 END IF
11488 IF(ia == 0) cycle ! skip empty lines
11489
11490 CALL rltext(text,ia,ib,nab) ! test content 'end'
11491 IF(ib == ia+2) THEN
11492 mat=matint(text(ia:ib),'end',npat,ntext)
11493 IF(mat == max(npat,ntext)) THEN ! exact matching
11494 text=' '
11495 CALL intext(text,nline)
11496 WRITE(*,*) ' end-statement after',nline,' text lines'
11497 EXIT
11498 END IF
11499 END IF
11500
11501 keystx='fortranfiles'
11502 mat=matint(text(ia:ib),keystx,npat,ntext)
11503 IF(mat == max(npat,ntext)) THEN ! exact matching
11504 nuf=3
11505 ! WRITE(*,*) 'Fortran files'
11506 cycle
11507 END IF
11508
11509 keystx='Cfiles'
11510 mat=matint(text(ia:ib),keystx,npat,ntext)
11511 IF(mat == max(npat,ntext)) THEN ! exact matching
11512 nuf=1
11513 ! WRITE(*,*) 'Cfiles'
11514 cycle
11515 END IF
11516
11517 keystx='closeandreopen' ! don't keep binary files open
11518 mat=matint(text(ia:ib),keystx,npat,ntext)
11519 IF(mat == max(npat,ntext)) THEN ! exact matching
11520 keepopen=0
11521 cycle
11522 END IF
11523
11524 ! file names
11525 ! check for file options (' -- ')
11526 ie=ib
11527 iopt=index(text(ia:ib),' -- ')
11528 IF (iopt > 0) ie=iopt-1
11529
11530 IF(nab == 0) cycle
11531 nu=nufile(text(ia:ie)) ! inquire on file existence
11532 IF(nu > 0) THEN ! existing file
11533 IF (nfiles == lenfileinfo) THEN ! increase length
11534 CALL mpalloc(temparray,rows,cols,'temp file info from steering')
11535 temparray=vecfileinfo
11536 CALL mpdealloc(vecfileinfo)
11537 lenfileinfo=lenfileinfo*2
11538 newcols=lenfileinfo
11539 CALL mpalloc(vecfileinfo,rows,newcols,'file info from steering')
11540 vecfileinfo(:,1:cols)=temparray(:,1:cols)
11541 CALL mpdealloc(temparray)
11542 cols=newcols
11543 ENDIF
11544 nfiles=nfiles+1 ! count number of files
11545 IF(nu == 1) nu=nuf !
11546 lenfilenames=lenfilenames+ie-ia+1 ! total length of file names
11547 vecfileinfo(1,nfiles)=nline ! line number
11548 vecfileinfo(2,nfiles)=nu ! cbinary =1, text =2, fbinary=3
11549 vecfileinfo(3,nfiles)=ia ! file name start
11550 vecfileinfo(4,nfiles)=ie ! file name end
11551 vecfileinfo(5,nfiles)=iopt ! option start
11552 vecfileinfo(6,nfiles)=ib ! option end
11553 ELSE
11554 ! WRITE(*,*) 'Open error for file ',TEXT(IA:IB)
11555 ! STOP
11556 END IF
11557 END DO
11558 rewind 10
11559 ! read again to fill dynamic arrays with file info
11560 length=nfiles
11561 CALL mpalloc(mfd,length,'file type')
11562 CALL mpalloc(nfd,length,'file line (in steering)')
11563 CALL mpalloc(lfd,length,'file name length')
11564 CALL mpalloc(ofd,length,'file option')
11565 length=lenfilenames
11566 CALL mpalloc(tfd,length,'file name')
11567 nline=0
11568 i=1
11569 ioff=0
11570 DO
11571 READ(10,102,iostat=ierrf) text ! read steering file
11572 IF (ierrf < 0) EXIT ! eof
11573 nline=nline+1
11574 IF (nline == vecfileinfo(1,i)) THEN
11575 nfd(i)=vecfileinfo(1,i)
11576 mfd(i)=vecfileinfo(2,i)
11577 ia=vecfileinfo(3,i)-1
11578 lfd(i)=vecfileinfo(4,i)-ia ! length file name
11579 DO k=1,lfd(i)
11580 tfd(ioff+k)=text(ia+k:ia+k)
11581 END DO
11582 ! tfd(i)=text(vecFileInfo(3,i):vecFileInfo(4,i)) ! file name
11583 ioff=ioff+lfd(i)
11584 ofd(i)=1.0 ! option for file
11585 IF (vecfileinfo(5,i) > 0) THEN
11586 CALL ratext(text(vecfileinfo(5,i)+4:vecfileinfo(6,i)),nums,dnum,mnum) ! translate text to DP numbers
11587 IF (nums > 0) ofd(i)=real(dnum(1),mps)
11588 END IF
11589 i=i+1
11590 IF (i > nfiles) EXIT
11591 ENDIF
11592 ENDDO
11593 CALL mpdealloc(vecfileinfo)
11594 rewind 10
11595 ! additional info for binary files
11596 length=nfiles; rows=2
11597 CALL mpalloc(ifd,length,'integrated record numbers (=offset)')
11598 CALL mpalloc(jfd,length,'number of accepted records')
11599 CALL mpalloc(kfd,rows,length,'number of records in file, file order')
11600 CALL mpalloc(dfd,length,'ndf sum')
11601 CALL mpalloc(xfd,length,'max. record size')
11602 CALL mpalloc(wfd,length,'file weight')
11603 CALL mpalloc(cfd,length,'chi2 sum')
11604 CALL mpalloc(sfd,rows,length,'start, end of file name in TFD')
11605 CALL mpalloc(yfd,length,'modification date')
11606 yfd=0
11607 !
11608 WRITE(*,*) '-------------------------'
11609 WRITE(*,*) ' '
11610
11611 ! print table of files ---------------------------------------------
11612
11613 IF (mprint > 1) THEN
11614 WRITE(*,*) 'Table of files:'
11615 WRITE(*,*) '---------------'
11616 END IF
11617 WRITE(8,*) ' '
11618 WRITE(8,*) 'Text and data files:'
11619 ioff=0
11620 DO i=1,nfiles
11621 DO k=1,lfd(i)
11622 fname(k:k)=tfd(ioff+k)
11623 END DO
11624 ! fname=tfd(i)(1:lfd(i))
11625 IF (mprint > 1) WRITE(*,103) i,bite(mfd(i)),fname(1:lfd(i))
11626 WRITE(8,103) i,bite(mfd(i)),fname(1:lfd(i))
11627 ioff=ioff+lfd(i)
11628 END DO
11629 IF (mprint > 1) THEN
11630 WRITE(*,*) '---------------'
11631 WRITE(*,*) ' '
11632 END IF
11633
11634 ! open the binary Fortran (data) files on unit 11, 12, ...
11635
11636 iosum=0
11637 nfilf=0
11638 nfilb=0
11639 nfilw=0
11640 ioff=0
11641 ifilb=0
11642 IF (keepopen < 1) ifilb=1
11643 DO i=1,nfiles
11644 IF(mfd(i) == 3) THEN
11645 nfilf=nfilf+1
11646 nfilb=nfilb+1
11647 ! next file name
11648 sfd(1,nfilb)=ioff
11649 sfd(2,nfilb)=lfd(i)
11650 CALL binopn(nfilb,ifilb,ios)
11651 IF(ios == 0) THEN
11652 wfd(nfilb)=ofd(i)
11653 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11654 ELSE ! failure
11655 iosum=iosum+1
11656 nfilf=nfilf-1
11657 nfilb=nfilb-1
11658 END IF
11659 END IF
11660 ioff=ioff+lfd(i)
11661 END DO
11662
11663 ! open the binary C files
11664
11665 nfilc=-1
11666 ioff=0
11667 DO i=1,nfiles ! Cfiles
11668 IF(mfd(i) == 1) THEN
11669#ifdef READ_C_FILES
11670 IF(nfilc < 0) THEN ! initialize
11671 CALL initc(max(nfiles,mthrdr)) ! uncommented by GF
11672 nfilc=0
11673 END IF
11674 nfilc=nfilc+1
11675 nfilb=nfilb+1
11676 ! next file name
11677 sfd(1,nfilb)=ioff
11678 sfd(2,nfilb)=lfd(i)
11679 CALL binopn(nfilb,ifilb,ios)
11680 IF(ios == 0) THEN
11681 wfd(nfilb)=ofd(i)
11682 IF (keepopen < 1) CALL bincls(nfilb,ifilb)
11683 ELSE ! failure
11684 iosum=iosum+1
11685 nfilc=nfilc-1
11686 nfilb=nfilb-1
11687 END IF
11688#else
11689 WRITE(*,*) 'Opening of C-files not supported.'
11690 ! GF add
11691 iosum=iosum+1
11692 ! GF add end
11693#endif
11694 END IF
11695 ioff=ioff+lfd(i)
11696 END DO
11697
11698 DO k=1,nfilb
11699 kfd(1,k)=1 ! reset (negated) record counters
11700 kfd(2,k)=k ! set file number
11701 ifd(k)=0 ! reset integrated record numbers
11702 xfd(k)=0 ! reset max record size
11703 END DO
11704
11705 IF(iosum /= 0) THEN
11706 CALL peend(15,'Aborted, open error(s) for binary files')
11707 stop 'FILETC: open error '
11708 END IF
11709 IF(nfilb == 0) THEN
11710 CALL peend(14,'Aborted, no binary files')
11711 stop 'FILETC: no binary files '
11712 END IF
11713 IF (keepopen > 0) THEN
11714 WRITE(*,*) nfilb,' binary files opened' ! corrected by GF
11715 ELSE
11716 WRITE(*,*) nfilb,' binary files opened and closed' ! corrected by GF
11717 END IF
11718101 FORMAT(i3,2x,a)
11719102 FORMAT(a)
11720103 FORMAT(i3,2x,a14,3x,a)
11721 ! CALL mend
11722 RETURN
11723END SUBROUTINE filetc
11724
11775
11776SUBROUTINE filetx ! ---------------------------------------------------
11777 USE mpmod
11778
11779 IMPLICIT NONE
11780 INTEGER(mpi) :: i
11781 INTEGER(mpi) :: ia
11782 INTEGER(mpi) :: ib
11783 INTEGER(mpi) :: ierrf
11784 INTEGER(mpi) :: ioff
11785 INTEGER(mpi) :: ios
11786 INTEGER(mpi) :: iosum
11787 INTEGER(mpi) :: k
11788 INTEGER(mpi) :: mat
11789 INTEGER(mpi) :: nab
11790 INTEGER(mpi) :: nfiln
11791 INTEGER(mpi) :: nline
11792 INTEGER(mpi) :: nlinmx
11793 INTEGER(mpi) :: npat
11794 INTEGER(mpi) :: ntext
11795 INTEGER(mpi) :: matint
11796
11797 ! CALL MSTART('FILETX')
11798
11799 CHARACTER (LEN=1024) :: text
11800 CHARACTER (LEN=1024) :: fname
11801
11802 WRITE(*,*) ' '
11803 WRITE(*,*) 'Processing text files ...'
11804 WRITE(*,*) ' '
11805
11806 iosum=0
11807 ioff=0
11808 DO i=0,nfiles
11809 IF(i == 0) THEN
11810 WRITE(*,*) 'File ',filnam(1:nfnam)
11811 nlinmx=100
11812 ELSE
11813 nlinmx=10
11814 ia=ioff
11815 ioff=ioff+lfd(i)
11816 IF(mfd(i) /= 2) cycle ! exclude binary files
11817 DO k=1,lfd(i)
11818 fname(k:k)=tfd(ia+k)
11819 END DO
11820 WRITE(*,*) 'File ',fname(1:lfd(i))
11821 IF (mprint > 1) WRITE(*,*) ' '
11822 OPEN(10,file=fname(1:lfd(i)),iostat=ios,form='FORMATTED')
11823 IF(ios /= 0) THEN
11824 WRITE(*,*) 'Open error for file ',fname(1:lfd(i))
11825 iosum=iosum+1
11826 cycle
11827 END IF
11828 END IF
11829
11830 nline=0
11831 nfiln=1
11832 ! read text file
11833 DO
11834 READ(10,102,iostat=ierrf) text
11835 IF (ierrf < 0) THEN
11836 text=' '
11837 CALL intext(text,nline)
11838 WRITE(*,*) ' end-of-file after',nline,' text lines'
11839 EXIT ! eof
11840 ENDIF
11841 nline=nline+1
11842 IF(nline <= nlinmx.AND.mprint > 1) THEN ! print first 10 lines of every text fiLE
11843 CALL rltext(text,ia,ib,nab)
11844 nab=max(1,nab)
11845 WRITE(*,101) nline,text(1:nab)
11846 IF(nline == nlinmx) WRITE(*,*) ' ...'
11847 END IF
11848
11849 CALL rltext(text,ia,ib,nab) ! test content 'end'
11850 IF(ib == ia+2) THEN
11851 mat=matint(text(ia:ib),'end',npat,ntext)
11852 IF(mat == max(npat,ntext)) THEN ! exact matching
11853 text=' '
11854 CALL intext(text,nline)
11855 WRITE(*,*) ' end-statement after',nline,' text lines'
11856 EXIT
11857 END IF
11858 END IF
11859
11860 IF(i == 0) THEN ! first text file - exclude lines with file names
11861 IF(nfiln <= nfiles) THEN
11862 IF(nline == nfd(nfiln)) THEN
11863 nfiln=nfiln+1
11864 text=' '
11865 ! WRITE(*,*) 'line is excluded ',TEXT(1:10)
11866 END IF
11867 END IF
11868 END IF
11869 ! WRITE(*,*) TEXT(1:40),' < interprete text'
11870 CALL intext(text,nline) ! interprete text
11871 END DO
11872 WRITE(*,*) ' '
11873 rewind 10
11874 CLOSE(unit=10)
11875 END DO
11876
11877 IF(iosum /= 0) THEN
11878 CALL peend(16,'Aborted, open error(s) for text files')
11879 stop 'FILETX: open error(s) in text files '
11880 END IF
11881
11882 WRITE(*,*) '... end of text file processing.'
11883 WRITE(*,*) ' '
11884
11885 IF(lunkno /= 0) THEN
11886 WRITE(*,*) ' '
11887 WRITE(*,*) lunkno,' unknown keywords in steering files, ', &
11888 'or file non-existing,'
11889 WRITE(*,*) ' see above!'
11890 WRITE(*,*) '------------> stop'
11891 WRITE(*,*) ' '
11892 CALL peend(13,'Aborted, unknown keywords in steering file')
11893 stop
11894 END IF
11895
11896 ! check methods
11897
11898 IF(metsol == 0) THEN ! if undefined
11899 IF(matsto == 0) THEN ! if unpacked symmetric
11900 metsol=8 ! LAPACK
11901 ELSE IF(matsto == 1) THEN ! if full symmetric
11902 metsol=4 ! MINRES
11903 ELSE IF(matsto == 2) THEN ! if sparse
11904 metsol=4 ! MINRES
11905 END IF
11906 ELSE IF(metsol == 1) THEN ! if inversion
11907 matsto=1
11908 ELSE IF(metsol == 2) THEN ! if diagonalization
11909 matsto=1
11910 ELSE IF(metsol == 3) THEN ! if decomposition
11911 matsto=1
11912 ELSE IF(metsol == 4) THEN ! if MINRES
11913 ! MATSTO=2 or 1
11914 ELSE IF(metsol == 5) THEN ! if MINRES-QLP
11915 ! MATSTO=2 or 1
11916 ELSE IF(metsol == 6) THEN ! if GMRES
11917 ! MATSTO=2 or 1
11918#ifdef LAPACK64
11919 ELSE IF(metsol == 7) THEN ! if LAPACK
11920 matsto=1
11921 ELSE IF(metsol == 8) THEN ! if LAPACK
11922 matsto=0
11923#ifdef PARDISO
11924 ELSE IF(metsol == 9) THEN ! if Intel oneMKL PARDISO
11925 matsto=3
11926#endif
11927#endif
11928 ELSE
11929 WRITE(*,*) 'MINRES forced with sparse matrix!'
11930 WRITE(*,*) ' '
11931 WRITE(*,*) 'MINRES forced with sparse matrix!'
11932 WRITE(*,*) ' '
11933 WRITE(*,*) 'MINRES forced with sparse matrix!'
11934 metsol=4 ! forced
11935 matsto=2 ! forced
11936 END IF
11937 IF(matsto > 4) THEN
11938 WRITE(*,*) 'MINRES forced with sparse matrix!'
11939 WRITE(*,*) ' '
11940 WRITE(*,*) 'MINRES forced with sparse matrix!'
11941 WRITE(*,*) ' '
11942 WRITE(*,*) 'MINRES forced with sparse matrix!'
11943 metsol=4 ! forced
11944 matsto=2 ! forced
11945 END IF
11946
11947 ! print information about methods and matrix storage modes
11948
11949 WRITE(*,*) ' '
11950 WRITE(*,*) 'Solution method and matrix-storage mode:'
11951 IF(metsol == 1) THEN
11952 WRITE(*,*) ' METSOL = 1: matrix inversion'
11953 ELSE IF(metsol == 2) THEN
11954 WRITE(*,*) ' METSOL = 2: diagonalization'
11955 ELSE IF(metsol == 3) THEN
11956 WRITE(*,*) ' METSOL = 3: decomposition'
11957 ELSE IF(metsol == 4) THEN
11958 WRITE(*,*) ' METSOL = 4: MINRES'
11959 ELSE IF(metsol == 5) THEN
11960 WRITE(*,*) ' METSOL = 5: MINRES-QLP'
11961 ELSE IF(metsol == 6) THEN
11962 WRITE(*,*) ' METSOL = 6: GMRES (-> MINRES)'
11963#ifdef LAPACK64
11964 ELSE IF(metsol == 7) THEN
11965 WRITE(*,*) ' METSOL = 7: LAPACK factorization'
11966 ELSE IF(metsol == 8) THEN
11967 WRITE(*,*) ' METSOL = 8: LAPACK factorization'
11968#ifdef PARDISO
11969 ELSE IF(metsol == 9) THEN
11970 WRITE(*,*) ' METSOL = 9: Intel oneMKL PARDISO'
11971#endif
11972#endif
11973 END IF
11974
11975 WRITE(*,*) ' with',mitera,' iterations'
11976
11977 IF(matsto == 0) THEN
11978 WRITE(*,*) ' MATSTO = 0: unpacked symmetric matrix, ', 'n*n elements'
11979 ELSEIF(matsto == 1) THEN
11980 WRITE(*,*) ' MATSTO = 1: full symmetric matrix, ', '(n*n+n)/2 elements'
11981 ELSE IF(matsto == 2) THEN
11982 WRITE(*,*) ' MATSTO = 2: sparse matrix (custom)'
11983 ELSE IF(matsto == 3) THEN
11984 IF (mpdbsz == 0) THEN
11985 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, CSR3)'
11986 ELSE
11987 WRITE(*,*) ' MATSTO = 3: sparse matrix (upper triangle, BSR3)'
11988 END IF
11989 END IF
11990 IF(mbandw /= 0.AND.(metsol >= 4.AND. metsol <7)) THEN ! band matrix as MINRES preconditioner
11991 WRITE(*,*) ' and band matrix, width',mbandw
11992 END IF
11993
11994 IF(chicut /= 0.0) THEN
11995 WRITE(*,*) 'Chi square cut equiv 3 st.dev applied ...'
11996 WRITE(*,*) ' in first iteration with factor',chicut
11997 WRITE(*,*) ' in second iteration with factor',chirem
11998 WRITE(*,*) ' (reduced by sqrt in next iterations)'
11999 END IF
12000
12001 IF(lhuber /= 0) THEN
12002 WRITE(*,*) ' Down-weighting of outliers in', lhuber,' iterations'
12003 WRITE(*,*) ' Cut on downweight fraction',dwcut
12004 END IF
12005
12006 WRITE(*,*) 'Iterations (solutions) with line search:'
12007 IF(lsearch > 2) THEN
12008 WRITE(*,*) ' All'
12009 ELSEIF (lsearch == 1) THEN
12010 WRITE(*,*) ' Last'
12011 ELSEIF (lsearch < 1) THEN
12012 WRITE(*,*) ' None'
12013 ELSE
12014 IF (chicut /= 0.0) THEN
12015 WRITE(*,*) ' All with Chi square cut scaling factor <= 1.'
12016 ELSE
12017 WRITE(*,*) ' All'
12018 ENDIF
12019 ENDIF
12020
12021 IF(nummeasurements>0) THEN
12022 WRITE(*,*)
12023 WRITE(*,*) ' Number of external measurements ', nummeasurements
12024 ENDIF
12025
12026 CALL mend
12027
12028101 FORMAT(i3,2x,a)
12029102 FORMAT(a)
12030END SUBROUTINE filetx
12031
12041
12042INTEGER(mpi) FUNCTION nufile(fname)
12043 USE mpdef
12044
12045 IMPLICIT NONE
12046 INTEGER(mpi) :: ios
12047 INTEGER(mpi) :: l1
12048 INTEGER(mpi) :: ll
12049 INTEGER(mpi) :: nm
12050 INTEGER(mpi) :: npat
12051 INTEGER(mpi) :: ntext
12052 INTEGER(mpi) :: nuprae
12053 INTEGER(mpi) :: matint
12054
12055 CHARACTER (LEN=*), INTENT(INOUT) :: fname
12056 LOGICAL :: ex
12057 SAVE
12058 ! ...
12059 nufile=0
12060 nuprae=0
12061 IF(len(fname) > 5) THEN
12062 IF(fname(1:5) == 'rfio:') nuprae=1
12063 IF(fname(1:5) == 'dcap:') nuprae=2
12064 IF(fname(1:5) == 'root:') nuprae=3
12065 END IF
12066 IF(nuprae == 0) THEN
12067 INQUIRE(file=fname,iostat=ios,exist=ex)
12068 IF(ios /= 0) nufile=-abs(ios)
12069 IF(ios /= 0) RETURN
12070 ELSE IF(nuprae == 1) THEN ! rfio:
12071 ll=len(fname)
12072 fname=fname(6:ll)
12073 ex=.true.
12074 nufile=1
12075 RETURN
12076 ELSE
12077 ex=.true. ! assume file existence
12078 END IF
12079 IF(ex) THEN
12080 nufile=1 ! binary
12081 ll=len(fname)
12082 l1=max(1,ll-3)
12083 nm=matint('xt',fname(l1:ll),npat,ntext)
12084 IF(nm == 2) nufile=2 ! text
12085 IF(nm < 2) THEN
12086 nm=matint('tx',fname(l1:ll),npat,ntext)
12087 IF(nm == 2) nufile=2 ! text
12088 END IF
12089 END IF
12090END FUNCTION nufile
12091
12099SUBROUTINE intext(text,nline)
12100 USE mpmod
12101 USE mptext
12102
12103 IMPLICIT NONE
12104 INTEGER(mpi) :: i
12105 INTEGER(mpi) :: ia
12106 INTEGER(mpi) :: ib
12107 INTEGER(mpi) :: ier
12108 INTEGER(mpi) :: iomp
12109 INTEGER(mpi) :: j
12110 INTEGER(mpi) :: k
12111 INTEGER(mpi) :: kkey
12112 INTEGER(mpi) :: label
12113 INTEGER(mpi) :: lkey
12114 INTEGER(mpi) :: mat
12115 INTEGER(mpi) :: miter
12116 INTEGER(mpi) :: nab
12117 INTEGER(mpi) :: nkey
12118 INTEGER(mpi) :: nkeys
12119 INTEGER(mpi) :: nl
12120 INTEGER(mpi) :: nmeth
12121 INTEGER(mpi) :: npat
12122 INTEGER(mpi) :: ntext
12123 INTEGER(mpi) :: nums
12124 INTEGER(mpi) :: matint
12125
12126 CHARACTER (LEN=*), INTENT(IN) :: text
12127 INTEGER(mpi), INTENT(IN) :: nline
12128
12129#ifdef LAPACK64
12130#ifdef PARDISO
12131 parameter(nkeys=7,nmeth=10)
12132#else
12133 parameter(nkeys=6,nmeth=9)
12134#endif
12135#else
12136 parameter(nkeys=6,nmeth=7)
12137#endif
12138 CHARACTER (LEN=16) :: methxt(nmeth)
12139 CHARACTER (LEN=16) :: keylst(nkeys)
12140 CHARACTER (LEN=32) :: keywrd
12141 CHARACTER (LEN=32) :: keystx
12142 CHARACTER (LEN=itemCLen) :: ctext
12143 INTEGER(mpi), PARAMETER :: mnum=100
12144 REAL(mpd) :: dnum(mnum)
12145#ifdef LAPACK64
12146#ifdef PARDISO
12147 INTEGER(mpi) :: ipvs ! ... integer value
12148#endif
12149#endif
12150 INTEGER(mpi) :: lpvs ! ... integer label
12151 REAL(mpd) :: plvs ! ... float value
12152
12153 INTERFACE
12154 SUBROUTINE additem(length,list,label,value)
12155 USE mpmod
12156 INTEGER(mpi), INTENT(IN OUT) :: length
12157 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12158 INTEGER(mpi), INTENT(IN) :: label
12159 REAL(mpd), INTENT(IN) :: value
12160 END SUBROUTINE additem
12161 SUBROUTINE additemc(length,list,label,text)
12162 USE mpmod
12163 INTEGER(mpi), INTENT(IN OUT) :: length
12164 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12165 INTEGER(mpi), INTENT(IN) :: label
12166 CHARACTER(LEN = itemCLen), INTENT(IN) :: text
12167 END SUBROUTINE additemc
12168 SUBROUTINE additemi(length,list,label,ivalue)
12169 USE mpmod
12170 INTEGER(mpi), INTENT(IN OUT) :: length
12171 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12172 INTEGER(mpi), INTENT(IN) :: label
12173 INTEGER(mpi), INTENT(IN) :: ivalue
12174 END SUBROUTINE additemi
12175 END INTERFACE
12176
12177 SAVE
12178#ifdef LAPACK64
12179#ifdef PARDISO
12180 DATA keylst/'unknown','parameter','constraint','measurement','method','comment','pardiso'/
12181 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12182 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK', &
12183 'sparsePARDISO'/
12184#else
12185 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12186 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12187 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition', 'fullLAPACK', 'unpackedLAPACK'/
12188#endif
12189#else
12190 DATA keylst/'unknown','parameter','constraint','measurement','method','comment'/
12191 DATA methxt/'diagonalization','inversion','fullMINRES', 'sparseMINRES', &
12192 'fullMINRES-QLP', 'sparseMINRES-QLP', 'decomposition'/
12193#endif
12194 DATA lkey/-1/ ! last keyword
12195
12196 ! ...
12197 nkey=-1 ! new keyword
12198 CALL rltext(text,ia,ib,nab) ! return indices for non-blank area
12199 IF(nab == 0) GOTO 10
12200 CALL ratext(text(1:nab),nums,dnum,mnum) ! translate text to DP numbers
12201
12202 IF(nums /= 0) nkey=0
12203 IF(keyb /= 0) THEN
12204 keywrd=text(keya:keyb) ! text is TEXT(KEYA)...TEXT(KEYB)
12205 ! WRITE(*,*) 'Keyword is ',KEYWRD
12206
12207 ! compare keywords
12208
12209 DO nkey=2,nkeys ! loop over all pede keywords
12210 keystx=keylst(nkey) ! copy NKEY.th pede keyword
12211 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12212 IF(100*mat >= 80*max(npat,ntext)) GO TO 10 ! 80% (symmetric) matching
12213 END DO
12214
12215 ! more comparisons
12216
12217 keystx='print'
12218 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12219 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12220 mprint=1
12221 IF(nums > 0) mprint=nint(dnum(1),mpi)
12222 RETURN
12223 END IF
12224
12225 keystx='debug'
12226 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12227 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12228 mdebug=3
12229 ! GF IF(NUMS.GT.0) MPRINT=DNUM(1)
12230 IF(nums > 0) mdebug=nint(dnum(1),mpi)
12231 IF(nums > 1) mdebg2=nint(dnum(2),mpi)
12232 RETURN
12233 END IF
12234
12235 keystx='entries'
12236 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12237 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12238 IF(nums > 0 .AND. dnum(1) > 0.5) mreqenf=nint(dnum(1),mpi)
12239 IF(nums > 1 .AND. dnum(2) > 0.5) mreqena=nint(dnum(2),mpi)
12240 IF(nums > 2 .AND. dnum(3) > 0.5) iteren=nint(dnum(1)*dnum(3),mpi)
12241 RETURN
12242 END IF
12243
12244 keystx='printrecord'
12245 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12246 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12247 IF(nums > 0) nrecpr=nint(dnum(1),mpi)
12248 IF(nums > 1) nrecp2=nint(dnum(2),mpi)
12249 RETURN
12250 END IF
12251
12252 keystx='maxrecord'
12253 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12254 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12255 IF (nums > 0.AND.dnum(1) > 0.) mxrec=nint(dnum(1),mpi)
12256 RETURN
12257 END IF
12258
12259 keystx='cache'
12260 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12261 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12262 IF (nums > 0.AND.dnum(1) >= 0.) ncache=nint(dnum(1),mpi) ! cache size, <0 keeps default
12263 IF (nums == 2.AND.dnum(2) > 0..AND.dnum(2) <= 1.0) & ! read cache fill level
12264 fcache(1)=real(dnum(2),mps)
12265 IF (nums >= 4) THEN ! explicit cache splitting
12266 DO k=1,3
12267 fcache(k)=real(dnum(k+1),mps)
12268 END DO
12269 END IF
12270 RETURN
12271 END IF
12272
12273 keystx='chisqcut'
12274 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12275 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12276 IF(nums == 0) THEN ! always 3-sigma cut
12277 chicut=1.0
12278 chirem=1.0
12279 ELSE
12280 chicut=real(dnum(1),mps)
12281 IF(chicut < 1.0) chicut=-1.0
12282 IF(nums == 1) THEN
12283 chirem=1.0 ! 3-sigma cut, if not specified
12284 ELSE
12285 chirem=real(dnum(2),mps)
12286 IF(chirem < 1.0) chirem=1.0
12287 IF(chicut >= 1.0) chirem=min(chirem,chicut)
12288 END IF
12289 END IF
12290 RETURN
12291 END IF
12292
12293 ! GF added:
12294 keystx='hugecut'
12295 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12296 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12297 IF(nums > 0) chhuge=real(dnum(1),mps)
12298 IF(chhuge < 1.0) chhuge=1.0 ! at least (!!) 3-sigma
12299 RETURN
12300 END IF
12301 ! GF added end
12302
12303 keystx='linesearch'
12304 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12305 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12306 IF(nums > 0) lsearch=nint(dnum(1),mpi)
12307 RETURN
12308 END IF
12309
12310 keystx='localfit'
12311 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12312 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12313 IF(nums > 0) lfitnp=nint(dnum(1),mpi)
12314 IF(nums > 1) lfitbb=nint(dnum(2),mpi)
12315 RETURN
12316 END IF
12317
12318 keystx='regularization'
12319 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12320 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12321 nregul=1
12322 regula=real(dnum(1),mps)
12323 IF(nums >= 2) regpre=real(dnum(2),mps)
12324 RETURN
12325 END IF
12326
12327 keystx='regularisation'
12328 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12329 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12330 nregul=1
12331 regula=real(dnum(1),mps)
12332 IF(nums >= 2) regpre=real(dnum(2),mps)
12333 RETURN
12334 END IF
12335
12336 keystx='presigma'
12337 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12338 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12339 regpre=real(dnum(1),mps)
12340 RETURN
12341 END IF
12342
12343 keystx='matiter'
12344 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12345 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12346 matrit=nint(dnum(1),mpi)
12347 RETURN
12348 END IF
12349
12350 keystx='matmoni'
12351 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12352 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12353 matmon=-1
12354 IF (nums > 0.AND.dnum(1) > 0.) matmon=nint(dnum(1),mpi)
12355 RETURN
12356 END IF
12357
12358 keystx='bandwidth'
12359 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12360 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12361 IF(nums > 0) mbandw=nint(dnum(1),mpi)
12362 IF(mbandw < 0) mbandw=-1
12363 IF(nums > 1) lprecm=nint(dnum(2),mpi)
12364 RETURN
12365 END IF
12366
12367 ! KEYSTX='outlierrejection'
12368 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12369 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12370 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12371 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12372 ! CHDFRJ=DNUM(1)
12373 ! IF(CHDFRJ.LT.3.0) CHDFRJ=100.0
12374 ! RETURN
12375 ! END IF
12376
12377 ! KEYSTX='outliersuppression'
12378 ! MAT=MATINT(TEXT(KEYA:KEYB),KEYSTX,NPAT,NTEXT) ! comparison
12379 ! WRITE(*,*) KEYSTX,MAT,(NTEXT+NTEXT)/3
12380 ! IF(MAT.GE.(NTEXT+NTEXT+NTEXT-2)/3) THEN
12381 ! IF(MAT.GE.(NPAT-NPAT/5)) THEN
12382 ! LHUBER=DNUM(1)
12383 ! IF(LHUBER.LE.2) LHUBER=2 ! at least 2 Huber iterations
12384 ! RETURN
12385 ! END IF
12386
12387 keystx='outlierdownweighting'
12388 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12389 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12390 lhuber=nint(dnum(1),mpi)
12391 IF(lhuber > 0.AND.lhuber <= 2) lhuber=2 ! at least 2 Huber iterations (if any)
12392 RETURN
12393 END IF
12394
12395 keystx='dwfractioncut'
12396 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12397 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12398 dwcut=real(dnum(1),mps)
12399 IF(dwcut > 0.5) dwcut=0.5
12400 RETURN
12401 END IF
12402
12403 keystx='maxlocalcond'
12404 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12405 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12406 IF (nums > 0.AND.dnum(1) > 0.0) cndlmx=real(dnum(1),mps)
12407 RETURN
12408 END IF
12409
12410 keystx='pullrange'
12411 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12412 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12413 prange=abs(real(dnum(1),mps))
12414 RETURN
12415 END IF
12416
12417 keystx='subito'
12418 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12419 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12420 isubit=1
12421 RETURN
12422 END IF
12423
12424 keystx='force'
12425 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12426 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12427 iforce=1
12428 RETURN
12429 END IF
12430
12431 keystx='memorydebug'
12432 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12433 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12434 memdbg=1
12435 IF (nums > 0.AND.dnum(1) > 0.0) memdbg=nint(dnum(1),mpi)
12436 RETURN
12437 END IF
12438
12439 keystx='globalcorr'
12440 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12441 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12442 igcorr=1
12443 RETURN
12444 END IF
12445
12446 keystx='printcounts'
12447 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12448 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12449 ipcntr=1
12450 IF (nums > 0) ipcntr=nint(dnum(1),mpi)
12451 RETURN
12452 END IF
12453
12454 keystx='weightedcons'
12455 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12456 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12457 iwcons=1
12458 IF (nums > 0) iwcons=nint(dnum(1),mpi)
12459 RETURN
12460 END IF
12461
12462 keystx='skipemptycons'
12463 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12464 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12465 iskpec=1
12466 RETURN
12467 END IF
12468
12469 keystx='resolveredundancycons'
12470 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12471 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12472 irslvrc=1
12473 RETURN
12474 END IF
12475
12476 keystx='withelimination'
12477 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12478 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12479 icelim=1
12480 RETURN
12481 END IF
12482
12483 keystx='postprocessing'
12484 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12485 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12486 lenpostproc=ib-keyb-1
12487 cpostproc(1:lenpostproc)=text(keyb+2:ib)
12488 RETURN
12489 END IF
12490
12491#ifdef LAPACK64
12492 keystx='withLAPACKelimination'
12493 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12494 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12495 icelim=2
12496 RETURN
12497 END IF
12498#endif
12499
12500 keystx='withmultipliers'
12501 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12502 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12503 icelim=0
12504 RETURN
12505 END IF
12506
12507 keystx='checkinput'
12508 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12509 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12510 icheck=1
12511 IF (nums > 0) icheck=nint(dnum(1),mpi)
12512 RETURN
12513 END IF
12514
12515 keystx='checkparametergroups'
12516 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12517 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12518 ichkpg=1
12519 RETURN
12520 END IF
12521
12522 keystx='monitorresiduals'
12523 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12524 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12525 imonit=3
12526 IF (nums > 0) imonit=nint(dnum(1),mpi)
12527 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12528 RETURN
12529 END IF
12530
12531 keystx='monitorpulls'
12532 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12533 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12534 imonit=3
12535 imonmd=1
12536 IF (nums > 0) imonit=nint(dnum(1),mpi)
12537 IF (nums > 1) measbins=max(measbins,nint(dnum(2),mpi))
12538 RETURN
12539 END IF
12540
12541 keystx='monitorprogress'
12542 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12543 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12544 monpg1=1
12545 monpg2=1024
12546 IF (nums > 0) monpg1=max(1,nint(dnum(1),mpi))
12547 IF (nums > 1) monpg2=max(1,nint(dnum(2),mpi))
12548 RETURN
12549 END IF
12550
12551 keystx='scaleerrors'
12552 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12553 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12554 iscerr=1
12555 IF (nums > 0) dscerr(1:2)=dnum(1)
12556 IF (nums > 1) dscerr(2)=dnum(2)
12557 RETURN
12558 END IF
12559
12560 keystx='iterateentries'
12561 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12562 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12563 iteren=huge(iteren)
12564 IF (nums > 0) iteren=nint(dnum(1),mpi)
12565 RETURN
12566 END IF
12567
12568 keystx='threads'
12569 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12570 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12571 iomp=0
12572 !$ IOMP=1
12573 !$ IF (IOMP.GT.0) THEN
12574 !$ IF (NUMS.GE.1.AND.DNUM(1).GT.0.) MTHRD =NINT(dnum(1),mpi)
12575 !$ MTHRDR=MTHRD
12576 !$ IF (NUMS.GE.2.AND.DNUM(2).GT.0.) MTHRDR=NINT(dnum(2),mpi)
12577 !$ ELSE
12578 WRITE(*,*) 'WARNING: multithreading not available'
12579 !$ ENDIF
12580 RETURN
12581 END IF
12582
12583 keystx='compress'
12584 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12585 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12586 WRITE(*,*) 'WARNING: keyword COMPRESS is obsolete (compression is default)'
12587 RETURN
12588 END IF
12589
12590 ! still experimental
12591 !keystx='extendedStorage'
12592 !mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12593 !IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12594 ! mextnd=1
12595 ! RETURN
12596 !END IF
12597
12598 keystx='countrecords'
12599 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12600 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12601 mcount=1
12602 RETURN
12603 END IF
12604
12605 keystx='errlabels'
12606 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12607 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12608 nl=min(nums,100-mnrsel)
12609 DO k=1,nl
12610 lbmnrs(mnrsel+k)=nint(dnum(k),mpi)
12611 END DO
12612 mnrsel=mnrsel+nl
12613 RETURN
12614 END IF
12615
12616 keystx='pairentries'
12617 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12618 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12619 ! This option could be implemented to get rid of parameter pairs
12620 ! that have very few entries - to save matrix memory size.
12621 IF (nums > 0.AND.dnum(1) > 0.0) THEN
12622 mreqpe=nint(dnum(1),mpi)
12623 IF (nums >= 2.AND.dnum(2) >= dnum(1)) mhispe=nint(dnum(2),mpi)
12624 IF (nums >= 3.AND.dnum(3) >= dnum(1)) msngpe=nint(dnum(3),mpi)
12625 END IF
12626 RETURN
12627 END IF
12628
12629 keystx='wolfe'
12630 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12631 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12632 wolfc1=real(dnum(1),mps)
12633 wolfc2=real(dnum(2),mps)
12634 RETURN
12635 END IF
12636
12637 ! GF added:
12638 ! convergence tolerance for minres:
12639 keystx='mrestol'
12640 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12641 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12642 IF(nums > 0) THEN
12643 IF (dnum(1) < 1.0e-10_mpd.OR.dnum(1) > 1.0e-04_mpd) THEN
12644 WRITE(*,*) 'ERROR: need 1.0D-10 <= MRESTL ', &
12645 '<= 1.0D-04, but get ', dnum(1)
12646 ELSE
12647 mrestl=dnum(1)
12648 END IF
12649 END IF
12650 RETURN
12651 END IF
12652 ! GF added end
12653
12654 keystx='mrestranscond'
12655 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12656 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12657 IF(nums > 0) THEN
12658 mrtcnd = dnum(1)
12659 END IF
12660 RETURN
12661 END IF
12662
12663 keystx='mresmode'
12664 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12665 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12666 IF(nums > 0) THEN
12667 mrmode = int(dnum(1),mpi)
12668 END IF
12669 RETURN
12670 END IF
12671
12672 keystx='nofeasiblestart'
12673 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12674 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12675 nofeas=1 ! do not make parameters feasible at start
12676 RETURN
12677 END IF
12678
12679 keystx='histprint'
12680 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12681 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12682 nhistp=1 ! print histograms
12683 RETURN
12684 END IF
12685
12686 keystx='readerroraseof' ! treat (C) read errors as eof
12687 mat=matint(text(ia:ib),keystx,npat,ntext)
12688 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12689 ireeof=1
12690 RETURN
12691 END IF
12692
12693#ifdef LAPACK64
12694 keystx='LAPACKwitherrors' ! calculate parameter errors with LAPACK
12695 mat=matint(text(ia:ib),keystx,npat,ntext)
12696 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12697 ilperr=1
12698 RETURN
12699 END IF
12700#ifdef PARDISO
12701 keystx='debugPARDISO' ! enable debug for Intel oneMKL PARDISO
12702 mat=matint(text(ia:ib),keystx,npat,ntext)
12703 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12704 ipddbg=1
12705 RETURN
12706 END IF
12707
12708 keystx='blocksizePARDISO' ! use BSR3 for Intel oneMKL PARDISO, list of (increasing) block sizes to be tried
12709 mat=matint(text(keya:keyb),keystx,npat,ntext) ! comparison
12710 IF(100*mat >= 80*max(npat,ntext).AND.mnrsel < 100) THEN ! 80% (symmetric) matching
12711 nl=min(nums,10-mpdbsz)
12712 DO k=1,nl
12713 IF (nint(dnum(k),mpi) > 0) THEN
12714 IF (mpdbsz == 0) THEN
12715 mpdbsz=mpdbsz+1
12716 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12717 ELSE IF (nint(dnum(k),mpi) > ipdbsz(mpdbsz)) THEN
12718 mpdbsz=mpdbsz+1
12719 ipdbsz(mpdbsz)=nint(dnum(k),mpi)
12720 END IF
12721 END IF
12722 END DO
12723 RETURN
12724 END IF
12725#endif
12726#endif
12727 keystx='fortranfiles'
12728 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12729 IF(mat == max(npat,ntext)) RETURN
12730
12731 keystx='Cfiles'
12732 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12733 IF(mat == max(npat,ntext)) RETURN
12734
12735 keystx='closeandreopen'
12736 mat=matint(text(ia:ib),keystx,npat,ntext) ! comparison
12737 IF(mat == max(npat,ntext)) RETURN
12738
12739 keystx=keylst(1)
12740 nkey=1 ! unknown keyword
12741 IF(nums /= 0) nkey=0
12742
12743 WRITE(*,*) ' '
12744 WRITE(*,*) '**************************************************'
12745 WRITE(*,*) ' '
12746 WRITE(*,*) 'Unknown keyword(s): ',text(1:min(nab,50))
12747 WRITE(*,*) ' '
12748 WRITE(*,*) '**************************************************'
12749 WRITE(*,*) ' '
12750 lunkno=lunkno+1
12751
12752 END IF
12753 ! result: NKEY = -1 blank
12754 ! NKEY = 0 numerical data, no text keyword or unknown
12755 ! NKEY > 0 keyword NKEY from list, keyword = KEYSTX
12756
12757
12758 ! content/lastcontent
12759 ! -------------------
12760 ! blank -1
12761 ! data 0
12762 ! keyword
12763 ! unknown 1
12764 ! parameter 2
12765 ! constraint 3
12766 ! measurement 4
12767 ! method 5
12768
12769
1277010 IF(nkey > 0) THEN ! new keyword
12771 lkey=nkey
12772 IF(lkey == 2) THEN ! parameter
12773 IF(nums == 3) THEN
12774 lpvs=nint(dnum(1),mpi) ! label
12775 IF(lpvs /= 0) THEN
12776 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12777 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12778 ELSE
12779 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12780 END IF
12781 ELSE IF(nums /= 0) THEN
12782 kkey=1 ! switch to "unknown" ?
12783 WRITE(*,*) 'Wrong text in line',nline
12784 WRITE(*,*) 'Status: new parameter'
12785 WRITE(*,*) '> ',text(1:nab)
12786 END IF
12787 ELSE IF(lkey == 3) THEN ! constraint
12788 ! WRITE(*,*) 'Keyword is constraint!',NUMS,' numerical data'
12789 IF(nums >= 1.AND.nums <= 2) THEN ! start constraint
12790 lpvs=-nline ! r = r.h.s. value
12791 CALL additem(lenconstraints,listconstraints,lpvs,dnum(1))
12792 lpvs=-1 ! constraint
12793 IF(iwcons > 0) lpvs=-2 ! weighted constraint
12794 plvs=0.0
12795 IF(nums == 2) plvs=dnum(2) ! sigma
12796 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12797 ELSE
12798 kkey=1 ! switch to "unknown"
12799 WRITE(*,*) 'Wrong text in line',nline
12800 WRITE(*,*) 'Status: new keyword constraint'
12801 WRITE(*,*) '> ',text(1:nab)
12802 END IF
12803 ELSE IF(lkey == 4) THEN ! measurement
12804 IF(nums == 2) THEN ! start measurement
12805 nummeasurements=nummeasurements+1
12806 lpvs=-nline ! r = r.h.s. value
12807 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(1))
12808 lpvs=-1 ! sigma
12809 CALL additem(lenmeasurements,listmeasurements,lpvs,dnum(2))
12810 ELSE
12811 kkey=1 ! switch to "unknown"
12812 WRITE(*,*) 'Wrong text in line',nline
12813 WRITE(*,*) 'Status: new keyword measurement'
12814 WRITE(*,*) '> ',text(1:nab)
12815 END IF
12816 ELSE IF(lkey == 5.AND.keyb < keyc) THEN ! method with text argument
12817 miter=mitera
12818 IF(nums >= 1) miter=nint(dnum(1),mpi)
12819 IF(miter >= 1) mitera=miter
12820 dflim=real(dnum(2),mps)
12821 lkey=0
12822 DO i=1,nmeth
12823 keystx=methxt(i)
12824 mat=matint(text(keyb+1:keyc),keystx,npat,ntext) ! comparison
12825 IF(100*mat >= 80*max(npat,ntext)) THEN ! 80% (symmetric) matching
12826 IF(i == 1) THEN ! diagonalization
12827 metsol=2
12828 matsto=1
12829 ELSE IF(i == 2) THEN ! inversion
12830 metsol=1
12831 matsto=1
12832 ELSE IF(i == 3) THEN ! fullMINRES
12833 metsol=4
12834 matsto=1
12835 ELSE IF(i == 4) THEN ! sparseMINRES
12836 metsol=4
12837 matsto=2
12838 ELSE IF(i == 5) THEN ! fullMINRES-QLP
12839 metsol=5
12840 matsto=1
12841 ELSE IF(i == 6) THEN ! sparseMINRES-QLP
12842 metsol=5
12843 matsto=2
12844 ELSE IF(i == 7) THEN ! decomposition
12845 metsol=3
12846 matsto=1
12847#ifdef LAPACK64
12848 ELSE IF(i == 8) THEN ! fullLAPACK factorization
12849 metsol=7
12850 matsto=1
12851 ELSE IF(i == 9) THEN ! unpackedLAPACK factorization
12852 metsol=8
12853 matsto=0
12854#ifdef PARDISO
12855 ELSE IF(i == 10) THEN ! Intel oneMKL PARDISO (sparse matrix (CSR3 or BSR3, upper triangle))
12856 metsol=9
12857 matsto=3
12858#endif
12859#endif
12860 END IF
12861 END IF
12862 END DO
12863 END IF
12864 ELSE IF(nkey == 0) THEN ! data for continuation
12865 IF(lkey == 2) THEN ! parameter
12866 IF(nums >= 3) THEN ! store data from this line
12867 lpvs=nint(dnum(1),mpi) ! label
12868 IF(lpvs /= 0) THEN
12869 CALL additem(lenparameters,listparameters,lpvs,dnum(2)) ! start value
12870 CALL additem(lenpresigmas,listpresigmas,lpvs,dnum(3)) ! pre-sigma
12871 ELSE
12872 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12873 END IF
12874 ELSE IF(nums > 1.AND.nums < 3) THEN
12875 kkey=1 ! switch to "unknown" ?
12876 WRITE(*,*) 'Wrong text in line',nline
12877 WRITE(*,*) 'Status continuation parameter'
12878 WRITE(*,*) '> ',text(1:nab)
12879 END IF
12880
12881 ELSE IF(lkey == 3) THEN ! constraint
12882 ier=0
12883 DO i=1,nums,2
12884 label=nint(dnum(i),mpi)
12885 IF(label <= 0) ier=1
12886 END DO
12887 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12888 IF(ier == 0) THEN
12889 DO i=1,nums,2
12890 lpvs=nint(dnum(i),mpi) ! label
12891 plvs=dnum(i+1) ! factor
12892 CALL additem(lenconstraints,listconstraints,lpvs,plvs)
12893 END DO
12894 ELSE
12895 kkey=0
12896 WRITE(*,*) 'Wrong text in line',nline
12897 WRITE(*,*) 'Status continuation constraint'
12898 WRITE(*,*) '> ',text(1:nab)
12899 END IF
12900
12901 ELSE IF(lkey == 4) THEN ! measurement
12902 ! WRITE(*,*) 'continuation < ',NUMS
12903 ier=0
12904 DO i=1,nums,2
12905 label=nint(dnum(i),mpi)
12906 IF(label <= 0) ier=1
12907 END DO
12908 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12909 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12910 IF(ier == 0) THEN
12911 DO i=1,nums,2
12912 lpvs=nint(dnum(i),mpi) ! label
12913 plvs=dnum(i+1) ! factor
12914 CALL additem(lenmeasurements,listmeasurements,lpvs,plvs)
12915 END DO
12916 ELSE
12917 kkey=0
12918 WRITE(*,*) 'Wrong text in line',nline
12919 WRITE(*,*) 'Status continuation measurement'
12920 WRITE(*,*) '> ',text(1:nab)
12921 END IF
12922 ELSE IF(lkey == 6) THEN ! comment
12923 IF(nums == 1) THEN
12924 lpvs=nint(dnum(1),mpi) ! label
12925 IF(lpvs /= 0) THEN
12926 ! skip label
12927 DO j=ia,ib
12928 IF (text(j:j) == ' ') EXIT
12929 END DO
12930 ctext=text(j:ib)
12931 CALL additemc(lencomments,listcomments,lpvs,ctext)
12932 ELSE
12933 WRITE(*,*) 'Line',nline,' error, label=',lpvs
12934 END IF
12935 ELSE IF(nums /= 0) THEN
12936 kkey=1 ! switch to "unknown"
12937 WRITE(*,*) 'Wrong text in line',nline
12938 WRITE(*,*) 'Status: continuation comment'
12939 WRITE(*,*) '> ',text(1:nab)
12940 END IF
12941#ifdef LAPACK64
12942#ifdef PARDISO
12943 ELSE IF(lkey == 7) THEN ! Intel oneMKL PARDISO parameters
12944 ier=0
12945 DO i=1,nums,2
12946 label=nint(dnum(i),mpi)
12947 IF(label <= 0.OR.label > 64) ier=1
12948 END DO
12949 IF(mod(nums,2) /= 0) ier=1 ! reject odd number
12950 ! WRITE(*,*) 'IER NUMS ',IER,NUMS
12951 IF(ier == 0) THEN
12952 DO i=1,nums,2
12953 lpvs=nint(dnum(i),mpi) ! label
12954 ipvs=nint(dnum(i+1),mpi) ! parameter
12955 CALL additemi(lenpardiso,listpardiso,lpvs,ipvs)
12956 END DO
12957 ELSE
12958 kkey=0
12959 WRITE(*,*) 'Wrong text in line',nline
12960 WRITE(*,*) 'Status continuation measurement'
12961 WRITE(*,*) '> ',text(1:nab)
12962 END IF
12963#endif
12964#endif
12965 END IF
12966 END IF
12967END SUBROUTINE intext
12968
12976SUBROUTINE additem(length,list,label,value)
12977 USE mpdef
12978 USE mpdalc
12979
12980 INTEGER(mpi), INTENT(IN OUT) :: length
12981 TYPE(listitem), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
12982 INTEGER(mpi), INTENT(IN) :: label
12983 REAL(mpd), INTENT(IN) :: value
12984
12985 INTEGER(mpl) :: newSize
12986 INTEGER(mpl) :: oldSize
12987 TYPE(listitem), DIMENSION(:), ALLOCATABLE :: tempList
12988
12989 IF (label > 0.AND.value == 0.) RETURN ! skip zero for valid labels
12990 IF (length == 0 ) THEN ! initial list with size = 100
12991 newsize = 100
12992 CALL mpalloc(list,newsize,' list ')
12993 ENDIF
12994 oldsize=size(list,kind=mpl)
12995 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
12996 newsize = oldsize + oldsize/5 + 100
12997 CALL mpalloc(templist,oldsize,' temp. list ')
12998 templist=list
12999 CALL mpdealloc(list)
13000 CALL mpalloc(list,newsize,' list ')
13001 list(1:oldsize)=templist(1:oldsize)
13002 CALL mpdealloc(templist)
13003 ENDIF
13004 ! add to end of list
13005 length=length+1
13006 list(length)%label=label
13007 list(length)%value=value
13008
13009END SUBROUTINE additem
13010
13018SUBROUTINE additemc(length,list,label,text)
13019 USE mpdef
13020 USE mpdalc
13021
13022 INTEGER(mpi), INTENT(IN OUT) :: length
13023 TYPE(listitemc), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
13024 INTEGER(mpi), INTENT(IN) :: label
13025 CHARACTER(len = itemCLen), INTENT(IN) :: text
13026
13027 INTEGER(mpl) :: newSize
13028 INTEGER(mpl) :: oldSize
13029 TYPE(listitemc), DIMENSION(:), ALLOCATABLE :: tempList
13030
13031 IF (label > 0.AND.text == '') RETURN ! skip empty text for valid labels
13032 IF (length == 0 ) THEN ! initial list with size = 100
13033 newsize = 100
13034 CALL mpalloc(list,newsize,' list ')
13035 ENDIF
13036 oldsize=size(list,kind=mpl)
13037 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
13038 newsize = oldsize + oldsize/5 + 100
13039 CALL mpalloc(templist,oldsize,' temp. list ')
13040 templist=list
13041 CALL mpdealloc(list)
13042 CALL mpalloc(list,newsize,' list ')
13043 list(1:oldsize)=templist(1:oldsize)
13044 CALL mpdealloc(templist)
13045 ENDIF
13046 ! add to end of list
13047 length=length+1
13048 list(length)%label=label
13049 list(length)%text=text
13050
13051END SUBROUTINE additemc
13052
13060SUBROUTINE additemi(length,list,label,ivalue)
13061 USE mpdef
13062 USE mpdalc
13063
13064 INTEGER(mpi), INTENT(IN OUT) :: length
13065 TYPE(listitemi), DIMENSION(:), INTENT(IN OUT), ALLOCATABLE :: list
13066 INTEGER(mpi), INTENT(IN) :: label
13067 INTEGER(mpi), INTENT(IN) :: ivalue
13068
13069 INTEGER(mpl) :: newSize
13070 INTEGER(mpl) :: oldSize
13071 TYPE(listitemi), DIMENSION(:), ALLOCATABLE :: tempList
13072
13073 IF (length == 0 ) THEN ! initial list with size = 100
13074 newsize = 100
13075 CALL mpalloc(list,newsize,' list ')
13076 ENDIF
13077 oldsize=size(list,kind=mpl)
13078 IF (length >= oldsize) THEN ! increase sizeby 20% + 100
13079 newsize = oldsize + oldsize/5 + 100
13080 CALL mpalloc(templist,oldsize,' temp. list ')
13081 templist=list
13082 CALL mpdealloc(list)
13083 CALL mpalloc(list,newsize,' list ')
13084 list(1:oldsize)=templist(1:oldsize)
13085 CALL mpdealloc(templist)
13086 ENDIF
13087 ! add to end of list
13088 length=length+1
13089 list(length)%label=label
13090 list(length)%ivalue=ivalue
13091
13092END SUBROUTINE additemi
13093
13095SUBROUTINE mstart(text)
13096 USE mpdef
13097 USE mpmod, ONLY: textl
13098
13099 IMPLICIT NONE
13100 INTEGER(mpi) :: i
13101 INTEGER(mpi) :: ka
13102 INTEGER(mpi) :: kb
13103 INTEGER(mpi) :: l
13104 CHARACTER (LEN=*), INTENT(IN) :: text
13105 CHARACTER (LEN=16) :: textc
13106 SAVE
13107 ! ...
13108 DO i=1,74
13109 textl(i:i)='_'
13110 END DO
13111 l=len(text)
13112 ka=(74-l)/2
13113 kb=ka+l-1
13114 textl(ka:kb)=text(1:l)
13115 WRITE(*,*) ' '
13116 WRITE(*,*) textl
13117 WRITE(*,*) ' '
13118 textc=text(1:l)//'-end'
13119
13120 DO i=1,74
13121 textl(i:i)='_'
13122 END DO
13123 l=l+4
13124 ka=(74-l)/2
13125 kb=ka+l-1
13126 textl(ka:kb)=textc(1:l)
13127 RETURN
13128END SUBROUTINE mstart
13129
13131SUBROUTINE mend
13132 USE mpmod, ONLY: textl
13133
13134 IMPLICIT NONE
13135 WRITE(*,*) ' '
13136 WRITE(*,*) textl
13137 CALL petime
13138 WRITE(*,*) ' '
13139END SUBROUTINE mend
13140
13147
13148SUBROUTINE mvopen(lun,fname)
13149 USE mpdef
13150
13151 IMPLICIT NONE
13152 INTEGER(mpi) :: l
13153 INTEGER(mpi), INTENT(IN) :: lun
13154 CHARACTER (LEN=*), INTENT(IN) :: fname
13155 CHARACTER (LEN=33) :: nafile
13156 CHARACTER (LEN=33) :: nbfile
13157 LOGICAL :: ex
13158 SAVE
13159 ! ...
13160 l=len(fname)
13161 IF(l > 32) THEN
13162 CALL peend(17,'Aborted, file name too long')
13163 stop 'File name too long '
13164 END IF
13165 nafile=fname
13166 nafile(l+1:l+1)='~'
13167
13168 INQUIRE(file=nafile(1:l),exist=ex)
13169 IF(ex) THEN
13170 INQUIRE(file=nafile(1:l+1),exist=ex)
13171 IF(ex) THEN
13172 CALL system('rm '//nafile)
13173 END IF
13174 nbfile=nafile
13175 nafile(l+1:l+1)=' '
13176 CALL system('mv '//nafile//nbfile)
13177 END IF
13178 OPEN(unit=lun,file=fname)
13179END SUBROUTINE mvopen
13180
13184
13185SUBROUTINE petime
13186 USE mpdef
13187
13188 IMPLICIT NONE
13189 REAL, DIMENSION(2) :: ta
13190 REAL etime
13191 REAL :: rst
13192 REAL :: delta
13193 REAL :: rstp
13194 REAL :: secnd1
13195 REAL :: secnd2
13196 INTEGER :: ncount
13197 INTEGER :: nhour1
13198 INTEGER :: minut1
13199 INTEGER :: nsecd1
13200 INTEGER :: nhour2
13201 INTEGER :: minut2
13202 INTEGER :: nsecd2
13203
13204 SAVE
13205 DATA ncount/0/
13206 ! ...
13207 ncount=ncount+1
13208 rst=etime(ta)
13209 IF(ncount > 1) THEN
13210 delta=rst
13211 nsecd1=int(delta,mpi) ! -> integer
13212 nhour1=nsecd1/3600
13213 minut1=nsecd1/60-60*nhour1
13214 secnd1=delta-60*(minut1+60*nhour1)
13215 delta=rst-rstp
13216 nsecd2=int(delta,mpi) ! -> integer
13217 nhour2=nsecd2/3600
13218 minut2=nsecd2/60-60*nhour2
13219 secnd2=delta-60*(minut2+60*nhour2)
13220 WRITE(*,101) nhour1,minut1,secnd1, nhour2,minut2,secnd2
13221 END IF
13222
13223 rstp=rst
13224 RETURN
13225101 FORMAT(i4,' h',i3,' min',f5.1,' sec total',18x,'elapsed', &
13226 i4,' h',i3,' min',f5.1,' sec')
13227END SUBROUTINE petime ! print
13228
13235
13236SUBROUTINE peend(icode, cmessage)
13237 USE mpdef
13238
13239 IMPLICIT NONE
13240 INTEGER(mpi), INTENT(IN) :: icode
13241 CHARACTER (LEN=*), INTENT(IN) :: cmessage
13242
13243 CALL mvopen(9,'millepede.end')
13244 WRITE(9,101) icode, cmessage
13245101 FORMAT(1x,i4,3x,a)
13246 CLOSE(9)
13247 RETURN
13248
13249END SUBROUTINE peend
13250
13257SUBROUTINE binopn(kfile, ithr, ierr)
13258 USE mpmod
13259
13260 IMPLICIT NONE
13261 INTEGER(mpi), INTENT(IN) :: kfile
13262 INTEGER(mpi), INTENT(IN) :: ithr
13263 INTEGER(mpi), INTENT(OUT) :: ierr
13264
13265 INTEGER(mpi), DIMENSION(13) :: ibuff
13266 INTEGER(mpi) :: ioff
13267 INTEGER(mpi) :: ios
13268 INTEGER(mpi) :: k
13269 INTEGER(mpi) :: lfn
13270 INTEGER(mpi) :: lun
13271 INTEGER(mpi) :: moddate
13272 CHARACTER (LEN=1024) :: fname
13273 CHARACTER (LEN=7) :: cfile
13274 INTEGER stat
13275
13276#ifdef READ_C_FILES
13277 INTERFACE
13278 SUBROUTINE openc(filename, lfn, lun, ios) BIND(c)
13279 USE iso_c_binding
13280 CHARACTER(kind=c_char), DIMENSION(*), INTENT(IN) :: filename
13281 INTEGER(c_int), INTENT(IN), VALUE :: lfn
13282 INTEGER(c_int), INTENT(IN), VALUE :: lun
13283 INTEGER(c_int), INTENT(INOUT) :: ios
13284 END SUBROUTINE openc
13285 END INTERFACE
13286#endif
13287
13288 ierr=0
13289 lun=ithr
13290 ! modification date (=0: open for first time, >0: reopen, <0: unknown )
13291 moddate=yfd(kfile)
13292 ! file name
13293 ioff=sfd(1,kfile)
13294 lfn=sfd(2,kfile)
13295 DO k=1,lfn
13296 fname(k:k)=tfd(ioff+k)
13297 END DO
13298 !print *, " opening binary ", kfile, ithr, moddate, " : ", fname(1:lfn)
13299 ! open
13300 ios=0
13301 IF(kfile <= nfilf) THEN
13302 ! Fortran file
13303 lun=kfile+10
13304 OPEN(lun,file=fname(1:lfn),iostat=ios, form='UNFORMATTED')
13305 print *, ' lun ', lun, ios
13306#ifdef READ_C_FILES
13307 ELSE
13308 ! C file
13309 CALL openc(fname(1:lfn),lfn,lun,ios)
13310#else
13311 WRITE(*,*) 'Opening of C-files not supported.'
13312 ierr=1
13313 RETURN
13314#endif
13315 END IF
13316 IF(ios /= 0) THEN
13317 ierr=1
13318 WRITE(*,*) 'Open error for file ',fname(1:lfn), ios
13319 IF (moddate /= 0) THEN
13320 WRITE(cfile,'(I7)') kfile
13321 CALL peend(15,'Aborted, open error(s) for binary file ' // cfile)
13322 stop 'PEREAD: open error'
13323 ENDIF
13324 RETURN
13325 END IF
13326 ! get status
13327 ios=stat(fname(1:lfn),ibuff)
13328 !print *, ' STAT ', ios, ibuff(10), moddate
13329 IF(ios /= 0) THEN
13330 ierr=1
13331 WRITE(*,*) 'STAT error for file ',fname(1:lfn), ios
13332 ibuff(10)=-1
13333 END IF
13334 ! check/store modification date
13335 IF (moddate /= 0) THEN
13336 IF (ibuff(10) /= moddate) THEN
13337 WRITE(cfile,'(I7)') kfile
13338 CALL peend(19,'Aborted, binary file modified (date) ' // cfile)
13339 stop 'PEREAD: file modified'
13340 END IF
13341 ELSE
13342 yfd(kfile)=ibuff(10)
13343 END IF
13344 RETURN
13345
13346END SUBROUTINE binopn
13347
13353SUBROUTINE bincls(kfile, ithr)
13354 USE mpmod
13355
13356 IMPLICIT NONE
13357 INTEGER(mpi), INTENT(IN) :: kfile
13358 INTEGER(mpi), INTENT(IN) :: ithr
13359
13360 INTEGER(mpi) :: lun
13361
13362#ifdef READ_C_FILES
13363 INTERFACE
13364 SUBROUTINE closec(lun) BIND(c)
13365 USE iso_c_binding
13366 INTEGER(c_int), INTENT(IN), VALUE :: lun
13367 END SUBROUTINE closec
13368 END INTERFACE
13369#endif
13370
13371 lun=ithr
13372 !print *, " closing binary ", kfile, ithr
13373 IF(kfile <= nfilf) THEN ! Fortran file
13374 lun=kfile+10
13375 CLOSE(lun)
13376#ifdef READ_C_FILES
13377 ELSE ! C file
13378 CALL closec(lun)
13379#endif
13380 END IF
13381
13382END SUBROUTINE bincls
13383
13388SUBROUTINE binrwd(kfile)
13389 USE mpmod
13390
13391 IMPLICIT NONE
13392 INTEGER(mpi), INTENT(IN) :: kfile
13393
13394 INTEGER(mpi) :: lun
13395
13396#ifdef READ_C_FILES
13397 INTERFACE
13398 SUBROUTINE resetc(lun) BIND(c)
13399 USE iso_c_binding
13400 INTEGER(c_int), INTENT(IN), VALUE :: lun
13401 END SUBROUTINE resetc
13402 END INTERFACE
13403#endif
13404
13405 !print *, " rewinding binary ", kfile
13406 IF (kfile <= nfilf) THEN
13407 lun=kfile+10
13408 rewind lun
13409#ifdef READ_C_FILES
13410 ELSE
13411 lun=kfile-nfilf
13412 CALL resetc(lun)
13413#endif
13414 END IF
13415
13416END SUBROUTINE binrwd
13417
13419SUBROUTINE ckpgrp
13420 USE mpmod
13421 USE mpdalc
13422
13423 IMPLICIT NONE
13424 INTEGER(mpi) :: i
13425 INTEGER(mpi) :: ipgrp
13426 INTEGER(mpi) :: irank
13427 INTEGER(mpi) :: isize
13428 INTEGER(mpi) :: ivoff
13429 INTEGER(mpi) :: itgbi
13430 INTEGER(mpi) :: j
13431 INTEGER(mpi) :: msize
13432 INTEGER(mpi), PARAMETER :: mxsize = 1000
13433 INTEGER(mpl):: ij
13434 INTEGER(mpl):: length
13435
13436 REAL(mpd), DIMENSION(:), ALLOCATABLE :: auxVectorD
13437 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: auxVectorI
13438 REAL(mpd), DIMENSION(:), ALLOCATABLE :: resParGroup
13439 REAL(mpd), DIMENSION(:), ALLOCATABLE :: blockParGroup
13440 REAL(mpd) :: matij
13441 SAVE
13442
13443 ! maximal group size
13444 msize=0
13445 DO ipgrp=1,nvpgrp
13446 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13447 IF (isize <= mxsize) THEN
13448 msize=max(msize,isize)
13449 ELSE
13450 print *, ' CKPGRP: par. group', ipgrp, ' not checked -- too large: ', isize
13451 END IF
13452 END DO
13453 IF (msize == 0) RETURN
13454
13455 ! (matrix) block for parameter groups
13456 length=int(msize,mpl)*(int(msize,mpl)+1)/2
13457 CALL mpalloc(blockpargroup,length,'(matrix) block for parameter groups (D)')
13458 length=msize
13459 CALL mpalloc(respargroup,length,'residuals for parameter groups (D)') ! double aux 1
13460 CALL mpalloc(auxvectori,length,'auxiliary array (I)') ! int aux 1
13461 CALL mpalloc(auxvectord,length,'auxiliary array (D)') ! double aux 1
13462
13463 respargroup=0
13464 print *
13465 print *,' CKPGRP par. group first label size rank'
13466 DO ipgrp=1,nvpgrp
13467 isize=globalallindexgroups(ipgrp+1)-globalallindexgroups(ipgrp)
13468 IF (isize > mxsize) cycle
13469 ! copy matrix block
13470 ivoff=globalallindexgroups(ipgrp)-1
13471 ij=0
13472 DO i=1,isize
13473 DO j=1,i
13474 ij=ij+1
13475 blockpargroup(ij)=matij(ivoff+i,ivoff+j)
13476 END DO
13477 END DO
13478 ! inversion of matrix block
13479 CALL sqminv(blockpargroup,respargroup,isize,irank, auxvectord, auxvectori)
13480 !
13482 IF (isize == irank) THEN
13483 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank
13484 ELSE
13485 ndefpg=ndefpg+1
13486 print *,' CKPGRP ', ipgrp, globalparlabelindex(1,itgbi), isize, irank, ' rank deficit !!!'
13487 END IF
13488 END DO
13489
13490 ! clean up
13491 CALL mpdealloc(auxvectord)
13492 CALL mpdealloc(auxvectori)
13493 CALL mpdealloc(respargroup)
13494 CALL mpdealloc(blockpargroup)
13495
13496END SUBROUTINE ckpgrp
13497
13499SUBROUTINE chkmat
13500 USE mpmod
13501
13502 IMPLICIT NONE
13503 INTEGER(mpl) :: i
13504 INTEGER(mpl) :: nan
13505 INTEGER(mpl) :: neg
13506
13507 print *, ' Checking global matrix(D) for NANs ', size(globalmatd,kind=mpl)
13508 nan=0
13509 DO i=1,size(globalmatd,kind=mpl)
13510 IF(.NOT.(globalmatd(i) <= 0.0_mpd).AND..NOT.(globalmatd(i) > 0.0_mpd)) THEN
13511 nan=nan+1
13512 print *, ' i, nan ', i, nan
13513 END IF
13514 END DO
13515
13516 IF (matsto > 1) RETURN
13517 print *
13518 print *, ' Checking diagonal elements ', nagb
13519 neg=0
13520 DO i=1,nagb
13521 IF(.NOT.(globalmatd(globalrowoffsets(i)+i) > 0.0_mpd)) THEN
13522 neg=neg+1
13523 print *, ' i, neg ', i, neg
13524 END IF
13525 END DO
13526 print *
13527 print *, ' CHKMAT summary ', nan, neg
13528 print *
13529
13530END SUBROUTINE chkmat
13531
13532
13533! ----- accurate summation ----(from mpnum) ---------------------------------
13534
13544
13545SUBROUTINE addsums(ithrd, chi2, ndf, dw)
13546 USE mpmod
13547
13548 IMPLICIT NONE
13549 REAL(mpd), INTENT(IN) :: chi2
13550 INTEGER(mpi), INTENT(IN) :: ithrd
13551 INTEGER(mpi), INTENT(IN) :: ndf
13552 REAL(mpd), INTENT(IN) :: dw
13553
13554 INTEGER(mpl) ::nadd
13555 REAL(mpd) ::add
13556 ! ...
13557 add=chi2*dw ! apply (file) weight
13558 nadd=int(add,mpl) ! convert to integer
13559 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+nadd ! sum integer
13560 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)+(add-real(nadd,mpd)) ! sum remainder
13561 IF(globalchi2sumd(ithrd) > 16.0_mpd) THEN ! + - 16
13562 globalchi2sumd(ithrd)=globalchi2sumd(ithrd)-16.0_mpd
13563 globalchi2sumi(ithrd)=globalchi2sumi(ithrd)+16_mpl
13564 END IF
13565 globalndfsum(ithrd)=globalndfsum(ithrd)+int(ndf,mpl)
13566 globalndfsumw(ithrd)=globalndfsumw(ithrd)+real(ndf,mpd)*dw
13567 RETURN
13568END SUBROUTINE addsums
13569
13577
13578SUBROUTINE getsums(chi2, ndf, wndf)
13579 USE mpmod
13580
13581 IMPLICIT NONE
13582 REAL(mpd), INTENT(OUT) ::chi2
13583 INTEGER(mpl), INTENT(OUT) ::ndf
13584 REAL(mpd), INTENT(OUT) ::wndf
13585 ! ...
13586 chi2=sum(globalchi2sumd)+real(sum(globalchi2sumi),mpd)
13587 ndf=sum(globalndfsum)
13588 wndf=sum(globalndfsumw)
13589 globalchi2sumd=0.0_mpd
13590 globalchi2sumi=0_mpl
13591 globalndfsum=0_mpl
13592 globalndfsumw=0.0_mpd
13593 RETURN
13594END SUBROUTINE getsums
allocate array
Definition: mpdalc.f90:36
deallocate array
Definition: mpdalc.f90:42
subroutine ptlopt(nf, m, slopes, steps)
Get details.
Definition: linesrch.f90:259
subroutine ptline(n, x, f, g, s, step, info)
Perform linesearch.
Definition: linesrch.f90:90
subroutine ptldef(gtole, stmax, minfe, maxfe)
Initialize line search.
Definition: linesrch.f90:233
subroutine ptlprt(lunp)
Print line search data.
Definition: linesrch.f90:295
subroutine pcbits(npgrp, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:1034
subroutine ndbits(npgrp, ndims, nsparr, ihst)
Analyze bit fields.
Definition: mpbits.f90:306
subroutine clbits(in, jreqpe, jhispe, jsngpe, jextnd, idimb, ispc)
Calculate bit (field) array size, encoding.
Definition: mpbits.f90:183
subroutine plbits(in, inar, inac, idimb)
Calculate bit field array size (PARDISO).
Definition: mpbits.f90:256
subroutine spbits(npgrp, nsparr, nsparc)
Create sparsity information.
Definition: mpbits.f90:1221
subroutine irbits(i, j)
Fill bit fields (counters, rectangular part).
Definition: mpbits.f90:150
subroutine clbmap(in)
Clear (additional) bit map.
Definition: mpbits.f90:1358
subroutine inbmap(im, jm)
Fill bit map.
Definition: mpbits.f90:1390
subroutine ckbits(npgrp, ndims)
Check sparsity of matrix.
Definition: mpbits.f90:1128
subroutine ggbmap(ipgrp, npair, npgrp)
Get paired (parameter) groups from map.
Definition: mpbits.f90:1470
subroutine prbits(npgrp, nsparr)
Analyze bit fields.
Definition: mpbits.f90:935
subroutine gpbmap(ngroup, npgrp, npair)
Get pairs (statistic) from map.
Definition: mpbits.f90:1424
subroutine pblbits(npgrp, ibsize, nsparr, nsparc)
Analyze bit fields.
Definition: mpbits.f90:762
subroutine pbsbits(npgrp, ibsize, nnzero, nblock, nbkrow)
Analyze bit fields.
Definition: mpbits.f90:579
subroutine inbits(im, jm, inc)
Fill bit fields (counters, triangular part).
Definition: mpbits.f90:74
subroutine hmplun(lunw)
unit for output
Definition: mphistab.f90:329
subroutine gmpdef(ig, ityp, text)
book, reset XY storage
Definition: mphistab.f90:702
subroutine gmpxy(ig, x, y)
add (X,Y) pair
Definition: mphistab.f90:767
subroutine hmpdef(ih, xa, xb, text)
book, reset histogram
Definition: mphistab.f90:122
subroutine gmplun(lunw)
unit for output
Definition: mphistab.f90:975
subroutine gmpxyd(ig, x, y, dx, dy)
add (X,Y,DX,DY)
Definition: mphistab.f90:782
subroutine hmpwrt(ih)
write histogram text file
Definition: mphistab.f90:341
subroutine gmpwrt(ig)
write XY text file
Definition: mphistab.f90:987
subroutine hmpldf(ih, text)
book, reset log histogram
Definition: mphistab.f90:158
subroutine gmprnt(ig)
print XY data
Definition: mphistab.f90:869
subroutine hmpent(ih, x)
entry flt.pt.
Definition: mphistab.f90:183
subroutine hmplnt(ih, ix)
entry integer
Definition: mphistab.f90:223
subroutine gmpms(ig, x, y)
mean sigma(X) from Y
Definition: mphistab.f90:805
subroutine hmprnt(ih)
print, content vert
Definition: mphistab.f90:254
subroutine monend()
End monitoring.
Definition: mpmon.f90:83
subroutine monini(l, n1, n2)
Initialize monitoring.
Definition: mpmon.f90:43
subroutine dbavat(v, a, w, n, m, iopt)
A V AT product (similarity).
Definition: mpnum.f90:1390
subroutine sqminl(v, b, n, nrank, diag, next, vk, mon)
Matrix inversion for LARGE matrices.
Definition: mpnum.f90:231
subroutine devsol(n, diag, u, b, x, work)
Solution by diagonalization.
Definition: mpnum.f90:650
subroutine dbsvxl(v, a, b, n)
Product LARGE symmetric matrix, vector.
Definition: mpnum.f90:1309
subroutine devrot(n, diag, u, v, work, iwork)
Diagonalization.
Definition: mpnum.f90:370
subroutine sort22l(a, b, n)
Quick sort 2 with index.
Definition: mpnum.f90:1982
subroutine dbavats(v, a, is, w, n, m, iopt, sc)
A V AT product (similarity, sparse).
Definition: mpnum.f90:1471
subroutine sqmibb(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag, evdmin, evdmax)
Bordered band matrix.
Definition: mpnum.f90:3119
subroutine chslv2(g, x, n)
Solve A*x=b using Cholesky decomposition.
Definition: mpnum.f90:954
subroutine sort1k(a, n)
Quick sort 1.
Definition: mpnum.f90:1715
subroutine sqminv(v, b, n, nrank, diag, next)
Matrix inversion and solution.
Definition: mpnum.f90:98
subroutine presols(p, n, b, nm, cu, a, l, s, x, y)
Constrained (sparse) preconditioner, solution.
Definition: mpnum.f90:2981
subroutine devinv(n, diag, u, v)
Inversion by diagonalization.
Definition: mpnum.f90:697
subroutine sqmibb2(v, b, n, nbdr, nbnd, inv, nrank, vbnd, vbdr, aux, vbk, vzru, scdiag, scflag, evdmin, evdmax)
Band bordered matrix.
Definition: mpnum.f90:3391
subroutine equdecs(n, m, b, nm, ls, c, india, l, nrkd, nrkd2)
Decomposition of (sparse) equilibrium systems.
Definition: mpnum.f90:2487
subroutine chdec2(g, n, nrank, evmax, evmin, mon)
Cholesky decomposition (LARGE pos.
Definition: mpnum.f90:892
subroutine sort2k(a, n)
Quick sort 2.
Definition: mpnum.f90:1800
subroutine devsig(n, diag, u, b, coef)
Calculate significances.
Definition: mpnum.f90:612
subroutine dbsvx(v, a, b, n)
Product symmetric matrix, vector.
Definition: mpnum.f90:1265
subroutine equslvs(n, m, b, nm, c, india, l, x)
Solution of (sparse) equilibrium systems (after decomposition).
Definition: mpnum.f90:2614
subroutine precons(p, n, b, nm, c, cu, a, l, s, nrkd)
Constrained (sparse) preconditioner, decomposition.
Definition: mpnum.f90:2882
subroutine sort2i(a, n)
Quick sort 2 with index.
Definition: mpnum.f90:1893
subroutine qlpssq(aprod, B, m, t)
Partial similarity transformation by Q(t).
Definition: mpqldec.f90:712
subroutine qldecb(a, bpar, bcon, rcon)
QL decomposition (for disjoint block matrix).
Definition: mpqldec.f90:220
subroutine qlmlq(x, m, t)
Multiply left by Q(t) (per block).
Definition: mpqldec.f90:405
subroutine qlsetb(ib)
Set block.
Definition: mpqldec.f90:1019
subroutine qlbsub(d, y)
Backward substitution (per block).
Definition: mpqldec.f90:992
subroutine qlini(n, m, l, s, k)
Initialize QL decomposition.
Definition: mpqldec.f90:62
subroutine qlgete(emin, emax)
Get eigenvalues.
Definition: mpqldec.f90:956
subroutine qlssq(aprod, A, s, roff, t)
Similarity transformation by Q(t).
Definition: mpqldec.f90:574
subroutine mptest
Generate test files.
Definition: mptest1.f90:79
subroutine mptst2(imodel)
Generate test files.
Definition: mptest2.f90:112
integer(mpi) function matint(pat, text, npat, ntext)
Approximate string matching.
Definition: mptext.f90:309
subroutine ratext(text, nums, dnum, mnum)
Translate text.
Definition: mptext.f90:51
subroutine rltext(text, ia, ib, nab)
Analyse text range.
Definition: mptext.f90:256
MINRES solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite and/...
subroutine, public minres(n, Aprod, Msolve, b, shift, checkA, precon, x, itnlim, nout, rtol, istop, itn, Anorm, Acond, rnorm, Arnorm, ynorm)
Solution of linear equation system.
MINRESQLP solves symmetric systems Ax = b or min ||Ax - b||_2, where the matrix A may be indefinite a...
subroutine, public minresqlp(n, Aprod, b, shift, Msolve, disable, nout, itnlim, rtol, maxxnorm, trancond, Acondlim, x, istop, itn, rnorm, Arnorm, xnorm, Anorm, Acond)
Solution of linear equation system or least squares problem.
(De)Allocate vectors and arrays.
Definition: mpdalc.f90:24
integer(mpl) maxwordsalloc
peak dynamic memory allocation (words)
Definition: mpdalc.f90:30
integer(mpi) printflagalloc
print flag for dynamic allocations
Definition: mpdalc.f90:33
Definition of constants.
Definition: mpdef.f90:24
integer, parameter mpl
long integer
Definition: mpdef.f90:36
integer, parameter mps
single precision
Definition: mpdef.f90:37
integer, parameter mpi
integer
Definition: mpdef.f90:35
Parameters, variables, dynamic arrays.
Definition: mpmod.f90:28
integer(mpl), dimension(:), allocatable csr3columnlist
list of columns for sparse matrix
Definition: mpmod.f90:284
integer(mpl) mszpcc
(integrated block) matrix size for constraint matrix for preconditioner
Definition: mpmod.f90:145
real(mpd), dimension(:), allocatable workspaceeigenvectors
workspace eigen vectors
Definition: mpmod.f90:232
real(mpd), dimension(:), allocatable globalparameter
global parameters (start values + sum(x_i))
Definition: mpmod.f90:198
integer(mpl) nrecal
number of records
Definition: mpmod.f90:168
integer(mpi), dimension(:), allocatable localglobalmap
matrix correlating local and global par, map (counts)
Definition: mpmod.f90:315
type(listitem), dimension(:), allocatable listparameters
list of parameters from steering file
Definition: mpmod.f90:332
integer(mpi), dimension(:), allocatable vecparblockconoffsets
global par block (constraint) offsets
Definition: mpmod.f90:299
real(mpd), dimension(:), allocatable lapacktau
LAPACK TAU (QL decomp.)
Definition: mpmod.f90:238
integer(mpl) mszprd
(integrated block) matrix size for (constraint) product matrix
Definition: mpmod.f90:143
integer(mpi) lunmon
unit for monitoring output file
Definition: mpmod.f90:127
real(mpd), dimension(:), allocatable vecconsresiduals
residuals of constraints
Definition: mpmod.f90:244
integer(mpl) nrec1
record number with largest residual
Definition: mpmod.f90:53
integer(mpi) iskpec
flag for skipping empty constraints (no variable parameters)
Definition: mpmod.f90:106
integer(mpi) mnrsel
number of MINRES error labels in LBMNRS (calc err, corr with SOLGLO)
Definition: mpmod.f90:89
real(mps) actfun
actual function change
Definition: mpmod.f90:67
integer(mpi), dimension(:), allocatable globalindexusage
indices of global par in record
Definition: mpmod.f90:292
real(mps) regpre
default presigma
Definition: mpmod.f90:72
integer(mpi) mnrsit
total number of MINRES internal iterations
Definition: mpmod.f90:93
integer(mpi), dimension(10) ipdbsz
PARDISO, list of block sizes to be tried (by PBSBITS)
Definition: mpmod.f90:185
integer(mpi) metsol
solution method (1: inversion, 2: diagonalization, 3: decomposition, 4: MINRES, 5: MINRES-QLP,...
Definition: mpmod.f90:34
integer(mpi) nagbn
max number of global paramters per record
Definition: mpmod.f90:146
character(len=74) textl
name of current MP 'module' (step)
Definition: mpmod.f90:159
integer(mpi) nloopn
number of data reading, fitting loops
Definition: mpmod.f90:43
integer(mpl) sumrecords
sum of records
Definition: mpmod.f90:190
integer(mpi) mreqpe
min number of pair entries
Definition: mpmod.f90:80
integer(mpi) memdbg
debug flag for memory management
Definition: mpmod.f90:96
integer(mpi), dimension(100) lbmnrs
MINRES error labels.
Definition: mpmod.f90:179
integer(mpi) ncgrp
number of (disjoint) constraint groups
Definition: mpmod.f90:140
real(mpd) mrtcnd
transition (QR -> QLP) (matrix) condition for MINRES-QLP
Definition: mpmod.f90:62
real(mpd), dimension(:), allocatable vbk
local fit 'matrix for border solution'
Definition: mpmod.f90:308
real(mps) prange
range (-PRANGE..PRANGE) for histograms of pulls, norm.
Definition: mpmod.f90:97
integer(mpi) matsto
(global) matrix storage mode (0: unpacked, 1: full = packed, 2: sparse(custom), 3: sparse(CSR3,...
Definition: mpmod.f90:35
integer(mpi), dimension(:,:), allocatable matconssort
keys and index for sorting
Definition: mpmod.f90:249
character(len=1024) cpostproc
post processing string
Definition: mpmod.f90:350
real(mpd), dimension(:), allocatable lapackwork
LAPACK work array.
Definition: mpmod.f90:239
integer(mpi) monpg1
progress monitoring, repetition rate start value
Definition: mpmod.f90:116
integer(mpi), dimension(:,:), allocatable readbufferinfo
buffer management (per thread)
Definition: mpmod.f90:286
integer(mpi) nhistp
flag for histogram printout
Definition: mpmod.f90:65
integer(mpl), dimension(:), allocatable csr3rowoffsets
row offsets for column list
Definition: mpmod.f90:283
real(mpd), dimension(:), allocatable globalparcopy
copy of global parameters
Definition: mpmod.f90:199
real(mpd), dimension(:), allocatable lapackql
LAPACK QL (QL decomp.)
Definition: mpmod.f90:237
real(mpd), dimension(2) dscerr
scaling factors for errors of 'global' and 'local' measurement
Definition: mpmod.f90:112
real(mps) chhuge
cut in terms of 3-sigma for unreasonable data, all iterations
Definition: mpmod.f90:50
integer(mpi), dimension(:), allocatable sparsematrixcolumns
(compressed) list of columns for sparse matrix
Definition: mpmod.f90:280
integer(mpl), dimension(:,:), allocatable sparsematrixoffsets
row offsets for column list, sparse matrix elements
Definition: mpmod.f90:281
integer(mpi) iteren
entries cut is iterated for parameters with less entries (if > mreqenf)
Definition: mpmod.f90:105
integer(mpi), dimension(:,:), allocatable matconsranges
parameter ranges for constraints
Definition: mpmod.f90:248
integer(mpi) lunkno
flag for unkown keywords
Definition: mpmod.f90:46
integer(mpi), dimension(:), allocatable scflag
local fit workspace (I)
Definition: mpmod.f90:311
real(mpd), parameter measbinsize
bins size for monitoring
Definition: mpmod.f90:178
integer(mpi) mdebug
debug flag (number of records to print)
Definition: mpmod.f90:38
integer(mpi) npblck
number of (disjoint) parameter blocks (>1: block diagonal storage)
Definition: mpmod.f90:139
real(mpd), dimension(:), allocatable matconsproduct
product matrix of constraints
Definition: mpmod.f90:243
integer(mpi), dimension(:), allocatable yfd
binary file: modification date
Definition: mpmod.f90:365
integer(mpi) nxlow
(max of) global parameters with too few accepted entries for icalcm=1
Definition: mpmod.f90:173
integer(mpl) ndgb
number of global derivatives read
Definition: mpmod.f90:153
real(mps) value1
largest residual
Definition: mpmod.f90:55
integer(mpi) ipddbg
flag for debugging Intel oneMKL PARDISO
Definition: mpmod.f90:121
real(mpd), dimension(:), allocatable localcorrections
local fit corrections (to residuals)
Definition: mpmod.f90:313
integer(mpl) nrec3
(1.) record number with error
Definition: mpmod.f90:79
real(mps) chirem
cut in terms of 3-sigma cut, other iterations, approaching 1.
Definition: mpmod.f90:49
real(mpd), dimension(:), allocatable localglobalmatrix
matrix correlating local and global par, content
Definition: mpmod.f90:314
integer(mpi) mhispe
upper bound for pair entry histogrammimg
Definition: mpmod.f90:81
integer(mpi) nfgb
number of fit parameters
Definition: mpmod.f90:133
integer(mpi), dimension(:,:), allocatable kfd
(1,.)= number of records in file, (2,..)= file order
Definition: mpmod.f90:356
real(mpd), dimension(:), allocatable globalchi2sumd
fractional part of Chi2 sum
Definition: mpmod.f90:221
integer(mpi) icheck
flag for checking input only (no solution determined)
Definition: mpmod.f90:103
integer(mpi), dimension(:), allocatable jfd
file: number of accepted records
Definition: mpmod.f90:358
integer(mpl) nzgb
number of zero global derivatives read
Definition: mpmod.f90:154
integer(mpl) nrecer
record with error (rank deficit or Not-a-Number) for printout
Definition: mpmod.f90:78
integer(mpi) matmon
record interval for monitoring of (sparse) matrix construction
Definition: mpmod.f90:86
integer(mpi) nbndx
max band width for local fit
Definition: mpmod.f90:77
type(listitem), dimension(:), allocatable listconstraints
list of constraints from steering file
Definition: mpmod.f90:336
real(mpd), dimension(:), allocatable globalmatd
global matrix 'A' (double, full or sparse)
Definition: mpmod.f90:207
real(mpr8), dimension(:), allocatable readbufferdatad
double data
Definition: mpmod.f90:290
type(listitem), dimension(:), allocatable listmeasurements
list of (external) measurements from steering file
Definition: mpmod.f90:339
integer(mpi) lsinfo
line search: returned information
Definition: mpmod.f90:164
integer(mpi) nregul
regularization flag
Definition: mpmod.f90:70
integer(mpi) nfilw
number of weighted binary files
Definition: mpmod.f90:374
integer(mpi) ndefpg
number of parameter groups with rank deficit (from inversion)
Definition: mpmod.f90:170
integer(mpi), dimension(:), allocatable paircounter
number of paired parameters (in equations)
Definition: mpmod.f90:295
integer(mpi) nummeasurements
number of (external) measurements from steering file
Definition: mpmod.f90:337
integer(mpl) nrec2
record number with largest chi^2/Ndf
Definition: mpmod.f90:54
integer(mpi) ndimbuf
default read buffer size (I/F words, half record length)
Definition: mpmod.f90:375
real(mpd) fvalue
function value (chi2 sum) solution
Definition: mpmod.f90:180
real(mpd), dimension(:), allocatable globalcorrections
correction x_i (from A*x_i=b_i in iteration i)
Definition: mpmod.f90:200
real(mps), dimension(:), allocatable cfd
file: chi2 sum
Definition: mpmod.f90:361
real(mps) regula
regularization parameter, add regula * norm(global par.) to objective function
Definition: mpmod.f90:71
integer(mpi) nspc
number of precision for sparse global matrix (1=D, 2=D+F)
Definition: mpmod.f90:175
integer(mpi) nfilc
number of C binary files
Definition: mpmod.f90:373
integer(mpi) nagb
number of all parameters (var.
Definition: mpmod.f90:132
integer(mpi) nmiss1
rank deficit for constraints
Definition: mpmod.f90:171
integer(mpi), dimension(:), allocatable globalparhashtable
global parameters hash table
Definition: mpmod.f90:262
integer(mpi) nalow
(sum of) global parameters with too few accepted entries
Definition: mpmod.f90:172
integer(mpi) iscerr
flag for scaling of errors
Definition: mpmod.f90:111
real(mpd) sumndf
weighted sum(ndf)
Definition: mpmod.f90:182
integer(mpi), dimension(2) nbndr
number of records with bordered band matrix for local fit (upper/left, lower/right)
Definition: mpmod.f90:75
integer(mpl), dimension(:), allocatable lapackipiv
LAPACK IPIV (pivot)
Definition: mpmod.f90:240
integer(mpi) iterat
iterations in solution
Definition: mpmod.f90:69
real(mpd) flines
function value line search
Definition: mpmod.f90:181
integer(mpi), dimension(:), allocatable meashists
measurement histograms (100 bins per thread)
Definition: mpmod.f90:256
integer(mpi), dimension(:), allocatable globalindexranges
global par ranges
Definition: mpmod.f90:297
integer(mpi) mthrd
number of (OpenMP) threads
Definition: mpmod.f90:84
integer(mpi) mbandw
band width of preconditioner matrix
Definition: mpmod.f90:44
integer(mpl) lplwrk
length of LAPACK WORK array
Definition: mpmod.f90:236
real(mps) dwcut
down-weight fraction cut
Definition: mpmod.f90:57
integer(mpl), dimension(:), allocatable globalcounter
global counter (entries in 'x')
Definition: mpmod.f90:211
real(mps), dimension(:), allocatable globalmatf
global matrix 'A' (float part for compressed sparse)
Definition: mpmod.f90:208
integer(mpi), dimension(:,:), allocatable matconsgroups
start of constraint groups, parameter range
Definition: mpmod.f90:250
real(mps), dimension(0:8) times
cpu time counters
Definition: mpmod.f90:157
integer(mpi) minrecordsinblock
min.
Definition: mpmod.f90:192
integer(mpi), dimension(:), allocatable localglobalstructure
matrix correlating local and global par, (sparsity) structure
Definition: mpmod.f90:316
real(mpd), dimension(:), allocatable globalndfsumw
weighted NDF sum
Definition: mpmod.f90:224
integer(mpi) naeqn
max number of equations (measurements) per record
Definition: mpmod.f90:148
integer(mpi) nfilb
number of binary files
Definition: mpmod.f90:371
real(mpd), dimension(:), allocatable vzru
local fit 'border solution'
Definition: mpmod.f90:309
real(mpd), dimension(:), allocatable globalparpreweight
weight from pre-sigma
Definition: mpmod.f90:203
integer(mpi) ictest
test mode '-t'
Definition: mpmod.f90:33
real(mpd), dimension(:), allocatable vbdr
local fit border part of 'A'
Definition: mpmod.f90:306
integer(mpi) mdebg2
number of measurements for record debug printout
Definition: mpmod.f90:39
integer(mpi), dimension(:,:), allocatable globaltotindexgroups
Definition: mpmod.f90:276
integer(mpi), dimension(:), allocatable vecconsgroupcounts
counter for constraint groups
Definition: mpmod.f90:251
real(mps) deltim
cpu time difference
Definition: mpmod.f90:166
integer(mpi) igcorr
flag for output of global correlations for inversion, =0: none
Definition: mpmod.f90:95
integer(mpi), dimension(-8:0) globalparheader
global parameters (mapping) header
Definition: mpmod.f90:265
integer(mpi) lencomments
length of list of (global parameter) comments from steering file
Definition: mpmod.f90:340
integer(mpl), dimension(:), allocatable offprecond
preconditioner (block matrix) offsets
Definition: mpmod.f90:219
real(mpd), dimension(:), allocatable vecconssolution
solution for constraint elimination
Definition: mpmod.f90:245
integer(mpi) nfiles
number of files
Definition: mpmod.f90:370
integer(mpi) ipcntr
flag for output of global parameter counts (entries), =0: none, =1: local fits, >1: binary files
Definition: mpmod.f90:100
integer(mpl) negb
number of equations read with global parameters
Definition: mpmod.f90:152
integer(mpi) keepopen
flag for keeping binary files open
Definition: mpmod.f90:113
real(mpd), dimension(:), allocatable workspacediagonalization
workspace diag.
Definition: mpmod.f90:230
real(mps), dimension(:), allocatable wfd
binary file: weight
Definition: mpmod.f90:363
real(mpd), dimension(:), allocatable matprecond
preconditioner matrix (band and other parts)
Definition: mpmod.f90:216
integer(mpi) ntgb
total number of global parameters
Definition: mpmod.f90:130
real(mps) angras
angle between gradient and search direction
Definition: mpmod.f90:68
type(listitemc), dimension(:), allocatable listcomments
list of comments from steering file
Definition: mpmod.f90:341
integer(mpi) mthrdr
number of threads for reading binary files
Definition: mpmod.f90:92
integer(mpi) numreadbuffer
number of buffers (records) in (read) block
Definition: mpmod.f90:188
integer(mpi) imonmd
monitoring mode: 0:residuals (normalized to average error), 1:pulls
Definition: mpmod.f90:110
character(len=1024) filnam
name of steering file
Definition: mpmod.f90:366
integer(mpi) lunlog
unit for logfile
Definition: mpmod.f90:128
integer(mpi) ncblck
number of (non overlapping) constraint blocks
Definition: mpmod.f90:141
real(mps), dimension(3) fcache
read cache, average fill level; write cache; dynamic size
Definition: mpmod.f90:91
real(mps) wolfc2
C_2 of strong Wolfe condition.
Definition: mpmod.f90:60
real(mpd), dimension(:), allocatable workspacerow
(pivot) row of global matrix (for global corr.)
Definition: mpmod.f90:228
integer(mpi) maxrecordsinblock
max.
Definition: mpmod.f90:193
real(mpd) mrestl
tolerance criterion for MINRES-QLP
Definition: mpmod.f90:61
real(mpd), dimension(:), allocatable globalparpresigma
pre-sigma for global parameters
Definition: mpmod.f90:202
integer(mpi) icelim
flag for using elimination (instead of multipliers) for constraints
Definition: mpmod.f90:102
integer(mpi) mitera
number of iterations
Definition: mpmod.f90:42
integer(mpi) lenpardiso
length of list of Intel oneMKL PARDISO parameters (indices 1..64)
Definition: mpmod.f90:344
integer(mpi) nbdrx
max border size for local fit
Definition: mpmod.f90:76
integer(mpi), dimension(:,:), allocatable globalparlabelindex
global parameters label, total -> var.
Definition: mpmod.f90:259
real(mpd), dimension(:), allocatable scdiag
local fit workspace (D)
Definition: mpmod.f90:310
integer(mpi), dimension(:), allocatable readbufferdatai
integer data
Definition: mpmod.f90:288
integer(mpi) mextnd
flag for extended storage (both 'halves' of sym.
Definition: mpmod.f90:83
integer(mpi), dimension(:,:), allocatable sfd
offset (1,..), length (2,..) of binary file name in tfd
Definition: mpmod.f90:364
integer(mpi) lenconstraints
length of list of constraints from steering file
Definition: mpmod.f90:335
integer(mpi), dimension(:), allocatable blockprecond
preconditioner (constraint) blocks
Definition: mpmod.f90:218
integer(mpi) lenparameters
list items from steering file
Definition: mpmod.f90:331
integer(mpi) lprecm
additional flag for preconditioner (band) matrix (>0: preserve rank by skyline matrix)
Definition: mpmod.f90:45
integer(mpi) ndefec
rank deficit for global matrix (from inversion)
Definition: mpmod.f90:169
integer(mpi) lenpostproc
length of post processing string
Definition: mpmod.f90:349
integer(mpl) nrecp2
record number with printout
Definition: mpmod.f90:52
integer(mpl) nrec
number of records read
Definition: mpmod.f90:149
integer(mpi), dimension(:,:), allocatable matparblockoffsets
global par block offsets (parameter, constraint blocks)
Definition: mpmod.f90:298
integer(mpl) nrecpr
record number with printout
Definition: mpmod.f90:51
integer(mpl), dimension(:), allocatable ifd
file: integrated record numbers (=offset)
Definition: mpmod.f90:357
integer(mpi) nofeas
flag for skipping making parameters feasible
Definition: mpmod.f90:64
integer(mpi) matbsz
(global) matrix (fixed) block size, only used for BSR3 storage mode (Intel oneMKL PARDISO)
Definition: mpmod.f90:36
integer(mpi) nfnam
length of sterring file name
Definition: mpmod.f90:367
real rstart
cpu start time for solution iterations
Definition: mpmod.f90:165
integer(mpi), dimension(:), allocatable writebufferindices
write buffer for indices
Definition: mpmod.f90:320
integer(mpi) iforce
switch to SUBITO for (global) rank defects if zero
Definition: mpmod.f90:94
real(mpd), dimension(:), allocatable workspacelinesearch
workspace line search
Definition: mpmod.f90:229
integer(mpi), dimension(:), allocatable globalparvartototal
global parameters variable -> total index
Definition: mpmod.f90:263
real(mpd), dimension(:), allocatable clmat
local fit matrix 'A' (in A*x=b)
Definition: mpmod.f90:302
integer(mpi), dimension(:), allocatable lfd
length of file name
Definition: mpmod.f90:354
integer(mpi) ntpgrp
number of parameter groups
Definition: mpmod.f90:136
character, dimension(:), allocatable tfd
file names (concatenation)
Definition: mpmod.f90:368
integer(mpi) ncgbe
number of empty constraints (no variable parameters)
Definition: mpmod.f90:135
integer(mpi) mprint
print flag (0: minimal, 1: normal, >1: more)
Definition: mpmod.f90:37
integer(mpi), dimension(:), allocatable vecconsstart
start of constraint in listConstraints (unsorted input)
Definition: mpmod.f90:247
integer(mpi) nummeas
number of measurement groups for monitoring
Definition: mpmod.f90:177
integer(mpi) lvllog
log level
Definition: mpmod.f90:129
integer(mpi), dimension(3) nprecond
number of constraints (blocks), matrix size for preconditioner
Definition: mpmod.f90:144
integer(mpi) nalcn
max number of local paramters per record
Definition: mpmod.f90:147
integer(mpi), dimension(:), allocatable globalparcomments
global parameters comments
Definition: mpmod.f90:205
integer(mpi) mreqenf
required number of entries (for variable global parameter from binary Files)
Definition: mpmod.f90:40
real(mps) value2
largest chi^2/Ndf
Definition: mpmod.f90:56
integer(mpi) icalcm
calculation mode (for XLOOPN) , >0: calculate matrix
Definition: mpmod.f90:74
integer(mpi) mcount
flag for grouping and counting global parameters on equlation (0) or record (1) level
Definition: mpmod.f90:115
real(mps), dimension(:), allocatable ofd
file: option
Definition: mpmod.f90:362
integer(mpi) ireeof
flag for treating (binary file) read errors as end-of-file
Definition: mpmod.f90:114
integer(mpi) ifile
current file (index)
Definition: mpmod.f90:369
real(mps) delfun
expected function change
Definition: mpmod.f90:66
integer(mpi) iitera
MINRES iterations.
Definition: mpmod.f90:162
integer(mpl) skippedrecords
number of skipped records (buffer too small)
Definition: mpmod.f90:191
integer(mpi) lenmeasurements
length of list of (external) measurements from steering file
Definition: mpmod.f90:338
real(mps) wolfc1
C_1 of strong Wolfe condition.
Definition: mpmod.f90:59
real(mpd), dimension(:), allocatable aux
local fit 'solutions for border rows'
Definition: mpmod.f90:307
integer(mpi) napgrp
number of all parameter groups (variable + Lagrange mult.)
Definition: mpmod.f90:138
integer(mpl) nrecd
number of records read containing doubles
Definition: mpmod.f90:150
integer(mpi), dimension(:,:), allocatable localequations
indices (ISJAJB) for local equations (measurements)
Definition: mpmod.f90:312
integer(mpi), dimension(:), allocatable globalallpartogroup
all parameters variable -> group index
Definition: mpmod.f90:264
integer(mpi), dimension(:), allocatable backindexusage
list of global par in record
Definition: mpmod.f90:293
integer(mpi), dimension(:), allocatable ibandh
local fit 'band width histogram' (band size autodetection)
Definition: mpmod.f90:303
integer(mpi) isubit
subito flag '-s'
Definition: mpmod.f90:58
integer(mpi), dimension(:), allocatable indprecond
preconditioner pointer array
Definition: mpmod.f90:217
real(mps) dflim
convergence limit
Definition: mpmod.f90:155
integer(mpi) ncache
buffer size for caching (default 100MB per thread)
Definition: mpmod.f90:90
integer(mpi) mxrec
max number of records
Definition: mpmod.f90:85
integer(mpi) mpdbsz
PARDISO, number of block sizes to be tried (by PBSBITS)
Definition: mpmod.f90:184
integer(mpi) lfitnp
local fit: number of iteration to calculate pulls
Definition: mpmod.f90:87
integer(mpl), dimension(6) nrejec
rejected records
Definition: mpmod.f90:156
integer(mpl), dimension(:), allocatable globalparlabelcounter
global parameters label counters
Definition: mpmod.f90:260
integer(mpi) lcalcm
last calclation mode
Definition: mpmod.f90:174
real(mpd), dimension(:), allocatable globalvector
global vector 'x' (in A*x=b)
Definition: mpmod.f90:209
real(mpd), dimension(:), allocatable writebufferupdates
write buffer for update matrices
Definition: mpmod.f90:321
integer(mpi) irslvrc
flag for resolving redundancy constraints (two equivalent parameter groups)
Definition: mpmod.f90:107
real(mpd), dimension(:), allocatable workspaced
(general) workspace (D)
Definition: mpmod.f90:226
integer(mpl) neqn
number of equations (measurements) read
Definition: mpmod.f90:151
integer(mpi) measbins
number of bins per measurement for monitoring
Definition: mpmod.f90:109
integer(mpl) mszcon
(integrated block) matrix size for constraint matrix
Definition: mpmod.f90:142
integer(mpi), dimension(:), allocatable nfd
index (line) in (steering) file
Definition: mpmod.f90:355
integer(mpi) ilperr
flag to calculate parameter errors with LAPACK
Definition: mpmod.f90:119
integer(mpl), dimension(:), allocatable globalparlabelzeros
global parameters label with zero derivative counters
Definition: mpmod.f90:261
integer(mpi) numblocks
number of (read) blocks
Definition: mpmod.f90:189
integer(mpi) ncgb
number of constraints
Definition: mpmod.f90:134
integer(mpi), dimension(:,:), allocatable matconsblocks
start of constraint blocks, parameter range
Definition: mpmod.f90:253
real(mpd), dimension(:), allocatable workspaceeigenvalues
workspace eigen values
Definition: mpmod.f90:231
integer(mpi) lhuber
Huber down-weighting flag.
Definition: mpmod.f90:47
integer(mpi) nvgb
number of variable global parameters
Definition: mpmod.f90:131
integer(mpi) nfilf
number of Fortran binary files
Definition: mpmod.f90:372
integer(mpi), dimension(:), allocatable measindex
mapping of 1.
Definition: mpmod.f90:255
integer(mpi) istopa
MINRES istop (convergence)
Definition: mpmod.f90:163
integer(mpi), dimension(:), allocatable mfd
file mode: cbinary =1, text =2, fbinary=3
Definition: mpmod.f90:353
real(mpd), dimension(:), allocatable blvec
local fit vector 'b' (in A*x=b), replaced by 'x'
Definition: mpmod.f90:301
logical newite
flag for new iteration
Definition: mpmod.f90:160
integer(mpi) nrderr
number of binary files with read errors
Definition: mpmod.f90:183
real(mpd), dimension(:), allocatable measres
average measurement error
Definition: mpmod.f90:257
real(mpd), dimension(:), allocatable vecxav
vector x for AVPROD (A*x=b)
Definition: mpmod.f90:213
real(mpd), dimension(:), allocatable globalparstart
start value for global parameters
Definition: mpmod.f90:201
integer(mpi), dimension(-6:6) writebufferheader
write buffer header (-6..-1: updates, 1..6: indices)
Definition: mpmod.f90:322
integer(mpi) monpg2
progress monitoring, repetition rate max increase
Definition: mpmod.f90:117
integer(mpl), dimension(:), allocatable globalrowoffsets
row offsets for full or unpacked matrix
Definition: mpmod.f90:210
integer(mpi) lenpresigmas
length of list of pre-sigmas from steering file
Definition: mpmod.f90:333
integer(mpi) npresg
number of pre-sigmas
Definition: mpmod.f90:167
integer(mpi), dimension(:), allocatable appearancecounter
appearance statistics for global par (first/last file,record)
Definition: mpmod.f90:294
integer(mpi) nvpgrp
number of variable parameter groups
Definition: mpmod.f90:137
integer(mpi), dimension(:), allocatable xfd
file: max.
Definition: mpmod.f90:360
integer(mpi) mreqena
required number of entries (for variable global parameter from Accepted local fits)
Definition: mpmod.f90:41
real(mps), dimension(:,:), allocatable writebufferdata
write buffer data (largest residual, Chi2/ndf, per thread)
Definition: mpmod.f90:319
real(mpd), dimension(:), allocatable workspacediag
diagonal of global matrix (for global corr.)
Definition: mpmod.f90:227
integer(mpl) ndfsum
sum(ndf)
Definition: mpmod.f90:161
integer(mpi) lenglobalvec
length of global vector 'b' (A*x=b)
Definition: mpmod.f90:194
real(mps) stepl
step length (line search)
Definition: mpmod.f90:158
integer(mpi) msngpe
upper bound for pair entry single precision storage
Definition: mpmod.f90:82
real(mps) cndlmx
cut on log10(condition of band part) of local (bordered-band matrix) fit
Definition: mpmod.f90:124
real(mpd), dimension(:), allocatable vecbav
vector b for AVPROD (A*x=b)
Definition: mpmod.f90:214
integer(mpl), dimension(:), allocatable globalchi2sumi
integer part of Chi2 sum
Definition: mpmod.f90:222
integer(mpl) ipdmem
memory (kB) used by Intel oneMKL PARDISO
Definition: mpmod.f90:346
integer(mpi), dimension(:), allocatable readbufferpointer
pointer to used buffers
Definition: mpmod.f90:287
integer(mpi), dimension(:), allocatable workspacei
(general) workspace (I)
Definition: mpmod.f90:233
integer(mpi), dimension(:), allocatable globalparcons
global parameters (number of) constraints
Definition: mpmod.f90:204
integer(mpi), dimension(:,:), allocatable writebufferinfo
write buffer management (per thread)
Definition: mpmod.f90:318
integer(mpl), dimension(:), allocatable globalndfsum
NDF sum.
Definition: mpmod.f90:223
integer(mpi) matrit
matrix calculation up to iteration MATRIT
Definition: mpmod.f90:73
real(mpd), dimension(:), allocatable vbnd
local fit band part of 'A'
Definition: mpmod.f90:305
real(mpr4), dimension(:), allocatable readbufferdataf
float data
Definition: mpmod.f90:289
type(listitemi), dimension(:), allocatable listpardiso
list of Intel oneMKL PARDISO parameters
Definition: mpmod.f90:345
integer(mpi) lfitbb
local fit: check for bordered band matrix (if >0)
Definition: mpmod.f90:88
integer(mpi) lsearch
iterations (solutions) with line search: >2: all, =2: all with (next) Chi2 cut scaling factor =1....
Definition: mpmod.f90:98
integer(mpi), dimension(:), allocatable dfd
file: ndf sum
Definition: mpmod.f90:359
integer(mpi) ichkpg
flag for checking (rank of) parameter groups
Definition: mpmod.f90:104
type(listitem), dimension(:), allocatable listpresigmas
list of pre-sgmas from steering file
Definition: mpmod.f90:334
integer(mpi), dimension(:), allocatable globalallindexgroups
Definition: mpmod.f90:277
integer(mpi) mrmode
MINRES-QLP mode (0: QR+QLP, 1: only QR, 2: only QLP factorization)
Definition: mpmod.f90:63
real(mps) chicut
cut in terms of 3-sigma cut, first iteration
Definition: mpmod.f90:48
integer(mpi) imonit
flag for monitoring residuals per local fit cycle (=0: none, <0: all, bit 0: first,...
Definition: mpmod.f90:108
Parameters and data.
Definition: mptest1.f90:35
real(mps), dimension(nplan) dvd
rel.
Definition: mptest1.f90:53
real(mps), dimension(nplan) del
shift (position deviation) (alignment parameter)
Definition: mptest1.f90:52
integer(mpi), parameter nplan
Definition: mptest1.f90:41
Parameters and data.
Definition: mptest2.f90:57
integer(mpi), parameter nmx
number of modules in x direction
Definition: mptest2.f90:65
real(mps), dimension(ntot) sdevx
shift in x (alignment parameter)
Definition: mptest2.f90:82
real(mps), dimension(ntot) sdevy
shift in y (alignment parameter)
Definition: mptest2.f90:83
integer(mpi), parameter nmy
number of modules in y direction
Definition: mptest2.f90:67
integer(mpi), parameter nlyr
number of detector layers
Definition: mptest2.f90:63
integer(mpi), parameter ntot
total number of modules
Definition: mptest2.f90:68
Keyword position.
Definition: mptext.f90:29
integer(mpi) keyb
end (position) of first keyword
Definition: mptext.f90:35
integer(mpi) keya
start (position) of first keyword
Definition: mptext.f90:34
integer(mpi) keyc
end (position) of last keyword
Definition: mptext.f90:36
subroutine ploopb(lunp)
Print iteration line.
Definition: pede.f90:3873
subroutine mchdec
Solution by Cholesky decomposition.
Definition: pede.f90:9064
subroutine bincls(kfile, ithr)
Close binary file.
Definition: pede.f90:13354
subroutine prpcon
Prepare constraints.
Definition: pede.f90:1955
subroutine mminrs
Solution with MINRES.
Definition: pede.f90:10138
subroutine prtrej(lun)
Print rejection statistics.
Definition: pede.f90:5391
subroutine mcsolv(n, x, y)
Solution for zero band width preconditioner.
Definition: pede.f90:10342
subroutine mupdat(i, j, add)
Update element of global matrix.
Definition: pede.f90:4095
subroutine peend(icode, cmessage)
Print exit code.
Definition: pede.f90:13237
subroutine loopn
Loop with fits and sums.
Definition: pede.f90:3438
subroutine loop1
First data loop (get global labels).
Definition: pede.f90:6942
subroutine feasma
Matrix for feasible solution.
Definition: pede.f90:2255
subroutine xloopn
Standard solution algorithm.
Definition: pede.f90:10396
subroutine ploopa(lunp)
Print title for iteration.
Definition: pede.f90:3852
subroutine isjajb(nst, is, ja, jb, jsp)
Decode Millepede record.
Definition: pede.f90:3387
subroutine additem(length, list, label, value)
add item to list
Definition: pede.f90:12977
subroutine mgupdt(i, j1, j2, il, jl, n, sub)
Update global matrix for parameter group.
Definition: pede.f90:4180
subroutine lpavat(t)
Similarity transformation by Q(t).
Definition: pede.f90:9626
subroutine binrwd(kfile)
Rewind binary file.
Definition: pede.f90:13389
subroutine zdiags
Covariance matrix for diagonalization (,correction of eigenvectors).
Definition: pede.f90:10101
subroutine solglo(ivgbi)
Error for single global parameter from MINRES.
Definition: pede.f90:1416
subroutine upone
Update, redefine hash indices.
Definition: pede.f90:6808
subroutine pargrp(inds, inde)
Parameter group info update for block of parameters.
Definition: pede.f90:3270
subroutine prtglo
Print final log file.
Definition: pede.f90:5420
subroutine monres
Monitor input residuals.
Definition: pede.f90:8647
subroutine intext(text, nline)
Interprete text.
Definition: pede.f90:12100
integer(mpl) function ijadd(itema, itemb)
Index for sparse storage (custom).
Definition: pede.f90:6441
subroutine mdiags
Solution by diagonalization.
Definition: pede.f90:9952
program mptwo
Millepede II main program Pede.
Definition: pede.f90:911
subroutine prtstat
Print input statistic.
Definition: pede.f90:5607
real(mpd) function matij(itema, itemb)
Get matrix element at (i,j).
Definition: pede.f90:6548
subroutine grpcon
Group constraints.
Definition: pede.f90:1657
subroutine loopbf(nrej, numfil, naccf, chi2f, ndff)
Loop over records in read buffer (block), fits and sums.
Definition: pede.f90:4348
subroutine peread(more)
Read (block of) records from binary files.
Definition: pede.f90:2591
subroutine filetx
Interprete text files.
Definition: pede.f90:11777
integer(mpi) function iprime(n)
largest prime number < N.
Definition: pede.f90:6910
subroutine ploopc(lunp)
Print sub-iteration line.
Definition: pede.f90:3930
integer(mpl) function ijcsr3(itema, itemb)
Index for sparse storage (CSR3).
Definition: pede.f90:6490
subroutine useone
Make usable (sort items and redefine hash indices).
Definition: pede.f90:6878
subroutine mvopen(lun, fname)
Open file.
Definition: pede.f90:13149
subroutine chkrej
Check rejection details.
Definition: pede.f90:11237
subroutine avprd0(n, l, x, b)
Product symmetric (sub block) matrix times vector.
Definition: pede.f90:6012
subroutine addsums(ithrd, chi2, ndf, dw)
Accurate summation.
Definition: pede.f90:13546
subroutine solgloqlp(ivgbi)
Error for single global parameter from MINRES-QLP.
Definition: pede.f90:1500
subroutine lpqldec(a, emin, emax)
QL decomposition.
Definition: pede.f90:9504
subroutine addcst
Add constraint information to matrix and vector.
Definition: pede.f90:1583
subroutine petime
Print times.
Definition: pede.f90:13186
subroutine mstart(text)
Start of 'module' printout.
Definition: pede.f90:13096
subroutine mend
End of 'module' printout.
Definition: pede.f90:13132
subroutine anasps
Analyse sparsity structure.
Definition: pede.f90:6180
subroutine minver
Solution by matrix inversion.
Definition: pede.f90:8951
subroutine peprep(mode)
Prepare records.
Definition: pede.f90:2943
integer(mpi) function ijprec(itema, itemb)
Precision for storage of parameter groups.
Definition: pede.f90:6412
subroutine explfc(lunit)
Print explanation of iteration table.
Definition: pede.f90:4004
subroutine getsums(chi2, ndf, wndf)
Get accurate sums.
Definition: pede.f90:13579
subroutine chkmat
Check global matrix.
Definition: pede.f90:13500
subroutine binopn(kfile, ithr, ierr)
Open binary file.
Definition: pede.f90:13258
subroutine pepgrp
Parameter group info update.
Definition: pede.f90:3116
subroutine sechms(deltat, nhour, minut, secnd)
Time conversion.
Definition: pede.f90:6693
integer(mpi) function inone(item)
Translate labels to indices (for global parameters).
Definition: pede.f90:6738
subroutine avprds(n, l, x, is, ie, b)
Product symmetric (sub block) matrix times sparse vector.
Definition: pede.f90:5798
subroutine avprod(n, x, b)
Product symmetric matrix times vector.
Definition: pede.f90:6274
subroutine ijpgrp(itema, itemb, ij, lr, iprc)
Index (region length and precision) for sparse storage of parameter groups.
Definition: pede.f90:6314
subroutine loop1i
Iteration of first data loop.
Definition: pede.f90:7313
subroutine mhalf2
Fill 2nd half of matrix for extended storage.
Definition: pede.f90:6606
subroutine ckpgrp
Check (rank of) parameter groups.
Definition: pede.f90:13420
subroutine additemi(length, list, label, ivalue)
add item to list
Definition: pede.f90:13061
subroutine mminrsqlp
Solution with MINRES-QLP.
Definition: pede.f90:10236
subroutine filetc
Interprete command line option, steering file.
Definition: pede.f90:11301
subroutine feasib(concut, iact)
Make parameters feasible.
Definition: pede.f90:2430
subroutine mspardiso
Solution with Intel(R) oneAPI Math Kernel Library (oneMKL) PARDISO.
Definition: pede.f90:9723
subroutine mdutrf
Solution by factorization.
Definition: pede.f90:9323
subroutine mdptrf
Solution by factorization.
Definition: pede.f90:9176
subroutine mvsolv(n, x, y)
Solution for finite band width preconditioner.
Definition: pede.f90:10363
subroutine vmprep(msize)
Prepare storage for vectors and matrices.
Definition: pede.f90:8754
subroutine ploopd(lunp)
Print solution line.
Definition: pede.f90:3978
subroutine pechk(ibuf, nerr)
Check Millepede record.
Definition: pede.f90:3044
subroutine loop2
Second data loop (number of derivatives, global label pairs).
Definition: pede.f90:7425
integer(mpi) function nufile(fname)
Inquire on file.
Definition: pede.f90:12043
subroutine additemc(length, list, label, text)
add character item to list
Definition: pede.f90:13019
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