本文整理汇总了C++中PetscFunctionReturn函数的典型用法代码示例。如果您正苦于以下问题:C++ PetscFunctionReturn函数的具体用法?C++ PetscFunctionReturn怎么用?C++ PetscFunctionReturn使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了PetscFunctionReturn函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: MatRARtSymbolic_SeqAIJ_SeqAIJ
PetscErrorCode MatRARtSymbolic_SeqAIJ_SeqAIJ(Mat A,Mat R,PetscReal fill,Mat *C)
{
PetscErrorCode ierr;
Mat P;
PetscInt *rti,*rtj;
Mat_RARt *rart;
PetscContainer container;
MatTransposeColoring matcoloring;
ISColoring iscoloring;
Mat Rt_dense,RARt_dense;
PetscLogDouble GColor=0.0,MCCreate=0.0,MDenCreate=0.0,t0,tf,etime=0.0;
Mat_SeqAIJ *c;
PetscFunctionBegin;
ierr = PetscGetTime(&t0);CHKERRQ(ierr);
/* create symbolic P=Rt */
ierr = MatGetSymbolicTranspose_SeqAIJ(R,&rti,&rtj);CHKERRQ(ierr);
ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,R->cmap->n,R->rmap->n,rti,rtj,PETSC_NULL,&P);CHKERRQ(ierr);
/* get symbolic C=Pt*A*P */
ierr = MatPtAPSymbolic_SeqAIJ_SeqAIJ(A,P,fill,C);CHKERRQ(ierr);
(*C)->rmap->bs = R->rmap->bs;
(*C)->cmap->bs = R->rmap->bs;
/* create a supporting struct */
ierr = PetscNew(Mat_RARt,&rart);CHKERRQ(ierr);
/* attach the supporting struct to C */
ierr = PetscContainerCreate(PETSC_COMM_SELF,&container);CHKERRQ(ierr);
ierr = PetscContainerSetPointer(container,rart);CHKERRQ(ierr);
ierr = PetscContainerSetUserDestroy(container,PetscContainerDestroy_Mat_RARt);CHKERRQ(ierr);
ierr = PetscObjectCompose((PetscObject)(*C),"Mat_RARt",(PetscObject)container);CHKERRQ(ierr);
ierr = PetscContainerDestroy(&container);CHKERRQ(ierr);
ierr = PetscGetTime(&tf);CHKERRQ(ierr);
etime += tf - t0;
/* Create MatTransposeColoring from symbolic C=R*A*R^T */
c=(Mat_SeqAIJ*)(*C)->data;
ierr = PetscGetTime(&t0);CHKERRQ(ierr);
ierr = MatGetColoring(*C,MATCOLORINGLF,&iscoloring);CHKERRQ(ierr);
ierr = PetscGetTime(&tf);CHKERRQ(ierr);
GColor += tf - t0;
ierr = PetscGetTime(&t0);CHKERRQ(ierr);
ierr = MatTransposeColoringCreate(*C,iscoloring,&matcoloring);CHKERRQ(ierr);
rart->matcoloring = matcoloring;
ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
ierr = PetscGetTime(&tf);CHKERRQ(ierr);
MCCreate += tf - t0;
ierr = PetscGetTime(&t0);CHKERRQ(ierr);
/* Create Rt_dense */
ierr = MatCreate(PETSC_COMM_SELF,&Rt_dense);CHKERRQ(ierr);
ierr = MatSetSizes(Rt_dense,A->cmap->n,matcoloring->ncolors,A->cmap->n,matcoloring->ncolors);CHKERRQ(ierr);
ierr = MatSetType(Rt_dense,MATSEQDENSE);CHKERRQ(ierr);
ierr = MatSeqDenseSetPreallocation(Rt_dense,PETSC_NULL);CHKERRQ(ierr);
Rt_dense->assembled = PETSC_TRUE;
rart->Rt = Rt_dense;
/* Create RARt_dense = R*A*Rt_dense */
ierr = MatCreate(PETSC_COMM_SELF,&RARt_dense);CHKERRQ(ierr);
ierr = MatSetSizes(RARt_dense,(*C)->rmap->n,matcoloring->ncolors,(*C)->rmap->n,matcoloring->ncolors);CHKERRQ(ierr);
ierr = MatSetType(RARt_dense,MATSEQDENSE);CHKERRQ(ierr);
ierr = MatSeqDenseSetPreallocation(RARt_dense,PETSC_NULL);CHKERRQ(ierr);
rart->RARt = RARt_dense;
/* Allocate work array to store columns of A*R^T used in MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqDense() */
ierr = PetscMalloc(A->rmap->n*4*sizeof(PetscScalar),&rart->work);CHKERRQ(ierr);
ierr = PetscGetTime(&tf);CHKERRQ(ierr);
MDenCreate += tf - t0;
rart->destroy = (*C)->ops->destroy;
(*C)->ops->destroy = MatDestroy_SeqAIJ_RARt;
/* clean up */
ierr = MatRestoreSymbolicTranspose_SeqAIJ(R,&rti,&rtj);CHKERRQ(ierr);
ierr = MatDestroy(&P);CHKERRQ(ierr);
#if defined(PETSC_USE_INFO)
{
PetscReal density= (PetscReal)(c->nz)/(RARt_dense->rmap->n*RARt_dense->cmap->n);
ierr = PetscInfo6(*C,"RARt_den %D %D; Rt_den %D %D, (RARt->nz %D)/(m*ncolors)=%g\n",RARt_dense->rmap->n,RARt_dense->cmap->n,Rt_dense->rmap->n,Rt_dense->cmap->n,c->nz,density);CHKERRQ(ierr);
ierr = PetscInfo5(*C,"Sym = GetColor %g + MColorCreate %g + MDenCreate %g + other %g = %g\n",GColor,MCCreate,MDenCreate,etime,GColor+MCCreate+MDenCreate+etime);CHKERRQ(ierr);
}
#endif
PetscFunctionReturn(0);
}
示例2: PetscViewerFileSetName_ASCII
PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
{
PetscErrorCode ierr;
size_t len;
char fname[PETSC_MAX_PATH_LEN],*gz;
PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
PetscBool isstderr,isstdout;
PetscMPIInt rank;
PetscFunctionBegin;
ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
if (!name) PetscFunctionReturn(0);
ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
/* Is this file to be compressed */
vascii->storecompressed = PETSC_FALSE;
ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
if (gz) {
ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
if (len == 3) {
*gz = 0;
vascii->storecompressed = PETSC_TRUE;
}
}
ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
if (!rank) {
ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
/* empty filename means stdout */
if (name[0] == 0) isstdout = PETSC_TRUE;
if (isstderr) vascii->fd = PETSC_STDERR;
else if (isstdout) vascii->fd = PETSC_STDOUT;
else {
ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
switch (vascii->mode) {
case FILE_MODE_READ:
vascii->fd = fopen(fname,"r");
break;
case FILE_MODE_WRITE:
vascii->fd = fopen(fname,"w");
break;
case FILE_MODE_APPEND:
vascii->fd = fopen(fname,"a");
break;
case FILE_MODE_UPDATE:
vascii->fd = fopen(fname,"r+");
if (!vascii->fd) vascii->fd = fopen(fname,"w+");
break;
case FILE_MODE_APPEND_UPDATE:
/* I really want a file which is opened at the end for updating,
not a+, which opens at the beginning, but makes writes at the end.
*/
vascii->fd = fopen(fname,"r+");
if (!vascii->fd) vascii->fd = fopen(fname,"w+");
else {
ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
}
break;
default:
SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
}
if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
}
}
#if defined(PETSC_USE_LOG)
PetscLogObjectState((PetscObject)viewer,"File: %s",name);
#endif
PetscFunctionReturn(0);
}
示例3: PetscFESetUp_Composite
PetscErrorCode PetscFESetUp_Composite(PetscFE fem)
{
PetscFE_Composite *cmp = (PetscFE_Composite *) fem->data;
DM K;
PetscReal *subpoint;
PetscBLASInt *pivots;
PetscBLASInt n, info;
PetscScalar *work, *invVscalar;
PetscInt dim, pdim, spdim, j, s;
PetscErrorCode ierr;
PetscFunctionBegin;
/* Get affine mapping from reference cell to each subcell */
ierr = PetscDualSpaceGetDM(fem->dualSpace, &K);CHKERRQ(ierr);
ierr = DMGetDimension(K, &dim);CHKERRQ(ierr);
ierr = DMPlexGetCellRefiner_Internal(K, &cmp->cellRefiner);CHKERRQ(ierr);
ierr = CellRefinerGetAffineTransforms_Internal(cmp->cellRefiner, &cmp->numSubelements, &cmp->v0, &cmp->jac, &cmp->invjac);CHKERRQ(ierr);
/* Determine dof embedding into subelements */
ierr = PetscDualSpaceGetDimension(fem->dualSpace, &pdim);CHKERRQ(ierr);
ierr = PetscSpaceGetDimension(fem->basisSpace, &spdim);CHKERRQ(ierr);
ierr = PetscMalloc1(cmp->numSubelements*spdim,&cmp->embedding);CHKERRQ(ierr);
ierr = DMGetWorkArray(K, dim, MPIU_REAL, &subpoint);CHKERRQ(ierr);
for (s = 0; s < cmp->numSubelements; ++s) {
PetscInt sd = 0;
for (j = 0; j < pdim; ++j) {
PetscBool inside;
PetscQuadrature f;
PetscInt d, e;
ierr = PetscDualSpaceGetFunctional(fem->dualSpace, j, &f);CHKERRQ(ierr);
/* Apply transform to first point, and check that point is inside subcell */
for (d = 0; d < dim; ++d) {
subpoint[d] = -1.0;
for (e = 0; e < dim; ++e) subpoint[d] += cmp->invjac[(s*dim + d)*dim+e]*(f->points[e] - cmp->v0[s*dim+e]);
}
ierr = CellRefinerInCellTest_Internal(cmp->cellRefiner, subpoint, &inside);CHKERRQ(ierr);
if (inside) {cmp->embedding[s*spdim+sd++] = j;}
}
if (sd != spdim) SETERRQ3(PetscObjectComm((PetscObject) fem), PETSC_ERR_PLIB, "Subelement %d has %d dual basis vectors != %d", s, sd, spdim);
}
ierr = DMRestoreWorkArray(K, dim, MPIU_REAL, &subpoint);CHKERRQ(ierr);
/* Construct the change of basis from prime basis to nodal basis for each subelement */
ierr = PetscMalloc1(cmp->numSubelements*spdim*spdim,&fem->invV);CHKERRQ(ierr);
ierr = PetscMalloc2(spdim,&pivots,spdim,&work);CHKERRQ(ierr);
#if defined(PETSC_USE_COMPLEX)
ierr = PetscMalloc1(cmp->numSubelements*spdim*spdim,&invVscalar);CHKERRQ(ierr);
#else
invVscalar = fem->invV;
#endif
for (s = 0; s < cmp->numSubelements; ++s) {
for (j = 0; j < spdim; ++j) {
PetscReal *Bf;
PetscQuadrature f;
const PetscReal *points, *weights;
PetscInt Nc, Nq, q, k;
ierr = PetscDualSpaceGetFunctional(fem->dualSpace, cmp->embedding[s*spdim+j], &f);CHKERRQ(ierr);
ierr = PetscQuadratureGetData(f, NULL, &Nc, &Nq, &points, &weights);CHKERRQ(ierr);
ierr = PetscMalloc1(f->numPoints*spdim*Nc,&Bf);CHKERRQ(ierr);
ierr = PetscSpaceEvaluate(fem->basisSpace, Nq, points, Bf, NULL, NULL);CHKERRQ(ierr);
for (k = 0; k < spdim; ++k) {
/* n_j \cdot \phi_k */
invVscalar[(s*spdim + j)*spdim+k] = 0.0;
for (q = 0; q < Nq; ++q) {
invVscalar[(s*spdim + j)*spdim+k] += Bf[q*spdim+k]*weights[q];
}
}
ierr = PetscFree(Bf);CHKERRQ(ierr);
}
n = spdim;
PetscStackCallBLAS("LAPACKgetrf", LAPACKgetrf_(&n, &n, &invVscalar[s*spdim*spdim], &n, pivots, &info));
PetscStackCallBLAS("LAPACKgetri", LAPACKgetri_(&n, &invVscalar[s*spdim*spdim], &n, pivots, work, &n, &info));
}
#if defined(PETSC_USE_COMPLEX)
for (s = 0; s <cmp->numSubelements*spdim*spdim; s++) fem->invV[s] = PetscRealPart(invVscalar[s]);
ierr = PetscFree(invVscalar);CHKERRQ(ierr);
#endif
ierr = PetscFree2(pivots,work);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例4: MatGetSubMatrices_MPIDense_Local
//.........这里部分代码省略.........
row = row - rstart;
mat_vi = mat_v + row;
imat_vi = imat_v + j;
for (k=0; k<ncol[i]; k++) {
col = icol[i][k];
imat_vi[k*m] = mat_vi[col*C->rmap->n];
}
}
}
}
}
/* Create row map-> This maps c->row to submat->row for each submat*/
/* this is a very expensive operation wrt memory usage */
ierr = PetscMalloc(ismax*sizeof(PetscInt*),&rmap);CHKERRQ(ierr);
ierr = PetscMalloc(ismax*C->rmap->N*sizeof(PetscInt),&rmap[0]);CHKERRQ(ierr);
ierr = PetscMemzero(rmap[0],ismax*C->rmap->N*sizeof(PetscInt));CHKERRQ(ierr);
for (i=1; i<ismax; i++) rmap[i] = rmap[i-1] + C->rmap->N;
for (i=0; i<ismax; i++) {
rmap_i = rmap[i];
irow_i = irow[i];
jmax = nrow[i];
for (j=0; j<jmax; j++) {
rmap_i[irow_i[j]] = j;
}
}
/* Now Receive the row_values and assemble the rest of the matrix */
ierr = PetscMalloc((nrqs+1)*sizeof(MPI_Status),&r_status2);CHKERRQ(ierr);
{
PetscInt is_max,tmp1,col,*sbuf1_i,is_sz;
PetscScalar *rbuf2_i,*imat_v,*imat_vi;
for (tmp1=0; tmp1<nrqs; tmp1++) { /* For each message */
ierr = MPI_Waitany(nrqs,r_waits2,&i,r_status2+tmp1);CHKERRQ(ierr);
/* Now dig out the corresponding sbuf1, which contains the IS data_structure */
sbuf1_i = sbuf1[pa[i]];
is_max = sbuf1_i[0];
ct1 = 2*is_max+1;
rbuf2_i = rbuf2[i];
for (j=1; j<=is_max; j++) { /* For each IS belonging to the message */
is_no = sbuf1_i[2*j-1];
is_sz = sbuf1_i[2*j];
mat = (Mat_SeqDense*)submats[is_no]->data;
imat_v = mat->v;
rmap_i = rmap[is_no];
m = nrow[is_no];
for (k=0; k<is_sz; k++,rbuf2_i+=N) { /* For each row */
row = sbuf1_i[ct1]; ct1++;
row = rmap_i[row];
imat_vi = imat_v + row;
for (l=0; l<ncol[is_no]; l++) { /* For each col */
col = icol[is_no][l];
imat_vi[l*m] = rbuf2_i[col];
}
}
}
}
}
/* End Send-Recv of row_values */
ierr = PetscFree(r_status2);CHKERRQ(ierr);
ierr = PetscFree(r_waits2);CHKERRQ(ierr);
ierr = PetscMalloc((nrqr+1)*sizeof(MPI_Status),&s_status2);CHKERRQ(ierr);
if (nrqr) {ierr = MPI_Waitall(nrqr,s_waits2,s_status2);CHKERRQ(ierr);}
ierr = PetscFree(s_status2);CHKERRQ(ierr);
ierr = PetscFree(s_waits2);CHKERRQ(ierr);
/* Restore the indices */
for (i=0; i<ismax; i++) {
ierr = ISRestoreIndices(isrow[i],irow+i);CHKERRQ(ierr);
ierr = ISRestoreIndices(iscol[i],icol+i);CHKERRQ(ierr);
}
/* Destroy allocated memory */
ierr = PetscFree5(irow,icol,nrow,ncol,rtable);CHKERRQ(ierr);
ierr = PetscFree3(w1,w3,w4);CHKERRQ(ierr);
ierr = PetscFree(pa);CHKERRQ(ierr);
for (i=0; i<nrqs; ++i) {
ierr = PetscFree(rbuf2[i]);CHKERRQ(ierr);
}
ierr = PetscFree(rbuf2);CHKERRQ(ierr);
ierr = PetscFree4(sbuf1,ptr,tmp,ctr);CHKERRQ(ierr);
ierr = PetscFree(rbuf1[0]);CHKERRQ(ierr);
ierr = PetscFree(rbuf1);CHKERRQ(ierr);
for (i=0; i<nrqr; ++i) {
ierr = PetscFree(sbuf2[i]);CHKERRQ(ierr);
}
ierr = PetscFree(sbuf2);CHKERRQ(ierr);
ierr = PetscFree(rmap[0]);CHKERRQ(ierr);
ierr = PetscFree(rmap);CHKERRQ(ierr);
for (i=0; i<ismax; i++) {
ierr = MatAssemblyBegin(submats[i],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(submats[i],MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
}
PetscFunctionReturn(0);
}
示例5: KSPSolve_STCG
PetscErrorCode KSPSolve_STCG(KSP ksp)
{
#ifdef PETSC_USE_COMPLEX
SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_SUP, "STCG is not available for complex systems");
#else
KSP_STCG *cg = (KSP_STCG *)ksp->data;
PetscErrorCode ierr;
MatStructure pflag;
Mat Qmat, Mmat;
Vec r, z, p, d;
PC pc;
PetscReal norm_r, norm_d, norm_dp1, norm_p, dMp;
PetscReal alpha, beta, kappa, rz, rzm1;
PetscReal rr, r2, step;
PetscInt max_cg_its;
PetscBool diagonalscale;
PetscFunctionBegin;
/***************************************************************************/
/* Check the arguments and parameters. */
/***************************************************************************/
ierr = PCGetDiagonalScale(ksp->pc, &diagonalscale);CHKERRQ(ierr);
if (diagonalscale) SETERRQ1(((PetscObject)ksp)->comm,PETSC_ERR_SUP, "Krylov method %s does not support diagonal scaling", ((PetscObject)ksp)->type_name);
if (cg->radius < 0.0) SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_ARG_OUTOFRANGE, "Input error: radius < 0");
/***************************************************************************/
/* Get the workspace vectors and initialize variables */
/***************************************************************************/
r2 = cg->radius * cg->radius;
r = ksp->work[0];
z = ksp->work[1];
p = ksp->work[2];
d = ksp->vec_sol;
pc = ksp->pc;
ierr = PCGetOperators(pc, &Qmat, &Mmat, &pflag);CHKERRQ(ierr);
ierr = VecGetSize(d, &max_cg_its);CHKERRQ(ierr);
max_cg_its = PetscMin(max_cg_its, ksp->max_it);
ksp->its = 0;
/***************************************************************************/
/* Initialize objective function and direction. */
/***************************************************************************/
cg->o_fcn = 0.0;
ierr = VecSet(d, 0.0);CHKERRQ(ierr); /* d = 0 */
cg->norm_d = 0.0;
/***************************************************************************/
/* Begin the conjugate gradient method. Check the right-hand side for */
/* numerical problems. The check for not-a-number and infinite values */
/* need be performed only once. */
/***************************************************************************/
ierr = VecCopy(ksp->vec_rhs, r);CHKERRQ(ierr); /* r = -grad */
ierr = VecDot(r, r, &rr);CHKERRQ(ierr); /* rr = r^T r */
if (PetscIsInfOrNanScalar(rr)) {
/*************************************************************************/
/* The right-hand side contains not-a-number or an infinite value. */
/* The gradient step does not work; return a zero value for the step. */
/*************************************************************************/
ksp->reason = KSP_DIVERGED_NAN;
ierr = PetscInfo1(ksp, "KSPSolve_STCG: bad right-hand side: rr=%g\n", rr);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
/***************************************************************************/
/* Check the preconditioner for numerical problems and for positive */
/* definiteness. The check for not-a-number and infinite values need be */
/* performed only once. */
/***************************************************************************/
ierr = KSP_PCApply(ksp, r, z);CHKERRQ(ierr); /* z = inv(M) r */
ierr = VecDot(r, z, &rz);CHKERRQ(ierr); /* rz = r^T inv(M) r */
if (PetscIsInfOrNanScalar(rz)) {
/*************************************************************************/
/* The preconditioner contains not-a-number or an infinite value. */
/* Return the gradient direction intersected with the trust region. */
/*************************************************************************/
ksp->reason = KSP_DIVERGED_NAN;
ierr = PetscInfo1(ksp, "KSPSolve_STCG: bad preconditioner: rz=%g\n", rz);CHKERRQ(ierr);
if (cg->radius != 0) {
if (r2 >= rr) {
alpha = 1.0;
cg->norm_d = PetscSqrtReal(rr);
}
else {
alpha = PetscSqrtReal(r2 / rr);
cg->norm_d = cg->radius;
//.........这里部分代码省略.........
示例6: MatSetUpMultiply_MPISBAIJ_2comm
//.........这里部分代码省略.........
/* use a table - Mark Adams */
PetscTableCreate(B->mbs,baij->Nbs+1,&gid1_lid1);
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
PetscInt data,gid1 = aj[B->i[i]+j] + 1;
ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr);
if (!data) {
/* one based table */
ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr);
}
}
}
/* form array of columns we need */
ierr = PetscMalloc(ec*sizeof(PetscInt),&garray);CHKERRQ(ierr);
ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr);
while (tpos) {
ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr);
gid--; lid--;
garray[lid] = gid;
}
ierr = PetscSortInt(ec,garray);CHKERRQ(ierr);
ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr);
for (i=0; i<ec; i++) {
ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr);
}
/* compact out the extra columns in B */
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
PetscInt gid1 = aj[B->i[i] + j] + 1;
ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr);
lid --;
aj[B->i[i]+j] = lid;
}
}
B->nbs = ec;
baij->B->cmap->n = baij->B->cmap->N = ec*mat->rmap->bs;
ierr = PetscLayoutSetUp((baij->B->cmap));CHKERRQ(ierr);
ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr);
#else
/* For the first stab we make an array as long as the number of columns */
/* mark those columns that are in baij->B */
ierr = PetscMalloc(Nbs*sizeof(PetscInt),&indices);CHKERRQ(ierr);
ierr = PetscMemzero(indices,Nbs*sizeof(PetscInt));CHKERRQ(ierr);
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
if (!indices[aj[B->i[i] + j]]) ec++;
indices[aj[B->i[i] + j] ] = 1;
}
}
/* form array of columns we need */
ierr = PetscMalloc(ec*sizeof(PetscInt),&garray);CHKERRQ(ierr);
ec = 0;
for (i=0; i<Nbs; i++) {
if (indices[i]) {
garray[ec++] = i;
}
}
/* make indices now point into garray */
for (i=0; i<ec; i++) {
indices[garray[i]] = i;
}
/* compact out the extra columns in B */
for (i=0; i<B->mbs; i++) {
for (j=0; j<B->ilen[i]; j++) {
aj[B->i[i] + j] = indices[aj[B->i[i] + j]];
}
}
B->nbs = ec;
baij->B->cmap->n = ec*mat->rmap->bs;
ierr = PetscFree(indices);CHKERRQ(ierr);
#endif
/* create local vector that is used to scatter into */
ierr = VecCreateSeq(PETSC_COMM_SELF,ec*bs,&baij->lvec);CHKERRQ(ierr);
/* create two temporary index sets for building scatter-gather */
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,garray,PETSC_COPY_VALUES,&from);CHKERRQ(ierr);
ierr = PetscMalloc(ec*sizeof(PetscInt),&stmp);CHKERRQ(ierr);
for (i=0; i<ec; i++) { stmp[i] = i; }
ierr = ISCreateBlock(PETSC_COMM_SELF,bs,ec,stmp,PETSC_OWN_POINTER,&to);CHKERRQ(ierr);
/* create temporary global vector to generate scatter context */
ierr = VecCreateMPIWithArray(((PetscObject)mat)->comm,1,mat->cmap->n,mat->cmap->N,PETSC_NULL,&gvec);CHKERRQ(ierr);
ierr = VecScatterCreate(gvec,from,baij->lvec,to,&baij->Mvctx);CHKERRQ(ierr);
ierr = VecDestroy(&gvec);CHKERRQ(ierr);
ierr = PetscLogObjectParent(mat,baij->Mvctx);CHKERRQ(ierr);
ierr = PetscLogObjectParent(mat,baij->lvec);CHKERRQ(ierr);
ierr = PetscLogObjectParent(mat,from);CHKERRQ(ierr);
ierr = PetscLogObjectParent(mat,to);CHKERRQ(ierr);
baij->garray = garray;
ierr = PetscLogObjectMemory(mat,(ec+1)*sizeof(PetscInt));CHKERRQ(ierr);
ierr = ISDestroy(&from);CHKERRQ(ierr);
ierr = ISDestroy(&to);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例7: ComputeMatrix
static PetscErrorCode ComputeMatrix(DomainData dd, Mat *A)
{
PetscErrorCode ierr;
GLLData gll;
Mat local_mat =0,temp_A=0;
ISLocalToGlobalMapping matis_map =0;
IS dirichletIS=0;
PetscFunctionBeginUser;
/* Compute some stuff of Gauss-Legendre-Lobatto quadrature rule */
ierr = GLLStuffs(dd,&gll);CHKERRQ(ierr);
/* Compute matrix of subdomain Neumann problem */
ierr = ComputeSubdomainMatrix(dd,gll,&local_mat);CHKERRQ(ierr);
/* Compute global mapping of local dofs */
ierr = ComputeMapping(dd,&matis_map);CHKERRQ(ierr);
/* Create MATIS object needed by BDDC */
ierr = MatCreateIS(dd.gcomm,1,PETSC_DECIDE,PETSC_DECIDE,dd.xm*dd.ym*dd.zm,dd.xm*dd.ym*dd.zm,matis_map,NULL,&temp_A);CHKERRQ(ierr);
/* Set local subdomain matrices into MATIS object */
ierr = MatScale(local_mat,dd.scalingfactor);CHKERRQ(ierr);
ierr = MatISSetLocalMat(temp_A,local_mat);CHKERRQ(ierr);
/* Call assembly functions */
ierr = MatAssemblyBegin(temp_A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(temp_A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
if (dd.DBC_zerorows) {
PetscInt dirsize;
ierr = ComputeSpecialBoundaryIndices(dd,&dirichletIS,NULL);CHKERRQ(ierr);
ierr = MatSetOption(local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatZeroRowsLocalIS(temp_A,dirichletIS,1.0,NULL,NULL);CHKERRQ(ierr);
ierr = ISGetLocalSize(dirichletIS,&dirsize);CHKERRQ(ierr);
/* giving hints to local and global matrices could be useful for the BDDC */
if (!dirsize) {
ierr = MatSetOption(local_mat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatSetOption(local_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
} else {
ierr = MatSetOption(local_mat,MAT_SYMMETRIC,PETSC_FALSE);CHKERRQ(ierr);
ierr = MatSetOption(local_mat,MAT_SPD,PETSC_FALSE);CHKERRQ(ierr);
}
ierr = ISDestroy(&dirichletIS);CHKERRQ(ierr);
} else { /* safe to set the options for the global matrices (they will be communicated to the matis local matrices) */
ierr = MatSetOption(temp_A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
ierr = MatSetOption(temp_A,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr);
}
#if DEBUG
{
Vec lvec,rvec;
PetscReal norm;
ierr = MatCreateVecs(temp_A,&lvec,&rvec);CHKERRQ(ierr);
ierr = VecSet(lvec,1.0);CHKERRQ(ierr);
ierr = MatMult(temp_A,lvec,rvec);CHKERRQ(ierr);
ierr = VecNorm(rvec,NORM_INFINITY,&norm);CHKERRQ(ierr);
printf("Test null space of global mat % 1.14e\n",norm);
ierr = VecDestroy(&lvec);CHKERRQ(ierr);
ierr = VecDestroy(&rvec);CHKERRQ(ierr);
}
#endif
/* free allocated workspace */
ierr = PetscFree(gll.zGL);CHKERRQ(ierr);
ierr = PetscFree(gll.rhoGL);CHKERRQ(ierr);
ierr = PetscFree(gll.A[0]);CHKERRQ(ierr);
ierr = PetscFree(gll.A);CHKERRQ(ierr);
ierr = MatDestroy(&gll.elem_mat);CHKERRQ(ierr);
ierr = MatDestroy(&local_mat);CHKERRQ(ierr);
ierr = ISLocalToGlobalMappingDestroy(&matis_map);CHKERRQ(ierr);
/* give back the pointer to te MATIS object */
*A = temp_A;
PetscFunctionReturn(0);
}
示例8: ComputeKSPBDDC
//.........这里部分代码省略.........
KSP temp_ksp;
PC pc;
IS dirichletIS=0,neumannIS=0,*bddc_dofs_splitting;
PetscInt localsize,*xadj=NULL,*adjncy=NULL;
MatNullSpace near_null_space;
PetscFunctionBeginUser;
ierr = KSPCreate(dd.gcomm,&temp_ksp);CHKERRQ(ierr);
ierr = KSPSetOperators(temp_ksp,A,A);CHKERRQ(ierr);
ierr = KSPSetType(temp_ksp,KSPCG);CHKERRQ(ierr);
ierr = KSPGetPC(temp_ksp,&pc);CHKERRQ(ierr);
ierr = PCSetType(pc,PCBDDC);CHKERRQ(ierr);
localsize = dd.xm_l*dd.ym_l*dd.zm_l;
/* BDDC customization */
/* jumping coefficients case */
ierr = PCISSetSubdomainScalingFactor(pc,dd.scalingfactor);CHKERRQ(ierr);
/* Dofs splitting
Simple stride-1 IS
It is not needed since, by default, PCBDDC assumes a stride-1 split */
ierr = PetscMalloc1(1,&bddc_dofs_splitting);CHKERRQ(ierr);
#if 1
ierr = ISCreateStride(PETSC_COMM_WORLD,localsize,0,1,&bddc_dofs_splitting[0]);CHKERRQ(ierr);
ierr = PCBDDCSetDofsSplittingLocal(pc,1,bddc_dofs_splitting);CHKERRQ(ierr);
#else
/* examples for global ordering */
/* each process lists the nodes it owns */
PetscInt sr,er;
ierr = MatGetOwnershipRange(A,&sr,&er);CHKERRQ(ierr);
ierr = ISCreateStride(PETSC_COMM_WORLD,er-sr,sr,1,&bddc_dofs_splitting[0]);CHKERRQ(ierr);
ierr = PCBDDCSetDofsSplitting(pc,1,bddc_dofs_splitting);CHKERRQ(ierr);
/* Split can be passed in a more general way since any process can list any node */
#endif
ierr = ISDestroy(&bddc_dofs_splitting[0]);CHKERRQ(ierr);
ierr = PetscFree(bddc_dofs_splitting);CHKERRQ(ierr);
/* Primal constraints implemented by using a near null space attached to A -> now it passes in only the constants
(which in practice is not needed since, by default, PCBDDC build the primal space using constants for quadrature formulas */
#if 0
Vec vecs[2];
PetscRandom rctx;
ierr = MatCreateVecs(A,&vecs[0],&vecs[1]);CHKERRQ(ierr);
ierr = PetscRandomCreate(dd.gcomm,&rctx);CHKERRQ(ierr);
ierr = VecSetRandom(vecs[0],rctx);CHKERRQ(ierr);
ierr = VecSetRandom(vecs[1],rctx);CHKERRQ(ierr);
ierr = MatNullSpaceCreate(dd.gcomm,PETSC_TRUE,2,vecs,&near_null_space);CHKERRQ(ierr);
ierr = VecDestroy(&vecs[0]);CHKERRQ(ierr);
ierr = VecDestroy(&vecs[1]);CHKERRQ(ierr);
ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr);
#else
ierr = MatNullSpaceCreate(dd.gcomm,PETSC_TRUE,0,NULL,&near_null_space);CHKERRQ(ierr);
#endif
ierr = MatSetNearNullSpace(A,near_null_space);CHKERRQ(ierr);
ierr = MatNullSpaceDestroy(&near_null_space);CHKERRQ(ierr);
/* CSR graph of subdomain dofs */
ierr = BuildCSRGraph(dd,&xadj,&adjncy);CHKERRQ(ierr);
ierr = PCBDDCSetLocalAdjacencyGraph(pc,localsize,xadj,adjncy,PETSC_OWN_POINTER);CHKERRQ(ierr);
/* Neumann/Dirichlet indices on the global boundary */
if (dd.DBC_zerorows) {
/* Only in case you eliminate some rows matrix with zerorows function, you need to set dirichlet indices into PCBDDC data */
ierr = ComputeSpecialBoundaryIndices(dd,&dirichletIS,&neumannIS);CHKERRQ(ierr);
ierr = PCBDDCSetNeumannBoundariesLocal(pc,neumannIS);CHKERRQ(ierr);
ierr = PCBDDCSetDirichletBoundariesLocal(pc,dirichletIS);CHKERRQ(ierr);
} else {
if (dd.pure_neumann) {
/* In such a case, all interface nodes lying on the global boundary are neumann nodes */
ierr = ComputeSpecialBoundaryIndices(dd,NULL,&neumannIS);CHKERRQ(ierr);
ierr = PCBDDCSetNeumannBoundariesLocal(pc,neumannIS);CHKERRQ(ierr);
} else {
/* It is wrong setting dirichlet indices without having zeroed the corresponding rows in the global matrix */
/* But we can still compute them since nodes near the dirichlet boundaries does not need to be defined as neumann nodes */
ierr = ComputeSpecialBoundaryIndices(dd,&dirichletIS,&neumannIS);CHKERRQ(ierr);
ierr = PCBDDCSetNeumannBoundariesLocal(pc,neumannIS);CHKERRQ(ierr);
}
}
/* Pass local null space information to local matrices (needed when using approximate local solvers) */
if (dd.ipx || dd.pure_neumann) {
MatNullSpace nsp;
Mat local_mat;
ierr = MatISGetLocalMat(A,&local_mat);CHKERRQ(ierr);
ierr = MatNullSpaceCreate(PETSC_COMM_SELF,PETSC_TRUE,0,NULL,&nsp);CHKERRQ(ierr);
ierr = MatSetNullSpace(local_mat,nsp);CHKERRQ(ierr);
ierr = MatNullSpaceDestroy(&nsp);CHKERRQ(ierr);
}
ierr = KSPSetComputeSingularValues(temp_ksp,PETSC_TRUE);CHKERRQ(ierr);
ierr = KSPSetFromOptions(temp_ksp);CHKERRQ(ierr);
ierr = KSPSetUp(temp_ksp);CHKERRQ(ierr);
*ksp = temp_ksp;
ierr = ISDestroy(&dirichletIS);CHKERRQ(ierr);
ierr = ISDestroy(&neumannIS);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例9: GLLStuffs
//.........这里部分代码省略.........
}
}
for (j=1; j<p+1; j++) {
x = glldata->zGL[j];
z0 = 1.0;
z1 = x;
for (n=1; n<p; n++) {
z2=x*z1*(2.0*n+1.0)/(n+1.0)-z0*(PetscScalar)(n/(n+1.0));
z0=z1;
z1=z2;
}
Lpj = z2;
glldata->A[j][0]=4.0*PetscPowRealInt(-1.0,p)/(p*(p+1.0)*Lpj*(1.0+glldata->zGL[j])*(1.0+glldata->zGL[j]));
glldata->A[0][j]=glldata->A[j][0];
}
for (j=0; j<p; j++) {
x = glldata->zGL[j];
z0 = 1.0;
z1 = x;
for (n=1; n<p; n++) {
z2=x*z1*(2.0*n+1.0)/(n+1.0)-z0*(PetscScalar)(n/(n+1.0));
z0=z1;
z1=z2;
}
Lpj=z2;
glldata->A[p][j]=4.0/(p*(p+1.0)*Lpj*(1.0-glldata->zGL[j])*(1.0-glldata->zGL[j]));
glldata->A[j][p]=glldata->A[p][j];
}
glldata->A[0][0]=0.5+(p*(p+1.0)-2.0)/6.0;
glldata->A[p][p]=glldata->A[0][0];
/* compute element matrix */
xloc = p+1;
yloc = p+1;
zloc = p+1;
if (dd.dim<2) yloc=1;
if (dd.dim<3) zloc=1;
xyloc = xloc*yloc;
xyzloc = xloc*yloc*zloc;
ierr = MatCreate(PETSC_COMM_SELF,&glldata->elem_mat);CHKERRQ(ierr);
ierr = MatSetSizes(glldata->elem_mat,xyzloc,xyzloc,xyzloc,xyzloc);CHKERRQ(ierr);
ierr = MatSetType(glldata->elem_mat,MATSEQAIJ);CHKERRQ(ierr);
ierr = MatSeqAIJSetPreallocation(glldata->elem_mat,xyzloc,NULL);CHKERRQ(ierr); /* overestimated */
ierr = MatZeroEntries(glldata->elem_mat);CHKERRQ(ierr);
ierr = MatSetOption(glldata->elem_mat,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr);
for (k=0; k<zloc; k++) {
if (dd.dim>2) rhoGLk=glldata->rhoGL[k];
else rhoGLk=1.0;
for (j=0; j<yloc; j++) {
if (dd.dim>1) rhoGLj=glldata->rhoGL[j];
else rhoGLj=1.0;
for (i=0; i<xloc; i++) {
ii = k*xyloc+j*xloc+i;
s = k;
r = j;
for (q=0; q<xloc; q++) {
jj = s*xyloc+r*xloc+q;
ierr = MatSetValue(glldata->elem_mat,jj,ii,glldata->A[i][q]*rhoGLj*rhoGLk,ADD_VALUES);CHKERRQ(ierr);
}
if (dd.dim>1) {
s=k;
q=i;
for (r=0; r<yloc; r++) {
jj = s*xyloc+r*xloc+q;
ierr = MatSetValue(glldata->elem_mat,jj,ii,glldata->A[j][r]*glldata->rhoGL[i]*rhoGLk,ADD_VALUES);CHKERRQ(ierr);
}
}
if (dd.dim>2) {
r=j;
q=i;
for (s=0; s<zloc; s++) {
jj = s*xyloc+r*xloc+q;
ierr = MatSetValue(glldata->elem_mat,jj,ii,glldata->A[k][s]*rhoGLj*glldata->rhoGL[i],ADD_VALUES);CHKERRQ(ierr);
}
}
}
}
}
ierr = MatAssemblyBegin(glldata->elem_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd (glldata->elem_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
#if DEBUG
{
Vec lvec,rvec;
PetscReal norm;
ierr = MatCreateVecs(glldata->elem_mat,&lvec,&rvec);CHKERRQ(ierr);
ierr = VecSet(lvec,1.0);CHKERRQ(ierr);
ierr = MatMult(glldata->elem_mat,lvec,rvec);CHKERRQ(ierr);
ierr = VecNorm(rvec,NORM_INFINITY,&norm);CHKERRQ(ierr);
printf("Test null space of elem mat % 1.14e\n",norm);
ierr = VecDestroy(&lvec);CHKERRQ(ierr);
ierr = VecDestroy(&rvec);CHKERRQ(ierr);
}
#endif
PetscFunctionReturn(0);
}
示例10: DomainDecomposition
static PetscErrorCode DomainDecomposition(DomainData *dd)
{
PetscMPIInt rank;
PetscInt i,j,k;
PetscFunctionBeginUser;
/* Subdomain index in cartesian coordinates */
MPI_Comm_rank(dd->gcomm,&rank);
dd->ipx = rank%dd->npx;
if (dd->dim>1) dd->ipz = rank/(dd->npx*dd->npy);
else dd->ipz = 0;
dd->ipy = rank/dd->npx-dd->ipz*dd->npy;
/* number of local elements */
dd->nex_l = dd->nex/dd->npx;
if (dd->ipx < dd->nex%dd->npx) dd->nex_l++;
if (dd->dim>1) {
dd->ney_l = dd->ney/dd->npy;
if (dd->ipy < dd->ney%dd->npy) dd->ney_l++;
} else {
dd->ney_l = 0;
}
if (dd->dim>2) {
dd->nez_l = dd->nez/dd->npz;
if (dd->ipz < dd->nez%dd->npz) dd->nez_l++;
} else {
dd->nez_l = 0;
}
/* local and global number of dofs */
dd->xm_l = dd->nex_l*dd->p+1;
dd->xm = dd->nex*dd->p+1;
dd->ym_l = dd->ney_l*dd->p+1;
dd->ym = dd->ney*dd->p+1;
dd->zm_l = dd->nez_l*dd->p+1;
dd->zm = dd->nez*dd->p+1;
if (!dd->pure_neumann) {
if (!dd->DBC_zerorows && !dd->ipx) dd->xm_l--;
if (!dd->DBC_zerorows) dd->xm--;
}
/* starting global index for local dofs (simple lexicographic order) */
dd->startx = 0;
j = dd->nex/dd->npx;
for (i=0; i<dd->ipx; i++) {
k = j;
if (i<dd->nex%dd->npx) k++;
dd->startx = dd->startx+k*dd->p;
}
if (!dd->pure_neumann && !dd->DBC_zerorows && dd->ipx) dd->startx--;
dd->starty = 0;
if (dd->dim > 1) {
j = dd->ney/dd->npy;
for (i=0; i<dd->ipy; i++) {
k = j;
if (i<dd->ney%dd->npy) k++;
dd->starty = dd->starty+k*dd->p;
}
}
dd->startz = 0;
if (dd->dim > 2) {
j = dd->nez/dd->npz;
for (i=0; i<dd->ipz; i++) {
k = j;
if (i<dd->nez%dd->npz) k++;
dd->startz = dd->startz+k*dd->p;
}
}
PetscFunctionReturn(0);
}
示例11: ComputeSubdomainMatrix
//.........这里部分代码省略.........
indexg[ii]=k*xloc*yloc+j*xloc+i;
ii++;
}
}
}
ierr = ISCreateGeneral(PETSC_COMM_SELF,ii,indexg,PETSC_COPY_VALUES,&submatIS);CHKERRQ(ierr);
ierr = MatGetSubMatrix(glldata.elem_mat,submatIS,submatIS,MAT_INITIAL_MATRIX,&elem_mat_DBC);CHKERRQ(ierr);
ierr = ISDestroy(&submatIS);CHKERRQ(ierr);
}
/* Assemble subdomain matrix */
localsize = dd.xm_l*dd.ym_l*dd.zm_l;
ierr = MatCreate(PETSC_COMM_SELF,&temp_local_mat);CHKERRQ(ierr);
ierr = MatSetSizes(temp_local_mat,localsize,localsize,localsize,localsize);CHKERRQ(ierr);
ierr = MatSetOptionsPrefix(temp_local_mat,"subdomain_");CHKERRQ(ierr);
/* set local matrices type: here we use SEQSBAIJ primarily for testing purpose */
/* in order to avoid conversions inside the BDDC code, use SeqAIJ if possible */
if (dd.DBC_zerorows && !dd.ipx) { /* in this case, we need to zero out some of the rows, so use seqaij */
ierr = MatSetType(temp_local_mat,MATSEQAIJ);CHKERRQ(ierr);
} else {
ierr = MatSetType(temp_local_mat,MATSEQSBAIJ);CHKERRQ(ierr);
}
ierr = MatSetFromOptions(temp_local_mat);CHKERRQ(ierr);
i = PetscPowRealInt(3.0*(dd.p+1.0),dd.dim);
ierr = MatSeqAIJSetPreallocation(temp_local_mat,i,NULL);CHKERRQ(ierr); /* very overestimated */
ierr = MatSeqSBAIJSetPreallocation(temp_local_mat,1,i,NULL);CHKERRQ(ierr); /* very overestimated */
ierr = MatSetOption(temp_local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr);
yloc = dd.p+1;
zloc = dd.p+1;
if (dd.dim < 3) zloc = 1;
if (dd.dim < 2) yloc = 1;
auxnez = dd.nez_l;
auxney = dd.ney_l;
auxnex = dd.nex_l;
if (dd.dim < 3) auxnez = 1;
if (dd.dim < 2) auxney = 1;
for (ke=0; ke<auxnez; ke++) {
for (je=0; je<auxney; je++) {
for (ie=0; ie<auxnex; ie++) {
/* customize element accounting for BC */
xloc = dd.p+1;
ming = 0;
usedmat = &glldata.elem_mat;
if (!dd.pure_neumann && !dd.DBC_zerorows && !dd.ipx) {
if (ie == 0) {
xloc = dd.p;
usedmat = &elem_mat_DBC;
} else {
ming = -1;
usedmat = &glldata.elem_mat;
}
}
/* local to the element/global to the subdomain indexing */
for (k=0; k<zloc; k++) {
kg = ke*dd.p+k;
for (j=0; j<yloc; j++) {
jg = je*dd.p+j;
for (i=0; i<xloc; i++) {
ig = ie*dd.p+i+ming;
ii = k*xloc*yloc+j*xloc+i;
indexg[ii] = kg*dd.xm_l*dd.ym_l+jg*dd.xm_l+ig;
}
}
}
/* Set values */
for (i=0; i<xloc*yloc*zloc; i++) {
ierr = MatGetRow(*usedmat,i,&j,(const PetscInt**)&cols,(const PetscScalar**)&vals);CHKERRQ(ierr);
for (k=0; k<j; k++) colsg[k] = indexg[cols[k]];
ierr = MatSetValues(temp_local_mat,1,&indexg[i],j,colsg,vals,ADD_VALUES);CHKERRQ(ierr);
ierr = MatRestoreRow(*usedmat,i,&j,(const PetscInt**)&cols,(const PetscScalar**)&vals);CHKERRQ(ierr);
}
}
}
}
ierr = PetscFree(indexg);CHKERRQ(ierr);
ierr = PetscFree(colsg);CHKERRQ(ierr);
ierr = MatAssemblyBegin(temp_local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd (temp_local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
#if DEBUG
{
Vec lvec,rvec;
PetscReal norm;
ierr = MatCreateVecs(temp_local_mat,&lvec,&rvec);CHKERRQ(ierr);
ierr = VecSet(lvec,1.0);CHKERRQ(ierr);
ierr = MatMult(temp_local_mat,lvec,rvec);CHKERRQ(ierr);
ierr = VecNorm(rvec,NORM_INFINITY,&norm);CHKERRQ(ierr);
printf("Test null space of local mat % 1.14e\n",norm);
ierr = VecDestroy(&lvec);CHKERRQ(ierr);
ierr = VecDestroy(&rvec);CHKERRQ(ierr);
}
#endif
*local_mat = temp_local_mat;
ierr = MatDestroy(&elem_mat_DBC);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例12: ComputeSpecialBoundaryIndices
//.........这里部分代码省略.........
ierr = PetscMalloc1(localsize,&indices);CHKERRQ(ierr);
ierr = PetscMalloc1(localsize,&touched);CHKERRQ(ierr);
for (i=0; i<localsize; i++) touched[i] = PETSC_FALSE;
if (dirichlet) {
i = 0;
/* west boundary */
if (dd.ipx == 0) {
for (k=0;k<dd.zm_l;k++) {
for (j=0;j<dd.ym_l;j++) {
indices[i]=k*dd.ym_l*dd.xm_l+j*dd.xm_l;
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
ierr = ISCreateGeneral(dd.gcomm,i,indices,PETSC_COPY_VALUES,&temp_dirichlet);CHKERRQ(ierr);
}
if (neumann) {
i = 0;
/* west boundary */
if (dd.ipx == 0) {
for (k=0;k<dd.zm_l;k++) {
for (j=0;j<dd.ym_l;j++) {
indices[i]=k*dd.ym_l*dd.xm_l+j*dd.xm_l;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
/* east boundary */
if (dd.ipx == dd.npx-1) {
for (k=0;k<dd.zm_l;k++) {
for (j=0;j<dd.ym_l;j++) {
indices[i]=k*dd.ym_l*dd.xm_l+j*dd.xm_l+dd.xm_l-1;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
/* south boundary */
if (dd.ipy == 0 && dd.dim > 1) {
for (k=0;k<dd.zm_l;k++) {
for (j=0;j<dd.xm_l;j++) {
indices[i]=k*dd.ym_l*dd.xm_l+j;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
/* north boundary */
if (dd.ipy == dd.npy-1 && dd.dim > 1) {
for (k=0;k<dd.zm_l;k++) {
for (j=0;j<dd.xm_l;j++) {
indices[i]=k*dd.ym_l*dd.xm_l+(dd.ym_l-1)*dd.xm_l+j;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
/* bottom boundary */
if (dd.ipz == 0 && dd.dim > 2) {
for (k=0;k<dd.ym_l;k++) {
for (j=0;j<dd.xm_l;j++) {
indices[i]=k*dd.xm_l+j;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
/* top boundary */
if (dd.ipz == dd.npz-1 && dd.dim > 2) {
for (k=0;k<dd.ym_l;k++) {
for (j=0;j<dd.xm_l;j++) {
indices[i]=(dd.zm_l-1)*dd.ym_l*dd.xm_l+k*dd.xm_l+j;
if (!touched[indices[i]]) {
touched[indices[i]]=PETSC_TRUE;
i++;
}
}
}
}
ierr = ISCreateGeneral(dd.gcomm,i,indices,PETSC_COPY_VALUES,&temp_neumann);CHKERRQ(ierr);
}
if (dirichlet) *dirichlet = temp_dirichlet;
if (neumann) *neumann = temp_neumann;
ierr = PetscFree(indices);CHKERRQ(ierr);
ierr = PetscFree(touched);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例13: MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqDense
PetscErrorCode MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqDense(Mat R,Mat A,Mat B,Mat RAB,PetscScalar *work)
{
Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*r=(Mat_SeqAIJ*)R->data;
PetscErrorCode ierr;
PetscScalar *b,r1,r2,r3,r4,*b1,*b2,*b3,*b4;
MatScalar *aa,*ra;
PetscInt cn=B->cmap->n,bm=B->rmap->n,col,i,j,n,*ai=a->i,*aj,am=A->rmap->n;
PetscInt am2=2*am,am3=3*am,bm4=4*bm;
PetscScalar *d,*c,*c2,*c3,*c4;
PetscInt *rj,rm=R->rmap->n,dm=RAB->rmap->n,dn=RAB->cmap->n;
PetscInt rm2=2*rm,rm3=3*rm,colrm;
PetscFunctionBegin;
if (!dm || !dn) PetscFunctionReturn(0);
if (bm != A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number columns in A %D not equal rows in B %D\n",A->cmap->n,bm);
if (am != R->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number columns in R %D not equal rows in A %D\n",R->cmap->n,am);
if (R->rmap->n != RAB->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number rows in RAB %D not equal rows in R %D\n",RAB->rmap->n,R->rmap->n);
if (B->cmap->n != RAB->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number columns in RAB %D not equal columns in B %D\n",RAB->cmap->n,B->cmap->n);
ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
ierr = MatDenseGetArray(RAB,&d);CHKERRQ(ierr);
b1 = b; b2 = b1 + bm; b3 = b2 + bm; b4 = b3 + bm;
c = work; c2 = c + am; c3 = c2 + am; c4 = c3 + am;
for (col=0; col<cn-4; col += 4){ /* over columns of C */
for (i=0; i<am; i++) { /* over rows of A in those columns */
r1 = r2 = r3 = r4 = 0.0;
n = ai[i+1] - ai[i];
aj = a->j + ai[i];
aa = a->a + ai[i];
for (j=0; j<n; j++) {
r1 += (*aa)*b1[*aj];
r2 += (*aa)*b2[*aj];
r3 += (*aa)*b3[*aj];
r4 += (*aa++)*b4[*aj++];
}
c[i] = r1;
c[am + i] = r2;
c[am2 + i] = r3;
c[am3 + i] = r4;
}
b1 += bm4;
b2 += bm4;
b3 += bm4;
b4 += bm4;
/* RAB[:,col] = R*C[:,col] */
colrm = col*rm;
for (i=0; i<rm; i++) { /* over rows of R in those columns */
r1 = r2 = r3 = r4 = 0.0;
n = r->i[i+1] - r->i[i];
rj = r->j + r->i[i];
ra = r->a + r->i[i];
for (j=0; j<n; j++) {
r1 += (*ra)*c[*rj];
r2 += (*ra)*c2[*rj];
r3 += (*ra)*c3[*rj];
r4 += (*ra++)*c4[*rj++];
}
d[colrm + i] = r1;
d[colrm + rm + i] = r2;
d[colrm + rm2 + i] = r3;
d[colrm + rm3 + i] = r4;
}
}
for (;col<cn; col++){ /* over extra columns of C */
for (i=0; i<am; i++) { /* over rows of A in those columns */
r1 = 0.0;
n = a->i[i+1] - a->i[i];
aj = a->j + a->i[i];
aa = a->a + a->i[i];
for (j=0; j<n; j++) {
r1 += (*aa++)*b1[*aj++];
}
c[i] = r1;
}
b1 += bm;
for (i=0; i<rm; i++) { /* over rows of R in those columns */
r1 = 0.0;
n = r->i[i+1] - r->i[i];
rj = r->j + r->i[i];
ra = r->a + r->i[i];
for (j=0; j<n; j++) {
r1 += (*ra++)*c[*rj++];
}
d[col*rm + i] = r1;
}
}
ierr = PetscLogFlops(cn*2.0*(a->nz + r->nz));CHKERRQ(ierr);
ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
ierr = MatDenseRestoreArray(RAB,&d);CHKERRQ(ierr);
ierr = MatAssemblyBegin(RAB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(RAB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例14: InitializeDomainData
static PetscErrorCode InitializeDomainData(DomainData *dd)
{
PetscErrorCode ierr;
PetscMPIInt sizes,rank;
PetscInt factor;
PetscFunctionBeginUser;
dd->gcomm = PETSC_COMM_WORLD;
ierr = MPI_Comm_size(dd->gcomm,&sizes);CHKERRQ(ierr);
ierr = MPI_Comm_rank(dd->gcomm,&rank);CHKERRQ(ierr);
/* test data passed in */
if (sizes<2) SETERRQ(dd->gcomm,PETSC_ERR_USER,"This is not a uniprocessor test");
/* Get informations from command line */
/* Processors/subdomains per dimension */
/* Default is 1d problem */
dd->npx = sizes;
dd->npy = 0;
dd->npz = 0;
dd->dim = 1;
ierr = PetscOptionsGetInt(NULL,NULL,"-npx",&dd->npx,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-npy",&dd->npy,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-npz",&dd->npz,NULL);CHKERRQ(ierr);
if (dd->npy) dd->dim++;
if (dd->npz) dd->dim++;
/* Number of elements per dimension */
/* Default is one element per subdomain */
dd->nex = dd->npx;
dd->ney = dd->npy;
dd->nez = dd->npz;
ierr = PetscOptionsGetInt(NULL,NULL,"-nex",&dd->nex,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-ney",&dd->ney,NULL);CHKERRQ(ierr);
ierr = PetscOptionsGetInt(NULL,NULL,"-nez",&dd->nez,NULL);CHKERRQ(ierr);
if (!dd->npy) {
dd->ney=0;
dd->nez=0;
}
if (!dd->npz) dd->nez=0;
/* Spectral degree */
dd->p = 3;
ierr = PetscOptionsGetInt(NULL,NULL,"-p",&dd->p,NULL);CHKERRQ(ierr);
/* pure neumann problem? */
dd->pure_neumann = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-pureneumann",&dd->pure_neumann,NULL);CHKERRQ(ierr);
/* How to enforce dirichlet boundary conditions (in case pureneumann has not been requested explicitly) */
dd->DBC_zerorows = PETSC_FALSE;
ierr = PetscOptionsGetBool(NULL,NULL,"-usezerorows",&dd->DBC_zerorows,NULL);CHKERRQ(ierr);
if (dd->pure_neumann) dd->DBC_zerorows = PETSC_FALSE;
dd->scalingfactor = 1.0;
factor = 0.0;
ierr = PetscOptionsGetInt(NULL,NULL,"-jump",&factor,NULL);CHKERRQ(ierr);
/* checkerboard pattern */
dd->scalingfactor = PetscPowScalar(10.0,(PetscScalar)factor*PetscPowScalar(-1.0,(PetscScalar)rank));
/* test data passed in */
if (dd->dim==1) {
if (sizes!=dd->npx) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of mpi procs in 1D must be equal to npx");
if (dd->nex<dd->npx) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of elements per dim must be greater/equal than number of procs per dim");
} else if (dd->dim==2) {
if (sizes!=dd->npx*dd->npy) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of mpi procs in 2D must be equal to npx*npy");
if (dd->nex<dd->npx || dd->ney<dd->npy) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of elements per dim must be greater/equal than number of procs per dim");
} else {
if (sizes!=dd->npx*dd->npy*dd->npz) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of mpi procs in 3D must be equal to npx*npy*npz");
if (dd->nex<dd->npx || dd->ney<dd->npy || dd->nez<dd->npz) SETERRQ(dd->gcomm,PETSC_ERR_USER,"Number of elements per dim must be greater/equal than number of procs per dim");
}
PetscFunctionReturn(0);
}
示例15: MatCholeskyFactorNumeric_SeqSBAIJ_6_NaturalOrdering
//.........这里部分代码省略.........
u0 = u[0]; u1 = u[1]; u2 = u[2]; u3 = u[3]; u4 = u[4]; u5 = u[5]; u6 = u[6];
u7 = u[7]; u8 = u[8]; u9 = u[9]; u10 = u[10]; u11 = u[11]; u12 = u[12]; u13 = u[13];
u14 = u[14]; u15 = u[15]; u16 = u[16]; u17 = u[17]; u18 = u[18]; u19 = u[19]; u20 = u[20];
u21 = u[21]; u22 = u[22]; u23 = u[23]; u24 = u[24]; u25 = u[25]; u26 = u[26]; u27 = u[27];
u28 = u[28]; u29 = u[29]; u30 = u[30]; u31 = u[31]; u32 = u[32]; u33 = u[33]; u34 = u[34];
u35 = u[35];
wp[0] += m0*u0 + m1*u1 + m2*u2 + m3*u3 + m4*u4 + m5*u5;
wp[1] += m6*u0 + m7*u1 + m8*u2 + m9*u3+ m10*u4+ m11*u5;
wp[2] += m12*u0+ m13*u1+ m14*u2+ m15*u3+ m16*u4+ m17*u5;
wp[3] += m18*u0+ m19*u1+ m20*u2+ m21*u3+ m22*u4+ m23*u5;
wp[4] += m24*u0+ m25*u1+ m26*u2+ m27*u3+ m28*u4+ m29*u5;
wp[5] += m30*u0+ m31*u1+ m32*u2+ m33*u3+ m34*u4+ m35*u5;
wp[6] += m0*u6 + m1*u7 + m2*u8 + m3*u9 + m4*u10 + m5*u11;
wp[7] += m6*u6 + m7*u7 + m8*u8 + m9*u9+ m10*u10+ m11*u11;
wp[8] += m12*u6+ m13*u7+ m14*u8+ m15*u9+ m16*u10+ m17*u11;
wp[9] += m18*u6+ m19*u7+ m20*u8+ m21*u9+ m22*u10+ m23*u11;
wp[10]+= m24*u6+ m25*u7+ m26*u8+ m27*u9+ m28*u10+ m29*u11;
wp[11]+= m30*u6+ m31*u7+ m32*u8+ m33*u9+ m34*u10+ m35*u11;
wp[12]+= m0*u12 + m1*u13 + m2*u14 + m3*u15 + m4*u16 + m5*u17;
wp[13]+= m6*u12 + m7*u13 + m8*u14 + m9*u15+ m10*u16+ m11*u17;
wp[14]+= m12*u12+ m13*u13+ m14*u14+ m15*u15+ m16*u16+ m17*u17;
wp[15]+= m18*u12+ m19*u13+ m20*u14+ m21*u15+ m22*u16+ m23*u17;
wp[16]+= m24*u12+ m25*u13+ m26*u14+ m27*u15+ m28*u16+ m29*u17;
wp[17]+= m30*u12+ m31*u13+ m32*u14+ m33*u15+ m34*u16+ m35*u17;
wp[18]+= m0*u18 + m1*u19 + m2*u20 + m3*u21 + m4*u22 + m5*u23;
wp[19]+= m6*u18 + m7*u19 + m8*u20 + m9*u21+ m10*u22+ m11*u23;
wp[20]+= m12*u18+ m13*u19+ m14*u20+ m15*u21+ m16*u22+ m17*u23;
wp[21]+= m18*u18+ m19*u19+ m20*u20+ m21*u21+ m22*u22+ m23*u23;
wp[22]+= m24*u18+ m25*u19+ m26*u20+ m27*u21+ m28*u22+ m29*u23;
wp[23]+= m30*u18+ m31*u19+ m32*u20+ m33*u21+ m34*u22+ m35*u23;
wp[24]+= m0*u24 + m1*u25 + m2*u26 + m3*u27 + m4*u28 + m5*u29;
wp[25]+= m6*u24 + m7*u25 + m8*u26 + m9*u27+ m10*u28+ m11*u29;
wp[26]+= m12*u24+ m13*u25+ m14*u26+ m15*u27+ m16*u28+ m17*u29;
wp[27]+= m18*u24+ m19*u25+ m20*u26+ m21*u27+ m22*u28+ m23*u29;
wp[28]+= m24*u24+ m25*u25+ m26*u26+ m27*u27+ m28*u28+ m29*u29;
wp[29]+= m30*u24+ m31*u25+ m32*u26+ m33*u27+ m34*u28+ m35*u29;
wp[30]+= m0*u30 + m1*u31 + m2*u32 + m3*u33 + m4*u34 + m5*u35;
wp[31]+= m6*u30 + m7*u31 + m8*u32 + m9*u33+ m10*u34+ m11*u35;
wp[32]+= m12*u30+ m13*u31+ m14*u32+ m15*u33+ m16*u34+ m17*u35;
wp[33]+= m18*u30+ m19*u31+ m20*u32+ m21*u33+ m22*u34+ m23*u35;
wp[34]+= m24*u30+ m25*u31+ m26*u32+ m27*u33+ m28*u34+ m29*u35;
wp[35]+= m30*u30+ m31*u31+ m32*u32+ m33*u33+ m34*u34+ m35*u35;
}
ierr = PetscLogFlops(2.0*216.0*(jmax-jmin));CHKERRQ(ierr);
/* ... add i to row list for next nonzero entry */
il[i] = jmin; /* update il(i) in column k+1, ... mbs-1 */
j = bj[jmin];
jl[i] = jl[j]; jl[j] = i; /* update jl */
}
i = nexti;
}
/* save nonzero entries in k-th row of U ... */
/* invert diagonal block */
d = ba+k*36;
ierr = PetscMemcpy(d,dk,36*sizeof(MatScalar));CHKERRQ(ierr);
ierr = PetscKernel_A_gets_inverse_A_6(d,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr);
if (zeropivotdetected) C->errortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
jmin = bi[k]; jmax = bi[k+1];
if (jmin < jmax) {
for (j=jmin; j<jmax; j++) {
vj = bj[j]; /* block col. index of U */
u = ba + j*36;
wp = w + vj*36;
for (k1=0; k1<36; k1++) {
*u++ = *wp;
*wp++ = 0.0;
}
}
/* ... add k to row list for first nonzero entry in k-th row */
il[k] = jmin;
i = bj[jmin];
jl[k] = jl[i]; jl[i] = k;
}
}
ierr = PetscFree(w);CHKERRQ(ierr);
ierr = PetscFree2(il,jl);CHKERRQ(ierr);
ierr = PetscFree2(dk,uik);CHKERRQ(ierr);
C->ops->solve = MatSolve_SeqSBAIJ_6_NaturalOrdering_inplace;
C->ops->solvetranspose = MatSolve_SeqSBAIJ_6_NaturalOrdering_inplace;
C->ops->forwardsolve = MatForwardSolve_SeqSBAIJ_6_NaturalOrdering_inplace;
C->ops->backwardsolve = MatBackwardSolve_SeqSBAIJ_6_NaturalOrdering_inplace;
C->assembled = PETSC_TRUE;
C->preallocated = PETSC_TRUE;
ierr = PetscLogFlops(1.3333*216*b->mbs);CHKERRQ(ierr); /* from inverting diagonal blocks */
PetscFunctionReturn(0);
}