159599516SKenneth E. Jansen subroutine SolMFG (y, ac, yold, acold, 259599516SKenneth E. Jansen & x, 359599516SKenneth E. Jansen & iBC, BC, res, 459599516SKenneth E. Jansen & BDiag, HBrg, eBrg, 559599516SKenneth E. Jansen & yBrg, Rcos, Rsin, iper, 659599516SKenneth E. Jansen & ilwork, shp, shgl, 759599516SKenneth E. Jansen & shpb, shglb, Dy, rerr) 859599516SKenneth E. Jansenc 959599516SKenneth E. Jansenc---------------------------------------------------------------------- 1059599516SKenneth E. Jansenc 1159599516SKenneth E. Jansenc This is the preconditioned matrix-free GMRES driver routine. 1259599516SKenneth E. Jansenc 1359599516SKenneth E. Jansenc input: 1459599516SKenneth E. Jansenc y (nshg,ndof) : Y-variables at n+alpha_v 1559599516SKenneth E. Jansenc ac (nshg,ndof) : Primvar. accel. variable n+alpha_m 1659599516SKenneth E. Jansenc yold (nshg,ndof) : Y-variables at beginning of step 1759599516SKenneth E. Jansenc acold (nshg,ndof) : Primvar. accel. variable at begng step 1859599516SKenneth E. Jansenc x (numnp,nsd) : node coordinates 1959599516SKenneth E. Jansenc iBC (nshg) : BC codes 2059599516SKenneth E. Jansenc BC (nshg,ndofBC) : BC constraint parameters 2159599516SKenneth E. Jansenc HBrg (Kspace+1,Kspace) : Hessenberg matrix (LHS matrix) 2259599516SKenneth E. Jansenc eBrg (Kspace+1) : RHS of Hessenberg minim. problem 2359599516SKenneth E. Jansenc yBrg (Kspace) : solution of Hessenberg minim. problem 2459599516SKenneth E. Jansenc Rcos (Kspace) : Rotational cosine of QR algorithm 2559599516SKenneth E. Jansenc Rsin (Kspace) : Rotational sine of QR algorithm 2659599516SKenneth E. Jansenc shp(b) (nen,maxsh,melCat) : element shape functions (boundary) 2759599516SKenneth E. Jansenc shgl(b)(nsd,nen,maxsh,melCat) : local gradients of shape functions 2859599516SKenneth E. Jansenc 2959599516SKenneth E. Jansenc output: 3059599516SKenneth E. Jansenc res (nshg,ndof) : preconditioned residual 3159599516SKenneth E. Jansenc BDiag (nshg,ndof,ndof) : block-diagonal preconditioner 3259599516SKenneth E. Jansenc 3359599516SKenneth E. Jansenc 3459599516SKenneth E. Jansenc Zdenek Johan, Winter 1991. (Fortran 90) 3559599516SKenneth E. Jansenc---------------------------------------------------------------------- 3659599516SKenneth E. Jansenc 3759599516SKenneth E. Jansen include "common.h" 3859599516SKenneth E. Jansen include "mpif.h" 3959599516SKenneth E. Jansen include "auxmpi.h" 4059599516SKenneth E. Jansenc 4159599516SKenneth E. Jansen dimension y(nshg,ndof), ac(nshg,ndof), 4259599516SKenneth E. Jansen & yold(nshg,ndof), acold(nshg,ndof), 4359599516SKenneth E. Jansen & x(numnp,nsd), 4459599516SKenneth E. Jansen & iBC(nshg), BC(nshg,ndofBC), 4559599516SKenneth E. Jansen & res(nshg,nflow), 4659599516SKenneth E. Jansen & BDiag(nshg,nflow,nflow), 4759599516SKenneth E. Jansen & HBrg(Kspace+1,Kspace), eBrg(Kspace+1), 4859599516SKenneth E. Jansen & yBrg(Kspace), Rcos(Kspace), 4959599516SKenneth E. Jansen & Rsin(Kspace), ilwork(nlwork), 5059599516SKenneth E. Jansen & iper(nshg) 5159599516SKenneth E. Jansenc 5259599516SKenneth E. Jansen dimension Dy(nshg,nflow), rmes(nshg,nflow), 5359599516SKenneth E. Jansen & ypre(nshg,nflow), temp(nshg,nflow), 5459599516SKenneth E. Jansen & uBrg(nshg,nflow,Kspace+1), ytmp(nshg,nflow) 5559599516SKenneth E. Jansen 5659599516SKenneth E. Jansenc 5759599516SKenneth E. Jansen dimension shp(MAXTOP,maxsh,MAXQPT), 5859599516SKenneth E. Jansen & shgl(MAXTOP,nsd,maxsh,MAXQPT), 5959599516SKenneth E. Jansen & shpb(MAXTOP,maxsh,MAXQPT), 6059599516SKenneth E. Jansen & shglb(MAXTOP,nsd,maxsh,MAXQPT) 6159599516SKenneth E. Jansenc 6259599516SKenneth E. Jansenc.... *******************>> Element Data Formation <<****************** 6359599516SKenneth E. Jansenc 6459599516SKenneth E. Jansenc 6559599516SKenneth E. Jansenc.... set the parameters for flux and surface tension calculations 6659599516SKenneth E. Jansenc 6759599516SKenneth E. Jansen idflx = zero 6859599516SKenneth E. Jansen if(idiff >= 1) idflx= idflx + (nflow-1) * nsd 6959599516SKenneth E. Jansen if (isurf == 1) idflx=idflx + nsd 7059599516SKenneth E. Jansenc 7159599516SKenneth E. Jansen call ElmMFG (y, ac, x, 7259599516SKenneth E. Jansen & shp, shgl, 7359599516SKenneth E. Jansen & iBC, BC, 7459599516SKenneth E. Jansen & shpb, shglb, 7559599516SKenneth E. Jansen & res, rmes, 7659599516SKenneth E. Jansen & BDiag, iper, ilwork, 7759599516SKenneth E. Jansen & rerr) 7859599516SKenneth E. Jansenc 7959599516SKenneth E. Jansenc.... **********************>> Matrix-Free GMRES <<******************** 8059599516SKenneth E. Jansenc 8159599516SKenneth E. Jansenc 8259599516SKenneth E. Jansenc.... start the timer 8359599516SKenneth E. Jansenc 8459599516SKenneth E. Jansen call timer ('Solver ') 8559599516SKenneth E. Jansenc 8659599516SKenneth E. Jansenc.... ------------------------> Initialization <----------------------- 8759599516SKenneth E. Jansenc 8859599516SKenneth E. Jansen 8959599516SKenneth E. Jansenc 9059599516SKenneth E. Jansenc.... LU decompose the block diagonals 9159599516SKenneth E. Jansenc 9259599516SKenneth E. Jansen if (iprec .ne. 0) 9359599516SKenneth E. Jansen & call i3LU (BDiag, res, 'LU_Fact ') 9459599516SKenneth E. Jansen 9559599516SKenneth E. Jansenc 9659599516SKenneth E. Jansenc.... block diagonal precondition residual 9759599516SKenneth E. Jansenc 9859599516SKenneth E. Jansen call i3LU (BDiag, res, 'forward ') 9959599516SKenneth E. Jansenc 10059599516SKenneth E. Jansenc This is a feature that allows one to take an extra pass just to 10159599516SKenneth E. Jansenc find the residual at the end of the last solve. 10259599516SKenneth E. Jansenc 10359599516SKenneth E. Jansenc$$$ if(iter.ge.(press*nitr) ) then 10459599516SKenneth E. Jansenc$$$ iKs=0 10559599516SKenneth E. Jansenc$$$ lGMRES=0 10659599516SKenneth E. Jansenc$$$ goto 3002 10759599516SKenneth E. Jansenc$$$ endif 10859599516SKenneth E. Jansen 10959599516SKenneth E. Jansenc 11059599516SKenneth E. Jansenc.... block diagonal precondition modified residual 11159599516SKenneth E. Jansenc 11259599516SKenneth E. Jansen call i3LU (BDiag, rmes, 'forward ') 11359599516SKenneth E. Jansen 11459599516SKenneth E. Jansenc 11559599516SKenneth E. Jansenc.... copy res in uBrg(1) 11659599516SKenneth E. Jansenc 11759599516SKenneth E. Jansen uBrg(:,:,1) = res 11859599516SKenneth E. Jansenc 11959599516SKenneth E. Jansenc.... initialize Dy 12059599516SKenneth E. Jansenc 12159599516SKenneth E. Jansen Dy = zero 12259599516SKenneth E. Jansenc 12359599516SKenneth E. Jansenc.... block diagonal precondition y-variables 12459599516SKenneth E. Jansenc 12559599516SKenneth E. Jansen ypre(:,:) = y(:,1:nflow) ! ypre is the pre-conditioned, 12659599516SKenneth E. Jansen ! unperturbed, base vector 12759599516SKenneth E. Jansenc 12859599516SKenneth E. Jansen call yshuffle(ypre,'new2old ') 12959599516SKenneth E. Jansenc 13059599516SKenneth E. Jansen call i3LU (BDiag, ypre, 'product ') 13159599516SKenneth E. Jansenc 13259599516SKenneth E. Jansenc since we will never use ypre in the "new" form again, leave it 13359599516SKenneth E. Jansenc shuffled 13459599516SKenneth E. Jansenc 13559599516SKenneth E. Jansenc call yshuffle(ypre, 'old2new ') 13659599516SKenneth E. Jansenc 13759599516SKenneth E. Jansenc.... calculate norm of residual 13859599516SKenneth E. Jansenc 13959599516SKenneth E. Jansen temp = res**2 14059599516SKenneth E. Jansen 14159599516SKenneth E. Jansenc call tnanq(temp,5,"res**2 ") 14259599516SKenneth E. Jansen 14359599516SKenneth E. Jansen call sumgat (temp, nflow, summed, ilwork) 14459599516SKenneth E. Jansen unorm = sqrt(summed) 14559599516SKenneth E. Jansenc 14659599516SKenneth E. Jansenc.... flop count 14759599516SKenneth E. Jansenc 148f4d0b58bSKenneth E. Jansen! flops = flops + ndof*nshg+nshg 14959599516SKenneth E. Jansenc 15059599516SKenneth E. Jansenc.... check if GMRES iterations are required 15159599516SKenneth E. Jansenc 15259599516SKenneth E. Jansen iKs = 0 15359599516SKenneth E. Jansen lGMRES = 0 15459599516SKenneth E. Jansenc 15559599516SKenneth E. Jansenc.... if we are down to machine precision, don't bother solving 15659599516SKenneth E. Jansenc 15759599516SKenneth E. Jansen if (unorm .lt. 100.*epsM**2) goto 3000 15859599516SKenneth E. Jansenc 15959599516SKenneth E. Jansenc.... set up tolerance of the Hessenberg's problem 16059599516SKenneth E. Jansenc 16159599516SKenneth E. Jansen epsnrm = etol * unorm 16259599516SKenneth E. Jansenc 16359599516SKenneth E. Jansenc.... compute the finite difference interval 16459599516SKenneth E. Jansenc 16559599516SKenneth E. Jansen if ((iter .eq. 1) .and. (mod(istep,20) .eq. 0)) then 16659599516SKenneth E. Jansen call itrFDI (ypre, y, ac, 16759599516SKenneth E. Jansen & x, rmes, 16859599516SKenneth E. Jansen & res, BDiag, iBC, 16959599516SKenneth E. Jansen & BC, iper, 17059599516SKenneth E. Jansen & ilwork, shp, shgl, 17159599516SKenneth E. Jansen & shpb, shglb) 17259599516SKenneth E. Jansen endif 17359599516SKenneth E. Jansen ires=2 17459599516SKenneth E. Jansenc 17559599516SKenneth E. Jansenc.... ------------------------> GMRES Loop <------------------------- 17659599516SKenneth E. Jansenc 17759599516SKenneth E. Jansenc.... loop through GMRES cycles 17859599516SKenneth E. Jansenc 17959599516SKenneth E. Jansen do 2000 mGMRES = 1, nGMRES 18059599516SKenneth E. Jansen lGMRES = mGMRES - 1 18159599516SKenneth E. Jansenc 18259599516SKenneth E. Jansen if (lGMRES .gt. 0) then 18359599516SKenneth E. Jansenc 18459599516SKenneth E. Jansenc.... calculate R - A u 18559599516SKenneth E. Jansenc 18659599516SKenneth E. Jansen call Au2MFG (ypre, y, ac, 18759599516SKenneth E. Jansen & x, rmes, 18859599516SKenneth E. Jansen & res, Dy, temp, 18959599516SKenneth E. Jansen & BDiag, iBC, BC, 19059599516SKenneth E. Jansen & iper, ilwork, 19159599516SKenneth E. Jansen & shp, shgl, 19259599516SKenneth E. Jansen & shpb, shglb) 19359599516SKenneth E. Jansen 19459599516SKenneth E. Jansenc 19559599516SKenneth E. Jansen uBrg(:,:,1) = temp 19659599516SKenneth E. Jansenc 19759599516SKenneth E. Jansenc.... calculate the norm 19859599516SKenneth E. Jansenc 19959599516SKenneth E. Jansen temp = temp**2 20059599516SKenneth E. Jansen call sumgat (temp, ndof, summed, ilwork) 20159599516SKenneth E. Jansen unorm = sqrt(summed) 20259599516SKenneth E. Jansen 20359599516SKenneth E. Jansenc 20459599516SKenneth E. Jansenc.... flop count 20559599516SKenneth E. Jansenc 206f4d0b58bSKenneth E. Jansen! flops = flops + ndof*nshg+nshg 20759599516SKenneth E. Jansenc 20859599516SKenneth E. Jansen endif 20959599516SKenneth E. Jansenc 21059599516SKenneth E. Jansenc.... set up RHS of the Hessenberg's problem 21159599516SKenneth E. Jansenc 21259599516SKenneth E. Jansen call clear (eBrg, Kspace+1) 21359599516SKenneth E. Jansen eBrg(1) = unorm 21459599516SKenneth E. Jansenc 21559599516SKenneth E. Jansenc.... normalize the first Krylov vector 21659599516SKenneth E. Jansenc 21759599516SKenneth E. Jansen uBrg(:,:,1) = uBrg(:,:,1) / unorm 21859599516SKenneth E. Jansenc 21959599516SKenneth E. Jansenc.... loop through GMRES iterations 22059599516SKenneth E. Jansenc 22159599516SKenneth E. Jansen do 1000 iK = 1, Kspace 22259599516SKenneth E. Jansen iKs = iK 22359599516SKenneth E. Jansenc 22459599516SKenneth E. Jansenc.... Au product 22559599516SKenneth E. Jansenc 22659599516SKenneth E. Jansen temp = uBrg(:,:,iKs) 22759599516SKenneth E. Jansenc 22859599516SKenneth E. Jansen call Au1MFG (ypre, y, ac, 22959599516SKenneth E. Jansen & x, rmes, 23059599516SKenneth E. Jansen & res, temp, BDiag, 23159599516SKenneth E. Jansen & iBC, BC, 23259599516SKenneth E. Jansen & iper, ilwork, 23359599516SKenneth E. Jansen & shp, shgl, 23459599516SKenneth E. Jansen & shpb, shglb) 23559599516SKenneth E. Jansenc 23659599516SKenneth E. Jansen uBrg(:,:,iKs+1) = temp ! u_{i+1}= J u_i In Johan Thesis p 15c 23759599516SKenneth E. Jansenc$$$c 23859599516SKenneth E. Jansenc$$$c.... debug 23959599516SKenneth E. Jansenc$$$c 24059599516SKenneth E. Jansenc$$$ do i=1,nshg 24159599516SKenneth E. Jansenc$$$ write(78,'(5(f14.7))')(uBrg(i,j,iKs+1),j=1,5) 24259599516SKenneth E. Jansenc$$$ enddo 24359599516SKenneth E. Jansenc$$$ stop 24459599516SKenneth E. Jansenc 24559599516SKenneth E. Jansenc.... orthogonalize and get the norm 24659599516SKenneth E. Jansenc 24759599516SKenneth E. Jansen do jK = 1, iKs+1 24859599516SKenneth E. Jansenc 24959599516SKenneth E. Jansen if (jK .eq. 1) then 25059599516SKenneth E. Jansenc 25159599516SKenneth E. Jansen temp = uBrg(:,:,iKs+1) * uBrg(:,:,1) ! {u_{i+1}*u_1} vector 25259599516SKenneth E. Jansen call sumgat (temp, nflow, beta, ilwork) ! sum vector=(u_{i+1},u_1) 25359599516SKenneth E. Jansenc 25459599516SKenneth E. Jansen else 25559599516SKenneth E. Jansenc 25659599516SKenneth E. Jansenc project off jK-1 vector 25759599516SKenneth E. Jansenc 25859599516SKenneth E. Jansen uBrg(:,:,iKs+1) = uBrg(:,:,iKs+1) - beta * uBrg(:,:,jK-1) 25959599516SKenneth E. Jansenc 26059599516SKenneth E. Jansen temp = uBrg(:,:,iKs+1) * uBrg(:,:,jK) !{u_{i+1}*u_j} vector 26159599516SKenneth E. Jansen call sumgat (temp, nflow, beta, ilwork) ! sum vector=(u_{i+1},u_j) 26259599516SKenneth E. Jansenc 26359599516SKenneth E. Jansen endif 26459599516SKenneth E. Jansenc 26559599516SKenneth E. Jansen HBrg(jK,iKs) = beta ! put this in the Hessenberg Matrix 26659599516SKenneth E. Jansenc 26759599516SKenneth E. Jansen enddo 26859599516SKenneth E. Jansenc 269f4d0b58bSKenneth E. Jansen! flops = flops + (3*iKs+1)*nflow*nshg+(iKs+1)*nshg 27059599516SKenneth E. Jansenc 27159599516SKenneth E. Jansenc the last inner product was with what was left of the vector (after 27259599516SKenneth E. Jansenc projecting off all of the previous vectors 27359599516SKenneth E. Jansenc 27459599516SKenneth E. Jansen unorm = sqrt(beta) 27559599516SKenneth E. Jansen HBrg(iKs+1,iKs) = unorm ! this fills the 1 sub diagonal band 27659599516SKenneth E. Jansenc 27759599516SKenneth E. Jansenc.... normalize the Krylov vector 27859599516SKenneth E. Jansenc 27959599516SKenneth E. Jansen uBrg(:,:,iKs+1) = uBrg(:,:,iKs+1) / unorm ! normalize the next Krylov 28059599516SKenneth E. Jansenc vector 28159599516SKenneth E. Jansenc 28259599516SKenneth E. Jansenc.... construct and reduce the Hessenberg Matrix 28359599516SKenneth E. Jansenc since there is only one subdiagonal we can use a Givens rotation to 28459599516SKenneth E. Jansenc rotate off each subdiagonal AS IT IS FORMED. We do this because it 28559599516SKenneth E. Jansenc allows us to check progress of solution and quit when satisfied. Note 28659599516SKenneth E. Jansenc that all future K vects will put a subdiagonal in the next column so 28759599516SKenneth E. Jansenc there is no penalty to work ahead as the rotation for the next vector 28859599516SKenneth E. Jansenc will be unaffected by this rotation. 28959599516SKenneth E. Jansen 29059599516SKenneth E. Jansenc 29159599516SKenneth E. Jansenc H Y = E ========> R_i H Y = R_i E 29259599516SKenneth E. Jansenc 29359599516SKenneth E. Jansen do jK = 1, iKs-1 29459599516SKenneth E. Jansen tmp = Rcos(jK) * HBrg(jK, iKs) + 29559599516SKenneth E. Jansen & Rsin(jK) * HBrg(jK+1,iKs) 29659599516SKenneth E. Jansen HBrg(jK+1,iKs) = -Rsin(jK) * HBrg(jK, iKs) + 29759599516SKenneth E. Jansen & Rcos(jK) * HBrg(jK+1,iKs) 29859599516SKenneth E. Jansen HBrg(jK, iKs) = tmp 29959599516SKenneth E. Jansen enddo 30059599516SKenneth E. Jansenc 30159599516SKenneth E. Jansen tmp = sqrt(HBrg(iKs,iKs)**2 + HBrg(iKs+1,iKs)**2) 30259599516SKenneth E. Jansen Rcos(iKs) = HBrg(iKs, iKs) / tmp 30359599516SKenneth E. Jansen Rsin(iKs) = HBrg(iKs+1,iKs) / tmp 30459599516SKenneth E. Jansen HBrg(iKs, iKs) = tmp 30559599516SKenneth E. Jansen HBrg(iKs+1,iKs) = zero 30659599516SKenneth E. Jansenc 30759599516SKenneth E. Jansenc.... rotate eBrg R_i E 30859599516SKenneth E. Jansenc 30959599516SKenneth E. Jansen tmp = Rcos(iKs) * eBrg(iKs) + Rsin(iKs) * eBrg(iKs+1) 31059599516SKenneth E. Jansen eBrg(iKs+1) = -Rsin(iKs) * eBrg(iKs) + Rcos(iKs) * eBrg(iKs+1) 31159599516SKenneth E. Jansen eBrg(iKs) = tmp 31259599516SKenneth E. Jansenc 31359599516SKenneth E. Jansenc.... check for convergence 31459599516SKenneth E. Jansenc 31559599516SKenneth E. Jansen ntotGM = ntotGM + 1 316*779e4b51SKenneth E. Jansen echeck=abs(eBrg(iKs+1)) 317*779e4b51SKenneth E. Jansen if (echeck .le. epsnrm.and. iKs .ge. minIters) exit 31859599516SKenneth E. Jansenc 31959599516SKenneth E. Jansenc.... end of GMRES iteration loop 32059599516SKenneth E. Jansenc 32159599516SKenneth E. Jansen1000 continue 32259599516SKenneth E. Jansenc 32359599516SKenneth E. Jansenc.... -------------------------> Solution <------------------------ 32459599516SKenneth E. Jansenc 32559599516SKenneth E. Jansenc.... if converged or end of Krylov space 32659599516SKenneth E. Jansenc 32759599516SKenneth E. Jansenc.... solve for yBrg 32859599516SKenneth E. Jansenc 32959599516SKenneth E. Jansen do jK = iKs, 1, -1 33059599516SKenneth E. Jansen yBrg(jK) = eBrg(jK) / HBrg(jK,jK) 33159599516SKenneth E. Jansen do lK = 1, jK-1 33259599516SKenneth E. Jansen eBrg(lK) = eBrg(lK) - yBrg(jK) * HBrg(lK,jK) 33359599516SKenneth E. Jansen enddo 33459599516SKenneth E. Jansen enddo 33559599516SKenneth E. Jansenc 33659599516SKenneth E. Jansenc.... update Dy 33759599516SKenneth E. Jansenc 33859599516SKenneth E. Jansen do jK = 1, iKs 33959599516SKenneth E. Jansen Dy = Dy + yBrg(jK) * uBrg(:,:,jK) 34059599516SKenneth E. Jansen enddo 34159599516SKenneth E. Jansenc 34259599516SKenneth E. Jansenc.... flop count 34359599516SKenneth E. Jansenc 344f4d0b58bSKenneth E. Jansen! flops = flops + (3*iKs+1)*nflow*nshg 34559599516SKenneth E. Jansenc 34659599516SKenneth E. Jansenc.... check for convergence 34759599516SKenneth E. Jansenc 34859599516SKenneth E. Jansen if (abs(eBrg(iKs+1)) .le. epsnrm) exit 34959599516SKenneth E. Jansenc 35059599516SKenneth E. Jansenc.... end of mGMRES loop 35159599516SKenneth E. Jansenc 35259599516SKenneth E. Jansen2000 continue 35359599516SKenneth E. Jansenc 35459599516SKenneth E. Jansenc.... ------------------------> Converged <------------------------ 35559599516SKenneth E. Jansenc 35659599516SKenneth E. Jansenc.... if converged 35759599516SKenneth E. Jansenc 35859599516SKenneth E. Jansen3000 continue 35959599516SKenneth E. Jansen 36059599516SKenneth E. Jansenc 36159599516SKenneth E. Jansenc.... back precondition the results 36259599516SKenneth E. Jansenc 36359599516SKenneth E. Jansen call i3LU (BDiag, Dy, 'backward') 36459599516SKenneth E. Jansenc 36559599516SKenneth E. Jansenc.... output the statistics 36659599516SKenneth E. Jansenc 36759599516SKenneth E. Jansen call rstat (res, ilwork) 36859599516SKenneth E. Jansenc 36959599516SKenneth E. Jansenc ... reset ires to 3 again (asires changed ires to 2) 37059599516SKenneth E. Jansenc 37159599516SKenneth E. Jansen ires = 3 37259599516SKenneth E. Jansenc 37359599516SKenneth E. Jansenc.... stop the timer 37459599516SKenneth E. Jansenc 37559599516SKenneth E. Jansen3002 continue ! no solve just res. 37659599516SKenneth E. Jansen call timer ('Back ') 37759599516SKenneth E. Jansenc 37859599516SKenneth E. Jansenc.... end 37959599516SKenneth E. Jansenc 38059599516SKenneth E. Jansen return 38159599516SKenneth E. Jansen end 382