63 MPI_Comm comm,
int numProcs,
int localProc){
68 std::vector<std::string> stdstrings;
72 const char** params = NULL;
79 std::string solverName;
89 fei::console_out() <<
"Failed to find one or more required parameters in input-file."
97 int nodes = (L+1)*(L+1);
100 FEI_COUT <<
"========================================================"
107 FEI_COUT <<
"========================================================"
111 if ((masterProc == localProc)&&(outputLevel>0)) {
115 if (outputLevel == 1) {
116 if (localProc != 0) outputLevel = 0;
122 PoissonData poissonData(L, numProcs, localProc, outputLevel);
135 if (factory.
get() == NULL) {
140 factory->parameters(paramset);
143 factory->createVectorSpace(comm,
"poisson3");
147 factory->createMatrixGraph(nodeSpace, dummy,
"poisson3");
150 matrixGraph->setParameters(paramset);
159 nodeSpace->defineFields( numFields, fieldIDs, fieldSizes );
162 nodeSpace->defineIDTypes( 1, &nodeIDType );
172 CHK_ERR( matrixGraph->initComplete() );
190 linSys->setMatrix(mat);
191 linSys->setSolutionVector(solnVec);
192 linSys->setRHS(rhsVec);
194 CHK_ERR( linSys->parameters(paramset));
199 CHK_ERR( linSys->loadComplete() );
216 int err = solver->solve(linSys.
get(),
218 paramset, itersTaken, status);
223 if (localProc==0)
FEI_COUT <<
"solve returned err: " << err <<
", status: "
227 CHK_ERR( solnVec->scatterToOverlap() );
233 int numNodes = nodeSpace->getNumOwnedAndSharedIDs(nodeIDType);
237 int lenNodeIDs = numNodes;
239 double* soln =
new double[lenNodeIDs];
240 if (nodeIDs != NULL && soln != NULL) {
241 CHK_ERR( nodeSpace->getOwnedAndSharedIDs(nodeIDType, numNodes,
242 nodeIDs, lenNodeIDs) );
245 CHK_ERR( solnVec->copyOutFieldData(fieldID, nodeIDType,
246 numNodes, nodeIDs, soln));
248 for(
int i=0; i<numNodes; i++) {
249 int nID = (int)nodeIDs[i];
250 double x = (1.0* ((nID-1)%(L+1)))/L;
251 double y = (1.0* ((nID-1)/(L+1)))/L;
253 double exactSoln = x*x + y*y;
254 double error = std::abs(exactSoln - soln[i]);
255 if (maxErr < error) maxErr = error;
268 double globalMaxErr = 0.0;
269 MPI_Allreduce(&maxErr, &globalMaxErr, 1, MPI_DOUBLE, MPI_MAX, comm);
270 maxErr = globalMaxErr;
272 bool testPassed =
true;
273 if (maxErr > 1.e-6) testPassed =
false;
282 <<
" FEI initialize: " << fei_init_time <<
FEI_ENDL
283 <<
" FEI load: " << fei_load_time <<
FEI_ENDL
284 <<
" solve: " << solve_time <<
FEI_ENDL
285 <<
"Total program time: " << elapsed_cpu_time <<
FEI_ENDL;
287#if defined(FEI_PLATFORM) && defined(FEI_OPT_LEVEL)
288 double benchmark = fei_init_time+fei_load_time;
290 testname <<
"poisson3_"<<L<<
"_"<<solverName<<
"_np"<<numProcs<<
"_"
291 <<FEI_PLATFORM<<
"_"<<FEI_OPT_LEVEL;
293 double file_value = 0.0;
294 bool file_value_available =
true;
297 testname.str().c_str());
299 catch(std::runtime_error& exc) {
300 file_value_available =
false;
303 if (file_value_available) {
307 returnValue = test_passed ? 0 : 1;
313 if (testPassed && returnValue==0 && localProc == 0) {
315 FEI_COUT <<
"poisson: TEST PASSED, maxErr = " << maxErr <<
", iterations: "
320 if ((testPassed ==
false || returnValue != 0) && localProc == 0) {
321 if (testPassed==
true) {
322 FEI_COUT <<
"maxErr = " << maxErr <<
", but time-taken outside margin. TEST FAILED" <<
FEI_ENDL;
327 FEI_COUT <<
"(Test is deemed to have passed if the maximum difference"
328 <<
" between the exact and computed solutions is 1.e-6 or less, *AND*"
329 <<
" time-taken matches file-benchmark if available.)"
int poisson3_main(int argc, char **argv, MPI_Comm comm, int numProcs, int localProc)