117860365SKenneth E. Jansen #ifdef HAVE_PETSC 210167291SKenneth E. Jansen #include <stdio.h> 310167291SKenneth E. Jansen 410167291SKenneth E. Jansen #include "petscsys.h" 510167291SKenneth E. Jansen #include "petscvec.h" 610167291SKenneth E. Jansen #include "petscmat.h" 710167291SKenneth E. Jansen #include "petscpc.h" 810167291SKenneth E. Jansen #include "petscksp.h" 910167291SKenneth E. Jansen 1010167291SKenneth E. Jansen #include "assert.h" 1110167291SKenneth E. Jansen #include "common_c.h" 1210167291SKenneth E. Jansen 1310167291SKenneth E. Jansen #include <FCMangle.h> 1410167291SKenneth E. Jansen #define SolGMRp FortranCInterface_GLOBAL_(solgmrp,SOLGMRP) 1510167291SKenneth E. Jansen #define SolGMRpSclr FortranCInterface_GLOBAL_(solgmrpsclr,SOLGMRPSCLR) 1610167291SKenneth E. Jansen #define ElmGMRPETSc FortranCInterface_GLOBAL_(elmgmrpetsc, ELMGMRPETSC) 1710167291SKenneth E. Jansen #define ElmGMRPETScSclr FortranCInterface_GLOBAL_(elmgmrpetscsclr, ELMGMRPETSCSCLR) 182801f607SKenneth E. Jansen #define rstatp FortranCInterface_GLOBAL_(rstatp, RSTATP) 192801f607SKenneth E. Jansen #define rstatpSclr FortranCInterface_GLOBAL_(rstatpsclr, RSTATPSCLR) 2010167291SKenneth E. Jansen #define min(a,b) (((a) < (b)) ? (a) : (b)) 2110167291SKenneth E. Jansen #define max(a,b) (((a) > (b)) ? (a) : (b)) 2210167291SKenneth E. Jansen #define get_time FortranCInterface_GLOBAL_(get_time,GET_TIME) 2310167291SKenneth E. Jansen #define get_max_time_diff FortranCInterface_GLOBAL_(get_max_time_diff,GET_MAX_TIME_DIFF) 2410167291SKenneth E. Jansen 2510167291SKenneth E. Jansen typedef long long int gcorp_t; 2610167291SKenneth E. Jansen 2710167291SKenneth E. Jansen void get_time(uint64_t* rv, uint64_t* cycle); 2810167291SKenneth E. Jansen void get_max_time_diff(uint64_t* first, uint64_t* last, uint64_t* c_first, uint64_t* c_last, char* lbl); 2910167291SKenneth E. Jansen 3010167291SKenneth E. Jansen //#include "auxmpi.h" 3110167291SKenneth E. Jansen // static PetscOffset poff; 3210167291SKenneth E. Jansen 3310167291SKenneth E. Jansen static Mat lhsP; 3410167291SKenneth E. Jansen static PC pc; 3510167291SKenneth E. Jansen static KSP ksp; 360be30ed5SKenneth E. Jansen static Vec DyP, resP, DyPLocal; 3710167291SKenneth E. Jansen static PetscErrorCode ierr; 3810167291SKenneth E. Jansen static PetscInt PetscOne, PetscRow, PetscCol, LocalRow, LocalCol; 398ae99c59SKenneth E. Jansen static IS LocalIndexSet; 4010167291SKenneth E. Jansen static ISLocalToGlobalMapping VectorMapping; 4110167291SKenneth E. Jansen static VecScatter scatter7; 4210167291SKenneth E. Jansen static int firstpetsccall = 1; 4310167291SKenneth E. Jansen 4410167291SKenneth E. Jansen static Mat lhsPs; 4510167291SKenneth E. Jansen static PC pcs; 4610167291SKenneth E. Jansen static KSP ksps; 470be30ed5SKenneth E. Jansen static Vec DyPs, resPs, DyPLocals; 488ae99c59SKenneth E. Jansen static IS LocalIndexSets; 4910167291SKenneth E. Jansen static ISLocalToGlobalMapping VectorMappings; 5010167291SKenneth E. Jansen static VecScatter scatter7s; 5110167291SKenneth E. Jansen static int firstpetsccalls = 1; 5210167291SKenneth E. Jansen 53175e1b6bSKenneth E. Jansen static int rankdump=-1; // 8121 was the problem rank with 3.5.3 542801f607SKenneth E. Jansen PetscReal resNrm; 55175e1b6bSKenneth E. Jansen 56175e1b6bSKenneth E. Jansen 5710167291SKenneth E. Jansen void SolGMRp(double* y, double* ac, double* yold, 5810167291SKenneth E. Jansen double* x, int* iBC, double* BC, 5910167291SKenneth E. Jansen int* col, int* row, double* lhsk, 6010167291SKenneth E. Jansen double* res, double* BDiag, 6110167291SKenneth E. Jansen int* iper, 6210167291SKenneth E. Jansen int* ilwork, double* shp, double* shgl, double* shpb, 6310167291SKenneth E. Jansen double* shglb, double* Dy, double* rerr, long long int* fncorp) 6410167291SKenneth E. Jansen { 6510167291SKenneth E. Jansen // 6610167291SKenneth E. Jansen // ---------------------------------------------------------------------- 6710167291SKenneth E. Jansen // 6810167291SKenneth E. Jansen // This is the preconditioned GMRES driver routine. 6910167291SKenneth E. Jansen // 7010167291SKenneth E. Jansen // input: 7110167291SKenneth E. Jansen // y (nshg,ndof) : Y-variables at n+alpha_v 7210167291SKenneth E. Jansen // ac (nshg,ndof) : Primvar. accel. variable n+alpha_m 7310167291SKenneth E. Jansen // yold (nshg,ndof) : Y-variables at beginning of step 7410167291SKenneth E. Jansen // acold (nshg,ndof) : Primvar. accel. variable at begng step 7510167291SKenneth E. Jansen // x (numnp,nsd) : node coordinates 7610167291SKenneth E. Jansen // iBC (nshg) : BC codes 7710167291SKenneth E. Jansen // BC (nshg,ndofBC) : BC constraint parameters 7810167291SKenneth E. Jansen // shp(b) (nen,maxsh,melCat) : element shape functions (boundary) 7910167291SKenneth E. Jansen // shgl(b)(nsd,nen,maxsh,melCat) : local gradients of shape functions 8010167291SKenneth E. Jansen // 8110167291SKenneth E. Jansen // output: 8210167291SKenneth E. Jansen // res (nshg,nflow) : preconditioned residual 8310167291SKenneth E. Jansen // BDiag (nshg,nflow,nflow) : block-diagonal preconditioner 8410167291SKenneth E. Jansen // 8510167291SKenneth E. Jansen // 8610167291SKenneth E. Jansen // Zdenek Johan, Winter 1991. (Fortran 90) 8710167291SKenneth E. Jansen // ---------------------------------------------------------------------- 8810167291SKenneth E. Jansen // 8910167291SKenneth E. Jansen 9010167291SKenneth E. Jansen 9110167291SKenneth E. Jansen // Get variables from common_c.h 9210167291SKenneth E. Jansen int nshg, nflow, nsd, iownnodes; 9310167291SKenneth E. Jansen nshg = conpar.nshg; 9410167291SKenneth E. Jansen nflow = conpar.nflow; 9510167291SKenneth E. Jansen nsd = NSD; 9610167291SKenneth E. Jansen iownnodes = conpar.iownnodes; 9710167291SKenneth E. Jansen 9810167291SKenneth E. Jansen gcorp_t nshgt; 9910167291SKenneth E. Jansen gcorp_t mbeg; 10010167291SKenneth E. Jansen gcorp_t mend; 10110167291SKenneth E. Jansen nshgt = (gcorp_t) newdim.nshgt; //Fix nshgt in common_c.h 10210167291SKenneth E. Jansen mbeg = (gcorp_t) newdim.minowned; 10310167291SKenneth E. Jansen mend = (gcorp_t) newdim.maxowned; 10410167291SKenneth E. Jansen 10510167291SKenneth E. Jansen 10610167291SKenneth E. Jansen int node, element, var, eqn; 10710167291SKenneth E. Jansen double valtoinsert; 10810167291SKenneth E. Jansen int nenl, iel, lelCat, lcsyst, iorder, nshl; 10910167291SKenneth E. Jansen int mattyp, ndofl, nsymdl, npro, ngauss, nppro; 11010167291SKenneth E. Jansen double DyFlat[nshg*nflow]; 11110167291SKenneth E. Jansen double DyFlatPhasta[nshg*nflow]; 11210167291SKenneth E. Jansen double rmes[nshg*nflow]; 11310167291SKenneth E. Jansen // DEBUG 11410167291SKenneth E. Jansen int i,j,k,l,m; 11510167291SKenneth E. Jansen 11610167291SKenneth E. Jansen // FIXME: PetscScalar 11710167291SKenneth E. Jansen double real_rtol, real_abstol, real_dtol; 11810167291SKenneth E. Jansen // /DEBUG 11910167291SKenneth E. Jansen //double parray[1]; // Should be a PetscScalar 12010167291SKenneth E. Jansen double *parray; // Should be a PetscScalar 12110167291SKenneth E. Jansen PetscInt petsc_bs, petsc_m, petsc_M,petsc_PA; 12210167291SKenneth E. Jansen PetscInt petsc_n; 12310167291SKenneth E. Jansen PetscOne = 1; 12410167291SKenneth E. Jansen uint64_t duration[4]; 12510167291SKenneth E. Jansen 12610167291SKenneth E. Jansen gcorp_t glbNZ; 12710167291SKenneth E. Jansen 12810167291SKenneth E. Jansen if(firstpetsccall == 1) { 1298ae99c59SKenneth E. Jansen //Everthing in this conditional block should be moved to a function to estimate the size of PETSc's matrix which improves time on the first matrix fill 1308ae99c59SKenneth E. Jansen // 131f4d0b58bSKenneth E. Jansen PetscInt* idiagnz= (PetscInt*) malloc(sizeof(PetscInt)*iownnodes); 132f4d0b58bSKenneth E. Jansen PetscInt* iodiagnz= (PetscInt*) malloc(sizeof(PetscInt)*iownnodes); 13310167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 13410167291SKenneth E. Jansen idiagnz[i]=0; 13510167291SKenneth E. Jansen iodiagnz[i]=0; 13610167291SKenneth E. Jansen } 13710167291SKenneth E. Jansen i=0; 13810167291SKenneth E. Jansen for(k=0;k<nshg;k++) { 13910167291SKenneth E. Jansen if((fncorp[k] < mbeg) || (fncorp[k] >mend)){ 14010167291SKenneth E. Jansen // this node is not owned by this rank so we skip 14110167291SKenneth E. Jansen } else { 14210167291SKenneth E. Jansen for(j=col[i]-1;j<col[i+1]-1;j++) { 14379f1763eSKenneth E. Jansen // assert(row[j]<=nshg); 14479f1763eSKenneth E. Jansen // assert(fncorp[row[j]-1]<=nshgt); 14579f1763eSKenneth E. Jansen glbNZ=fncorp[row[j]-1]; 14610167291SKenneth E. Jansen if((glbNZ < mbeg) || (glbNZ > mend)) { 14710167291SKenneth E. Jansen iodiagnz[i]++; 14810167291SKenneth E. Jansen } else { 14910167291SKenneth E. Jansen idiagnz[i]++; 15010167291SKenneth E. Jansen } 15110167291SKenneth E. Jansen } 15210167291SKenneth E. Jansen i++; 15310167291SKenneth E. Jansen } 15410167291SKenneth E. Jansen } 15510167291SKenneth E. Jansen gcorp_t mind=1000; 15610167291SKenneth E. Jansen gcorp_t mino=1000; 15710167291SKenneth E. Jansen gcorp_t maxd=0; 15810167291SKenneth E. Jansen gcorp_t maxo=0; 15910167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 16010167291SKenneth E. Jansen mind=min(mind,idiagnz[i]); 16110167291SKenneth E. Jansen mino=min(mino,iodiagnz[i]); 16210167291SKenneth E. Jansen maxd=max(maxd,idiagnz[i]); 16310167291SKenneth E. Jansen maxo=max(maxo,iodiagnz[i]); 16410167291SKenneth E. Jansen // iodiagnz[i]=max(iodiagnz[i],10); 16510167291SKenneth E. Jansen // idiagnz[i]=max(idiagnz[i],10); 16610167291SKenneth E. Jansen // iodiagnz[i]=2*iodiagnz[i]; // estimate a bit higher for off-part interactions 16710167291SKenneth E. Jansen // idiagnz[i]=2*idiagnz[i]; // estimate a bit higher for off-part interactions 16810167291SKenneth E. Jansen } 16910167291SKenneth E. Jansen // the above was pretty good but below is faster and not too much more memory...of course once you do this 17010167291SKenneth E. Jansen // could just use the constant fill parameters in create but keep it alive for potential later optimization 17110167291SKenneth E. Jansen 17210167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 17310167291SKenneth E. Jansen iodiagnz[i]=1.3*maxd; 17410167291SKenneth E. Jansen idiagnz[i]=1.3*maxd; 17510167291SKenneth E. Jansen } 17610167291SKenneth E. Jansen 17710167291SKenneth E. Jansen 17810167291SKenneth E. Jansen 17910167291SKenneth E. Jansen if(workfc.numpe < 200){ 18010167291SKenneth E. Jansen printf("myrank,i,iownnodes,nshg %d %d %d %d \n",workfc.myrank,i,iownnodes,nshg); 18110167291SKenneth E. Jansen printf("myrank,mind,maxd,mino,maxo %d %d %d %d %d \n",workfc.myrank,mind,maxd,mino,maxo); 18210167291SKenneth E. Jansen } 18310167291SKenneth E. Jansen // Print debug info 18410167291SKenneth E. Jansen if(nshgt < 200){ 18510167291SKenneth E. Jansen int irank; 18610167291SKenneth E. Jansen for(irank=0;irank<workfc.numpe;irank++) { 18710167291SKenneth E. Jansen if(irank == workfc.myrank){ 18810167291SKenneth E. Jansen printf("mbeg,mend,myrank,idiagnz, iodiagnz %d %d %d \n",mbeg,mend,workfc.myrank); 18910167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 19010167291SKenneth E. Jansen printf("%d %ld %ld \n",workfc.myrank,idiagnz[i],iodiagnz[i]); 19110167291SKenneth E. Jansen } 19210167291SKenneth E. Jansen } 19310167291SKenneth E. Jansen MPI_Barrier(MPI_COMM_WORLD); 19410167291SKenneth E. Jansen } 19510167291SKenneth E. Jansen } 19610167291SKenneth E. Jansen petsc_bs = (PetscInt) nflow; 19710167291SKenneth E. Jansen petsc_m = (PetscInt) nflow* (PetscInt) iownnodes; 19810167291SKenneth E. Jansen petsc_M = (PetscInt) nshgt * (PetscInt) nflow; 19910167291SKenneth E. Jansen petsc_PA = (PetscInt) 40; 20010167291SKenneth E. Jansen ierr = MatCreateBAIJ(PETSC_COMM_WORLD, petsc_bs, petsc_m, petsc_m, petsc_M, petsc_M, 20110167291SKenneth E. Jansen 0, idiagnz, 0, iodiagnz, &lhsP); 20210167291SKenneth E. Jansen 20310167291SKenneth E. Jansen ierr = MatSetOption(lhsP, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE); 20410167291SKenneth E. Jansen 20510167291SKenneth E. Jansen // Next is Jed Brown's improvement to imprint Assembly to make that stage scalable after the first call 2068ae99c59SKenneth E. Jansen #ifdef JEDBROWN 20710167291SKenneth E. Jansen ierr = MatSetOption(lhsP, MAT_SUBSET_OFF_PROC_ENTRIES, PETSC_TRUE); 208dcce770dSKenneth E. Jansen #endif 20910167291SKenneth E. Jansen ierr = MatSetUp(lhsP); 21010167291SKenneth E. Jansen 21110167291SKenneth E. Jansen PetscInt myMatStart, myMatEnd; 21210167291SKenneth E. Jansen ierr = MatGetOwnershipRange(lhsP, &myMatStart, &myMatEnd); 213175e1b6bSKenneth E. Jansen //debug 214175e1b6bSKenneth E. Jansen if(workfc.myrank == rankdump) printf("Flow myrank,myMatStart,myMatEnd %d,%d,%d, \n", workfc.myrank,myMatStart,myMatEnd); 21510167291SKenneth E. Jansen } 21610167291SKenneth E. Jansen if(genpar.lhs ==1) ierr = MatZeroEntries(lhsP); 21710167291SKenneth E. Jansen 2188ae99c59SKenneth E. Jansen // 2198ae99c59SKenneth E. Jansen // .... *******************>> Element Data Formation <<****************** 2208ae99c59SKenneth E. Jansen // 2218ae99c59SKenneth E. Jansen // 2228ae99c59SKenneth E. Jansen // .... set the parameters for flux and surface tension calculations 2238ae99c59SKenneth E. Jansen // 2248ae99c59SKenneth E. Jansen // 2258ae99c59SKenneth E. Jansen genpar.idflx = 0 ; 2268ae99c59SKenneth E. Jansen if(genpar.idiff >= 1) genpar.idflx= genpar.idflx + (nflow-1) * nsd; 2278ae99c59SKenneth E. Jansen if (genpar.isurf == 1) genpar.idflx=genpar.idflx + nsd; 22810167291SKenneth E. Jansen 2298ae99c59SKenneth E. Jansen get_time(duration, (duration+1)); 23010167291SKenneth E. Jansen 23110167291SKenneth E. Jansen ElmGMRPETSc(y, ac, x, 23210167291SKenneth E. Jansen shp, shgl, iBC, 23310167291SKenneth E. Jansen BC, shpb, 23410167291SKenneth E. Jansen shglb, res, 23510167291SKenneth E. Jansen rmes, iper, 23610167291SKenneth E. Jansen ilwork, rerr , &lhsP); 2378ae99c59SKenneth E. Jansen 23810167291SKenneth E. Jansen get_time((duration+2), (duration+3)); 23910167291SKenneth E. Jansen get_max_time_diff((duration), (duration+2), 24010167291SKenneth E. Jansen (duration+1), (duration+3), 24110167291SKenneth E. Jansen "ElmGMRPETSc \0"); // char(0)) 24210167291SKenneth E. Jansen if(firstpetsccall == 1) { 24310167291SKenneth E. Jansen // Setup IndexSet. For now, we mimic vector insertion procedure 24410167291SKenneth E. Jansen // Since we always reference by global indexes this doesn't matter 24510167291SKenneth E. Jansen // except for cache performance) 24610167291SKenneth E. Jansen // TODO: Better arrangment? 2478636783dSKenneth E. Jansen PetscInt* indexsetary = malloc(sizeof(PetscInt)*nflow*nshg); 2488636783dSKenneth E. Jansen PetscInt nodetoinsert; 24910167291SKenneth E. Jansen nodetoinsert = 0; 25010167291SKenneth E. Jansen k=0; 2518ae99c59SKenneth E. Jansen //debug 252175e1b6bSKenneth E. Jansen if(workfc.myrank == rankdump) { 253175e1b6bSKenneth E. Jansen printf("myrank,i,iownnodes,nshg %d %d %d %d \n",workfc.myrank,i,iownnodes,nshg); 254175e1b6bSKenneth E. Jansen printf("myrank,mbeg,mend %d %d %d \n",workfc.myrank,mbeg,mend); 255175e1b6bSKenneth E. Jansen } 25610167291SKenneth E. Jansen if(workfc.numpe > 1) { 25710167291SKenneth E. Jansen for (i=0; i<nshg ; i++) { 25810167291SKenneth E. Jansen nodetoinsert = fncorp[i]-1; 259175e1b6bSKenneth E. Jansen //debug 260175e1b6bSKenneth E. Jansen if(workfc.myrank == rankdump) { 261175e1b6bSKenneth E. Jansen printf("myrank,i,nodetoinsert %d %d %d \n",workfc.myrank,i,nodetoinsert); 262175e1b6bSKenneth E. Jansen } 263175e1b6bSKenneth E. Jansen 26410167291SKenneth E. Jansen // assert(fncorp[i]>=0); 26510167291SKenneth E. Jansen for (j=1; j<=nflow; j++) { 26610167291SKenneth E. Jansen indexsetary[k] = nodetoinsert*nflow+(j-1); 26710167291SKenneth E. Jansen assert(indexsetary[k]>=0); 26810167291SKenneth E. Jansen // assert(fncorp[i]>=0); 26910167291SKenneth E. Jansen k = k+1; 27010167291SKenneth E. Jansen } 27110167291SKenneth E. Jansen } 27210167291SKenneth E. Jansen } 27310167291SKenneth E. Jansen else { 27410167291SKenneth E. Jansen for (i=0; i<nshg ; i++) { 27510167291SKenneth E. Jansen nodetoinsert = i; 27610167291SKenneth E. Jansen for (j=1; j<=nflow; j++) { 27710167291SKenneth E. Jansen indexsetary[k] = nodetoinsert*nflow+(j-1); 27810167291SKenneth E. Jansen k = k+1; 27910167291SKenneth E. Jansen } 28010167291SKenneth E. Jansen } 28110167291SKenneth E. Jansen } 28210167291SKenneth E. Jansen 28310167291SKenneth E. Jansen // Create Vector Index Maps 28410167291SKenneth E. Jansen petsc_n = (PetscInt) nshg * (PetscInt) nflow; 28510167291SKenneth E. Jansen ierr = ISCreateGeneral(PETSC_COMM_SELF, petsc_n, indexsetary, 28610167291SKenneth E. Jansen PETSC_COPY_VALUES, &LocalIndexSet); 2878636783dSKenneth E. Jansen free(indexsetary); 28810167291SKenneth E. Jansen } 28910167291SKenneth E. Jansen if(genpar.lhs == 1) { 29010167291SKenneth E. Jansen get_time((duration), (duration+1)); 29110167291SKenneth E. Jansen ierr = MatAssemblyBegin(lhsP, MAT_FINAL_ASSEMBLY); 29210167291SKenneth E. Jansen ierr = MatAssemblyEnd(lhsP, MAT_FINAL_ASSEMBLY); 29310167291SKenneth E. Jansen get_time((duration+2),(duration+3)); 29410167291SKenneth E. Jansen get_max_time_diff((duration), (duration+2), 29510167291SKenneth E. Jansen (duration+1), (duration+3), 29610167291SKenneth E. Jansen "MatAssembly \0"); // char(0)) 29710167291SKenneth E. Jansen get_time(duration, (duration+1)); 29810167291SKenneth E. Jansen } 29910167291SKenneth E. Jansen if(firstpetsccall == 1) { 30010167291SKenneth E. Jansen ierr = MatGetLocalSize(lhsP, &LocalRow, &LocalCol); 30110167291SKenneth E. Jansen ierr = VecCreateMPI(PETSC_COMM_WORLD, LocalRow, petsc_M, &resP); 30210167291SKenneth E. Jansen ierr = VecCreateMPI(PETSC_COMM_WORLD, LocalRow, petsc_M, &DyP); 30310167291SKenneth E. Jansen } 30410167291SKenneth E. Jansen ierr = VecZeroEntries(resP); 30510167291SKenneth E. Jansen if(firstpetsccall == 1) { 30610167291SKenneth E. Jansen ierr = VecCreateSeq(PETSC_COMM_SELF, petsc_n, &DyPLocal); 30710167291SKenneth E. Jansen } 30810167291SKenneth E. Jansen 30910167291SKenneth E. Jansen PetscRow=0; 31010167291SKenneth E. Jansen k = 0; 31110167291SKenneth E. Jansen int index; 31210167291SKenneth E. Jansen for (i=0; i<nshg; i++ ){ 31310167291SKenneth E. Jansen for (j = 1; j<=nflow; j++){ 31410167291SKenneth E. Jansen index = i + (j-1)*nshg; 31510167291SKenneth E. Jansen valtoinsert = res[index]; 31610167291SKenneth E. Jansen if(workfc.numpe > 1) { 31710167291SKenneth E. Jansen PetscRow = (fncorp[i]-1)*nflow+(j-1); 31810167291SKenneth E. Jansen } 31910167291SKenneth E. Jansen else { 32010167291SKenneth E. Jansen PetscRow = i*nflow+(j-1); 32110167291SKenneth E. Jansen } 32210167291SKenneth E. Jansen assert(fncorp[i]<=nshgt); 32310167291SKenneth E. Jansen assert(fncorp[i]>0); 32410167291SKenneth E. Jansen assert(PetscRow>=0); 32510167291SKenneth E. Jansen assert(PetscRow<=nshgt*nflow); 3262801f607SKenneth E. Jansen ierr = VecSetValue(resP, PetscRow, valtoinsert, ADD_VALUES); 32710167291SKenneth E. Jansen } 32810167291SKenneth E. Jansen } 32910167291SKenneth E. Jansen ierr = VecAssemblyBegin(resP); 33010167291SKenneth E. Jansen ierr = VecAssemblyEnd(resP); 3312801f607SKenneth E. Jansen ierr = VecNorm(resP,NORM_2,&resNrm); 33210167291SKenneth E. Jansen get_time((duration+2), (duration+3)); 33310167291SKenneth E. Jansen get_max_time_diff((duration), (duration+2), 33410167291SKenneth E. Jansen (duration+1), (duration+3), 33510167291SKenneth E. Jansen "VectorWorkPre \0"); // char(0)) 33610167291SKenneth E. Jansen 33710167291SKenneth E. Jansen get_time((duration),(duration+1)); 33810167291SKenneth E. Jansen 33910167291SKenneth E. Jansen if(firstpetsccall == 1) { 34010167291SKenneth E. Jansen ierr = KSPCreate(PETSC_COMM_WORLD, &ksp); 34110167291SKenneth E. Jansen ierr = KSPSetOperators(ksp, lhsP, lhsP); 34210167291SKenneth E. Jansen ierr = KSPGetPC(ksp, &pc); 34310167291SKenneth E. Jansen ierr = PCSetType(pc, PCPBJACOBI); 34410167291SKenneth E. Jansen PetscInt maxits; 34510167291SKenneth E. Jansen maxits = (PetscInt) solpar.nGMRES * (PetscInt) solpar.Kspace; 34610167291SKenneth E. Jansen ierr = KSPSetTolerances(ksp, timdat.etol, PETSC_DEFAULT, PETSC_DEFAULT, maxits); 34710167291SKenneth E. Jansen ierr = KSPSetFromOptions(ksp); 34810167291SKenneth E. Jansen } 34910167291SKenneth E. Jansen ierr = KSPSolve(ksp, resP, DyP); 35010167291SKenneth E. Jansen get_time((duration+2),(duration+3)); 35110167291SKenneth E. Jansen get_max_time_diff((duration), (duration+2), 35210167291SKenneth E. Jansen (duration+1), (duration+3), 35310167291SKenneth E. Jansen "KSPSolve \0"); // char(0)) 35410167291SKenneth E. Jansen get_time((duration),(duration+1)); 35510167291SKenneth E. Jansen if(firstpetsccall == 1) { 3568ae99c59SKenneth E. Jansen ierr = VecScatterCreate(DyP, LocalIndexSet, DyPLocal, NULL, &scatter7); 35710167291SKenneth E. Jansen } 35810167291SKenneth E. Jansen ierr = VecScatterBegin(scatter7, DyP, DyPLocal, INSERT_VALUES, SCATTER_FORWARD); 35910167291SKenneth E. Jansen ierr = VecScatterEnd(scatter7, DyP, DyPLocal, INSERT_VALUES, SCATTER_FORWARD); 36010167291SKenneth E. Jansen ierr = VecGetArray(DyPLocal, &parray); 36110167291SKenneth E. Jansen PetscRow = 0; 36210167291SKenneth E. Jansen for ( node = 0; node< nshg; node++) { 36310167291SKenneth E. Jansen for (var = 1; var<= nflow; var++) { 36410167291SKenneth E. Jansen index = node + (var-1)*nshg; 36510167291SKenneth E. Jansen Dy[index] = parray[PetscRow]; 36610167291SKenneth E. Jansen PetscRow = PetscRow+1; 36710167291SKenneth E. Jansen } 36810167291SKenneth E. Jansen } 36910167291SKenneth E. Jansen ierr = VecRestoreArray(DyPLocal, &parray); 37010167291SKenneth E. Jansen 37110167291SKenneth E. Jansen firstpetsccall = 0; 3728636783dSKenneth E. Jansen 37310167291SKenneth E. Jansen // .... output the statistics 37410167291SKenneth E. Jansen // 37510167291SKenneth E. Jansen itrpar.iKs=0; // see rstat() 37610167291SKenneth E. Jansen PetscInt its; 37710167291SKenneth E. Jansen ierr = KSPGetIterationNumber(ksp, &its); 37810167291SKenneth E. Jansen itrpar.iKs = (int) its; 37910167291SKenneth E. Jansen get_time((duration+2),(duration+3)); 38010167291SKenneth E. Jansen get_max_time_diff((duration), (duration+2), 38110167291SKenneth E. Jansen (duration+1), (duration+3), 38210167291SKenneth E. Jansen "solWork \0"); // char(0)) 38310167291SKenneth E. Jansen itrpar.ntotGM += (int) its; 3842801f607SKenneth E. Jansen rstatp (&resNrm); 38510167291SKenneth E. Jansen // 38610167291SKenneth E. Jansen // .... end 38710167291SKenneth E. Jansen // 38810167291SKenneth E. Jansen } 38910167291SKenneth E. Jansen 39010167291SKenneth E. Jansen void SolGMRpSclr(double* y, double* ac, 39110167291SKenneth E. Jansen double* x, double* elDw, int* iBC, double* BC, 39210167291SKenneth E. Jansen int* col, int* row, 39310167291SKenneth E. Jansen int* iper, 39410167291SKenneth E. Jansen int* ilwork, double* shp, double* shgl, double* shpb, 39510167291SKenneth E. Jansen double* shglb, double* res, double* Dy, long long int* fncorp) 39610167291SKenneth E. Jansen { 39710167291SKenneth E. Jansen // 39810167291SKenneth E. Jansen // ---------------------------------------------------------------------- 39910167291SKenneth E. Jansen // 40010167291SKenneth E. Jansen // This is the preconditioned GMRES driver routine. 40110167291SKenneth E. Jansen // 40210167291SKenneth E. Jansen // input: 40310167291SKenneth E. Jansen // y (nshg,ndof) : Y-variables at n+alpha_v 40410167291SKenneth E. Jansen // ac (nshg,ndof) : Primvar. accel. variable n+alpha_m 40510167291SKenneth E. Jansen // yold (nshg,ndof) : Y-variables at beginning of step 40610167291SKenneth E. Jansen // acold (nshg,ndof) : Primvar. accel. variable at begng step 40710167291SKenneth E. Jansen // x (numnp,nsd) : node coordinates 40810167291SKenneth E. Jansen // iBC (nshg) : BC codes 40910167291SKenneth E. Jansen // BC (nshg,ndofBC) : BC constraint parameters 41010167291SKenneth E. Jansen // shp(b) (nen,maxsh,melCat) : element shape functions (boundary) 41110167291SKenneth E. Jansen // shgl(b)(nsd,nen,maxsh,melCat) : local gradients of shape functions 41210167291SKenneth E. Jansen // 41310167291SKenneth E. Jansen // ---------------------------------------------------------------------- 41410167291SKenneth E. Jansen // 41510167291SKenneth E. Jansen 41610167291SKenneth E. Jansen 41710167291SKenneth E. Jansen // Get variables from common_c.h 41810167291SKenneth E. Jansen int nshg, nflow, nsd, iownnodes; 41910167291SKenneth E. Jansen nshg = conpar.nshg; 42010167291SKenneth E. Jansen nsd = NSD; 42110167291SKenneth E. Jansen iownnodes = conpar.iownnodes; 42210167291SKenneth E. Jansen 42310167291SKenneth E. Jansen gcorp_t nshgt; 42410167291SKenneth E. Jansen gcorp_t mbeg; 42510167291SKenneth E. Jansen gcorp_t mend; 42610167291SKenneth E. Jansen nshgt = (gcorp_t) newdim.nshgt; //Fix nshgt in common_c.h 42710167291SKenneth E. Jansen mbeg = (gcorp_t) newdim.minowned; 42810167291SKenneth E. Jansen mend = (gcorp_t) newdim.maxowned; 42910167291SKenneth E. Jansen 43010167291SKenneth E. Jansen 43110167291SKenneth E. Jansen int node, element, var, eqn; 43210167291SKenneth E. Jansen double valtoinsert; 43310167291SKenneth E. Jansen int nenl, iel, lelCat, lcsyst, iorder, nshl; 43410167291SKenneth E. Jansen int mattyp, ndofl, nsymdl, npro, ngauss, nppro; 43510167291SKenneth E. Jansen double DyFlats[nshg]; 43610167291SKenneth E. Jansen double DyFlatPhastas[nshg]; 43710167291SKenneth E. Jansen double rmes[nshg]; 43810167291SKenneth E. Jansen // DEBUG 43910167291SKenneth E. Jansen int i,j,k,l,m; 44010167291SKenneth E. Jansen 44110167291SKenneth E. Jansen double real_rtol, real_abstol, real_dtol; 44210167291SKenneth E. Jansen double *parray; 44310167291SKenneth E. Jansen PetscInt petsc_bs, petsc_m, petsc_M,petsc_PA; 44410167291SKenneth E. Jansen PetscInt petsc_n; 44510167291SKenneth E. Jansen PetscOne = 1; 44610167291SKenneth E. Jansen uint64_t duration[4]; 44710167291SKenneth E. Jansen 44810167291SKenneth E. Jansen 44910167291SKenneth E. Jansen // 45010167291SKenneth E. Jansen // 45110167291SKenneth E. Jansen // .... *******************>> Element Data Formation <<****************** 45210167291SKenneth E. Jansen // 45310167291SKenneth E. Jansen // 45410167291SKenneth E. Jansen // .... set the parameters for flux and surface tension calculations 45510167291SKenneth E. Jansen // 45610167291SKenneth E. Jansen // 45710167291SKenneth E. Jansen genpar.idflx = 0 ; 45810167291SKenneth E. Jansen if(genpar.idiff >= 1) genpar.idflx= genpar.idflx + (nflow-1) * nsd; 45910167291SKenneth E. Jansen if (genpar.isurf == 1) genpar.idflx=genpar.idflx + nsd; 46010167291SKenneth E. Jansen 46110167291SKenneth E. Jansen 46210167291SKenneth E. Jansen 46310167291SKenneth E. Jansen gcorp_t glbNZ; 46410167291SKenneth E. Jansen 46510167291SKenneth E. Jansen if(firstpetsccalls == 1) { 466f4d0b58bSKenneth E. Jansen PetscInt* idiagnz= (PetscInt*) malloc(sizeof(PetscInt)*iownnodes); 467f4d0b58bSKenneth E. Jansen PetscInt* iodiagnz= (PetscInt*) malloc(sizeof(PetscInt)*iownnodes); 46810167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 46910167291SKenneth E. Jansen idiagnz[i]=0; 47010167291SKenneth E. Jansen iodiagnz[i]=0; 47110167291SKenneth E. Jansen } 47210167291SKenneth E. Jansen i=0; 47310167291SKenneth E. Jansen for(k=0;k<nshg;k++) { 47410167291SKenneth E. Jansen if((fncorp[k] < mbeg) || (fncorp[k] >mend)){ 47510167291SKenneth E. Jansen // this node is not owned by this rank so we skip 47610167291SKenneth E. Jansen } else { 47710167291SKenneth E. Jansen for(j=col[i]-1;j<col[i+1]-1;j++) { 478f4d0b58bSKenneth E. Jansen glbNZ=fncorp[row[j]-1]; 47910167291SKenneth E. Jansen if((glbNZ < mbeg) || (glbNZ > mend)) { 48010167291SKenneth E. Jansen iodiagnz[i]++; 48110167291SKenneth E. Jansen } else { 48210167291SKenneth E. Jansen idiagnz[i]++; 48310167291SKenneth E. Jansen } 48410167291SKenneth E. Jansen } 48510167291SKenneth E. Jansen i++; 48610167291SKenneth E. Jansen } 48710167291SKenneth E. Jansen } 48810167291SKenneth E. Jansen gcorp_t mind=1000; 48910167291SKenneth E. Jansen gcorp_t mino=1000; 49010167291SKenneth E. Jansen gcorp_t maxd=0; 49110167291SKenneth E. Jansen gcorp_t maxo=0; 49210167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 49310167291SKenneth E. Jansen mind=min(mind,idiagnz[i]); 49410167291SKenneth E. Jansen mino=min(mino,iodiagnz[i]); 49510167291SKenneth E. Jansen maxd=max(maxd,idiagnz[i]); 49610167291SKenneth E. Jansen maxo=max(maxo,iodiagnz[i]); 49710167291SKenneth E. Jansen } 49810167291SKenneth E. Jansen 49910167291SKenneth E. Jansen for(i=0;i<iownnodes;i++) { 50010167291SKenneth E. Jansen iodiagnz[i]=1.3*maxd; 50110167291SKenneth E. Jansen idiagnz[i]=1.3*maxd; 50210167291SKenneth E. Jansen } 50310167291SKenneth E. Jansen 50410167291SKenneth E. Jansen 50510167291SKenneth E. Jansen 506f4d0b58bSKenneth E. Jansen // } 507f4d0b58bSKenneth E. Jansen // if(firstpetsccalls == 1) { 50810167291SKenneth E. Jansen 50910167291SKenneth E. Jansen petsc_m = (PetscInt) iownnodes; 51010167291SKenneth E. Jansen petsc_M = (PetscInt) nshgt; 51110167291SKenneth E. Jansen petsc_PA = (PetscInt) 40; 51210167291SKenneth E. Jansen 51310167291SKenneth E. Jansen ierr = MatCreateAIJ(PETSC_COMM_WORLD, petsc_m, petsc_m, petsc_M, petsc_M, 51410167291SKenneth E. Jansen 0, idiagnz, 0, iodiagnz, &lhsPs); 51510167291SKenneth E. Jansen 51610167291SKenneth E. Jansen ierr = MatSetOption(lhsPs, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE); 51710167291SKenneth E. Jansen 51810167291SKenneth E. Jansen // Next is Jed Brown's improvement to imprint Assembly to make that stage scalable after the first call 519175e1b6bSKenneth E. Jansen #ifdef HIDEJEDBROWN 52010167291SKenneth E. Jansen ierr = MatSetOption(lhsPs, MAT_SUBSET_OFF_PROC_ENTRIES, PETSC_TRUE); 521dcce770dSKenneth E. Jansen #endif 52210167291SKenneth E. Jansen ierr = MatSetUp(lhsPs); 52310167291SKenneth E. Jansen 52410167291SKenneth E. Jansen PetscInt myMatStart, myMatEnd; 525175e1b6bSKenneth E. Jansen ierr = MatGetOwnershipRange(lhsPs, &myMatStart, &myMatEnd); 526175e1b6bSKenneth E. Jansen if(workfc.myrank ==rankdump) printf("Sclr myrank,myMatStart,myMatEnd %d,%d,%d, \n", workfc.myrank,myMatStart,myMatEnd); 52710167291SKenneth E. Jansen } 52810167291SKenneth E. Jansen // MPI_Barrier(MPI_COMM_WORLD); 52910167291SKenneth E. Jansen // if(workfc.myrank ==0) printf("Before MatZeroEntries \n"); 53010167291SKenneth E. Jansen if(genpar.lhs == 1) ierr = MatZeroEntries(lhsPs); 53110167291SKenneth E. Jansen 53210167291SKenneth E. Jansen get_time(duration, (duration+1)); 53310167291SKenneth E. Jansen 53410167291SKenneth E. Jansen // MPI_Barrier(MPI_COMM_WORLD); 53510167291SKenneth E. Jansen // if(workfc.myrank ==0) printf("Before elmgmr \n"); 53610167291SKenneth E. Jansen // for (i=0; i<nshg ; i++) { 53710167291SKenneth E. Jansen // assert(fncorp[i]>0); 53810167291SKenneth E. Jansen // } 53910167291SKenneth E. Jansen 54010167291SKenneth E. Jansen ElmGMRPETScSclr(y, ac, x, elDw, 54110167291SKenneth E. Jansen shp, shgl, iBC, 54210167291SKenneth E. Jansen BC, shpb, 54310167291SKenneth E. Jansen shglb, res, 54410167291SKenneth E. Jansen rmes, iper, 54510167291SKenneth E. Jansen ilwork, &lhsPs); 54610167291SKenneth E. Jansen if(firstpetsccalls == 1) { 54710167291SKenneth E. Jansen // Setup IndexSet. For now, we mimic vector insertion procedure 54810167291SKenneth E. Jansen // Since we always reference by global indexes this doesn't matter 54910167291SKenneth E. Jansen // except for cache performance) 55010167291SKenneth E. Jansen // TODO: Better arrangment? 5518636783dSKenneth E. Jansen 5528636783dSKenneth E. Jansen PetscInt* indexsetarys = malloc(sizeof(PetscInt)*nshg); 5538636783dSKenneth E. Jansen PetscInt nodetoinsert; 5548636783dSKenneth E. Jansen 55510167291SKenneth E. Jansen nodetoinsert = 0; 55610167291SKenneth E. Jansen k=0; 557175e1b6bSKenneth E. Jansen 558175e1b6bSKenneth E. Jansen //debug 559175e1b6bSKenneth E. Jansen if(workfc.myrank == rankdump) { 560175e1b6bSKenneth E. Jansen printf("myrank,i,iownnodes,nshg %d %d %d %d \n",workfc.myrank,i,iownnodes,nshg); 561175e1b6bSKenneth E. Jansen printf("myrank,mbeg,mend %d %d %d \n",workfc.myrank,mbeg,mend); 562175e1b6bSKenneth E. Jansen } 563175e1b6bSKenneth E. Jansen 56410167291SKenneth E. Jansen if(workfc.numpe > 1) { 56510167291SKenneth E. Jansen for (i=0; i<nshg ; i++) { 56610167291SKenneth E. Jansen nodetoinsert = fncorp[i]-1; 567175e1b6bSKenneth E. Jansen //debug 568175e1b6bSKenneth E. Jansen if(workfc.myrank == rankdump) { 569175e1b6bSKenneth E. Jansen printf("myrank,i,nodetoinsert %d %d %d \n",workfc.myrank,i,nodetoinsert); 570175e1b6bSKenneth E. Jansen } 571175e1b6bSKenneth E. Jansen 57210167291SKenneth E. Jansen indexsetarys[k] = nodetoinsert; 57310167291SKenneth E. Jansen k = k+1; 57410167291SKenneth E. Jansen } 57510167291SKenneth E. Jansen } 57610167291SKenneth E. Jansen else { 57710167291SKenneth E. Jansen for (i=0; i<nshg ; i++) { 57810167291SKenneth E. Jansen nodetoinsert = i; 57910167291SKenneth E. Jansen indexsetarys[k] = nodetoinsert; 58010167291SKenneth E. Jansen k = k+1; 58110167291SKenneth E. Jansen } 58210167291SKenneth E. Jansen } 58310167291SKenneth E. Jansen 58410167291SKenneth E. Jansen // Create Vector Index Maps 58510167291SKenneth E. Jansen petsc_n = (PetscInt) nshg; 58610167291SKenneth E. Jansen ierr = ISCreateGeneral(PETSC_COMM_SELF, petsc_n, indexsetarys, 58710167291SKenneth E. Jansen PETSC_COPY_VALUES, &LocalIndexSets); 5888636783dSKenneth E. Jansen free(indexsetarys); 58910167291SKenneth E. Jansen } 59010167291SKenneth E. Jansen if(genpar.lhs ==1) { 59110167291SKenneth E. Jansen ierr = MatAssemblyBegin(lhsPs, MAT_FINAL_ASSEMBLY); 59210167291SKenneth E. Jansen ierr = MatAssemblyEnd(lhsPs, MAT_FINAL_ASSEMBLY); 59310167291SKenneth E. Jansen } 59410167291SKenneth E. Jansen if(firstpetsccalls == 1) { 59510167291SKenneth E. Jansen ierr = MatGetLocalSize(lhsPs, &LocalRow, &LocalCol); 59610167291SKenneth E. Jansen ierr = VecCreateMPI(PETSC_COMM_WORLD, LocalRow, petsc_M, &resPs); 59710167291SKenneth E. Jansen ierr = VecCreateMPI(PETSC_COMM_WORLD, LocalRow, petsc_M, &DyPs); 59810167291SKenneth E. Jansen } 59910167291SKenneth E. Jansen ierr = VecZeroEntries(resPs); 60010167291SKenneth E. Jansen if(firstpetsccalls == 1) { 60110167291SKenneth E. Jansen ierr = VecCreateSeq(PETSC_COMM_SELF, petsc_n, &DyPLocals); 60210167291SKenneth E. Jansen } 60310167291SKenneth E. Jansen 60410167291SKenneth E. Jansen PetscRow=0; 60510167291SKenneth E. Jansen k = 0; 60610167291SKenneth E. Jansen int index; 60710167291SKenneth E. Jansen for (i=0; i<nshg; i++ ){ 60810167291SKenneth E. Jansen valtoinsert = res[i]; 60910167291SKenneth E. Jansen if(workfc.numpe > 1) { 61010167291SKenneth E. Jansen PetscRow = (fncorp[i]-1); 61110167291SKenneth E. Jansen } 61210167291SKenneth E. Jansen else { 613*c90fc7c7SKenneth E. Jansen PetscRow = i; 61410167291SKenneth E. Jansen } 61510167291SKenneth E. Jansen assert(fncorp[i]<=nshgt); 61610167291SKenneth E. Jansen assert(fncorp[i]>0); 61710167291SKenneth E. Jansen assert(PetscRow>=0); 61810167291SKenneth E. Jansen assert(PetscRow<=nshgt); 6192801f607SKenneth E. Jansen ierr = VecSetValue(resPs, PetscRow, valtoinsert, ADD_VALUES); 62010167291SKenneth E. Jansen } 62110167291SKenneth E. Jansen ierr = VecAssemblyBegin(resPs); 62210167291SKenneth E. Jansen ierr = VecAssemblyEnd(resPs); 6232801f607SKenneth E. Jansen ierr = VecNorm(resPs,NORM_2,&resNrm); 62410167291SKenneth E. Jansen 62510167291SKenneth E. Jansen if(firstpetsccalls == 1) { 62610167291SKenneth E. Jansen ierr = KSPCreate(PETSC_COMM_WORLD, &ksps); 62710167291SKenneth E. Jansen ierr = KSPSetOperators(ksps, lhsPs, lhsPs); 62810167291SKenneth E. Jansen ierr = KSPGetPC(ksps, &pcs); 62910167291SKenneth E. Jansen ierr = PCSetType(pcs, PCPBJACOBI); 63010167291SKenneth E. Jansen PetscInt maxits; 63110167291SKenneth E. Jansen maxits = (PetscInt) solpar.nGMRES * (PetscInt) solpar.Kspace; 63210167291SKenneth E. Jansen ierr = KSPSetTolerances(ksps, timdat.etol, PETSC_DEFAULT, PETSC_DEFAULT, maxits); 63310167291SKenneth E. Jansen ierr = KSPSetFromOptions(ksps); 63410167291SKenneth E. Jansen } 63510167291SKenneth E. Jansen ierr = KSPSolve(ksps, resPs, DyPs); 63610167291SKenneth E. Jansen if(firstpetsccalls == 1) { 6378ae99c59SKenneth E. Jansen ierr = VecScatterCreate(DyPs, LocalIndexSets, DyPLocals, NULL, &scatter7s); 63810167291SKenneth E. Jansen } 63910167291SKenneth E. Jansen ierr = VecScatterBegin(scatter7s, DyPs, DyPLocals, INSERT_VALUES, SCATTER_FORWARD); 64010167291SKenneth E. Jansen ierr = VecScatterEnd(scatter7s, DyPs, DyPLocals, INSERT_VALUES, SCATTER_FORWARD); 64110167291SKenneth E. Jansen ierr = VecGetArray(DyPLocals, &parray); 64210167291SKenneth E. Jansen PetscRow = 0; 64310167291SKenneth E. Jansen for ( node = 0; node< nshg; node++) { 64410167291SKenneth E. Jansen index = node; 64510167291SKenneth E. Jansen Dy[index] = parray[PetscRow]; 64610167291SKenneth E. Jansen PetscRow = PetscRow+1; 64710167291SKenneth E. Jansen } 64810167291SKenneth E. Jansen ierr = VecRestoreArray(DyPLocals, &parray); 64910167291SKenneth E. Jansen 65010167291SKenneth E. Jansen firstpetsccalls = 0; 65110167291SKenneth E. Jansen 65210167291SKenneth E. Jansen // .... output the statistics 65310167291SKenneth E. Jansen // 65410167291SKenneth E. Jansen // itrpar.iKss=0; // see rstat() 65510167291SKenneth E. Jansen PetscInt its; 65610167291SKenneth E. Jansen ierr = KSPGetIterationNumber(ksps, &its); 65710167291SKenneth E. Jansen itrpar.iKss = (int) its; 65810167291SKenneth E. Jansen itrpar.ntotGMs += (int) its; 6592801f607SKenneth E. Jansen rstatpSclr (&resNrm); 66010167291SKenneth E. Jansen // 66110167291SKenneth E. Jansen // .... end 66210167291SKenneth E. Jansen // 66310167291SKenneth E. Jansen } 66417860365SKenneth E. Jansen #endif 665