bool SuperLUSolverTest::runTests() { if (checkSolver()) { info = "Solver test done"; } else { info = "Solver test failed"; } //int gb1 = 134217728; //double *aaa = new double[gb1 * 4]; /* ISquareMatrix *matrix = new ArraySquareMatrix(MATRIX_SIZE); IVector *vector = new ArrayVector(MATRIX_SIZE); IVector *original; MatrixFactory::fillRandomMatrix(matrix); MatrixFactory::fillRandomVector(vector); original = new ArrayVector(vector); std::cout << "waiting..." << std::endl; std::cin.get();*/ /*std::cout << "Matrix:"; MatrixUtils::print(matrix, std::cout, 8, 4); std::cout << std::endl << "Vector:" << std::endl; MatrixUtils::print(vector, std::cout, 7, 4); std::cout << std::endl; clock_t timestamp = clock(); AbstractSolver *solver = new SequentialSolver(); solver->setMatrix(matrix); solver->prepare(); solver->solve(vector); timestamp = clock() - timestamp; std::cout << "Result:" << std::endl; MatrixUtils::print(vector, std::cout, 8, 4); IVector *check = new ArrayVector(MATRIX_SIZE); MatrixUtils::product(matrix, vector, check); std::cout << "Check:" << std::endl; MatrixUtils::print(check, std::cout, 8, 4); double norm = 0; for (int i = 0; i < MATRIX_SIZE; i++) { double difference = check->get(i) - original->get(i); norm += difference * difference; } norm = sqrt(norm); std::cout << "Norm: " << norm << std::endl; std::cout << "Time: " << (float) timestamp / CLOCKS_PER_SEC << std::endl;*/ return 0; }
void DUAL_ELLIPTIC_SOLVER::solve1d(double *soln) { int index,index_nb[2],size; double k_nb[2]; double rhs,coeff[2]; int I,I_nb[2]; int i,j,ii,jj,l,icoords[MAXD]; COMPONENT comp; double aII; int num_nb; GRID_DIRECTION dir[2] = {WEST,EAST}; boolean use_neumann_solver = YES; PetscInt num_iter = 0; double rel_residual = 0.0; HYPER_SURF *hs; double crx_coords[MAXD]; int status; POINTER intfc_state; int icrds_max[MAXD],icrds_min[MAXD]; if (debugging("trace")) (void) printf("Entering DUAL_ELLIPTIC_SOLVER::solve1d()\n"); PETSc solver; solver.Create(ilower, iupper-1, 3, 3); solver.Reset_A(); solver.Reset_b(); solver.Reset_x(); size = iupper - ilower; max_soln = -HUGE; min_soln = HUGE; for (i = cimin; i <= cimax; i++) { index = d_index1d(i,ctop_gmax); comp = ctop_comp[index]; I = i_to_I[i]; if (I == -1) continue; I_nb[0] = i_to_I[i-1]; I_nb[1] = i_to_I[i+1]; icoords[0] = i; get_dual_D(icoords,k_nb); num_nb = 0; for (l = 0; l < 2; ++l) { status = (*findStateAtCrossing)(front,icoords,dir[l],comp, &intfc_state,&hs,crx_coords); if (status != CONST_V_PDE_BOUNDARY) num_nb++; coeff[l] = k_nb[l]/(top_h[l/2]*top_h[l/2]); } rhs = source[index]; aII = 0.0; for (l = 0; l < 2; ++l) { if (num_nb == 0) break; status = (*findStateAtCrossing)(front,icoords,dir[l],comp, &intfc_state,&hs,crx_coords); if (status == NO_PDE_BOUNDARY) { solver.Set_A(I,I_nb[l],coeff[l]); aII += -coeff[l]; } else if (status == CONST_P_PDE_BOUNDARY) { rhs += -coeff[l]*getStateVar(intfc_state); aII += -coeff[l]; use_neumann_solver = NO; } } /* * This change reflects the need to treat point with only one * interior neighbor (a convex point). Not sure why PETSc cannot * handle such case. If we have better understanding, this should * be changed back. */ if(num_nb > 0) { solver.Set_A(I,I,aII); } else { (void) printf("WARNING: isolated value!\n"); solver.Set_A(I,I,1.0); rhs = soln[index]; } solver.Set_b(I,rhs); } use_neumann_solver = pp_min_status(use_neumann_solver); solver.SetMaxIter(40000); solver.SetTol(1e-10); start_clock("Petsc Solver"); if (use_neumann_solver) { (void) printf("\nUsing Neumann Solver!\n"); if (size < 6) { (void) printf("Isolated small region for solve2d()\n"); stop_clock("Petsc Solver"); } solver.Solve_withPureNeumann(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); if(rel_residual > 1) { (void) printf("\n The solution diverges! The residual " "is %g. Solve again using GMRES!\n",rel_residual); solver.Reset_x(); solver.Solve_withPureNeumann_GMRES(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); } } else { (void) printf("\nUsing non-Neumann Solver!\n"); solver.Solve(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); if(rel_residual > 1) { (void) printf("\n The solution diverges! The residual " "is %g. Solve again using GMRES!\n",rel_residual); solver.Reset_x(); solver.Solve_GMRES(); solver.GetNumIterations(&num_iter); solver.GetFinalRelativeResidualNorm(&rel_residual); } } stop_clock("Petsc Solver"); double *x; FT_VectorMemoryAlloc((POINTER*)&x,size,sizeof(double)); solver.Get_x(x); if (debugging("PETSc")) (void) printf("In poisson_solver(): " "num_iter = %d, rel_residual = %g \n", num_iter, rel_residual); for (i = cimin; i <= cimax; i++) { index = d_index1d(i,ctop_gmax); I = i_to_I[i]; if (I == -1) continue; else soln[index] = x[I-ilower]; if (max_soln < soln[index]) { icrds_max[0] = i; max_soln = soln[index]; } if (min_soln > soln[index]) { icrds_min[0] = i; min_soln = soln[index]; } } FT_ParallelExchCompGridArrayBuffer(soln,front,NULL); pp_global_max(&max_soln,1); pp_global_min(&min_soln,1); if (debugging("step_size")) { (void) printf("Max solution = %20.14f occuring at: %d\n", max_soln,icrds_max[0]); checkSolver(icrds_max,YES); (void) printf("Min solution = %20.14f occuring at: %d\n", min_soln,icrds_min[0]); checkSolver(icrds_min,YES); } if (debugging("elliptic_error")) { double error,max_error = 0.0; for (i = cimin; i <= cimax; i++) { icoords[0] = i; if (i_to_I[i] == -1) continue; error = checkSolver(icoords,NO); if (error > max_error) { max_error = error; icrds_max[0] = i; } } (void) printf("In dual elliptic solver:\n"); (void) printf("Max relative elliptic error: %20.14f\n",max_error); (void) printf("Occuring at (%d)\n",icrds_max[0]); error = checkSolver(icrds_max,YES); } FT_FreeThese(1,x); if (debugging("trace")) (void) printf("Leaving DUAL_ELLIPTIC_SOLVER::solve1d()\n"); } /* end solve1d */