PetscErrorCode QPIPComputeNormFromCentralPath(TAO_BQPIP *qp, PetscReal *norm) { PetscErrorCode ierr; PetscReal gap[2],mu[2], nmu; PetscFunctionBegin; ierr = VecPointwiseMult(qp->GZwork, qp->G, qp->Z);CHKERRQ(ierr); ierr = VecPointwiseMult(qp->TSwork, qp->T, qp->S);CHKERRQ(ierr); ierr = VecNorm(qp->TSwork, NORM_1, &mu[0]);CHKERRQ(ierr); ierr = VecNorm(qp->GZwork, NORM_1, &mu[1]);CHKERRQ(ierr); nmu=-(mu[0]+mu[1])/qp->m; ierr = VecShift(qp->GZwork,nmu);CHKERRQ(ierr); ierr = VecShift(qp->TSwork,nmu);CHKERRQ(ierr); ierr = VecNorm(qp->GZwork,NORM_2,&gap[0]);CHKERRQ(ierr); ierr = VecNorm(qp->TSwork,NORM_2,&gap[1]);CHKERRQ(ierr); gap[0]*=gap[0]; gap[1]*=gap[1]; qp->pathnorm=PetscSqrtScalar( (gap[0]+gap[1]) ); *norm=qp->pathnorm; PetscFunctionReturn(0); }
PetscErrorCode SetInitialGuess(Vec X,AppCtx* user) { PetscErrorCode ierr; PetscScalar *x,*u; PetscInt n,i; Vec rand; PetscFunctionBegin; /* u = -0.4 + 0.05*rand(N,1)*(rand(N,1) - 0.5) */ ierr = VecDuplicate(user->u,&rand); ierr = VecSetRandom(rand,PETSC_NULL); ierr = VecCopy(rand,user->u); ierr = VecShift(rand,-0.5);CHKERRQ(ierr); ierr = VecPointwiseMult(user->u,user->u,rand);CHKERRQ(ierr); ierr = VecDestroy(&rand);CHKERRQ(ierr); ierr = VecScale(user->u,0.05);CHKERRQ(ierr); ierr = VecShift(user->u,-0.4);CHKERRQ(ierr); ierr = VecGetLocalSize(X,&n);CHKERRQ(ierr); ierr = VecGetArray(X,&x);CHKERRQ(ierr); ierr = VecGetArray(user->u,&u);CHKERRQ(ierr); /* Set initial guess, only set value for 2nd dof */ for(i=0;i<n/2;i++) { x[2*i+1] = u[i]; } ierr = VecRestoreArray(X,&x);CHKERRQ(ierr); ierr = VecRestoreArray(user->u,&u);CHKERRQ(ierr); PetscFunctionReturn(0); }
//////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////// int cornergen(Vec x, Vec y, Vec z,PetscScalar dy , PetscScalar dz, Vec x1, Vec y1, Vec z1) { PetscErrorCode ierr; ierr = VecCopy(x,x1);CHKERRQ(ierr); ierr = VecCopy(y,y1);CHKERRQ(ierr); ierr = VecCopy(z,z1);CHKERRQ(ierr); ierr = VecShift(y1, dy);CHKERRQ(ierr); ierr = VecShift(z1, dz);CHKERRQ(ierr);
/*@C MatNullSpaceRemove - Removes all the components of a null space from a vector. Collective on MatNullSpace Input Parameters: + sp - the null space context (if this is NULL then no null space is removed) - vec - the vector from which the null space is to be removed Level: advanced .keywords: PC, null space, remove .seealso: MatNullSpaceCreate(), MatNullSpaceDestroy(), MatNullSpaceSetFunction() @*/ PetscErrorCode MatNullSpaceRemove(MatNullSpace sp,Vec vec) { PetscScalar sum; PetscInt i,N; PetscErrorCode ierr; PetscFunctionBegin; if (!sp) PetscFunctionReturn(0); PetscValidHeaderSpecific(sp,MAT_NULLSPACE_CLASSID,1); PetscValidHeaderSpecific(vec,VEC_CLASSID,2); if (sp->has_cnst) { ierr = VecGetSize(vec,&N);CHKERRQ(ierr); if (N > 0) { ierr = VecSum(vec,&sum);CHKERRQ(ierr); sum = sum/((PetscScalar)(-1.0*N)); ierr = VecShift(vec,sum);CHKERRQ(ierr); } } if (sp->n) { ierr = VecMDot(vec,sp->n,sp->vecs,sp->alpha);CHKERRQ(ierr); for (i=0; i<sp->n; i++) sp->alpha[i] = -sp->alpha[i]; ierr = VecMAXPY(vec,sp->n,sp->alpha,sp->vecs);CHKERRQ(ierr); } if (sp->remove) { ierr = (*sp->remove)(sp,vec,sp->rmctx);CHKERRQ(ierr); } PetscFunctionReturn(0); }
void N_VAddConst_Petsc(N_Vector x, realtype b, N_Vector z) { Vec *xv = NV_PVEC_PTC(x); Vec *zv = NV_PVEC_PTC(z); if(z != x) VecCopy(*xv, *zv); /* copy x~>z */ VecShift(*zv, b); return; }
extern PetscErrorCode DefiantUpdatePorosity(BlackOilReservoirSimulation* MySim) { PetscErrorCode ierr; Vec TempVec; PetscFunctionBegin; ierr = VecDuplicate(MySim->Po, &TempVec);CHKERRQ(ierr); ierr = VecCopy(MySim->Po, TempVec);CHKERRQ(ierr); ierr = VecShift(TempVec, -1.0*MySim->RockCompRefPressure);CHKERRQ(ierr); ierr = VecScale(TempVec, MySim->RockCompressibility);CHKERRQ(ierr); ierr = VecShift(TempVec, 1.0);CHKERRQ(ierr); ierr = VecScale(TempVec, MySim->RockCompRefPorosity);CHKERRQ(ierr); /* copy back to porosity */ ierr = VecCopy(TempVec, MySim->Phi);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* MSA_InitialPoint - Calculates the initial guess in one of three ways. Input Parameters: . user - user-defined application context . X - vector for initial guess Output Parameters: . X - newly computed initial guess */ static int MSA_InitialPoint(AppCtx * user, Vec X) { int info; PetscInt start2=-1,i,j; PetscReal start1=0; PetscTruth flg1,flg2; info = PetscOptionsGetReal(PETSC_NULL,"-start",&start1,&flg1); CHKERRQ(info); info = PetscOptionsGetInt(PETSC_NULL,"-random",&start2,&flg2); CHKERRQ(info); if (flg1){ /* The zero vector is reasonable */ info = VecSet(X, start1); CHKERRQ(info); } else if (flg2 && start2>0){ /* Try a random start between -0.5 and 0.5 */ PetscRandom rctx; PetscScalar np5=-0.5; info = PetscRandomCreate(PETSC_COMM_WORLD,&rctx); CHKERRQ(info); for (i=0; i<start2; i++){ info = VecSetRandom(X, rctx); CHKERRQ(info); } info = PetscRandomDestroy(rctx); CHKERRQ(info); info = VecShift(X, np5); CHKERRQ(info); } else { /* Take an average of the boundary conditions */ PetscInt xs,xm,ys,ym; PetscInt mx=user->mx,my=user->my; PetscScalar **x; /* Get local mesh boundaries */ info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); /* Get pointers to vector data */ info = DAVecGetArray(user->da,X,(void**)&x); /* Perform local computations */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ x[j][i] = ( ((j+1)*user->bottom[i-xs+1]+(my-j+1)*user->top[i-xs+1])/(my+2)+ ((i+1)*user->left[j-ys+1]+(mx-i+1)*user->right[j-ys+1])/(mx+2))/2.0; } } /* Restore vectors */ info = DAVecRestoreArray(user->da,X,(void**)&x); CHKERRQ(info); info = PetscLogFlops(9*xm*ym); CHKERRQ(info); } return 0; }
void _remove_constant_nullsp( Vec v ) { PetscInt N; PetscScalar sum; VecGetSize( v, &N ); if( N > 0 ) { VecSum( v, &sum ); sum = sum/( -1.0*N ); VecShift( v, sum ); } }
PetscErrorCode DPsi(AppCtx *user) { PetscErrorCode ierr; PetscScalar Evf=user->Evf,Eif=user->Eif,kBT=user->kBT,A=user->A; PetscScalar *cv_p,*ci_p,*eta_p,*logcv_p,*logci_p,*logcvi_p,*DPsiv_p,*DPsii_p,*DPsieta_p; PetscInt n,i; PetscFunctionBeginUser; ierr = VecGetLocalSize(user->cv,&n);CHKERRQ(ierr); ierr = VecGetArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecGetArray(user->ci,&ci_p);CHKERRQ(ierr); ierr = VecGetArray(user->eta,&eta_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcv,&logcv_p);CHKERRQ(ierr); ierr = VecGetArray(user->logci,&logci_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcvi,&logcvi_p);CHKERRQ(ierr); ierr = VecGetArray(user->DPsiv,&DPsiv_p);CHKERRQ(ierr); ierr = VecGetArray(user->DPsii,&DPsii_p);CHKERRQ(ierr); ierr = VecGetArray(user->DPsieta,&DPsieta_p);CHKERRQ(ierr); ierr = Llog(user->cv,user->logcv);CHKERRQ(ierr); ierr = Llog(user->ci,user->logci);CHKERRQ(ierr); ierr = VecCopy(user->cv,user->cvi);CHKERRQ(ierr); ierr = VecAXPY(user->cvi,1.0,user->ci);CHKERRQ(ierr); ierr = VecScale(user->cvi,-1.0);CHKERRQ(ierr); ierr = VecShift(user->cvi,1.0);CHKERRQ(ierr); ierr = Llog(user->cvi,user->logcvi);CHKERRQ(ierr); for (i=0; i<n; i++) { DPsiv_p[i] = (eta_p[i]-1.0)*(eta_p[i]-1.0)*(Evf + kBT*(logcv_p[i] - logcvi_p[i])) + eta_p[i]*eta_p[i]*2*A*(cv_p[i]-1); DPsii_p[i] = (eta_p[i]-1.0)*(eta_p[i]-1.0)*(Eif + kBT*(logci_p[i] - logcvi_p[i])) + eta_p[i]*eta_p[i]*2*A*ci_p[i]; DPsieta_p[i] = 2.0*(eta_p[i]-1.0)*(Evf*cv_p[i] + Eif*ci_p[i] + kBT*(cv_p[i]* logcv_p[i] + ci_p[i]* logci_p[i] + (1-cv_p[i]-ci_p[i])*logcvi_p[i])) + 2.0*eta_p[i]*A*((cv_p[i]-1.0)*(cv_p[i]-1.0) + ci_p[i]*ci_p[i]); } ierr = VecRestoreArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->ci,&ci_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->eta,&eta_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->logcv,&logcv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->logci,&logci_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->logcvi,&logcvi_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->DPsiv,&DPsiv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->DPsii,&DPsii_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->DPsieta,&DPsieta_p);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode Update_q(AppCtx *user) { PetscErrorCode ierr; PetscScalar *q_p,*w1,*w2; PetscInt i,n; PetscFunctionBeginUser; ierr = VecPointwiseMult(user->Rr,user->eta,user->eta);CHKERRQ(ierr); ierr = VecScale(user->Rr,user->Rsurf);CHKERRQ(ierr); ierr = VecShift(user->Rr,user->Rbulk);CHKERRQ(ierr); ierr = VecPointwiseMult(user->Riv,user->cv,user->ci);CHKERRQ(ierr); ierr = VecPointwiseMult(user->Riv,user->Rr,user->Riv);CHKERRQ(ierr); ierr = VecGetArray(user->q,&q_p);CHKERRQ(ierr); ierr = VecGetArray(user->work1,&w1);CHKERRQ(ierr); ierr = VecGetArray(user->work2,&w2);CHKERRQ(ierr); ierr = VecCopy(user->cv,user->work1);CHKERRQ(ierr); ierr = VecAXPY(user->work1,1.0,user->Pv);CHKERRQ(ierr); ierr = VecScale(user->work1,-1.0);CHKERRQ(ierr); ierr = MatMult(user->M_0,user->work1,user->work2);CHKERRQ(ierr); ierr = VecGetLocalSize(user->work1,&n);CHKERRQ(ierr); for (i=0; i<n; i++) q_p[5*i]=w2[i]; ierr = MatMult(user->M_0,user->DPsiv,user->work1);CHKERRQ(ierr); for (i=0; i<n; i++) q_p[5*i+1]=w1[i]; ierr = VecCopy(user->ci,user->work1);CHKERRQ(ierr); ierr = VecAXPY(user->work1,1.0,user->Pi);CHKERRQ(ierr); ierr = VecScale(user->work1,-1.0);CHKERRQ(ierr); ierr = MatMult(user->M_0,user->work1,user->work2);CHKERRQ(ierr); for (i=0; i<n; i++) q_p[5*i+2]=w2[i]; ierr = MatMult(user->M_0,user->DPsii,user->work1);CHKERRQ(ierr); for (i=0; i<n; i++) q_p[5*i+3]=w1[i]; ierr = VecCopy(user->eta,user->work1);CHKERRQ(ierr); ierr = VecScale(user->work1,-1.0/user->dt);CHKERRQ(ierr); ierr = VecAXPY(user->work1,user->L,user->DPsieta);CHKERRQ(ierr); ierr = VecAXPY(user->work1,-1.0,user->Piv);CHKERRQ(ierr); ierr = MatMult(user->M_0,user->work1,user->work2);CHKERRQ(ierr); for (i=0; i<n; i++) q_p[5*i+4]=w2[i]; ierr = VecRestoreArray(user->q,&q_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->work1,&w1);CHKERRQ(ierr); ierr = VecRestoreArray(user->work2,&w2);CHKERRQ(ierr); PetscFunctionReturn(0); }
void PkStruct::finalize() { VecAssemblyBegin(pkvec); VecAssemblyEnd(pkvec); VecAssemblyBegin(nmodes); VecAssemblyEnd(nmodes); VecAssemblyBegin(kvec); VecAssemblyEnd(kvec); //Normalize and return VecShift(nmodes, 1.e-20); VecPointwiseDivide(pkvec, nmodes); VecPointwiseDivide(kvec, nmodes); VecGetArray(kvec, &_kvec); VecGetArray(pkvec, &_pkvec); VecGetArray(nmodes, &_nmodes); }
PetscErrorCode MatGetDiagonal_Shell(Mat A,Vec v) { Mat_Shell *shell = (Mat_Shell*)A->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = (*shell->getdiagonal)(A,v);CHKERRQ(ierr); ierr = VecScale(v,shell->vscale);CHKERRQ(ierr); if (shell->dshift) { ierr = VecPointwiseMult(v,v,shell->dshift);CHKERRQ(ierr); } else { ierr = VecShift(v,shell->vshift);CHKERRQ(ierr); } if (shell->left) {ierr = VecPointwiseMult(v,v,shell->left);CHKERRQ(ierr);} if (shell->right) {ierr = VecPointwiseMult(v,v,shell->right);CHKERRQ(ierr);} PetscFunctionReturn(0); }
/* Computes the wind speed using Weibull distribution */ PetscErrorCode WindSpeeds(AppCtx *user) { PetscErrorCode ierr; PetscScalar *x,*t,avg_dev,sum; PetscInt i; PetscFunctionBegin; user->cw = 5; user->kw = 2; /* Rayleigh distribution */ user->nsamples = 2000; user->Tw = 0.2; ierr = PetscOptionsBegin(PETSC_COMM_WORLD,PETSC_NULL,"Wind Speed Options","");CHKERRQ(ierr); { ierr = PetscOptionsReal("-cw","","",user->cw,&user->cw,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-kw","","",user->kw,&user->kw,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-nsamples","","",user->nsamples,&user->nsamples,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-Tw","","",user->Tw,&user->Tw,PETSC_NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&user->wind_data);CHKERRQ(ierr); ierr = VecSetSizes(user->wind_data,PETSC_DECIDE,user->nsamples);CHKERRQ(ierr); ierr = VecSetFromOptions(user->wind_data);CHKERRQ(ierr); ierr = VecDuplicate(user->wind_data,&user->t_wind);CHKERRQ(ierr); ierr = VecGetArray(user->t_wind,&t);CHKERRQ(ierr); for(i=0;i < user->nsamples;i++) t[i] = (i+1)*tmax/user->nsamples; ierr = VecRestoreArray(user->t_wind,&t);CHKERRQ(ierr); /* Wind speed deviation = (-log(rand)/cw)^(1/kw) */ ierr = VecSetRandom(user->wind_data,PETSC_NULL);CHKERRQ(ierr); ierr = VecLog(user->wind_data);CHKERRQ(ierr); ierr = VecScale(user->wind_data,-1/user->cw);CHKERRQ(ierr); ierr = VecGetArray(user->wind_data,&x);CHKERRQ(ierr); for(i=0;i < user->nsamples;i++) { x[i] = PetscPowScalar(x[i],(1/user->kw)); } ierr = VecRestoreArray(user->wind_data,&x);CHKERRQ(ierr); ierr = VecSum(user->wind_data,&sum);CHKERRQ(ierr); avg_dev = sum/user->nsamples; /* Wind speed (t) = (1 + wind speed deviation(t) - avg_dev)*average wind speed */ ierr = VecShift(user->wind_data,(1-avg_dev));CHKERRQ(ierr); ierr = VecScale(user->wind_data,vwa);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode DPsi(AppCtx *user) { PetscErrorCode ierr; PetscScalar Evf=user->Evf,A=user->A,B=user->B,cv0=user->cv0; PetscScalar *cv_p,*eta_p,*logcv_p,*logcv2_p,*DPsiv_p,*DPsieta_p; PetscInt n,i; PetscFunctionBeginUser; ierr = VecGetLocalSize(user->cv,&n); ierr = VecGetArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecGetArray(user->eta,&eta_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcv,&logcv_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcv2,&logcv2_p);CHKERRQ(ierr); ierr = VecGetArray(user->DPsiv,&DPsiv_p);CHKERRQ(ierr); ierr = VecGetArray(user->DPsieta,&DPsieta_p);CHKERRQ(ierr); ierr = Llog(user->cv,user->logcv);CHKERRQ(ierr); ierr = VecCopy(user->cv,user->work1);CHKERRQ(ierr); ierr = VecScale(user->work1,-1.0);CHKERRQ(ierr); ierr = VecShift(user->work1,1.0);CHKERRQ(ierr); ierr = Llog(user->work1,user->logcv2);CHKERRQ(ierr); for (i=0; i<n; i++) { DPsiv_p[i] = (eta_p[i]-1.0)*(eta_p[i]-1.0)*(eta_p[i]+1.0)*(eta_p[i]+1.0)*(Evf + logcv_p[i] - logcv2_p[i]) - 2.0*A*(cv_p[i] - cv0)*eta_p[i]*(eta_p[i]+2.0)*(eta_p[i]-1.0)*(eta_p[i]-1.0) + 2.0*B*(cv_p[i] - 1.0)*eta_p[i]*eta_p[i]; DPsieta_p[i] = 4.0*eta_p[i]*(eta_p[i]-1.0)*(eta_p[i]+1.0)*(Evf*cv_p[i] + cv_p[i]*logcv_p[i] + (1.0-cv_p[i])*logcv2_p[i]) - A*(cv_p[i] - cv0)*(cv_p[i] - cv0)*(4.0*eta_p[i]*eta_p[i]*eta_p[i] - 6.0*eta_p[i] + 2.0) + 2.0*B*(cv_p[i]-1.0)*(cv_p[i]-1.0)*eta_p[i]; } ierr = VecRestoreArray(user->cv,&cv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->eta,&eta_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcv,&logcv_p);CHKERRQ(ierr); ierr = VecGetArray(user->logcv2,&logcv2_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->DPsiv,&DPsiv_p);CHKERRQ(ierr); ierr = VecRestoreArray(user->DPsieta,&DPsieta_p);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc, char** args){ PetscErrorCode err; PetscViewer fd = NULL; Mat invL1 = NULL, invU1 = NULL, invL2 = NULL, invU2 = NULL, H12 = NULL, H21 = NULL; Vec order = NULL, r = NULL; //, or = NULL; //dimension: n: n1 + n2 Vec seeds = NULL; // Vec r1 = NULL, q1 = NULL, t1_1 = NULL, t1_2 = NULL, t1_3 = NULL, t1_4 = NULL, t1_5 = NULL; // dimension: n1 // Vec r2 = NULL, q2 = NULL, q_tilda = NULL, t2_1 = NULL, t2_2 = NULL, t2_3 = NULL; // dimension: n2 PetscRandom rand; PetscLogDouble tic, toc, total_time, time; PetscInt n, i; PetscMPIInt rank, size; PetscInt seed; PetscScalar c, val; PetscInt QN = 100; // Initialize PETSC and MPI err = PetscInitialize(&argc, &args, (char*) 0, help); CHKERRQ(err); err = MPI_Comm_size(PETSC_COMM_WORLD, &size); CHKERRQ(err); err = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(err); err = PetscPrintf(PETSC_COMM_WORLD, "mpi size: %d\n", size); CHKERRQ(err); // Read matrices and an ordering vector err = PetscPrintf(PETSC_COMM_WORLD, "Read inputs (invL1, invU1, invL2, invU2, H12, H21, order)\n"); CHKERRQ(err); err = loadMat("./data/invL1.dat", &invL1, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("invL1", invL1); CHKERRQ(err); err = loadMat("./data/invU1.dat", &invU1, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("invU1", invU1); CHKERRQ(err); err = loadMat("./data/invL2.dat", &invL2, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("invL2", invL2); CHKERRQ(err); err = loadMat("./data/invU2.dat", &invU2, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("invU2", invU2); CHKERRQ(err); err = loadMat("./data/H12.dat", &H12, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("H12", H12); CHKERRQ(err); err = loadMat("./data/H21.dat", &H21, PETSC_COMM_WORLD, MATMPIAIJ, &fd); CHKERRQ(err); err = checkMat("H21", H21); CHKERRQ(err); err = loadVec("./data/order.dat", &order, PETSC_COMM_SELF, &fd); CHKERRQ(err); //all processes must have this vector for ordering the result vector. err = checkVec("order", order); CHKERRQ(err); // shift -1 for zero-based index err = VecShift(order, -1); CHKERRQ(err); err = VecGetSize(order, &n); CHKERRQ(err); seed = 5; c = 0.05; err = PetscTime(&tic); CHKERRQ(err); //err = BearQueryMat(seed, c, invL1, invU1, invL2, invU2, H12, H21, order); CHKERRQ(err); //err = PetscTime(&toc); CHKERRQ(err); //time = toc - tic; //err = PetscPrintf(PETSC_COMM_WORLD, "running time: %f sec\n", time); CHKERRQ(err); ///* 100 times querying err = VecCreateSeq(PETSC_COMM_SELF, QN, &seeds); CHKERRQ(err); err = VecSetFromOptions(seeds); CHKERRQ(err); err = PetscRandomCreate(PETSC_COMM_WORLD, &rand); CHKERRQ(err); err = PetscRandomSetSeed(rand, 100); CHKERRQ(err); err = PetscRandomSetInterval(rand, (PetscScalar) 0, (PetscScalar) n); CHKERRQ(err); err = PetscRandomSetFromOptions(rand); CHKERRQ(err); err = VecSetRandom(seeds, rand); CHKERRQ(err); err = PetscRandomDestroy(&rand); CHKERRQ(err); seed = 5; //seed is give by user on one-based index c = 0.05; i = 0; err = VecDuplicate(order, &r); CHKERRQ(err); for(i = 0; i < QN; i++){ err = VecGetValues(seeds, 1, &i, &val); seed = (PetscInt) val; //err = PetscPrintf(PETSC_COMM_SELF, "rank: %d, seed: %d\n", rank, seed); err = PetscTime(&tic); CHKERRQ(err); err = BearQuery(seed, c, invL1, invU1, invL2, invU2, H12, H21, order, r); CHKERRQ(err); err = PetscTime(&toc); CHKERRQ(err); time = toc - tic; err = PetscPrintf(PETSC_COMM_WORLD, "running time: %f sec\n", time); CHKERRQ(err); total_time += time; } err = PetscPrintf(PETSC_COMM_WORLD, "average running time: %f sec\n", total_time/QN); CHKERRQ(err); err = VecDestroy(&r); /* err = MatGetSize(H12, &n1, &n2); CHKERRQ(err); n = n1 + n2; err = PetscPrintf(PETSC_COMM_WORLD, "n1: %d, n2: %d\n", n1, n2); CHKERRQ(err); err = VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, n, &r); CHKERRQ(err); err = VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, n1, &q1); CHKERRQ(err); err = VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, n2, &q2); CHKERRQ(err); err = VecSet(q1, 0); CHKERRQ(err); err = VecSet(q2, 0); CHKERRQ(err); seed = seed - 1; // shift -1 for zero-based index err = VecGetValues(order, 1, &seed, &val); CHKERRQ(err); oseed = (PetscInt) val; err = PetscPrintf(PETSC_COMM_WORLD, "Given seed: %d, Reorered seed: %d (0 ~ n-1)\n", seed, oseed); CHKERRQ(err); if(oseed < n1){ err = VecSetValues(q1, 1, &oseed, &one, INSERT_VALUES); CHKERRQ(err); }else{ oseed = oseed - n1; err = VecSetValues(q2, 1, &oseed, &one, INSERT_VALUES); CHKERRQ(err); //err = printVecSum(q2); } err = VecAssemblyBegin(q1); CHKERRQ(err); err = VecAssemblyBegin(q2); CHKERRQ(err); err = VecAssemblyEnd(q1); CHKERRQ(err); err = VecAssemblyEnd(q2); CHKERRQ(err); err = VecDuplicate(q1, &r1); CHKERRQ(err); err = VecDuplicate(q1, &t1_1); CHKERRQ(err); err = VecDuplicate(q1, &t1_2); CHKERRQ(err); err = VecDuplicate(q1, &t1_3); CHKERRQ(err); err = VecDuplicate(q1, &t1_4); CHKERRQ(err); err = VecDuplicate(q1, &t1_5); CHKERRQ(err); err = VecDuplicate(q2, &r2); CHKERRQ(err); err = VecDuplicate(q2, &q_tilda); CHKERRQ(err); err = VecDuplicate(q2, &t2_1); CHKERRQ(err); err = VecDuplicate(q2, &t2_2); CHKERRQ(err); err = VecDuplicate(q2, &t2_3); CHKERRQ(err); // Start matrix-vec multiplications err = MatMult(invL1, q1, t1_1); CHKERRQ(err); err = MatMult(invU1, t1_1, t1_2); CHKERRQ(err); err = MatMult(H21, t1_2, t2_1); CHKERRQ(err); err = VecAXPBYPCZ(q_tilda, 1.0, -1.0, 0.0, q2, t2_1); CHKERRQ(err); err = MatMult(invL2, q_tilda, t2_2); CHKERRQ(err); err = MatMult(invU2, t2_2, r2); CHKERRQ(err); err = MatMult(H12, r2, t1_3); CHKERRQ(err); err = VecAXPBYPCZ(t1_4, 1.0, -1.0, 0.0, q1, t1_3); CHKERRQ(err); err = MatMult(invL1, t1_4, t1_5); CHKERRQ(err); err = MatMult(invU1, t1_5, r1); CHKERRQ(err); //err = printVecSum(r1); //err = VecView(r2, PETSC_VIEWER_STDOUT_WORLD); // Concatenate r1 and r2 err = VecMerge(r1, r2, r); CHKERRQ(err); err = VecScale(r, c); CHKERRQ(err); //err = VecView(r, PETSC_VIEWER_STDOUT_WORLD); err = VecDuplicate(r, &or); CHKERRQ(err); err = VecReorder(r, order, or); CHKERRQ(err); //err = VecView(or, PETSC_VIEWER_STDOUT_WORLD);*/ // Destory matrices and vectors err = MatDestroy(&invL1); CHKERRQ(err); err = MatDestroy(&invU1); CHKERRQ(err); err = MatDestroy(&invL2); CHKERRQ(err); err = MatDestroy(&invU2); CHKERRQ(err); err = MatDestroy(&H12); CHKERRQ(err); err = MatDestroy(&H21); CHKERRQ(err); err = VecDestroy(&order); CHKERRQ(err); err = VecDestroy(&r); CHKERRQ(err); err = VecDestroy(&seeds); CHKERRQ(err); //err = VecDestroy(&or); CHKERRQ(err); /* err = VecDestroy(&r1); CHKERRQ(err); err = VecDestroy(&q1); CHKERRQ(err); err = VecDestroy(&t1_1); CHKERRQ(err); err = VecDestroy(&t1_2); CHKERRQ(err); err = VecDestroy(&t1_3); CHKERRQ(err); err = VecDestroy(&t1_4); CHKERRQ(err); err = VecDestroy(&t1_5); CHKERRQ(err); err = VecDestroy(&r2); CHKERRQ(err); err = VecDestroy(&q2); CHKERRQ(err); err = VecDestroy(&q_tilda); CHKERRQ(err); err = VecDestroy(&t2_1); CHKERRQ(err); err = VecDestroy(&t2_2); CHKERRQ(err); err = VecDestroy(&t2_3); CHKERRQ(err);*/ // Finalize err = PetscFinalize(); CHKERRQ(err); return 0; }
/* MSA_InitialPoint - Calculates the initial guess in one of three ways. Input Parameters: . user - user-defined application context . X - vector for initial guess Output Parameters: . X - newly computed initial guess */ static PetscErrorCode MSA_InitialPoint(AppCtx * user, Vec X) { PetscErrorCode ierr; PetscInt start=-1,i,j; PetscReal zero=0.0; PetscBool flg; ierr = PetscOptionsGetInt(NULL,NULL,"-start",&start,&flg);CHKERRQ(ierr); if (flg && start==0){ /* The zero vector is reasonable */ ierr = VecSet(X, zero);CHKERRQ(ierr); } else if (flg && start>0){ /* Try a random start between -0.5 and 0.5 */ PetscRandom rctx; PetscReal np5=-0.5; ierr = PetscRandomCreate(MPI_COMM_WORLD,&rctx);CHKERRQ(ierr); for (i=0; i<start; i++){ ierr = VecSetRandom(X, rctx);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = VecShift(X, np5); } else { /* Take an average of the boundary conditions */ PetscInt row,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscInt mx=user->mx,my=user->my; PetscReal *x,*left,*right,*bottom,*top; Vec localX = user->localX; /* Get local mesh boundaries */ ierr = DMDAGetCorners(user->dm,&xs,&ys,NULL,&xm,&ym,NULL);CHKERRQ(ierr); ierr = DMDAGetGhostCorners(user->dm,&gxs,&gys,NULL,&gxm,&gym,NULL);CHKERRQ(ierr); /* Get pointers to vector data */ ierr = VecGetArray(user->Top,&top);CHKERRQ(ierr); ierr = VecGetArray(user->Bottom,&bottom);CHKERRQ(ierr); ierr = VecGetArray(user->Left,&left);CHKERRQ(ierr); ierr = VecGetArray(user->Right,&right);CHKERRQ(ierr); ierr = VecGetArray(localX,&x);CHKERRQ(ierr); /* Perform local computations */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ row=(j-gys)*gxm + (i-gxs); x[row] = ( (j+1)*bottom[i-xs+1]/my + (my-j+1)*top[i-xs+1]/(my+2)+ (i+1)*left[j-ys+1]/mx + (mx-i+1)*right[j-ys+1]/(mx+2))/2.0; } } /* Restore vectors */ ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); ierr = VecRestoreArray(user->Left,&left);CHKERRQ(ierr); ierr = VecRestoreArray(user->Top,&top);CHKERRQ(ierr); ierr = VecRestoreArray(user->Bottom,&bottom);CHKERRQ(ierr); ierr = VecRestoreArray(user->Right,&right);CHKERRQ(ierr); /* Scatter values into global vector */ ierr = DMLocalToGlobalBegin(user->dm,localX,INSERT_VALUES,X);CHKERRQ(ierr); ierr = DMLocalToGlobalEnd(user->dm,localX,INSERT_VALUES,X);CHKERRQ(ierr); } return 0; }
static PetscErrorCode TaoSolve_IPM(Tao tao) { PetscErrorCode ierr; TAO_IPM *ipmP = (TAO_IPM*)tao->data; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; PetscInt its,i; PetscScalar stepsize=1.0; PetscScalar step_s,step_l,alpha,tau,sigma,phi_target; PetscFunctionBegin; /* Push initial point away from bounds */ ierr = IPMInitializeBounds(tao);CHKERRQ(ierr); ierr = IPMPushInitialPoint(tao);CHKERRQ(ierr); ierr = VecCopy(tao->solution,ipmP->rhs_x);CHKERRQ(ierr); ierr = IPMEvaluate(tao);CHKERRQ(ierr); ierr = IPMComputeKKT(tao);CHKERRQ(ierr); ierr = TaoMonitor(tao,tao->niter++,ipmP->kkt_f,ipmP->phi,0.0,1.0,&reason);CHKERRQ(ierr); while (reason == TAO_CONTINUE_ITERATING) { tao->ksp_its=0; ierr = IPMUpdateK(tao);CHKERRQ(ierr); /* rhs.x = -rd rhs.lame = -rpe rhs.lami = -rpi rhs.com = -com */ ierr = VecCopy(ipmP->rd,ipmP->rhs_x);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->rpe,ipmP->rhs_lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->rpi,ipmP->rhs_lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); } ierr = IPMGatherRHS(tao,ipmP->bigrhs,ipmP->rhs_x,ipmP->rhs_lamdae,ipmP->rhs_lamdai,ipmP->rhs_s);CHKERRQ(ierr); ierr = VecScale(ipmP->bigrhs,-1.0);CHKERRQ(ierr); /* solve K * step = rhs */ ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its += its; tao->ksp_tot_its+=its; /* Find distance along step direction to closest bound */ if (ipmP->nb > 0) { ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); alpha = PetscMin(step_s,step_l); alpha = PetscMin(alpha,1.0); ipmP->alpha1 = alpha; } else { ipmP->alpha1 = alpha = 1.0; } /* x_aff = x + alpha*d */ ierr = VecCopy(tao->solution,ipmP->save_x);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->lamdae,ipmP->save_lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->lamdai,ipmP->save_lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->s,ipmP->save_s);CHKERRQ(ierr); } ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); } /* Recompute kkt to find centering parameter sigma = (new_mu/old_mu)^3 */ if (ipmP->mu == 0.0) { sigma = 0.0; } else { sigma = 1.0/ipmP->mu; } ierr = IPMComputeKKT(tao);CHKERRQ(ierr); sigma *= ipmP->mu; sigma*=sigma*sigma; /* revert kkt info */ ierr = VecCopy(ipmP->save_x,tao->solution);CHKERRQ(ierr); if (ipmP->me > 0) { ierr = VecCopy(ipmP->save_lamdae,ipmP->lamdae);CHKERRQ(ierr); } if (ipmP->nb > 0) { ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); } ierr = IPMComputeKKT(tao);CHKERRQ(ierr); /* update rhs with new complementarity vector */ if (ipmP->nb > 0) { ierr = VecCopy(ipmP->complementarity,ipmP->rhs_s);CHKERRQ(ierr); ierr = VecScale(ipmP->rhs_s,-1.0);CHKERRQ(ierr); ierr = VecShift(ipmP->rhs_s,sigma*ipmP->mu);CHKERRQ(ierr); } ierr = IPMGatherRHS(tao,ipmP->bigrhs,NULL,NULL,NULL,ipmP->rhs_s);CHKERRQ(ierr); /* solve K * step = rhs */ ierr = KSPSetOperators(tao->ksp,ipmP->K,ipmP->K);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,ipmP->bigrhs,ipmP->bigstep);CHKERRQ(ierr); ierr = IPMScatterStep(tao,ipmP->bigstep,tao->stepdirection,ipmP->ds,ipmP->dlamdae,ipmP->dlamdai);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its += its; tao->ksp_tot_its+=its; if (ipmP->nb > 0) { /* Get max step size and apply frac-to-boundary */ tau = PetscMax(ipmP->taumin,1.0-ipmP->mu); tau = PetscMin(tau,1.0); if (tau != 1.0) { ierr = VecScale(ipmP->s,tau);CHKERRQ(ierr); ierr = VecScale(ipmP->lamdai,tau);CHKERRQ(ierr); } ierr = VecStepBoundInfo(ipmP->s,ipmP->ds,ipmP->Zero_nb,ipmP->Inf_nb,&step_s,NULL,NULL);CHKERRQ(ierr); ierr = VecStepBoundInfo(ipmP->lamdai,ipmP->dlamdai,ipmP->Zero_nb,ipmP->Inf_nb,&step_l,NULL,NULL);CHKERRQ(ierr); if (tau != 1.0) { ierr = VecCopy(ipmP->save_s,ipmP->s);CHKERRQ(ierr); ierr = VecCopy(ipmP->save_lamdai,ipmP->lamdai);CHKERRQ(ierr); } alpha = PetscMin(step_s,step_l); alpha = PetscMin(alpha,1.0); } else { alpha = 1.0; } ipmP->alpha2 = alpha; /* TODO make phi_target meaningful */ phi_target = ipmP->dec * ipmP->phi; for (i=0; i<11;i++) { ierr = VecAXPY(tao->solution,alpha,tao->stepdirection);CHKERRQ(ierr); if (ipmP->nb > 0) { ierr = VecAXPY(ipmP->s,alpha,ipmP->ds);CHKERRQ(ierr); ierr = VecAXPY(ipmP->lamdai,alpha,ipmP->dlamdai);CHKERRQ(ierr); } if (ipmP->me > 0) { ierr = VecAXPY(ipmP->lamdae,alpha,ipmP->dlamdae);CHKERRQ(ierr); } /* update dual variables */ if (ipmP->me > 0) { ierr = VecCopy(ipmP->lamdae,tao->DE);CHKERRQ(ierr); } ierr = IPMEvaluate(tao);CHKERRQ(ierr); ierr = IPMComputeKKT(tao);CHKERRQ(ierr); if (ipmP->phi <= phi_target) break; alpha /= 2.0; } ierr = TaoMonitor(tao,tao->niter,ipmP->kkt_f,ipmP->phi,0.0,stepsize,&reason);CHKERRQ(ierr); tao->niter++; } PetscFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; DomainData dd; PetscReal norm,maxeig,mineig; PetscScalar scalar_value; PetscInt ndofs,its; Mat A =0,F=0; KSP KSPwithBDDC =0,KSPwithFETIDP=0; Vec fetidp_solution_all=0,bddc_solution=0,bddc_rhs=0; Vec exact_solution =0,fetidp_solution=0,fetidp_rhs=0; /* Init PETSc */ ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; /* Initialize DomainData */ ierr = InitializeDomainData(&dd);CHKERRQ(ierr); /* Decompose domain */ ierr = DomainDecomposition(&dd);CHKERRQ(ierr); #if DEBUG printf("Subdomain data\n"); printf("IPS : %d %d %d\n",dd.ipx,dd.ipy,dd.ipz); printf("NEG : %d %d %d\n",dd.nex,dd.ney,dd.nez); printf("NEL : %d %d %d\n",dd.nex_l,dd.ney_l,dd.nez_l); printf("LDO : %d %d %d\n",dd.xm_l,dd.ym_l,dd.zm_l); printf("SIZES : %d %d %d\n",dd.xm,dd.ym,dd.zm); printf("STARTS: %d %d %d\n",dd.startx,dd.starty,dd.startz); #endif /* assemble global matrix */ ierr = ComputeMatrix(dd,&A);CHKERRQ(ierr); /* get work vectors */ ierr = MatCreateVecs(A,&bddc_solution,NULL);CHKERRQ(ierr); ierr = VecDuplicate(bddc_solution,&bddc_rhs);CHKERRQ(ierr); ierr = VecDuplicate(bddc_solution,&fetidp_solution_all);CHKERRQ(ierr); ierr = VecDuplicate(bddc_solution,&exact_solution);CHKERRQ(ierr); /* create and customize KSP/PC for BDDC */ ierr = ComputeKSPBDDC(dd,A,&KSPwithBDDC);CHKERRQ(ierr); /* create KSP/PC for FETIDP */ ierr = ComputeKSPFETIDP(dd,KSPwithBDDC,&KSPwithFETIDP);CHKERRQ(ierr); /* create random exact solution */ ierr = VecSetRandom(exact_solution,NULL);CHKERRQ(ierr); ierr = VecShift(exact_solution,-0.5);CHKERRQ(ierr); ierr = VecScale(exact_solution,100.0);CHKERRQ(ierr); ierr = VecGetSize(exact_solution,&ndofs);CHKERRQ(ierr); if (dd.pure_neumann) { ierr = VecSum(exact_solution,&scalar_value);CHKERRQ(ierr); scalar_value = -scalar_value/(PetscScalar)ndofs; ierr = VecShift(exact_solution,scalar_value);CHKERRQ(ierr); } /* assemble BDDC rhs */ ierr = MatMult(A,exact_solution,bddc_rhs);CHKERRQ(ierr); /* test ksp with BDDC */ ierr = KSPSolve(KSPwithBDDC,bddc_rhs,bddc_solution);CHKERRQ(ierr); ierr = KSPGetIterationNumber(KSPwithBDDC,&its);CHKERRQ(ierr); ierr = KSPComputeExtremeSingularValues(KSPwithBDDC,&maxeig,&mineig);CHKERRQ(ierr); if (dd.pure_neumann) { ierr = VecSum(bddc_solution,&scalar_value);CHKERRQ(ierr); scalar_value = -scalar_value/(PetscScalar)ndofs; ierr = VecShift(bddc_solution,scalar_value);CHKERRQ(ierr); } /* check exact_solution and BDDC solultion */ ierr = VecAXPY(bddc_solution,-1.0,exact_solution);CHKERRQ(ierr); ierr = VecNorm(bddc_solution,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"---------------------BDDC stats-------------------------------\n");CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Number of degrees of freedom : %8D \n",ndofs);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Number of iterations : %8D \n",its);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Eigenvalues preconditioned operator : %1.2e %1.2e\n",(double)mineig,(double)maxeig);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Error betweeen exact and computed solution : %1.2e\n",(double)norm);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"--------------------------------------------------------------\n");CHKERRQ(ierr); /* assemble fetidp rhs on the space of Lagrange multipliers */ ierr = KSPGetOperators(KSPwithFETIDP,&F,NULL);CHKERRQ(ierr); ierr = MatCreateVecs(F,&fetidp_solution,&fetidp_rhs);CHKERRQ(ierr); ierr = PCBDDCMatFETIDPGetRHS(F,bddc_rhs,fetidp_rhs);CHKERRQ(ierr); ierr = VecSet(fetidp_solution,0.0);CHKERRQ(ierr); /* test ksp with FETIDP */ ierr = KSPSolve(KSPwithFETIDP,fetidp_rhs,fetidp_solution);CHKERRQ(ierr); ierr = KSPGetIterationNumber(KSPwithFETIDP,&its);CHKERRQ(ierr); ierr = KSPComputeExtremeSingularValues(KSPwithFETIDP,&maxeig,&mineig);CHKERRQ(ierr); /* assemble fetidp solution on physical domain */ ierr = PCBDDCMatFETIDPGetSolution(F,fetidp_solution,fetidp_solution_all);CHKERRQ(ierr); /* check FETIDP sol */ if (dd.pure_neumann) { ierr = VecSum(fetidp_solution_all,&scalar_value);CHKERRQ(ierr); scalar_value = -scalar_value/(PetscScalar)ndofs; ierr = VecShift(fetidp_solution_all,scalar_value);CHKERRQ(ierr); } ierr = VecAXPY(fetidp_solution_all,-1.0,exact_solution);CHKERRQ(ierr); ierr = VecNorm(fetidp_solution_all,NORM_INFINITY,&norm);CHKERRQ(ierr); ierr = VecGetSize(fetidp_solution,&ndofs);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"------------------FETI-DP stats-------------------------------\n");CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Number of degrees of freedom : %8D \n",ndofs);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Number of iterations : %8D \n",its);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Eigenvalues preconditioned operator : %1.2e %1.2e\n",(double)mineig,(double)maxeig);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"Error betweeen exact and computed solution : %1.2e\n",(double)norm);CHKERRQ(ierr); ierr = PetscPrintf(dd.gcomm,"--------------------------------------------------------------\n");CHKERRQ(ierr); /* Free workspace */ ierr = VecDestroy(&exact_solution);CHKERRQ(ierr); ierr = VecDestroy(&bddc_solution);CHKERRQ(ierr); ierr = VecDestroy(&fetidp_solution);CHKERRQ(ierr); ierr = VecDestroy(&fetidp_solution_all);CHKERRQ(ierr); ierr = VecDestroy(&bddc_rhs);CHKERRQ(ierr); ierr = VecDestroy(&fetidp_rhs);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = KSPDestroy(&KSPwithBDDC);CHKERRQ(ierr); ierr = KSPDestroy(&KSPwithFETIDP);CHKERRQ(ierr); /* Quit PETSc */ ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Vec x,b,u; /* approx solution, RHS, exact solution */ Mat A; /* linear system matrix */ KSP ksp; /* KSP context */ PetscErrorCode ierr; PetscInt i,n = 10,col[3],its,i1,i2; PetscScalar none = -1.0,value[3],avalue; PetscReal norm; PC pc; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); /* Create vectors */ ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr); ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&u);CHKERRQ(ierr); /* create a solution that is orthogonal to the constants */ ierr = VecGetOwnershipRange(u,&i1,&i2);CHKERRQ(ierr); for (i=i1; i<i2; i++) { avalue = i; VecSetValues(u,1,&i,&avalue,INSERT_VALUES); } ierr = VecAssemblyBegin(u);CHKERRQ(ierr); ierr = VecAssemblyEnd(u);CHKERRQ(ierr); ierr = VecSum(u,&avalue);CHKERRQ(ierr); avalue = -avalue/(PetscReal)n; ierr = VecShift(u,avalue);CHKERRQ(ierr); /* Create and assemble matrix */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; value[1] = 1.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 1.0; value[1] = -1.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatMult(A,u,b);CHKERRQ(ierr); /* Create KSP context; set operators and options; solve linear system */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); /* Insure that preconditioner has same null space as matrix */ /* currently does not do anything */ ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* ierr = KSPView(ksp,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); */ /* Check error */ ierr = VecAXPY(x,none,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g, Iterations %D\n",(double)norm,its);CHKERRQ(ierr); /* Free work space */ ierr = VecDestroy(&x);CHKERRQ(ierr);ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr);ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
static PetscErrorCode TaoSolve_BQPIP(Tao tao) { TAO_BQPIP *qp = (TAO_BQPIP*)tao->data; PetscErrorCode ierr; PetscInt iter=0,its; PetscReal d1,d2,ksptol,sigma; PetscReal sigmamu; PetscReal dstep,pstep,step=0; PetscReal gap[4]; TaoConvergedReason reason; PetscFunctionBegin; qp->dobj = 0.0; qp->pobj = 1.0; qp->gap = 10.0; qp->rgap = 1.0; qp->mu = 1.0; qp->sigma = 1.0; qp->dinfeas = 1.0; qp->psteplength = 0.0; qp->dsteplength = 0.0; /* Tighten infinite bounds, things break when we don't do this -- see test_bqpip.c */ ierr = VecSet(qp->XU,1.0e20);CHKERRQ(ierr); ierr = VecSet(qp->XL,-1.0e20);CHKERRQ(ierr); ierr = VecPointwiseMax(qp->XL,qp->XL,tao->XL);CHKERRQ(ierr); ierr = VecPointwiseMin(qp->XU,qp->XU,tao->XU);CHKERRQ(ierr); ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&qp->c,qp->C0);CHKERRQ(ierr); ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); ierr = MatMult(tao->hessian, tao->solution, qp->Work);CHKERRQ(ierr); ierr = VecDot(tao->solution, qp->Work, &d1);CHKERRQ(ierr); ierr = VecAXPY(qp->C0, -1.0, qp->Work);CHKERRQ(ierr); ierr = VecDot(qp->C0, tao->solution, &d2);CHKERRQ(ierr); qp->c -= (d1/2.0+d2); ierr = MatGetDiagonal(tao->hessian, qp->HDiag);CHKERRQ(ierr); ierr = QPIPSetInitialPoint(qp,tao);CHKERRQ(ierr); ierr = QPIPComputeResidual(qp,tao);CHKERRQ(ierr); /* Enter main loop */ while (1){ /* Check Stopping Condition */ ierr = TaoMonitor(tao,iter++,qp->pobj,PetscSqrtScalar(qp->gap + qp->dinfeas), qp->pinfeas, step, &reason);CHKERRQ(ierr); if (reason != TAO_CONTINUE_ITERATING) break; /* Dual Infeasibility Direction should already be in the right hand side from computing the residuals */ ierr = QPIPComputeNormFromCentralPath(qp,&d1);CHKERRQ(ierr); if (iter > 0 && (qp->rnorm>5*qp->mu || d1*d1>qp->m*qp->mu*qp->mu) ) { sigma=1.0;sigmamu=qp->mu; sigma=0.0;sigmamu=0; } else { sigma=0.0;sigmamu=0; } ierr = VecSet(qp->DZ, sigmamu);CHKERRQ(ierr); ierr = VecSet(qp->DS, sigmamu);CHKERRQ(ierr); if (sigmamu !=0){ ierr = VecPointwiseDivide(qp->DZ, qp->DZ, qp->G);CHKERRQ(ierr); ierr = VecPointwiseDivide(qp->DS, qp->DS, qp->T);CHKERRQ(ierr); ierr = VecCopy(qp->DZ,qp->RHS2);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, 1.0, qp->DS);CHKERRQ(ierr); } else { ierr = VecZeroEntries(qp->RHS2);CHKERRQ(ierr); } /* Compute the Primal Infeasiblitiy RHS and the Diagonal Matrix to be added to H and store in Work */ ierr = VecPointwiseDivide(qp->DiagAxpy, qp->Z, qp->G);CHKERRQ(ierr); ierr = VecPointwiseMult(qp->GZwork, qp->DiagAxpy, qp->R3);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS, -1.0, qp->GZwork);CHKERRQ(ierr); ierr = VecPointwiseDivide(qp->TSwork, qp->S, qp->T);CHKERRQ(ierr); ierr = VecAXPY(qp->DiagAxpy, 1.0, qp->TSwork);CHKERRQ(ierr); ierr = VecPointwiseMult(qp->TSwork, qp->TSwork, qp->R5);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS, -1.0, qp->TSwork);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, 1.0, qp->RHS);CHKERRQ(ierr); /* Determine the solving tolerance */ ksptol = qp->mu/10.0; ksptol = PetscMin(ksptol,0.001); ierr = MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = KSPSetOperators(tao->ksp, tao->hessian, tao->hessian_pre);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp, qp->RHS, tao->stepdirection);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its+=its; ierr = VecScale(qp->DiagAxpy, -1.0);CHKERRQ(ierr); ierr = MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecScale(qp->DiagAxpy, -1.0);CHKERRQ(ierr); ierr = QPComputeStepDirection(qp,tao);CHKERRQ(ierr); ierr = QPStepLength(qp); CHKERRQ(ierr); /* Calculate New Residual R1 in Work vector */ ierr = MatMult(tao->hessian, tao->stepdirection, qp->RHS2);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, 1.0, qp->DS);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, -1.0, qp->DZ);CHKERRQ(ierr); ierr = VecAYPX(qp->RHS2, qp->dsteplength, tao->gradient);CHKERRQ(ierr); ierr = VecNorm(qp->RHS2, NORM_2, &qp->dinfeas);CHKERRQ(ierr); ierr = VecDot(qp->DZ, qp->DG, gap);CHKERRQ(ierr); ierr = VecDot(qp->DS, qp->DT, gap+1);CHKERRQ(ierr); qp->rnorm=(qp->dinfeas+qp->psteplength*qp->pinfeas)/(qp->m+qp->n); pstep = qp->psteplength; dstep = qp->dsteplength; step = PetscMin(qp->psteplength,qp->dsteplength); sigmamu= ( pstep*pstep*(gap[0]+gap[1]) + (1 - pstep + pstep*sigma)*qp->gap )/qp->m; if (qp->predcorr && step < 0.9){ if (sigmamu < qp->mu){ sigmamu=sigmamu/qp->mu; sigmamu=sigmamu*sigmamu*sigmamu; } else {sigmamu = 1.0;} sigmamu = sigmamu*qp->mu; /* Compute Corrector Step */ ierr = VecPointwiseMult(qp->DZ, qp->DG, qp->DZ);CHKERRQ(ierr); ierr = VecScale(qp->DZ, -1.0);CHKERRQ(ierr); ierr = VecShift(qp->DZ, sigmamu);CHKERRQ(ierr); ierr = VecPointwiseDivide(qp->DZ, qp->DZ, qp->G);CHKERRQ(ierr); ierr = VecPointwiseMult(qp->DS, qp->DS, qp->DT);CHKERRQ(ierr); ierr = VecScale(qp->DS, -1.0);CHKERRQ(ierr); ierr = VecShift(qp->DS, sigmamu);CHKERRQ(ierr); ierr = VecPointwiseDivide(qp->DS, qp->DS, qp->T);CHKERRQ(ierr); ierr = VecCopy(qp->DZ, qp->RHS2);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, -1.0, qp->DS);CHKERRQ(ierr); ierr = VecAXPY(qp->RHS2, 1.0, qp->RHS);CHKERRQ(ierr); /* Approximately solve the linear system */ ierr = MatDiagonalSet(tao->hessian, qp->DiagAxpy, ADD_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp, qp->RHS2, tao->stepdirection);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its+=its; ierr = MatDiagonalSet(tao->hessian, qp->HDiag, INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(tao->hessian,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = QPComputeStepDirection(qp,tao);CHKERRQ(ierr); ierr = QPStepLength(qp);CHKERRQ(ierr); } /* End Corrector step */ /* Take the step */ pstep = qp->psteplength; dstep = qp->dsteplength; ierr = VecAXPY(qp->Z, dstep, qp->DZ);CHKERRQ(ierr); ierr = VecAXPY(qp->S, dstep, qp->DS);CHKERRQ(ierr); ierr = VecAXPY(tao->solution, dstep, tao->stepdirection);CHKERRQ(ierr); ierr = VecAXPY(qp->G, dstep, qp->DG);CHKERRQ(ierr); ierr = VecAXPY(qp->T, dstep, qp->DT);CHKERRQ(ierr); /* Compute Residuals */ ierr = QPIPComputeResidual(qp,tao);CHKERRQ(ierr); /* Evaluate quadratic function */ ierr = MatMult(tao->hessian, tao->solution, qp->Work);CHKERRQ(ierr); ierr = VecDot(tao->solution, qp->Work, &d1);CHKERRQ(ierr); ierr = VecDot(tao->solution, qp->C0, &d2);CHKERRQ(ierr); ierr = VecDot(qp->G, qp->Z, gap);CHKERRQ(ierr); ierr = VecDot(qp->T, qp->S, gap+1);CHKERRQ(ierr); qp->pobj=d1/2.0 + d2+qp->c; /* Compute the duality gap */ qp->gap = (gap[0]+gap[1]); qp->dobj = qp->pobj - qp->gap; if (qp->m>0) qp->mu=qp->gap/(qp->m); qp->rgap=qp->gap/( PetscAbsReal(qp->dobj) + PetscAbsReal(qp->pobj) + 1.0 ); } /* END MAIN LOOP */ PetscFunctionReturn(0); }
Geometry CreateGeometry(int N[3], double h[3], int Npml[3], int Nc, int LowerPML, double *eps, double *epsI, double *fprof, double wa, double y){ int i; Geometry geo = (Geometry) malloc(sizeof(struct Geometry_s)); geo->Nc = Nc; geo->LowerPML = LowerPML; geo->interference = 0.0; // default no interference for(i=0; i<3; i++){ geo->h[i] = h[i]; geo->Npml[i] = Npml[i]; } CreateGrid(&geo->gN, N, geo->Nc, 2); CreateGrid(&geo->gM, N, 1, 1); // 3/3/14: set M = N as per Steven CreateVec(2*Nxyzc(geo)+2, &geo->vepspml); int manual_epspml = 0; PetscOptionsGetInt(PETSC_NULL,PETSC_NULL,"-manual_epspml", &manual_epspml, NULL); if(manual_epspml == 0){ Vecfun pml; CreateVecfun(&pml,geo->vepspml); for(i=pml.ns; i<pml.ne; i++){ Point p; CreatePoint_i(&p, i, &geo->gN); project(&p, 3); dcomp eps_geoal; eps_geoal = pmlval(xyzc(&p), N, geo->Npml, geo->h, geo->LowerPML, 0); setr(&pml, i, p.ir? cimag(eps_geoal) : creal(eps_geoal) ); } DestroyVecfun(&pml); } CreateVec(Mxyz(geo), &geo->vMscratch[0]); for(i=0; i<SCRATCHNUM; i++){ geo->vNhscratch[i] = 0; // allows checking whether vN created or not if(i>0)VecDuplicate(geo->vMscratch[0], &geo->vMscratch[i]); } double *scratch; int ms, me; VecGetOwnershipRange(geo->vMscratch[0], &ms, &me); if( !manual_epspml){ VecGetArray(geo->vMscratch[0], &scratch); for(i=ms; i<me;i++) scratch[i-ms] = eps[i-ms]; VecRestoreArray(geo->vMscratch[0], &scratch); } CreateVec(2*Nxyzc(geo)+2, &geo->vH); VecDuplicate(geo->vH, &geo->veps); VecDuplicate(geo->vH, &geo->vIeps); for(i=0; i<SCRATCHNUM; i++) VecDuplicate(geo->vH, &geo->vscratch[i]); VecSet(geo->vH, 1.0); if( !manual_epspml){ VecShift(geo->vMscratch[0], -1.0); //hack, for background dielectric InterpolateVec(geo, geo->vMscratch[0], geo->vscratch[1]); VecShift(geo->vscratch[1], 1.0); VecPointwiseMult(geo->veps, geo->vscratch[1], geo->vepspml); if(epsI != NULL){ // imaginary part of passive dielectric VecGetArray(geo->vMscratch[0], &scratch); for(i=ms; i<me; i++){ scratch[i-ms] = epsI[i-ms]; } VecRestoreArray(geo->vMscratch[0], &scratch); InterpolateVec(geo, geo->vMscratch[0], geo->vscratch[1]); VecPointwiseMult(geo->vscratch[1], geo->vscratch[1], geo->vepspml); TimesI(geo, geo->vscratch[1], geo->vscratch[2]); VecAXPY(geo->veps, 1.0, geo->vscratch[2]); } } if(manual_epspml){ char epsManualfile[PETSC_MAX_PATH_LEN]; PetscOptionsGetString(PETSC_NULL,PETSC_NULL,"-epsManualfile", epsManualfile, PETSC_MAX_PATH_LEN, NULL); FILE *fp = fopen(epsManualfile, "r"); ReadVectorC(fp, 2*Nxyzc(geo)+2, geo->veps); // 07/11/15: if manual_epspml, then directly read in the Nxyzcr+2 vector fclose(fp); } TimesI(geo, geo->veps, geo->vIeps); // vIeps for convenience only, make sure to update it later if eps ever changes! geo->D = 0.0; geo->wa = wa; geo->y = y; VecDuplicate(geo->veps, &geo->vf); VecDuplicate(geo->vMscratch[0], &geo->vfM); VecGetArray(geo->vfM, &scratch); for(i=ms; i<me;i++) scratch[i-ms] = fprof[i-ms]; VecRestoreArray(geo->vfM, &scratch); InterpolateVec(geo, geo->vfM, geo->vf); return geo; }
extern PetscErrorCode MatLMVMUpdate(Mat M, Vec x, Vec g) { MatLMVMCtx *ctx; PetscReal rhotemp, rhotol; PetscReal y0temp, s0temp; PetscReal yDy, yDs, sDs; PetscReal sigmanew, denom; PetscErrorCode ierr; PetscInt i; PetscBool same; PetscReal yy_sum=0.0, ys_sum=0.0, ss_sum=0.0; PetscFunctionBegin; PetscValidHeaderSpecific(x,VEC_CLASSID,2); PetscValidHeaderSpecific(g,VEC_CLASSID,3); ierr = PetscObjectTypeCompare((PetscObject)M,MATSHELL,&same);CHKERRQ(ierr); if (!same) SETERRQ(PETSC_COMM_SELF,1,"Matrix M is not type MatLMVM"); ierr = MatShellGetContext(M,(void**)&ctx);CHKERRQ(ierr); if (!ctx->allocated) { ierr = MatLMVMAllocateVectors(M, x); CHKERRQ(ierr); } if (0 == ctx->iter) { ierr = MatLMVMReset(M);CHKERRQ(ierr); } else { ierr = VecAYPX(ctx->Gprev,-1.0,g);CHKERRQ(ierr); ierr = VecAYPX(ctx->Xprev,-1.0,x);CHKERRQ(ierr); ierr = VecDot(ctx->Gprev,ctx->Xprev,&rhotemp);CHKERRQ(ierr); ierr = VecDot(ctx->Gprev,ctx->Gprev,&y0temp);CHKERRQ(ierr); rhotol = ctx->eps * y0temp; if (rhotemp > rhotol) { ++ctx->nupdates; ctx->lmnow = PetscMin(ctx->lmnow+1, ctx->lm); ierr=PetscObjectDereference((PetscObject)ctx->S[ctx->lm]);CHKERRQ(ierr); ierr=PetscObjectDereference((PetscObject)ctx->Y[ctx->lm]);CHKERRQ(ierr); for (i = ctx->lm-1; i >= 0; --i) { ctx->S[i+1] = ctx->S[i]; ctx->Y[i+1] = ctx->Y[i]; ctx->rho[i+1] = ctx->rho[i]; } ctx->S[0] = ctx->Xprev; ctx->Y[0] = ctx->Gprev; PetscObjectReference((PetscObject)ctx->S[0]); PetscObjectReference((PetscObject)ctx->Y[0]); ctx->rho[0] = 1.0 / rhotemp; /* Compute the scaling */ switch(ctx->scaleType) { case MatLMVM_Scale_None: break; case MatLMVM_Scale_Scalar: /* Compute s^T s */ ierr = VecDot(ctx->Xprev,ctx->Xprev,&s0temp);CHKERRQ(ierr); /* Scalar is positive; safeguards are not required. */ /* Save information for scalar scaling */ ctx->yy_history[(ctx->nupdates - 1) % ctx->scalar_history] = y0temp; ctx->ys_history[(ctx->nupdates - 1) % ctx->scalar_history] = rhotemp; ctx->ss_history[(ctx->nupdates - 1) % ctx->scalar_history] = s0temp; /* Compute summations for scalar scaling */ yy_sum = 0; /* No safeguard required; y^T y > 0 */ ys_sum = 0; /* No safeguard required; y^T s > 0 */ ss_sum = 0; /* No safeguard required; s^T s > 0 */ for (i = 0; i < PetscMin(ctx->nupdates, ctx->scalar_history); ++i) { yy_sum += ctx->yy_history[i]; ys_sum += ctx->ys_history[i]; ss_sum += ctx->ss_history[i]; } if (0.0 == ctx->s_alpha) { /* Safeguard ys_sum */ if (0.0 == ys_sum) { ys_sum = TAO_ZERO_SAFEGUARD; } sigmanew = ss_sum / ys_sum; } else if (1.0 == ctx->s_alpha) { /* Safeguard yy_sum */ if (0.0 == yy_sum) { yy_sum = TAO_ZERO_SAFEGUARD; } sigmanew = ys_sum / yy_sum; } else { denom = 2*ctx->s_alpha*yy_sum; /* Safeguard denom */ if (0.0 == denom) { denom = TAO_ZERO_SAFEGUARD; } sigmanew = ((2*ctx->s_alpha-1)*ys_sum + PetscSqrtScalar((2*ctx->s_alpha-1)*(2*ctx->s_alpha-1)*ys_sum*ys_sum - 4*(ctx->s_alpha)*(ctx->s_alpha-1)*yy_sum*ss_sum)) / denom; } switch(ctx->limitType) { case MatLMVM_Limit_Average: if (1.0 == ctx->mu) { ctx->sigma = sigmanew; } else if (ctx->mu) { ctx->sigma = ctx->mu * sigmanew + (1.0 - ctx->mu) * ctx->sigma; } break; case MatLMVM_Limit_Relative: if (ctx->mu) { ctx->sigma = TaoMid((1.0 - ctx->mu) * ctx->sigma, sigmanew, (1.0 + ctx->mu) * ctx->sigma); } break; case MatLMVM_Limit_Absolute: if (ctx->nu) { ctx->sigma = TaoMid(ctx->sigma - ctx->nu, sigmanew, ctx->sigma + ctx->nu); } break; default: ctx->sigma = sigmanew; break; } break; case MatLMVM_Scale_Broyden: /* Original version */ /* Combine DFP and BFGS */ /* This code appears to be numerically unstable. We use the */ /* original version because this was used to generate all of */ /* the data and because it may be the least unstable of the */ /* bunch. */ /* P = Q = inv(D); */ ierr = VecCopy(ctx->D,ctx->P);CHKERRQ(ierr); ierr = VecReciprocal(ctx->P);CHKERRQ(ierr); ierr = VecCopy(ctx->P,ctx->Q);CHKERRQ(ierr); /* V = y*y */ ierr = VecPointwiseMult(ctx->V,ctx->Gprev,ctx->Gprev);CHKERRQ(ierr); /* W = inv(D)*s */ ierr = VecPointwiseMult(ctx->W,ctx->Xprev,ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->W,ctx->Xprev,&sDs);CHKERRQ(ierr); /* Safeguard rhotemp and sDs */ if (0.0 == rhotemp) { rhotemp = TAO_ZERO_SAFEGUARD; } if (0.0 == sDs) { sDs = TAO_ZERO_SAFEGUARD; } if (1.0 != ctx->phi) { /* BFGS portion of the update */ /* U = (inv(D)*s)*(inv(D)*s) */ ierr = VecPointwiseMult(ctx->U,ctx->W,ctx->W);CHKERRQ(ierr); /* Assemble */ ierr = VecAXPY(ctx->P,1.0/rhotemp,ctx->V);CHKERRQ(ierr); ierr = VecAXPY(ctx->P,-1.0/sDs,ctx->U);CHKERRQ(ierr); } if (0.0 != ctx->phi) { /* DFP portion of the update */ /* U = inv(D)*s*y */ ierr = VecPointwiseMult(ctx->U, ctx->W, ctx->Gprev);CHKERRQ(ierr); /* Assemble */ ierr = VecAXPY(ctx->Q,1.0/rhotemp + sDs/(rhotemp*rhotemp), ctx->V);CHKERRQ(ierr); ierr = VecAXPY(ctx->Q,-2.0/rhotemp,ctx->U);CHKERRQ(ierr); } if (0.0 == ctx->phi) { ierr = VecCopy(ctx->P,ctx->U);CHKERRQ(ierr); } else if (1.0 == ctx->phi) { ierr = VecCopy(ctx->Q,ctx->U);CHKERRQ(ierr); } else { /* Broyden update U=(1-phi)*P + phi*Q */ ierr = VecCopy(ctx->Q,ctx->U);CHKERRQ(ierr); ierr = VecAXPBY(ctx->U,1.0-ctx->phi, ctx->phi, ctx->P);CHKERRQ(ierr); } /* Obtain inverse and ensure positive definite */ ierr = VecReciprocal(ctx->U);CHKERRQ(ierr); ierr = VecAbs(ctx->U);CHKERRQ(ierr); switch(ctx->rScaleType) { case MatLMVM_Rescale_None: break; case MatLMVM_Rescale_Scalar: case MatLMVM_Rescale_GL: if (ctx->rScaleType == MatLMVM_Rescale_GL) { /* Gilbert and Lemarachal use the old diagonal */ ierr = VecCopy(ctx->D,ctx->P);CHKERRQ(ierr); } else { /* The default version uses the current diagonal */ ierr = VecCopy(ctx->U,ctx->P);CHKERRQ(ierr); } /* Compute s^T s */ ierr = VecDot(ctx->Xprev,ctx->Xprev,&s0temp);CHKERRQ(ierr); /* Save information for special cases of scalar rescaling */ ctx->yy_rhistory[(ctx->nupdates - 1) % ctx->rescale_history] = y0temp; ctx->ys_rhistory[(ctx->nupdates - 1) % ctx->rescale_history] = rhotemp; ctx->ss_rhistory[(ctx->nupdates - 1) % ctx->rescale_history] = s0temp; if (0.5 == ctx->r_beta) { if (1 == PetscMin(ctx->nupdates, ctx->rescale_history)) { ierr = VecPointwiseMult(ctx->V,ctx->Y[0],ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->V,ctx->Y[0],&yy_sum);CHKERRQ(ierr); ierr = VecPointwiseDivide(ctx->W,ctx->S[0],ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->W,ctx->S[0],&ss_sum);CHKERRQ(ierr); ys_sum = ctx->ys_rhistory[0]; } else { ierr = VecCopy(ctx->P,ctx->Q);CHKERRQ(ierr); ierr = VecReciprocal(ctx->Q);CHKERRQ(ierr); /* Compute summations for scalar scaling */ yy_sum = 0; /* No safeguard required */ ys_sum = 0; /* No safeguard required */ ss_sum = 0; /* No safeguard required */ for (i = 0; i < PetscMin(ctx->nupdates, ctx->rescale_history); ++i) { ierr = VecPointwiseMult(ctx->V,ctx->Y[i],ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->V,ctx->Y[i],&yDy);CHKERRQ(ierr); yy_sum += yDy; ierr = VecPointwiseMult(ctx->W,ctx->S[i],ctx->Q);CHKERRQ(ierr); ierr = VecDot(ctx->W,ctx->S[i],&sDs);CHKERRQ(ierr); ss_sum += sDs; ys_sum += ctx->ys_rhistory[i]; } } } else if (0.0 == ctx->r_beta) { if (1 == PetscMin(ctx->nupdates, ctx->rescale_history)) { /* Compute summations for scalar scaling */ ierr = VecPointwiseDivide(ctx->W,ctx->S[0],ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->W, ctx->Y[0], &ys_sum);CHKERRQ(ierr); ierr = VecDot(ctx->W, ctx->W, &ss_sum);CHKERRQ(ierr); yy_sum += ctx->yy_rhistory[0]; } else { ierr = VecCopy(ctx->Q, ctx->P);CHKERRQ(ierr); ierr = VecReciprocal(ctx->Q);CHKERRQ(ierr); /* Compute summations for scalar scaling */ yy_sum = 0; /* No safeguard required */ ys_sum = 0; /* No safeguard required */ ss_sum = 0; /* No safeguard required */ for (i = 0; i < PetscMin(ctx->nupdates, ctx->rescale_history); ++i) { ierr = VecPointwiseMult(ctx->W, ctx->S[i], ctx->Q);CHKERRQ(ierr); ierr = VecDot(ctx->W, ctx->Y[i], &yDs);CHKERRQ(ierr); ys_sum += yDs; ierr = VecDot(ctx->W, ctx->W, &sDs);CHKERRQ(ierr); ss_sum += sDs; yy_sum += ctx->yy_rhistory[i]; } } } else if (1.0 == ctx->r_beta) { /* Compute summations for scalar scaling */ yy_sum = 0; /* No safeguard required */ ys_sum = 0; /* No safeguard required */ ss_sum = 0; /* No safeguard required */ for (i = 0; i < PetscMin(ctx->nupdates, ctx->rescale_history); ++i) { ierr = VecPointwiseMult(ctx->V, ctx->Y[i], ctx->P);CHKERRQ(ierr); ierr = VecDot(ctx->V, ctx->S[i], &yDs);CHKERRQ(ierr); ys_sum += yDs; ierr = VecDot(ctx->V, ctx->V, &yDy);CHKERRQ(ierr); yy_sum += yDy; ss_sum += ctx->ss_rhistory[i]; } } else { ierr = VecCopy(ctx->Q, ctx->P);CHKERRQ(ierr); ierr = VecPow(ctx->P, ctx->r_beta);CHKERRQ(ierr); ierr = VecPointwiseDivide(ctx->Q, ctx->P, ctx->Q);CHKERRQ(ierr); /* Compute summations for scalar scaling */ yy_sum = 0; /* No safeguard required */ ys_sum = 0; /* No safeguard required */ ss_sum = 0; /* No safeguard required */ for (i = 0; i < PetscMin(ctx->nupdates, ctx->rescale_history); ++i) { ierr = VecPointwiseMult(ctx->V, ctx->P, ctx->Y[i]);CHKERRQ(ierr); ierr = VecPointwiseMult(ctx->W, ctx->Q, ctx->S[i]);CHKERRQ(ierr); ierr = VecDot(ctx->V, ctx->V, &yDy);CHKERRQ(ierr); ierr = VecDot(ctx->V, ctx->W, &yDs);CHKERRQ(ierr); ierr = VecDot(ctx->W, ctx->W, &sDs);CHKERRQ(ierr); yy_sum += yDy; ys_sum += yDs; ss_sum += sDs; } } if (0.0 == ctx->r_alpha) { /* Safeguard ys_sum */ if (0.0 == ys_sum) { ys_sum = TAO_ZERO_SAFEGUARD; } sigmanew = ss_sum / ys_sum; } else if (1.0 == ctx->r_alpha) { /* Safeguard yy_sum */ if (0.0 == yy_sum) { ys_sum = TAO_ZERO_SAFEGUARD; } sigmanew = ys_sum / yy_sum; } else { denom = 2*ctx->r_alpha*yy_sum; /* Safeguard denom */ if (0.0 == denom) { denom = TAO_ZERO_SAFEGUARD; } sigmanew = ((2*ctx->r_alpha-1)*ys_sum + PetscSqrtScalar((2*ctx->r_alpha-1)*(2*ctx->r_alpha-1)*ys_sum*ys_sum - 4*ctx->r_alpha*(ctx->r_alpha-1)*yy_sum*ss_sum)) / denom; } /* If Q has small values, then Q^(r_beta - 1) */ /* can have very large values. Hence, ys_sum */ /* and ss_sum can be infinity. In this case, */ /* sigmanew can either be not-a-number or infinity. */ if (PetscIsInfOrNanReal(sigmanew)) { /* sigmanew is not-a-number; skip rescaling */ } else if (!sigmanew) { /* sigmanew is zero; this is a bad case; skip rescaling */ } else { /* sigmanew is positive */ ierr = VecScale(ctx->U, sigmanew);CHKERRQ(ierr); } break; } /* Modify for previous information */ switch(ctx->limitType) { case MatLMVM_Limit_Average: if (1.0 == ctx->mu) { ierr = VecCopy(ctx->D, ctx->U);CHKERRQ(ierr); } else if (ctx->mu) { ierr = VecAXPBY(ctx->D,ctx->mu, 1.0-ctx->mu,ctx->U);CHKERRQ(ierr); } break; case MatLMVM_Limit_Relative: if (ctx->mu) { /* P = (1-mu) * D */ ierr = VecAXPBY(ctx->P, 1.0-ctx->mu, 0.0, ctx->D);CHKERRQ(ierr); /* Q = (1+mu) * D */ ierr = VecAXPBY(ctx->Q, 1.0+ctx->mu, 0.0, ctx->D);CHKERRQ(ierr); ierr = VecMedian(ctx->P, ctx->U, ctx->Q, ctx->D);CHKERRQ(ierr); } break; case MatLMVM_Limit_Absolute: if (ctx->nu) { ierr = VecCopy(ctx->P, ctx->D);CHKERRQ(ierr); ierr = VecShift(ctx->P, -ctx->nu);CHKERRQ(ierr); ierr = VecCopy(ctx->D, ctx->Q);CHKERRQ(ierr); ierr = VecShift(ctx->Q, ctx->nu);CHKERRQ(ierr); ierr = VecMedian(ctx->P, ctx->U, ctx->Q, ctx->P);CHKERRQ(ierr); } break; default: ierr = VecCopy(ctx->U, ctx->D);CHKERRQ(ierr); break; } break; } ierr = PetscObjectDereference((PetscObject)ctx->Xprev);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)ctx->Gprev);CHKERRQ(ierr); ctx->Xprev = ctx->S[ctx->lm]; ctx->Gprev = ctx->Y[ctx->lm]; ierr = PetscObjectReference((PetscObject)ctx->S[ctx->lm]);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)ctx->Y[ctx->lm]);CHKERRQ(ierr); } else { ++ctx->nrejects; } } ++ctx->iter; ierr = VecCopy(x, ctx->Xprev);CHKERRQ(ierr); ierr = VecCopy(g, ctx->Gprev);CHKERRQ(ierr); PetscFunctionReturn(0); }