Example #1
0
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);
			}
		}
	}
}
Example #4
0
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);
    }}}
}