double volumeIntegration(Mat<> f) { double sumf = f.baseInterface().sum(); return sumf/1000*comdata.deltax*comdata.deltay*comdata.deltaz; }
// // volumeIntegration // double GeometricFlow::volumeIntegration(const Mat<>& f) { double sumf = f.baseInterface().sum(); return sumf/1000 * p_comdata.deltax() * p_comdata.deltay() * p_comdata.deltaz(); }
// // pbsolver // void GeometricFlow::pbsolver(const Mat<>& eps, Mat<>& phi, const Mat<>& bgf, double tol, int iter) { //cout << "eps: " ; eps.print(); std::cout << std::endl ; //cout << "bgf: " ; bgf.print(); std::cout << std::endl ; size_t nx = eps.nx(), ny = eps.ny(), nz = eps.nz(); double dx = p_comdata.deltax(), dy = p_comdata.deltay(), dz = p_comdata.deltaz(); Mat<> eps1(nx,ny,nz), eps2(nx,ny,nz), eps3(nx,ny,nz); for(size_t i = 1; i < nx; ++i) { for(size_t j = 1; j < ny; ++j) { for(size_t k = 1; k < nz; ++k) { eps1(i,j,k) = (eps(i+1,j,k) + eps(i,j,k))/2.0; eps2(i,j,k) = (eps(i,j+1,k) + eps(i,j,k))/2.0; eps3(i,j,k) = (eps(i,j,k+1) + eps(i,j,k))/2.0; } } } std::vector <Eigen::Triplet<double> > tripletList; tripletList.reserve(nx*ny*nz); Eigen::VectorXd phi_flat(nx*ny*nz); size_t n = nx*ny*nz; for (size_t i = 1; i <= nx; ++i) { for (size_t j = 1; j <= ny; ++j) { for(size_t k = 1; k <= nz; ++k) { size_t ijk = (i-1)*nz*ny + (j-1)*nz + k-1; if (i==1 || i==nx || j==1 || j==ny || k==1 || k==nz) { tripletList.push_back(Eigen::Triplet<double>(ijk, ijk, 1.0)); } else { double f = -( (eps1(i,j,k) + eps1(i-1,j,k))/dx/dx + (eps2(i,j,k) + eps2(i,j-1,k))/dy/dy + (eps3(i,j,k) + eps3(i,j,k-1))/dz/dz ); tripletList.push_back(Eigen::Triplet<double>(ijk, ijk, f)); double weit[6]; weit[0] = eps1(i-1,j,k)/dx/dx; weit[1] = eps2(i,j-1,k)/dy/dy; weit[2] = eps3(i,j,k-1)/dz/dz; weit[3] = eps3(i,j,k)/dz/dz; weit[4] = eps2(i,j,k)/dy/dy; weit[5] = eps1(i,j,k)/dx/dx; assert(ijk > nz*ny); size_t jj = ijk - nz*ny; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[0])); assert(ijk > nz); jj = ijk - nz; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[1])); assert(ijk > 1); jj = ijk - 1; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[2])); assert(ijk + 1 < n); jj = ijk + 1; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[3])); assert(ijk + nz < n); jj = ijk + nz; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[4])); assert(ijk + nz*ny < n); jj = ijk + nz*ny; tripletList.push_back(Eigen::Triplet<double>(ijk, jj, weit[5])); } phi_flat(ijk) = phi(i,j,k); } } } Eigen::SparseMatrix<double> A(n, n); A.setFromTriplets(tripletList.begin(), tripletList.end()); A.makeCompressed(); //std::cout << "A: " << A << std::endl; ?? // // bi conjugate gradient stabilized solver for sparse square problems. // http://en.wikipedia.org/wiki/Biconjugate_gradient_method // Eigen::BiCGSTAB<Eigen::SparseMatrix<double>, Eigen::IdentityPreconditioner> solver(A); solver.setMaxIterations(iter); solver.setTolerance(tol); // KTS Note -- I remember being here writing the unit tests, and thinking // that this may have had something to do with the difference in the elec // energies. I don't remember the details, but it's something to do with // the Eigen solver being different from what is in the Fortran code. // phi_flat = solver.solveWithGuess(bgf.baseInterface(), phi_flat); // ERJ Note -- Fortran solver: // http://sdphca.ucsd.edu/slatec_top/source/dsluom.f (DSLUOM is the // Incomplete LU Orthomin Sparse Iterative Ax=b Solver.) phi_flat = solver.solve(bgf.baseInterface()); //std::cout << "phi_flat: " << phi_flat << std::endl; for(size_t i = 1; i <= nx; ++i) { for(size_t j = 1; j <= ny; ++j) { for(size_t k = 1; k <= nz; ++k) { size_t ijk = (i-1)*nz*ny + (j-1)*nz + k-1; phi(i,j,k) = phi_flat(ijk); } } } }
void pbsolver(Mat<>& eps, Mat<>& phi, Mat<>& bgf, double dcel, double tol, int iter){ size_t nx = eps.nx(), ny = eps.ny(), nz = eps.nz(); double dx = comdata.deltax, dy = comdata.deltay, dz = comdata.deltaz; Mat<> eps1(nx,ny,nz), eps2(nx,ny,nz), eps3(nx,ny,nz); for(size_t i=1; i<nx; ++i){ for(size_t j=1; j<ny; ++j){ for(size_t k=1; k<nz; ++k){ eps1(i,j,k) = (eps(i+1,j,k) + eps(i,j,k))/2.0; eps2(i,j,k) = (eps(i,j+1,k) + eps(i,j,k))/2.0; eps3(i,j,k) = (eps(i,j,k+1) + eps(i,j,k))/2.0; }}} std::vector< Eigen::Triplet<double> > tripletList; tripletList.reserve(nx*ny*nz); Eigen::VectorXd phi_flat(nx*ny*nz); size_t n = nx*ny*nz; for(size_t i=1; i<=nx; ++i){ for(size_t j=1; j<=ny; ++j){ for(size_t k=1; k<=nz; ++k){ size_t ijk = (i-1)*nz*ny + (j-1)*nz + k-1; if(i==1 || i==nx || j==1 || j==ny || k==1 || k==nz){ tripletList.push_back( Eigen::Triplet<double>(ijk, ijk, 1.0) ); }else{ double f = -( (eps1(i,j,k) + eps1(i-1,j,k))/dx/dx + (eps2(i,j,k) + eps2(i,j-1,k))/dy/dy + (eps3(i,j,k) + eps3(i,j,k-1))/dz/dz ); tripletList.push_back( Eigen::Triplet<double>(ijk, ijk, f) ); double weit[6]; weit[0] = eps1(i-1,j,k)/dx/dx; weit[1] = eps2(i,j-1,k)/dy/dy; weit[2] = eps3(i,j,k-1)/dz/dz; weit[3] = eps3(i,j,k)/dz/dz; weit[4] = eps2(i,j,k)/dy/dy; weit[5] = eps1(i,j,k)/dx/dx; size_t jj = ijk - nz*ny; if(jj>=0){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[0]) ); } jj = ijk - nz; if(jj>=0){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[1]) ); } jj = ijk - 1; if(jj>=0){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[2]) ); } jj = ijk + 1; if(jj<n){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[3]) ); } jj = ijk + nz; if(jj<n){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[4]) ); } jj = ijk + nz*ny; if(jj<n){ tripletList.push_back( Eigen::Triplet<double>(ijk, jj, weit[5]) ); } } phi_flat(ijk) = phi(i,j,k); }}} Eigen::SparseMatrix<double> A(n, n); A.setFromTriplets(tripletList.begin(), tripletList.end()); A.makeCompressed(); Eigen::BiCGSTAB<Eigen::SparseMatrix<double>, Eigen::IdentityPreconditioner > solver(A); solver.setMaxIterations(iter); solver.setTolerance(tol); phi_flat = solver.solveWithGuess(bgf.baseInterface(), phi_flat); for(size_t i=1; i<=nx; ++i){ for(size_t j=1; j<=ny; ++j){ for(size_t k=1; k<=nz; ++k){ size_t ijk = (i-1)*nz*ny + (j-1)*nz + k-1; phi(i,j,k) = phi_flat(ijk); }}} }