void PetscVector<T>::pointwise_mult (const NumericVector<T>& vec1, const NumericVector<T>& vec2) { this->_restore_array(); PetscErrorCode ierr = 0; // Convert arguments to PetscVector*. const PetscVector<T>* vec1_petsc = libmesh_cast_ptr<const PetscVector<T>*>(&vec1); const PetscVector<T>* vec2_petsc = libmesh_cast_ptr<const PetscVector<T>*>(&vec2); // Call PETSc function. #if PETSC_VERSION_LESS_THAN(2,3,1) libMesh::out << "This method has been developed with PETSc 2.3.1. " << "No one has made it backwards compatible with older " << "versions of PETSc so far; however, it might work " << "without any change with some older version." << std::endl; libmesh_error(); #else if(this->type() != GHOSTED) { ierr = VecPointwiseMult(this->vec(), const_cast<PetscVector<T>*>(vec1_petsc)->vec(), const_cast<PetscVector<T>*>(vec2_petsc)->vec()); CHKERRABORT(libMesh::COMM_WORLD,ierr); } else { Vec loc_vec; Vec v1_loc_vec; Vec v2_loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostGetLocalForm (const_cast<PetscVector<T>*>(vec1_petsc)->vec(),&v1_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostGetLocalForm (const_cast<PetscVector<T>*>(vec2_petsc)->vec(),&v2_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecPointwiseMult(loc_vec,v1_loc_vec,v2_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (const_cast<PetscVector<T>*>(vec1_petsc)->vec(),&v1_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (const_cast<PetscVector<T>*>(vec2_petsc)->vec(),&v2_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } #endif }
void PetscVector<T>::add (const T a_in, const NumericVector<T>& v_in) { this->_restore_array(); PetscErrorCode ierr = 0; PetscScalar a = static_cast<PetscScalar>(a_in); // Make sure the NumericVector passed in is really a PetscVector const PetscVector<T>* v = libmesh_cast_ptr<const PetscVector<T>*>(&v_in); v->_restore_array(); libmesh_assert_equal_to (this->size(), v->size()); if(this->type() != GHOSTED) { #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecAXPY(&a, v->_vec, _vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecAXPY(_vec, a, v->_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif } else { Vec loc_vec; Vec v_loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostGetLocalForm (v->_vec,&v_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecAXPY(&a, v_loc_vec, loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecAXPY(loc_vec, a, v_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif ierr = VecGhostRestoreLocalForm (v->_vec,&v_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } }
void CalculateRezidual(Grid& g, Vec u, Vec r) { Vec uLoc, rLoc; const double *ul; double *rl; VecGhostGetLocalForm(u, &uLoc); VecGetArrayRead(uLoc, &ul); VecGhostGetLocalForm(r, &rLoc); VecSet(rLoc, 0.0); VecGetArray(rLoc, &rl); for (auto f: g.internalFaces()) { double flux = Flux( ul[f.owner], ul[f.neighbour], f.s); rl[f.owner] -= flux; rl[f.neighbour] += flux; } for (auto bnd: g.boundaryPatches()) { double ub = 0; if (bnd.first == BND_BOTTOM) ub = 1; for (auto f: bnd.second) { rl[f.owner] -= Flux( ul[f.owner], ub, f.s); } } VecRestoreArray(rLoc, &rl); VecGhostRestoreLocalForm(r, &rLoc); VecRestoreArrayRead(uLoc, &ul); VecGhostRestoreLocalForm(u, &uLoc); VecGhostUpdateBegin(r,ADD_VALUES,SCATTER_REVERSE); VecGhostUpdateEnd(r,ADD_VALUES,SCATTER_REVERSE); VecGetArray(r, &rl); for (size_t i=0; i<g.cells().size(); i++) rl[i] /= g.cells()[i].vol; VecRestoreArray(r, &rl); }
PetscScalar* PETScVector::getLocalVector() const { PetscScalar *loc_array; if (_has_ghost_id) { VecGhostUpdateBegin(_v, INSERT_VALUES, SCATTER_FORWARD); VecGhostUpdateEnd(_v, INSERT_VALUES, SCATTER_FORWARD); VecGhostGetLocalForm(_v, &_v_loc); VecGetArray(_v_loc, &loc_array); } else VecGetArray(_v, &loc_array); return loc_array; }
NumericVector<T>& PetscVector<T>::operator = (const T s_in) { this->_restore_array(); libmesh_assert(this->closed()); PetscErrorCode ierr = 0; PetscScalar s = static_cast<PetscScalar>(s_in); if (this->size() != 0) { if(this->type() != GHOSTED) { #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecSet(&s, _vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecSet(_vec, s); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif } else { Vec loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecSet(&s, loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecSet(loc_vec, s); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } } return *this; }
inline void PetscVector::zero (){ this->_restore_array(); int ierr=0; PetscScalar z=0.; if (this->type() != GHOSTED) { ierr = VecSet (_vec, z); CHKERRABORT(MPI_COMM_WORLD,ierr); } else { /* Vectors that include ghost values require a special handling. */ Vec loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(MPI_COMM_WORLD,ierr); ierr = VecSet (loc_vec, z); CHKERRABORT(MPI_COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(MPI_COMM_WORLD,ierr); } }
/** Apply rotation to global vector * * @note does nothing if rotation is NULL **/ dErr dFSRotationApply(dFSRotation rot,Vec g,dFSRotateMode rmode,dFSHomogeneousMode hmode) { dErr err; Vec gc,lf; dFunctionBegin; if (!rot) dFunctionReturn(0); dValidHeader(rot,dFSROT_CLASSID,1); dValidHeader(g,VEC_CLASSID,2); if (rot->ops->apply) { err = rot->ops->apply(rot,g,rmode,hmode);dCHK(err); } else { err = VecDohpGetClosure(g,&gc);dCHK(err); err = VecGhostGetLocalForm(gc,&lf);dCHK(err); err = dFSRotationApplyLocal(rot,lf,rmode,hmode);dCHK(err); /* \todo only rotate the global portion */ err = VecGhostRestoreLocalForm(gc,&lf);dCHK(err); err = VecDohpRestoreClosure(g,&gc);dCHK(err); } dFunctionReturn(0); }
inline void PetscVector::_get_array(void) const { assert (this->initialized()); if (!_array_is_present) { int ierr=0; if (this->type() != GHOSTED) { ierr = VecGetArray(_vec, &_values); CHKERRABORT(MPI_COMM_WORLD,ierr); } else { ierr = VecGhostGetLocalForm (_vec,&_local_form); CHKERRABORT(MPI_COMM_WORLD,ierr); ierr = VecGetArray(_local_form, &_values); CHKERRABORT(MPI_COMM_WORLD,ierr); #ifndef NDEBUG int local_size = 0; ierr = VecGetLocalSize(_local_form, &local_size); CHKERRABORT(MPI_COMM_WORLD,ierr); _local_size = static_cast<int>(local_size); #endif } _array_is_present = true; } }
void PetscVector<T>::scale (const T factor_in) { this->_restore_array(); PetscErrorCode ierr = 0; PetscScalar factor = static_cast<PetscScalar>(factor_in); if(this->type() != GHOSTED) { #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecScale(&factor, _vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecScale(_vec, factor); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif } else { Vec loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #if PETSC_VERSION_LESS_THAN(2,3,0) // 2.2.x & earlier style ierr = VecScale(&factor, loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); #else // 2.3.x & later style ierr = VecScale(loc_vec, factor); CHKERRABORT(libMesh::COMM_WORLD,ierr); #endif ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } }
void PetscVector<T>::abs() { this->_restore_array(); PetscErrorCode ierr = 0; if(this->type() != GHOSTED) { ierr = VecAbs(_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } else { Vec loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecAbs(loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } }
int main(int argc,char **argv) { PetscMPIInt rank,size; PetscInt nlocal = 6,nghost = 2,ifrom[2],i,rstart,rend; PetscErrorCode ierr; PetscBool flg,flg2; PetscScalar value,*array,*tarray=0; Vec lx,gx,gxs; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 2) SETERRQ(PETSC_COMM_SELF,1,"Must run example with two processors\n"); /* Construct a two dimensional graph connecting nlocal degrees of freedom per processor. From this we will generate the global indices of needed ghost values For simplicity we generate the entire graph on each processor: in real application the graph would stored in parallel, but this example is only to demonstrate the management of ghost padding with VecCreateGhost(). In this example we consider the vector as representing degrees of freedom in a one dimensional grid with periodic boundary conditions. ----Processor 1--------- ----Processor 2 -------- 0 1 2 3 4 5 6 7 8 9 10 11 |----| |-------------------------------------------------| */ if (!rank) { ifrom[0] = 11; ifrom[1] = 6; } else { ifrom[0] = 0; ifrom[1] = 5; } /* Create the vector with two slots for ghost points. Note that both the local vector (lx) and the global vector (gx) share the same array for storing vector values. */ ierr = PetscOptionsHasName(PETSC_NULL,"-allocate",&flg);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-vecmpisetghost",&flg2);CHKERRQ(ierr); if (flg) { ierr = PetscMalloc((nlocal+nghost)*sizeof(PetscScalar),&tarray);CHKERRQ(ierr); ierr = VecCreateGhostWithArray(PETSC_COMM_WORLD,nlocal,PETSC_DECIDE,nghost,ifrom,tarray,&gxs);CHKERRQ(ierr); } else if (flg2) { ierr = VecCreate(PETSC_COMM_WORLD,&gxs);CHKERRQ(ierr); ierr = VecSetType(gxs,VECMPI);CHKERRQ(ierr); ierr = VecSetSizes(gxs,nlocal,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecMPISetGhost(gxs,nghost,ifrom);CHKERRQ(ierr); } else { ierr = VecCreateGhost(PETSC_COMM_WORLD,nlocal,PETSC_DECIDE,nghost,ifrom,&gxs);CHKERRQ(ierr); } /* Test VecDuplicate() */ ierr = VecDuplicate(gxs,&gx);CHKERRQ(ierr); ierr = VecDestroy(&gxs);CHKERRQ(ierr); /* Access the local representation */ ierr = VecGhostGetLocalForm(gx,&lx);CHKERRQ(ierr); /* Set the values from 0 to 12 into the "global" vector */ ierr = VecGetOwnershipRange(gx,&rstart,&rend);CHKERRQ(ierr); for (i=rstart; i<rend; i++) { value = (PetscScalar) i; ierr = VecSetValues(gx,1,&i,&value,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(gx);CHKERRQ(ierr); ierr = VecAssemblyEnd(gx);CHKERRQ(ierr); ierr = VecGhostUpdateBegin(gx,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecGhostUpdateEnd(gx,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); /* Print out each vector, including the ghost padding region. */ ierr = VecGetArray(lx,&array);CHKERRQ(ierr); for (i=0; i<nlocal+nghost; i++) { ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,"%D %G\n",i,PetscRealPart(array[i]));CHKERRQ(ierr); } ierr = VecRestoreArray(lx,&array);CHKERRQ(ierr); ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(gx,&lx);CHKERRQ(ierr); ierr = VecDestroy(&gx);CHKERRQ(ierr); if (flg) {ierr = PetscFree(tarray);CHKERRQ(ierr);} ierr = PetscFinalize(); return 0; }
int main(int argc,char *argv[]) { char mat_type[256] = "aij"; /* default matrix type */ PetscErrorCode ierr; MPI_Comm comm; PetscMPIInt rank,size; DM slice; PetscInt i,bs=1,N=5,n,m,rstart,ghosts[2],*d_nnz,*o_nnz,dfill[4]={1,0,0,1},ofill[4]={1,1,1,1}; PetscReal alpha =1,K=1,rho0=1,u0=0,sigma=0.2; PetscBool useblock=PETSC_TRUE; PetscScalar *xx; Mat A; Vec x,b,lf; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); comm = PETSC_COMM_WORLD; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = PetscOptionsBegin(comm,0,"Options for DMSliced test",0);CHKERRQ(ierr); { ierr = PetscOptionsInt("-n","Global number of nodes","",N,&N,NULL);CHKERRQ(ierr); ierr = PetscOptionsInt("-bs","Block size (1 or 2)","",bs,&bs,NULL);CHKERRQ(ierr); if (bs != 1) { if (bs != 2) SETERRQ(PETSC_COMM_WORLD,1,"Block size must be 1 or 2"); ierr = PetscOptionsReal("-alpha","Inverse time step for wave operator","",alpha,&alpha,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-K","Bulk modulus of compressibility","",K,&K,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-rho0","Reference density","",rho0,&rho0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-u0","Reference velocity","",u0,&u0,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-sigma","Width of Gaussian density perturbation","",sigma,&sigma,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-block","Use block matrix assembly","",useblock,&useblock,NULL);CHKERRQ(ierr); } ierr = PetscOptionsString("-sliced_mat_type","Matrix type to use (aij or baij)","",mat_type,mat_type,sizeof(mat_type),NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Split ownership, set up periodic grid in 1D */ n = PETSC_DECIDE; ierr = PetscSplitOwnership(comm,&n,&N);CHKERRQ(ierr); rstart = 0; ierr = MPI_Scan(&n,&rstart,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr); rstart -= n; ghosts[0] = (N+rstart-1)%N; ghosts[1] = (rstart+n)%N; ierr = PetscMalloc2(n,PetscInt,&d_nnz,n,PetscInt,&o_nnz);CHKERRQ(ierr); for (i=0; i<n; i++) { if (size > 1 && (i==0 || i==n-1)) { d_nnz[i] = 2; o_nnz[i] = 1; } else { d_nnz[i] = 3; o_nnz[i] = 0; } } ierr = DMSlicedCreate(comm,bs,n,2,ghosts,d_nnz,o_nnz,&slice);CHKERRQ(ierr); /* Currently does not copy X_nnz so we can't free them until after DMSlicedGetMatrix */ if (!useblock) {ierr = DMSlicedSetBlockFills(slice,dfill,ofill);CHKERRQ(ierr);} /* Irrelevant for baij formats */ ierr = DMSetMatType(slice,mat_type);CHKERRQ(ierr); ierr = DMCreateMatrix(slice,&A);CHKERRQ(ierr); ierr = PetscFree2(d_nnz,o_nnz);CHKERRQ(ierr); ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slice,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecGhostGetLocalForm(x,&lf);CHKERRQ(ierr); ierr = VecGetSize(lf,&m);CHKERRQ(ierr); if (m != (n+2)*bs) SETERRQ2(PETSC_COMM_SELF,1,"size of local form %D, expected %D",m,(n+2)*bs); ierr = VecGetArray(lf,&xx);CHKERRQ(ierr); for (i=0; i<n; i++) { PetscInt row[2],col[9],im,ip; PetscScalar v[12]; const PetscReal xref = 2.0*(rstart+i)/N - 1; /* [-1,1] */ const PetscReal h = 1.0/N; /* grid spacing */ im = (i==0) ? n : i-1; ip = (i==n-1) ? n+1 : i+1; switch (bs) { case 1: /* Laplacian with periodic boundaries */ col[0] = im; col[1] = i; col[2] = ip; v[0] = -h; v[1] = 2*h; v[2] = -h; ierr = MatSetValuesLocal(A,1,&i,3,col,v,INSERT_VALUES);CHKERRQ(ierr); xx[i] = sin(xref*PETSC_PI); break; case 2: /* Linear acoustic wave operator in variables [rho, u], central differences, periodic, timestep 1/alpha */ v[0] = -0.5*u0; v[1] = -0.5*K; v[2] = alpha; v[3] = 0; v[4] = 0.5*u0; v[5] = 0.5*K; v[6] = -0.5/rho0; v[7] = -0.5*u0; v[8] = 0; v[9] = alpha; v[10] = 0.5/rho0; v[11] = 0.5*u0; if (useblock) { row[0] = i; col[0] = im; col[1] = i; col[2] = ip; ierr = MatSetValuesBlockedLocal(A,1,row,3,col,v,INSERT_VALUES);CHKERRQ(ierr); } else { row[0] = 2*i; row[1] = 2*i+1; col[0] = 2*im; col[1] = 2*im+1; col[2] = 2*i; col[3] = 2*ip; col[4] = 2*ip+1; v[3] = v[4]; v[4] = v[5]; /* pack values in first row */ ierr = MatSetValuesLocal(A,1,row,5,col,v,INSERT_VALUES);CHKERRQ(ierr); col[2] = 2*i+1; v[8] = v[9]; v[9] = v[10]; v[10] = v[11]; /* pack values in second row */ ierr = MatSetValuesLocal(A,1,row+1,5,col,v+6,INSERT_VALUES);CHKERRQ(ierr); } /* Set current state (gaussian density perturbation) */ xx[2*i] = 0.2*exp(-PetscSqr(xref)/(2*PetscSqr(sigma))); xx[2*i+1] = 0; break; default: SETERRQ1(PETSC_COMM_SELF,1,"not implemented for block size %D",bs); } } ierr = VecRestoreArray(lf,&xx);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(x,&lf);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); /* Update the ghosted values, view the result on rank 0. */ ierr = VecGhostUpdateBegin(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecGhostUpdateEnd(b,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (!rank) { ierr = VecGhostGetLocalForm(b,&lf);CHKERRQ(ierr); ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_SELF,"Local form of b on rank 0, last two nodes are ghost nodes\n");CHKERRQ(ierr); ierr = VecView(lf,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecGhostRestoreLocalForm(b,&lf);CHKERRQ(ierr); } ierr = DMDestroy(&slice);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscVector<T>& PetscVector<T>::operator = (const PetscVector<T>& v) { this->_restore_array(); v._restore_array(); libmesh_assert_equal_to (this->size(), v.size()); libmesh_assert_equal_to (this->local_size(), v.local_size()); libmesh_assert (v.closed()); PetscErrorCode ierr = 0; if (((this->type()==PARALLEL) && (v.type()==GHOSTED)) || ((this->type()==GHOSTED) && (v.type()==PARALLEL)) || ((this->type()==GHOSTED) && (v.type()==SERIAL)) || ((this->type()==SERIAL) && (v.type()==GHOSTED))) { /* Allow assignment of a ghosted to a parallel vector since this causes no difficulty. See discussion in libmesh-devel of June 24, 2010. */ ierr = VecCopy (v._vec, this->_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } else { /* In all other cases, we assert that both vectors are of equal type. */ libmesh_assert_equal_to (this->_type, v._type); libmesh_assert (this->_global_to_local_map == v._global_to_local_map); if (v.size() != 0) { if(this->type() != GHOSTED) { ierr = VecCopy (v._vec, this->_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } else { Vec loc_vec; Vec v_loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostGetLocalForm (v._vec,&v_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecCopy (v_loc_vec, loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (v._vec,&v_loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } } } close(); return *this; }
void PetscVector<T>::add (const T v_in) { this->_restore_array(); PetscErrorCode ierr=0; PetscScalar* values; const PetscScalar v = static_cast<PetscScalar>(v_in); if(this->type() != GHOSTED) { const PetscInt n = static_cast<PetscInt>(this->local_size()); const PetscInt fli = static_cast<PetscInt>(this->first_local_index()); for (PetscInt i=0; i<n; i++) { ierr = VecGetArray (_vec, &values); CHKERRABORT(libMesh::COMM_WORLD,ierr); PetscInt ig = fli + i; PetscScalar value = (values[i] + v); ierr = VecRestoreArray (_vec, &values); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecSetValues (_vec, 1, &ig, &value, INSERT_VALUES); CHKERRABORT(libMesh::COMM_WORLD,ierr); } } else { /* Vectors that include ghost values require a special handling. */ Vec loc_vec; ierr = VecGhostGetLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); PetscInt n=0; ierr = VecGetSize(loc_vec, &n); CHKERRABORT(libMesh::COMM_WORLD,ierr); for (PetscInt i=0; i<n; i++) { ierr = VecGetArray (loc_vec, &values); CHKERRABORT(libMesh::COMM_WORLD,ierr); PetscScalar value = (values[i] + v); ierr = VecRestoreArray (loc_vec, &values); CHKERRABORT(libMesh::COMM_WORLD,ierr); ierr = VecSetValues (loc_vec, 1, &i, &value, INSERT_VALUES); CHKERRABORT(libMesh::COMM_WORLD,ierr); } ierr = VecGhostRestoreLocalForm (_vec,&loc_vec); CHKERRABORT(libMesh::COMM_WORLD,ierr); } this->_is_closed = false; }