/* examples/C/ssmfe/precond_core.f90 */ /* Laplacian on a square grid (using SPRAL_SSMFE_CORE routines) */ #include "spral.h" #include #include #include #include /* Header that implements Laplacian and preconditioners */ #include "laplace2d.h" int main(void) { const int ngrid = 20; /* grid points along each side */ const int n = ngrid*ngrid; /* problem size */ const int nep = 5; /* eigenpairs wanted */ const int m = 3; /* dimension of the iterated subspace */ const double tol = 1.e-6; /* eigenvector tolerance */ int state = SPRAL_RANDOM_INITIAL_SEED; /* PRNG state */ int *ind = malloc(m * sizeof(*ind)); /* permutation index */ double *lambda = malloc(n * sizeof(*lambda)); /* eigenvalues */ double (*X)[n][n] = malloc(sizeof(*X)); /* eigenvectors */ /* Work arrays */ double *lmd = malloc(m * sizeof(*lmd)); double (*rr)[3][2*m][2*m] = malloc(sizeof(*rr)); double (*W)[7][m][n] = malloc(sizeof(*W)); double (*U)[m][n] = malloc(sizeof(*U)); /* Derived types */ struct spral_ssmfe_rcid rci; /* reverse communication data */ struct spral_ssmfe_core_options options; /* options */ void *keep; /* private data */ struct spral_ssmfe_inform inform; /* information */ /* Initialize options to default values */ spral_ssmfe_core_default_options(&options); /* Initialize W to lin indep vectors by randomizing */ for(int i=0; i 0 && inform.err_X[j] < tol ) inform.converged[j] = 1; } break; case 5: if ( rci.i < 0 ) continue; for(int k=0; k= nep || inform.iteration > 300 ) goto finished; break; case 11: if ( rci.i == 0 ) { if ( rci.kx != rci.ky || rci.jx > rci.jy ) { cblas_dcopy(n*rci.nx, &(*W)[rci.kx][rci.jx][0], 1, &(*W)[rci.ky][rci.jy][0], 1); } else if ( rci.jx < rci.jy ) { for(int j=rci.nx-1; j>=0; j--) cblas_dcopy(n, &(*W)[rci.kx][rci.jx+j][0], 1, &(*W)[rci.ky][rci.jy+j][0], 1); } } else { for(int i=0; i 0 ) cblas_dscal(n, 1/s, &(*W)[rci.kx][rci.jx+i][0], 1); } else { double s = sqrt(fabs(cblas_ddot( n, &(*W)[rci.kx][rci.jx+i][0], 1, &(*W)[rci.ky][rci.jy+i][0], 1) )); if ( s > 0 ) { cblas_dscal(n, 1/s, &(*W)[rci.kx][rci.jx+i][0], 1); cblas_dscal(n, 1/s, &(*W)[rci.ky][rci.jy+i][0], 1); } else { for(int j=0; j 0 && rci.ny > 0 ) cblas_dgemm( CblasColMajor, CblasTrans, CblasNoTrans, rci.nx, rci.ny, n, rci.alpha, &(*W)[rci.kx][rci.jx][0], n, &(*W)[rci.ky][rci.jy][0], n, rci.beta, &(*rr)[rci.k][rci.j][rci.i], 2*m ); break; case 16: // Fall through to 17 case 17: if( rci.ny < 1 ) continue; if( rci.nx < 1 ) { if( rci.job == 17 ) continue; if( rci.beta == 1.0 ) continue; for(int j=rci.jy; j 0 ) { cblas_dgemm( CblasColMajor, CblasTrans, CblasNoTrans, ncon, rci.nx, n, 1.0, &(*X)[0][0], n, &(*W)[rci.ky][rci.jy][0], n, 0.0, &(*U)[0][0], n ); cblas_dgemm( CblasColMajor, CblasNoTrans, CblasNoTrans, n, rci.nx, ncon, -1.0, &(*X)[0][0], n, &(*U)[0][0], n, 1.0, &(*W)[rci.kx][rci.jx][0], n ); } break; default: goto finished; } } finished: if(inform.flag != 0) printf("inform.flag = %d\n", inform.flag); printf("%3d eigenpairs converged in %d iterations\n", ncon, inform.iteration); for(int i=0; i