HYPRE_Int hypre_AMESolve(void *esolver) { hypre_AMEData *ame_data = esolver; HYPRE_Int nit; lobpcg_BLASLAPACKFunctions blap_fn; lobpcg_Tolerance lobpcg_tol; HYPRE_Real *residuals; #ifdef HYPRE_USING_ESSL blap_fn.dsygv = dsygv; blap_fn.dpotrf = dpotrf; #else blap_fn.dsygv = hypre_F90_NAME_LAPACK(dsygv,DSYGV); blap_fn.dpotrf = hypre_F90_NAME_LAPACK(dpotrf,DPOTRF); #endif lobpcg_tol.relative = ame_data -> tol; lobpcg_tol.absolute = ame_data -> tol; residuals = hypre_TAlloc(HYPRE_Real, ame_data -> block_size); lobpcg_solve((mv_MultiVectorPtr) ame_data -> eigenvectors, esolver, hypre_AMEMultiOperatorA, esolver, hypre_AMEMultiOperatorM, esolver, hypre_AMEMultiOperatorB, NULL, blap_fn, lobpcg_tol, ame_data -> maxit, ame_data -> print_level, &nit, ame_data -> eigenvalues, NULL, ame_data -> block_size, residuals, NULL, ame_data -> block_size); hypre_TFree(residuals); return hypre_error_flag; }
HYPRE_Int hypre_LOBPCGSolve( void *vdata, mv_MultiVectorPtr con, mv_MultiVectorPtr vec, double* val ) { hypre_LOBPCGData* data = vdata; HYPRE_Int (*precond)() = (data->precondFunctions).Precond; void* opB = data->B; void (*prec)( void*, void*, void* ); void (*operatorA)( void*, void*, void* ); void (*operatorB)( void*, void*, void* ); HYPRE_Int maxit = lobpcg_maxIterations(data->lobpcgData); HYPRE_Int verb = lobpcg_verbosityLevel(data->lobpcgData); HYPRE_Int n = mv_MultiVectorWidth( vec ); lobpcg_BLASLAPACKFunctions blap_fn; utilities_FortranMatrix* lambdaHistory; utilities_FortranMatrix* residuals; utilities_FortranMatrix* residualsHistory; lambdaHistory = lobpcg_eigenvaluesHistory(data->lobpcgData); residuals = lobpcg_residualNorms(data->lobpcgData); residualsHistory = lobpcg_residualNormsHistory(data->lobpcgData); utilities_FortranMatrixAllocateData( n, maxit + 1, lambdaHistory ); utilities_FortranMatrixAllocateData( n, 1, residuals ); utilities_FortranMatrixAllocateData( n, maxit + 1, residualsHistory ); if ( precond != NULL ) prec = hypre_LOBPCGMultiPreconditioner; else prec = NULL; operatorA = hypre_LOBPCGMultiOperatorA; if ( opB != NULL ) operatorB = hypre_LOBPCGMultiOperatorB; else operatorB = NULL; blap_fn.dsygv = dsygv_interface; blap_fn.dpotrf = dpotrf_interface; lobpcg_solve( vec, vdata, operatorA, vdata, operatorB, vdata, prec, con, blap_fn, lobpcg_tolerance(data->lobpcgData), maxit, verb, &(lobpcg_iterationNumber(data->lobpcgData)), val, utilities_FortranMatrixValues(lambdaHistory), utilities_FortranMatrixGlobalHeight(lambdaHistory), utilities_FortranMatrixValues(residuals), utilities_FortranMatrixValues(residualsHistory), utilities_FortranMatrixGlobalHeight(residualsHistory) ); return hypre_error_flag; }
void petsc_lobpcg_solve_c( Vec* u, /* prototype of a vector, not used */ int* my_own_eq, /* equations owned by this processor */ int* num_eval, /* number of eigenvalues to compute */ int* maxit, /* maximum number of iterations */ double* atol, /* absolute error tolerance */ double* rtol, /* relative error tolerance */ double* eigenvalues, /* computed eigenvalues */ void *matmult_opA, /* Fortran routine for operator A */ void *matmult_opB, /* Fortran routine for operator B */ void *matmult_opT, /* Fortran routine for operator T */ void *petsc_lobpcg_return_evec, /* Fortran routine gets eigenvectors */ void *petsc_lobpcg_initial_guess, /* Fortran routine for initial guess */ int* info) /* error code */ { PetscErrorCode ierr; /* for PETSc return code */ mv_MultiVectorPtr eigenvectors; /* the eigenvectors */ double * eigs; /* the eigenvalues */ double * eigs_hist; /* history of eigenvalues */ double * resid; /* the residuals */ double * resid_hist; /* history of residuals */ int iterations; /* number of iterations */ int n_eigs; /* number of eigenvalues */ int i,j; PetscTruth outpt=PETSC_FALSE; /* print evals and resids */ lobpcg_Tolerance lobpcg_tol; /* residual tolerance */ mv_InterfaceInterpreter ii; /* Interface Interpreter */ lobpcg_BLASLAPACKFunctions blap_fn; /* BLAS functions */ aux_data_struct aux_data; /* auxillary data */ /* set the number of eigenvalues to compute */ n_eigs = *num_eval; /* set pointers to the Fortran callback functions */ hold_matmult_opA = matmult_opA; hold_matmult_opB = matmult_opB; hold_matmult_opT = matmult_opT; hold_petsc_lobpcg_initial_guess = petsc_lobpcg_initial_guess; hold_petsc_lobpcg_return_evec = petsc_lobpcg_return_evec; /* allocate memory for the eigenvalues, residuals and histories */ ierr = PetscMalloc(sizeof(double)*n_eigs,&eigs); ierr = PetscMalloc(sizeof(double)*n_eigs*(*maxit+1),&eigs_hist); ierr = PetscMalloc(sizeof(double)*n_eigs,&resid); ierr = PetscMalloc(sizeof(double)*n_eigs*(*maxit+1),&resid_hist); /* create the Interface Interpreter and put it in auxillary data */ PETSCSetupInterpreter( &ii ); aux_data.ii = ii; /* set tolerances and BLAS routines */ lobpcg_tol.absolute = *atol; lobpcg_tol.relative = *rtol; blap_fn.dpotrf = PETSC_dpotrf_interface; blap_fn.dsygv = PETSC_dsygv_interface; /* create the multivector for eigenvectors */ eigenvectors = mv_MultiVectorCreateFromSampleVector(&ii, n_eigs,*u); /* set the initial guess. The second instance of eigenvectors in this call isn't actually used, but something has to be passed in */ petsc_lobpcg_initial_guess_MultiVector(&aux_data, mv_MultiVectorGetData(eigenvectors), mv_MultiVectorGetData(eigenvectors)); /* call the lobpcg solver from BLOPEX */ ierr = lobpcg_solve( eigenvectors, &aux_data, OperatorAMultiVector, &aux_data, OperatorBMultiVector, &aux_data, OperatorTMultiVector, NULL, blap_fn, lobpcg_tol, *maxit, 0, /* verbosity, use 2 for debugging */ &iterations, eigs, eigs_hist, n_eigs, resid, resid_hist, n_eigs ); /* set the return error code to lobpcg's error code */ *info = ierr; /* copy the eigenvalues to the return variable */ for (i=0;i<n_eigs;i++) eigenvalues[i] = eigs[i]; /* return the eigenvectors. The second instance of eigenvectors isn't used here either */ petsc_lobpcg_return_evec_MultiVector(&aux_data, mv_MultiVectorGetData(eigenvectors), mv_MultiVectorGetData(eigenvectors)); /* printed output, for debugging */ if (outpt) { PetscPrintf(PETSC_COMM_WORLD,"Output from LOBPCG driver\n"); PetscPrintf(PETSC_COMM_WORLD," iterations: %d\n",iterations); PetscPrintf(PETSC_COMM_WORLD," eigenvalues and residuals:\n"); for (i=0;i<n_eigs;i++) { ierr = PetscPrintf(PETSC_COMM_WORLD,"%e %e\n",eigs[i],resid[i]); } /* PetscPrintf(PETSC_COMM_WORLD,"Output from LOBPCG, eigenvalues history:\n"); for (j=0; j<iterations+1; j++) for (i=0;i<n_eigs;i++) { ierr = PetscPrintf(PETSC_COMM_WORLD,"%e\n",*(eigs_hist+j*n_eigs+i)); } PetscPrintf(PETSC_COMM_WORLD,"Output from LOBPCG, residual norms:\n"); for (i=0;i<n_eigs;i++) { ierr = PetscPrintf(PETSC_COMM_WORLD,"%e\n",resid[i]); } PetscPrintf(PETSC_COMM_WORLD,"Output from LOBPCG, residual norms history:\n"); for (j=0; j<iterations+1; j++) for (i=0;i<n_eigs;i++) { ierr = PetscPrintf(PETSC_COMM_WORLD,"%e\n",*(resid_hist+j*n_eigs+i)); } */ } /* free work space */ mv_MultiVectorDestroy(eigenvectors); ierr = PetscFree(eigs); ierr = PetscFree(eigs_hist); ierr = PetscFree(resid); ierr = PetscFree(resid_hist); }