void CopyBoundary(State *BHD, Vec gfrom, Vec gto, real zpad) { PData PD; DA da; int x[3], n[3], i[3], ic[3], dim, k, N[3], border; PetscScalar ***gfrom_vec, ***gto_vec; PD = BHD->PD; da = BHD->da; FOR_DIM N[dim] = PD->N[dim]; VecSet(gto, 0.0); border = (int) ceil( ((PD->interval[1]-PD->interval[0])-(2.*zpad))/PD->h[0]/2. ); /* Get local portion of the grid */ DAGetCorners(da, &(x[0]), &(x[1]), &(x[2]), &(n[0]), &(n[1]), &(n[2])); DAVecGetArray(da, gfrom, &gfrom_vec); DAVecGetArray(da, gto, >o_vec); /* FOR_DIM */ /* { */ /* ic[0]=dim; */ /* ic[1]=(dim+1)%3; */ /* ic[2]=(dim+2)%3; */ /* i[ic[0]] = 0; */ /* if( x[ic[0]] == 0 ) */ /* for( i[ic[1]]=x[ic[1]]; i[ic[1]]<x[ic[1]]+n[ic[1]]; i[ic[1]]++) */ /* for( i[ic[2]]=x[ic[2]]; i[ic[2]]<x[ic[2]]+n[ic[2]]; i[ic[2]]++) */ /* gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]]; */ /* i[ic[0]] = N[ic[0]]-1; */ /* if( x[ic[0]]+n[ic[0]] == N[ic[0]] ) */ /* for( i[ic[1]]=x[ic[1]]; i[ic[1]]<x[ic[1]]+n[ic[1]]; i[ic[1]]++) */ /* for( i[ic[2]]=x[ic[2]]; i[ic[2]]<x[ic[2]]+n[ic[2]]; i[ic[2]]++) */ /* gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]]; */ /* } */ /* loop over local portion of grid */ for(i[2]=x[2]; i[2]<x[2]+n[2]; i[2]++) for(i[1]=x[1]; i[1]<x[1]+n[1]; i[1]++) for(i[0]=x[0]; i[0]<x[0]+n[0]; i[0]++) { if( ( i[0]<=border+1 || i[0]>=N[0]-1-border) || ( i[1]<=border+1 || i[1]>=N[1]-1-border) || ( i[2]<=border+1 || i[2]>=N[2]-1-border) ) gto_vec[i[2]][i[1]][i[0]] = gfrom_vec[i[2]][i[1]][i[0]]; } DAVecRestoreArray(da, gfrom, &gfrom_vec); DAVecRestoreArray(da, gto, >o_vec); }
/* 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; }
int main(int argc, char **args) { PetscErrorCode ierr; ierr = PetscInitialize(&argc, &args, (char *) 0, ""); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "Start %s\n", __FILE__); CHKERRQ(ierr); MPI_Comm comm = PETSC_COMM_WORLD; DA da; Mat mat; int MX = 100; int dof = 3; ierr = PetscPrintf(comm,"Started Assembly\n"); CHKERRQ(ierr); ierr = MatMake(MX,dof,&da, &mat); CHKERRQ(ierr); ierr = MatWrite("J",mat); CHKERRQ(ierr); ierr = PetscPrintf(comm,"Finished Assembly\n"); CHKERRQ(ierr); Vec rhs, sol; ierr = DACreateGlobalVector(da,&rhs); CHKERRQ(ierr); ierr = DACreateGlobalVector(da,&sol); CHKERRQ(ierr); int i,j; int xs,ys,xm,ym; Field **array; ierr = DAVecGetArray(da,rhs,&array); CHKERRQ(ierr); ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(ierr); for (j = xs; j < xm; ++j) { for (i = ys; i < ym; ++i) { if( 3*MX/4 > i && i > MX/4 && 3*MX/4 > j && j > MX/4 ) { array[j][i].u = 100.; array[j][i].v = 100.; } } } ierr = DAVecRestoreArray(da,rhs,&array); CHKERRQ(ierr); KSP ksp; ierr = KSPCreate(comm,&ksp); CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPPREONLY); CHKERRQ(ierr); ierr = KSPSetOperators(ksp,mat,mat,DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); //Split pressure from velocity PC pc; ierr = KSPGetPC(ksp,&pc); CHKERRQ(ierr); ierr = PCSetType(pc, PCFIELDSPLIT); CHKERRQ(ierr); ierr = PCFieldSplitSetType(pc,PC_COMPOSITE_SCHUR); CHKERRQ(ierr); ierr = PCFieldSplitSetBlockSize(pc,3); CHKERRQ(ierr); ierr = PCFieldSplitSetFields(pc,2,(int[]){0,1}); CHKERRQ(ierr);
PetscErrorCode ComputeFunction(SNES snes,Vec x,Vec f,void *ctx) { PetscInt i,Mx,xs,xm; PetscScalar *xx,*ff,hx; DA da = (DA) ctx; Vec xlocal; DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal); DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal); DAVecGetArray(da,xlocal,&xx); DAVecGetArray(da,f,&ff); DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL); for (i=xs; i<xs+xm; i++) { if (i == 0 || i == Mx-1) ff[i] = xx[i]/hx; else ff[i] = (2.0*xx[i] - xx[i-1] - xx[i+1])/hx - hx*PetscExpScalar(xx[i]); } DAVecRestoreArray(da,xlocal,&xx); DARestoreLocalVector(da,&xlocal);DAVecRestoreArray(da,f,&ff); return 0;}
PetscErrorCode FormFunction1(SNES snes,Vec X,Vec F,void *ptr) { AppCtx *user = (AppCtx*)ptr; PetscErrorCode ierr; PetscInt i,j,k,loc,mx,my,mz,xs,ys,zs,xm,ym,zm,Xs,Ys,Zs,Xm,Ym,Zm,base1,base2; PetscReal two = 2.0,one = 1.0,lambda,Hx,Hy,Hz,HxHzdHy,HyHzdHx,HxHydHz; PetscScalar u,uxx,uyy,sc,*x,*f,uzz; Vec localX = user->localX,localF = user->localF; mx = user->mx; my = user->my; mz = user->mz; lambda = user->param; Hx = one / (PetscReal)(mx-1); Hy = one / (PetscReal)(my-1); Hz = one / (PetscReal)(mz-1); sc = Hx*Hy*Hz*lambda; HxHzdHy = Hx*Hz/Hy; HyHzdHx = Hy*Hz/Hx; HxHydHz = Hx*Hy/Hz; ierr = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); ierr = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); ierr = VecGetArray(localX,&x);CHKERRQ(ierr); ierr = VecGetArray(localF,&f);CHKERRQ(ierr); ierr = DAGetCorners(user->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DAGetGhostCorners(user->da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { base1 = (Xm*Ym)*(k-Zs); for (j=ys; j<ys+ym; j++) { base2 = base1 + (j-Ys)*Xm; for (i=xs; i<xs+xm; i++) { loc = base2 + (i-Xs); if (i == 0 || j == 0 || k== 0 || i == mx-1 || j == my-1 || k == mz-1) { f[loc] = x[loc]; } else { u = x[loc]; uxx = (two*u - x[loc-1] - x[loc+1])*HyHzdHx; uyy = (two*u - x[loc-Xm] - x[loc+Xm])*HxHzdHy; uzz = (two*u - x[loc-Xm*Ym] - x[loc+Xm*Ym])*HxHydHz; f[loc] = uxx + uyy + uzz - sc*PetscExpScalar(u); } } } } ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); ierr = VecRestoreArray(localF,&f);CHKERRQ(ierr); /* stick values into global vector */ ierr = DALocalToGlobal(user->da,localF,INSERT_VALUES,F);CHKERRQ(ierr); ierr = PetscLogFlops(11.0*ym*xm*zm);CHKERRQ(ierr); return 0; }
/* FormInitialGuessLocal - Forms initial approximation for this process Input Parameters: user - user-defined application context X - vector (DA local vector) Output Parameter: X - vector with the local values set */ PetscErrorCode FormInitialGuessLocal(DMMG dmmg,Vec X) { AppCtx *user = (AppCtx*)dmmg->user; DA da = (DA)dmmg->dm; PetscInt i,j,mx,xs,ys,xm,ym; PetscErrorCode ierr; PetscReal grashof,dx; Field **x; grashof = user->grashof; ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dx = 1.0/(mx-1); /* Get local grid boundaries (for 2-dimensional DA): xs, ys - starting grid indices (no ghost points) xm, ym - widths of local grid (no ghost points) */ ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); /* Get a pointer to vector data. - For default PETSc vectors, VecGetArray() returns a pointer to the data array. Otherwise, the routine is implementation dependent. - You MUST call VecResetArraystoreArray() when you no longer need access to the array. */ ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr); /* Compute initial guess over the locally owned part of the grid Initial condition is motionless fluid and equilibrium temperature U = V = Omega = 0.0; Temp[x_i, y_j] = x_i; */ for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { x[j][i].u = 0.0; x[j][i].v = 0.0; x[j][i].omega = 0.0; x[j][i].temp = (grashof>0)*i*dx; } } /* Restore vector */ ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr); return 0; }
/* PostCheck - Optional user-defined routine that checks the validity of candidate steps of a line search method. Set by SNESLineSearchSetPostCheck(). Input Parameters: snes - the SNES context ctx - optional user-defined context for private data for the monitor routine, as set by SNESLineSearchSetPostCheck() xcurrent - current solution y - search direction and length x - the new candidate iterate Output Parameters: y - proposed step (search direction and length) (possibly changed) x - current iterate (possibly modified) */ PetscErrorCode PostCheck(SNES snes,Vec xcurrent,Vec y,Vec x,void *ctx,PetscTruth *changed_y,PetscTruth *changed_x) { PetscErrorCode ierr; PetscInt i,iter,xs,xm; StepCheckCtx *check = (StepCheckCtx*) ctx; ApplicationCtx *user = check->user; PetscScalar *xa,*xa_last,tmp; PetscReal rdiff; DA da; PetscFunctionBegin; *changed_x = PETSC_FALSE; *changed_y = PETSC_FALSE; ierr = SNESGetIterationNumber(snes,&iter);CHKERRQ(ierr); /* iteration 1 indicates we are working on the second iteration */ if (iter > 0) { da = user->da; ierr = PetscPrintf(PETSC_COMM_WORLD,"Checking candidate step at iteration %D with tolerance %G\n",iter,check->tolerance);CHKERRQ(ierr); /* Access local array data */ ierr = DAVecGetArray(da,check->last_step,&xa_last);CHKERRQ(ierr); ierr = DAVecGetArray(da,x,&xa);CHKERRQ(ierr); ierr = DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* If we fail the user-defined check for validity of the candidate iterate, then modify the iterate as we like. (Note that the particular modification below is intended simply to demonstrate how to manipulate this data, not as a meaningful or appropriate choice.) */ for (i=xs; i<xs+xm; i++) { if (!PetscAbsScalar(xa[i])) rdiff = 2*check->tolerance; else rdiff = PetscAbsScalar((xa[i] - xa_last[i])/xa[i]); if (rdiff > check->tolerance) { tmp = xa[i]; xa[i] = .5*(xa[i] + xa_last[i]); *changed_x = PETSC_TRUE; ierr = PetscPrintf(PETSC_COMM_WORLD," Altering entry %D: x=%G, x_last=%G, diff=%G, x_new=%G\n", i,PetscAbsScalar(tmp),PetscAbsScalar(xa_last[i]),rdiff,PetscAbsScalar(xa[i]));CHKERRQ(ierr); } } ierr = DAVecRestoreArray(da,check->last_step,&xa_last);CHKERRQ(ierr); ierr = DAVecRestoreArray(da,x,&xa);CHKERRQ(ierr); } ierr = VecCopy(x,check->last_step);CHKERRQ(ierr); PetscFunctionReturn(0); }
int Initialize(DMMG *dmmg) /* ------------------------------------------------------------------- */ { AppCtx *user = (AppCtx*)dmmg[0]->user; Parameter *param; DA da; PetscReal PI = 3.14159265358979323846; PetscReal sigma,xc,zc; PetscReal dx=user->grid->dx,dz=user->grid->dz; int i,j,ierr,is,js,im,jm; Field **x; ierr = PetscBagGetData(user->bag,(void**)¶m); CHKERRQ(ierr); sigma=param->sigma; xc=param->xctr; zc=param->zctr; /* Get the DA and grid */ da = (DA)(dmmg[0]->dm); ierr = DAGetCorners(da,&is,&js,PETSC_NULL,&im,&jm,PETSC_NULL); CHKERRQ(ierr); ierr = DAVecGetArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); for (j=js; j<js+jm; j++) { for (i=is; i<is+im; i++) { if (param->flow_type == SHEAR_CELL) { x[j][i].u = -sin(PI*i*dx)*cos(PI*j*dz)/dx; x[j][i].w = sin(PI*j*dz)*cos(PI*i*dx)/dz; } else { x[j][i].u = 0.0; x[j][i].w = -1.0/dz; } x[j][i].phi = 100*exp(-0.5*((i*dx-xc)*(i*dx-xc)+(j*dz-zc)*(j*dz-zc))/sigma/sigma); } } /* restore the grid to it's vector */ ierr = DAVecRestoreArray(da,user->Xold,(void**)&x); CHKERRQ(ierr); ierr = VecCopy(user->Xold, DMMGGetx(dmmg)); CHKERRQ(ierr); return 0; }
int FormJacobian_Grid(GridCtx *grid,Mat *J) { Mat jac = *J; PetscErrorCode ierr; PetscInt i,j,row,mx,my,xs,ys,xm,ym,Xs,Ys,Xm,Ym,col[5]; PetscInt nloc,*ltog,grow; PetscScalar two = 2.0,one = 1.0,v[5],hx,hy,hxdhy,hydhx,value; mx = grid->mx; my = grid->my; hx = one/(PetscReal)(mx-1); hy = one/(PetscReal)(my-1); hxdhy = hx/hy; hydhx = hy/hx; /* Get ghost points */ ierr = DAGetCorners(grid->da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); ierr = DAGetGhostCorners(grid->da,&Xs,&Ys,0,&Xm,&Ym,0);CHKERRQ(ierr); ierr = DAGetGlobalIndices(grid->da,&nloc,<og);CHKERRQ(ierr); /* Evaluate Jacobian of function */ for (j=ys; j<ys+ym; j++) { row = (j - Ys)*Xm + xs - Xs - 1; for (i=xs; i<xs+xm; i++) { row++; grow = ltog[row]; if (i > 0 && i < mx-1 && j > 0 && j < my-1) { v[0] = -hxdhy; col[0] = ltog[row - Xm]; v[1] = -hydhx; col[1] = ltog[row - 1]; v[2] = two*(hydhx + hxdhy); col[2] = grow; v[3] = -hydhx; col[3] = ltog[row + 1]; v[4] = -hxdhy; col[4] = ltog[row + Xm]; ierr = MatSetValues(jac,1,&grow,5,col,v,INSERT_VALUES);CHKERRQ(ierr); } else if ((i > 0 && i < mx-1) || (j > 0 && j < my-1)){ value = .5*two*(hydhx + hxdhy); ierr = MatSetValues(jac,1,&grow,1,&grow,&value,INSERT_VALUES);CHKERRQ(ierr); } else { value = .25*two*(hydhx + hxdhy); ierr = MatSetValues(jac,1,&grow,1,&grow,&value,INSERT_VALUES);CHKERRQ(ierr); } } } ierr = MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); return 0; }
PetscErrorCode ComputeJacobian(SNES snes,Vec x,Mat *J,Mat *B,MatStructure *flag,void *ctx){ DA da = (DA) ctx; PetscInt i,Mx,xm,xs; PetscScalar hx,*xx; Vec xlocal; DAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); hx = 1.0/(PetscReal)(Mx-1); DAGetLocalVector(da,&xlocal);DAGlobalToLocalBegin(da,x,INSERT_VALUES,xlocal); DAGlobalToLocalEnd(da,x,INSERT_VALUES,xlocal); DAVecGetArray(da,xlocal,&xx); DAGetCorners(da,&xs,PETSC_NULL,PETSC_NULL,&xm,PETSC_NULL,PETSC_NULL); for (i=xs; i<xs+xm; i++) { if (i == 0 || i == Mx-1) { MatSetValue(*J,i,i,1.0/hx,INSERT_VALUES);} else { MatSetValue(*J,i,i-1,-1.0/hx,INSERT_VALUES); MatSetValue(*J,i,i,2.0/hx - hx*PetscExpScalar(xx[i]),INSERT_VALUES); MatSetValue(*J,i,i+1,-1.0/hx,INSERT_VALUES); } } MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY); *flag = SAME_NONZERO_PATTERN; DAVecRestoreArray(da,xlocal,&xx);DARestoreLocalVector(da,&xlocal); return 0;}
/* Form initial guess for Physic 1 */ PetscErrorCode FormInitialGuessLocal1(DMMG dmmg,Vec X) { AppCtx *user = (AppCtx*)dmmg->user; DA da = (DA)dmmg->dm; PetscInt i,j,mx,xs,ys,xm,ym; PetscErrorCode ierr; Field1 **x; ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { x[j][i].u = 0.0; x[j][i].v = 0.0; x[j][i].omega = 0.0; } } ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr); return 0; }
int ComputeB(AppCtx* user) { int info; PetscInt i,j,k; PetscInt nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscReal two=2.0, pi=4.0*atan(1.0); PetscReal hx,hy,ehxhy; PetscReal temp,*b; PetscReal ecc=user->ecc; nx=user->nx; ny=user->ny; hx=two*pi/(nx+1.0); hy=two*user->b/(ny+1.0); ehxhy = ecc*hx*hy; /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info); /* Compute the linear term in the objective function */ info = VecGetArray(user->B,&b); CHKERRQ(info); for (i=xs; i<xs+xm; i++){ temp=sin((i+1)*hx); for (j=ys; j<ys+ym; j++){ k=xm*(j-ys)+(i-xs); b[k]= - ehxhy*temp; } } info = VecRestoreArray(user->B,&b); CHKERRQ(info); info = PetscLogFlops(5*xm*ym+3*xm); CHKERRQ(info); return 0; }
PetscErrorCode FormInitialGuess1(AppCtx *user,Vec X) { PetscInt i,j,k,loc,mx,my,mz,xs,ys,zs,xm,ym,zm,Xm,Ym,Zm,Xs,Ys,Zs,base1; PetscErrorCode ierr; PetscReal one = 1.0,lambda,temp1,temp,Hx,Hy; PetscScalar *x; Vec localX = user->localX; mx = user->mx; my = user->my; mz = user->mz; lambda = user->param; Hx = one / (PetscReal)(mx-1); Hy = one / (PetscReal)(my-1); ierr = VecGetArray(localX,&x);CHKERRQ(ierr); temp1 = lambda/(lambda + one); ierr = DAGetCorners(user->da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); ierr = DAGetGhostCorners(user->da,&Xs,&Ys,&Zs,&Xm,&Ym,&Zm);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++) { base1 = (Xm*Ym)*(k-Zs); for (j=ys; j<ys+ym; j++) { temp = (PetscReal)(PetscMin(j,my-j-1))*Hy; for (i=xs; i<xs+xm; i++) { loc = base1 + i-Xs + (j-Ys)*Xm; if (i == 0 || j == 0 || k == 0 || i==mx-1 || j==my-1 || k==mz-1) { x[loc] = 0.0; continue; } x[loc] = temp1*sqrt(PetscMin((PetscReal)(PetscMin(i,mx-i-1))*Hx,temp)); } } } ierr = VecRestoreArray(localX,&x);CHKERRQ(ierr); /* stick values into global vector */ ierr = DALocalToGlobal(user->da,localX,INSERT_VALUES,X);CHKERRQ(ierr); return 0; }/* -------------------- Evaluate Function F(x) --------------------- */
/* Form initial guess for Physic 2 */ PetscErrorCode FormInitialGuessLocal2(DMMG dmmg,Vec X) { AppCtx *user = (AppCtx*)dmmg->user; DA da = (DA)dmmg->dm; PetscInt i,j,mx,xs,ys,xm,ym; PetscErrorCode ierr; PetscReal grashof,dx; Field2 **x; grashof = user->grashof; ierr = DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);CHKERRQ(ierr); dx = 1.0/(mx-1); ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); ierr = DAVecGetArray(da,X,&x);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { x[j][i].temp = (grashof>0)*i*dx; } } ierr = DAVecRestoreArray(da,X,&x);CHKERRQ(ierr); return 0; }
int FormBratuFunction(SNES snes, Vec v, Vec f, void* ctx) { UserBratuCtx* bratu = (UserBratuCtx *) ctx; DA da = bratu->da; double lambda = bratu->lambda; double h = bratu->h; Vec lv; int i,j; int lli, llj, ni, nj; const double **varr; double **fvarr; DAGetCorners(da, &lli, &llj, 0, &ni, &nj, 0); DAGetLocalVector(da, &lv); DAGlobalToLocalBegin(da, v, INSERT_VALUES, lv); DAGlobalToLocalEnd(da, v, INSERT_VALUES,lv); DAVecGetArray(da, lv, (void**) &varr); DAVecGetArray(da, f, (void**) &fvarr); for(j=llj; j<llj+nj; j++){ for(i=lli; i<lli+ni; i++){ if(i==0 || j==0 ||i=bratu->n+1 || j==bratu->n+1){ fvarr[j][i] = 0.0; } else{ fvarr[j][i] = -(varr[j-1][i] + varr[j][i-1] + varr[j+1][i] + varr[j][i+1] - 4*varr[j][i])/(h*h) - lambda*exp(varr[j][i]); } } } DAVecRestoreArray(da, f, (void**) &fvarr); DAVecRestoreArray(da, lv, (void**) &varr); DARestoreLocalVector(da, &lv); return 0; }
/* Compute production variables, update Observations vector */ extern PetscErrorCode DefiantBlackOil3PhProduction(BlackOilReservoirSimulation* MySim) { PetscErrorCode ierr; PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs; /* Well handling variables */ PetscInt PerfIDMine, WellID; PetscFunctionBegin; /* Get dimensions and extents of the local vectors */ ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr); ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); /* Sync everything before we start */ ierr = DefiantBlackOilComputePerfIndicesSyncPerfs(MySim);CHKERRQ(ierr); for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) { for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) { if (MySim->Wells[WellID].Perforations[PerfIDMine].IsActive == PETSC_TRUE ){ if (MySim->Wells[WellID].Perforations[PerfIDMine].Constraint == FLOW_RATE_CONSTRAINT) { MySim->Wells[WellID].Perforations[PerfIDMine].BHPo = MySim->Wells[WellID].Perforations[PerfIDMine].Bo / (MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3) * MySim->Wells[WellID].Perforations[PerfIDMine].Muo / MySim->Wells[WellID].Perforations[PerfIDMine].Kro / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex + MySim->Wells[WellID].Perforations[PerfIDMine].Po + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3); MySim->Wells[WellID].Perforations[PerfIDMine].BHPw = MySim->Wells[WellID].Perforations[PerfIDMine].Bw / (MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3) * MySim->Wells[WellID].Perforations[PerfIDMine].Muw / MySim->Wells[WellID].Perforations[PerfIDMine].Krw / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex + MySim->Wells[WellID].Perforations[PerfIDMine].Pw + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhow * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3); MySim->Wells[WellID].Perforations[PerfIDMine].BHPg = MySim->Wells[WellID].Perforations[PerfIDMine].Bg / (MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3) * MySim->Wells[WellID].Perforations[PerfIDMine].Mug / MySim->Wells[WellID].Perforations[PerfIDMine].Krg / MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex + MySim->Wells[WellID].Perforations[PerfIDMine].Pg + MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhog * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3); } else if (MySim->Wells[WellID].Perforations[PerfIDMine].Constraint == BHP_CONSTRAINT) { MySim->Wells[WellID].Perforations[PerfIDMine].Qo = MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex * MySim->Wells[WellID].Perforations[PerfIDMine].Kro / MySim->Wells[WellID].Perforations[PerfIDMine].Muo * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPo - MySim->Wells[WellID].Perforations[PerfIDMine].Po - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3)) * MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3 / MySim->Wells[WellID].Perforations[PerfIDMine].Bo; MySim->Wells[WellID].Perforations[PerfIDMine].Qw = MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex * MySim->Wells[WellID].Perforations[PerfIDMine].Krw / MySim->Wells[WellID].Perforations[PerfIDMine].Muw * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPw - MySim->Wells[WellID].Perforations[PerfIDMine].Pw - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhow * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3)) * MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3 / MySim->Wells[WellID].Perforations[PerfIDMine].Bw; MySim->Wells[WellID].Perforations[PerfIDMine].Qg = MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex * MySim->Wells[WellID].Perforations[PerfIDMine].Krg / MySim->Wells[WellID].Perforations[PerfIDMine].Mug * (MySim->Wells[WellID].Perforations[PerfIDMine].BHPg - MySim->Wells[WellID].Perforations[PerfIDMine].Pg - MySim->GravAcc * MySim->Wells[WellID].Perforations[PerfIDMine].Rhog * (MySim->Wells[WellID].Perforations[PerfIDMine].zbh - MySim->Wells[WellID].Perforations[PerfIDMine].x3)) * MySim->Wells[WellID].Perforations[PerfIDMine].h1 * MySim->Wells[WellID].Perforations[PerfIDMine].h2 * MySim->Wells[WellID].Perforations[PerfIDMine].h3 / MySim->Wells[WellID].Perforations[PerfIDMine].Bg; } } } } PetscFunctionReturn(0); }
extern PetscErrorCode DefiantBlackOilSyncPerfOwners(BlackOilReservoirSimulation* MySim) { PetscErrorCode ierr; PetscInt i, rank, TotalNumberOfPerfs; PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs; /* Well handling variables */ PetscInt PerfIDMine, WellID; PetscInt MyI, MyJ, MyK; /* temporary array */ PetscInt *InBuffer, *OutBuffer; PetscFunctionBegin; /* Get dimensions and extents of the local vectors */ ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr); ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); /* Get the current rank */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);CHKMEMQ; /* Allocate memory to the in and out Buffers */ /* Find the total number of perforations */ TotalNumberOfPerfs = 0; for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) TotalNumberOfPerfs++; /* Allocate the In and out Buffers */ ierr = PetscMalloc(sizeof(PetscInt)*TotalNumberOfPerfs, &InBuffer);CHKERRQ(ierr);CHKMEMQ; ierr = PetscMalloc(sizeof(PetscInt)*TotalNumberOfPerfs, &OutBuffer);CHKERRQ(ierr);CHKMEMQ; /* Pack all the perf owner location int the in buffer */ i = 0; for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) { for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) { MyI = (MySim->Wells[WellID]).Perforations[PerfIDMine].I;CHKMEMQ; MyJ = (MySim->Wells[WellID]).Perforations[PerfIDMine].J;CHKMEMQ; MyK = (MySim->Wells[WellID]).Perforations[PerfIDMine].K;CHKMEMQ; if (MyI >= xs && MyI < xs+xm && MyJ >= ys && MyJ < ys+ym && MyK >= zs && MyK < zs+zm) MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = rank; else MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = -1; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank; i++; } } /* Make the syncrhonization call */ ierr = MPI_Allreduce(InBuffer, OutBuffer, TotalNumberOfPerfs, MPI_INT, MPI_MAX, PETSC_COMM_WORLD);CHKERRQ(ierr);CHKMEMQ; /* Now unpack all the perf owner location int the in buffer */ i = 0; for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) { for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) { MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank = OutBuffer[i]; i++; } } PetscFunctionReturn(0); }
extern PetscErrorCode DefiantComputeTransmissibilities( BlackOilReservoirSimulation* MySim) { PetscErrorCode ierr; PetscInt i, j, k, mx, my, mz, xm, ym, zm, xs, ys, zs; PetscScalar ***LocalFlowMask; /* Area * Permeability divided by height */ PetscScalar ***LocalAKHx1m, ***LocalAKHx2m, ***LocalAKHx3m; PetscScalar ***LocalAKHx1p, ***LocalAKHx2p, ***LocalAKHx3p; /* Local viscosity at the faces */ PetscScalar ***LocalMuox1m, ***LocalMuox1p, ***LocalMuwx1m, ***LocalMuwx1p, ***LocalMugx1m, ***LocalMugx1p; PetscScalar ***LocalMuox2m, ***LocalMuox2p, ***LocalMuwx2m, ***LocalMuwx2p, ***LocalMugx2m, ***LocalMugx2p; PetscScalar ***LocalMuox3m, ***LocalMuox3p, ***LocalMuwx3m, ***LocalMuwx3p, ***LocalMugx3m, ***LocalMugx3p; /* Relative Permeabilities at the faces */ PetscScalar ***LocalRelPermox1m, ***LocalRelPermox1p, ***LocalRelPermox2m, ***LocalRelPermox2p, ***LocalRelPermox3m, ***LocalRelPermox3p; PetscScalar ***LocalRelPermwx1m, ***LocalRelPermwx1p, ***LocalRelPermwx2m, ***LocalRelPermwx2p, ***LocalRelPermwx3m, ***LocalRelPermwx3p; PetscScalar ***LocalRelPermgx1m, ***LocalRelPermgx1p, ***LocalRelPermgx2m, ***LocalRelPermgx2p, ***LocalRelPermgx3m, ***LocalRelPermgx3p; /* Volume factors at cell center */ PetscScalar ***LocalBo, ***LocalBw, ***LocalBg; /* Volume factors at cell faces */ PetscScalar ***LocalBox1p, ***LocalBox2p, ***LocalBox3p; PetscScalar ***LocalBox1m, ***LocalBox2m, ***LocalBox3m; PetscScalar ***LocalBwx1p, ***LocalBwx2p, ***LocalBwx3p; PetscScalar ***LocalBwx1m, ***LocalBwx2m, ***LocalBwx3m; PetscScalar ***LocalBgx1p, ***LocalBgx2p, ***LocalBgx3p; PetscScalar ***LocalBgx1m, ***LocalBgx2m, ***LocalBgx3m; /* Transmissibility For Oil*/ PetscScalar ***LocalTox1p, ***LocalTox2p, ***LocalTox3p; PetscScalar ***LocalTox1m, ***LocalTox2m, ***LocalTox3m; /* Transmissibility For Water*/ PetscScalar ***LocalTwx1p, ***LocalTwx2p, ***LocalTwx3p; PetscScalar ***LocalTwx1m, ***LocalTwx2m, ***LocalTwx3m; /* Transmissibility For Gas*/ PetscScalar ***LocalTgx1p, ***LocalTgx2p, ***LocalTgx3p; PetscScalar ***LocalTgx1m, ***LocalTgx2m, ***LocalTgx3m; PetscFunctionBegin; /* Get dimensions and extents of the local vectors */ ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr); ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); /* Grab the data for the flow field */ ierr = DAVecGetArray(MySim->SimDA, MySim->FlowMask, &LocalFlowMask);CHKERRQ(ierr); /* Grab the local data for area * permeability divided by height */ ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx1m, &LocalAKHx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx2m, &LocalAKHx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx3m, &LocalAKHx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx1p, &LocalAKHx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx2p, &LocalAKHx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->AKHx3p, &LocalAKHx3p);CHKERRQ(ierr); /* Grab the local data for the face viscosities */ ierr = DAVecGetArray(MySim->SimDA, MySim->Muox1m, &LocalMuox1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muox1p, &LocalMuox1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx1m, &LocalMuwx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx1p, &LocalMuwx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx1m, &LocalMugx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx1p, &LocalMugx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muox2m, &LocalMuox2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muox2p, &LocalMuox2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx2m, &LocalMuwx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx2p, &LocalMuwx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx2m, &LocalMugx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx2p, &LocalMugx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muox3m, &LocalMuox3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muox3p, &LocalMuox3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx3m, &LocalMuwx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Muwx3p, &LocalMuwx3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx3m, &LocalMugx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Mugx3p, &LocalMugx3p);CHKERRQ(ierr); /* Grab the local data for the face Relative Permeabilities */ ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox1m, &LocalRelPermox1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox1p, &LocalRelPermox1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox2m, &LocalRelPermox2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox2p, &LocalRelPermox2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox3m, &LocalRelPermox3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermox3p, &LocalRelPermox3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx1m, &LocalRelPermwx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx1p, &LocalRelPermwx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx2m, &LocalRelPermwx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx2p, &LocalRelPermwx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx3m, &LocalRelPermwx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermwx3p, &LocalRelPermwx3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx1m, &LocalRelPermgx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx1p, &LocalRelPermgx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx2m, &LocalRelPermgx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx2p, &LocalRelPermgx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx3m, &LocalRelPermgx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->RelPermgx3p, &LocalRelPermgx3p);CHKERRQ(ierr); /* Grab the local data for volume factors at the cell centers */ ierr = DAVecGetArray(MySim->SimDA, MySim->Bo, &LocalBo);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bw, &LocalBw);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bg, &LocalBg);CHKERRQ(ierr); /* Grab the local data for Volume factors at the faces */ ierr = DAVecGetArray(MySim->SimDA, MySim->Box1p, &LocalBox1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Box2p, &LocalBox2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Box3p, &LocalBox3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Box1m, &LocalBox1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Box2m, &LocalBox2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Box3m, &LocalBox3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx1p, &LocalBwx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx2p, &LocalBwx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx3p, &LocalBwx3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx1m, &LocalBwx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx2m, &LocalBwx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bwx3m, &LocalBwx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx1p, &LocalBgx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx2p, &LocalBgx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx3p, &LocalBgx3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx1m, &LocalBgx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx2m, &LocalBgx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Bgx3m, &LocalBgx3m);CHKERRQ(ierr); /* Grab the local data for the transmissibilities */ ierr = DAVecGetArray(MySim->SimDA, MySim->Tox1m, &LocalTox1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tox1p, &LocalTox1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx1m, &LocalTwx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx1p, &LocalTwx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx1m, &LocalTgx1m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx1p, &LocalTgx1p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tox2m, &LocalTox2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tox2p, &LocalTox2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx2m, &LocalTwx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx2p, &LocalTwx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx2m, &LocalTgx2m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx2p, &LocalTgx2p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tox3m, &LocalTox3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tox3p, &LocalTox3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx3m, &LocalTwx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Twx3p, &LocalTwx3p);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx3m, &LocalTgx3m);CHKERRQ(ierr); ierr = DAVecGetArray(MySim->SimDA, MySim->Tgx3p, &LocalTgx3p);CHKERRQ(ierr); for (k = zs; k < zs + zm; k++) { for (j = ys; j < ys + ym; j++) { for (i = xs; i < xs + xm; i++) { if (i == 0 || j == 0 || k == 0 || i == mx - 1 || j == my - 1 || k == mz - 1) { } else if (ABS(LocalFlowMask[k][j][i]-FLUID_FLOW) < EPSILON) { /* Transmissibility */ LocalTox1m[k][j][i] = LocalRelPermox1m[k][j][i] * LocalAKHx1m[k][j][i] / LocalMuox1m[k][j][i] / LocalBox1m[k][j][i]; LocalTox1p[k][j][i] = LocalRelPermox1p[k][j][i] * LocalAKHx1p[k][j][i] / LocalMuox1p[k][j][i] / LocalBox1p[k][j][i]; LocalTox2m[k][j][i] = LocalRelPermox2m[k][j][i] * LocalAKHx2m[k][j][i] / LocalMuox2m[k][j][i] / LocalBox2m[k][j][i]; LocalTox2p[k][j][i] = LocalRelPermox2p[k][j][i] * LocalAKHx2p[k][j][i] / LocalMuox2p[k][j][i] / LocalBox2p[k][j][i]; LocalTox3m[k][j][i] = LocalRelPermox3m[k][j][i] * LocalAKHx3m[k][j][i] / LocalMuox3m[k][j][i] / LocalBox3m[k][j][i]; LocalTox3p[k][j][i] = LocalRelPermox3p[k][j][i] * LocalAKHx3p[k][j][i] / LocalMuox3p[k][j][i] / LocalBox3p[k][j][i]; LocalTwx1m[k][j][i] = LocalRelPermwx1m[k][j][i] * LocalAKHx1m[k][j][i] / LocalMuwx1m[k][j][i] / LocalBwx1m[k][j][i]; LocalTwx1p[k][j][i] = LocalRelPermwx1p[k][j][i] * LocalAKHx1p[k][j][i] / LocalMuwx1p[k][j][i] / LocalBwx1p[k][j][i]; LocalTwx2m[k][j][i] = LocalRelPermwx2m[k][j][i] * LocalAKHx2m[k][j][i] / LocalMuwx2m[k][j][i] / LocalBwx2m[k][j][i]; LocalTwx2p[k][j][i] = LocalRelPermwx2p[k][j][i] * LocalAKHx2p[k][j][i] / LocalMuwx2p[k][j][i] / LocalBwx2p[k][j][i]; LocalTwx3m[k][j][i] = LocalRelPermwx3m[k][j][i] * LocalAKHx3m[k][j][i] / LocalMuwx3m[k][j][i] / LocalBwx3m[k][j][i]; LocalTwx3p[k][j][i] = LocalRelPermwx3p[k][j][i] * LocalAKHx3p[k][j][i] / LocalMuwx3p[k][j][i] / LocalBwx3p[k][j][i]; LocalTgx1m[k][j][i] = LocalRelPermgx1m[k][j][i] * LocalAKHx1m[k][j][i] / LocalMugx1m[k][j][i] / LocalBgx1m[k][j][i]; LocalTgx1p[k][j][i] = LocalRelPermgx1p[k][j][i] * LocalAKHx1p[k][j][i] / LocalMugx1p[k][j][i] / LocalBgx1p[k][j][i]; LocalTgx2m[k][j][i] = LocalRelPermgx2m[k][j][i] * LocalAKHx2m[k][j][i] / LocalMugx2m[k][j][i] / LocalBgx2m[k][j][i]; LocalTgx2p[k][j][i] = LocalRelPermgx2p[k][j][i] * LocalAKHx2p[k][j][i] / LocalMugx2p[k][j][i] / LocalBgx2p[k][j][i]; LocalTgx3m[k][j][i] = LocalRelPermgx3m[k][j][i] * LocalAKHx3m[k][j][i] / LocalMugx3m[k][j][i] / LocalBgx3m[k][j][i]; LocalTgx3p[k][j][i] = LocalRelPermgx3p[k][j][i] * LocalAKHx3p[k][j][i] / LocalMugx3p[k][j][i] / LocalBgx3p[k][j][i]; } } } } /* Restore the new arrays to their reightful place */ ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox1m, &LocalTox1m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox1p, &LocalTox1p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx1m, &LocalTwx1m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx1p, &LocalTwx1p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx1m, &LocalTgx1m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx1p, &LocalTgx1p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox2m, &LocalTox2m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox2p, &LocalTox2p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx2m, &LocalTwx2m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx2p, &LocalTwx2p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx2m, &LocalTgx2m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx2p, &LocalTgx2p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox3m, &LocalTox3m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tox3p, &LocalTox3p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx3m, &LocalTwx3m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Twx3p, &LocalTwx3p);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx3m, &LocalTgx3m);CHKERRQ(ierr); ierr = DAVecRestoreArray(MySim->SimDA, MySim->Tgx3p, &LocalTgx3p);CHKERRQ(ierr); /* Begin Assembly for vectors */ ierr = VecAssemblyBegin(MySim->Tox1p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tox2p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tox3p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tox1m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tox2m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tox3m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx1p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx2p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx3p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx1m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx2m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Twx3m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx1p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx2p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx3p);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx1m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx2m);CHKERRQ(ierr); ierr = VecAssemblyBegin(MySim->Tgx3m);CHKERRQ(ierr); /* And end Assembly */ ierr = VecAssemblyEnd(MySim->Tox1p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tox2p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tox3p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tox1m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tox2m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tox3m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx1p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx2p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx3p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx1m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx2m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Twx3m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx1p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx2p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx3p);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx1m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx2m);CHKERRQ(ierr); ierr = VecAssemblyEnd(MySim->Tgx3m);CHKERRQ(ierr); PetscFunctionReturn(0); }
void getForces(Vec params, std::vector<Vec> &forces, DA da, timeInfo ti, int numParams) { #ifdef __DEBUG__ std::cout << RED"Entering "NRM << __func__ << std::endl; #endif // Generate the force vector based on the current parameters ... // F = Sum { B_i a_i} PetscScalar * pVec; VecGetArray(params, &pVec); // Clear the Forces for (unsigned int i=0; i<forces.size(); i++) { if (forces[i] != NULL) { VecDestroy(forces[i]); } } forces.clear(); unsigned int numSteps = (unsigned int)(ceil(( ti.stop - ti.start)/ti.step)); // create and initialize to 0 for (unsigned int i=0; i<numSteps+1; i++) { Vec tmp; DACreateGlobalVector(da, &tmp); VecZeroEntries(tmp); forces.push_back(tmp); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PetscScalar ***tauArray; unsigned int paramTimeSteps = (unsigned int)(ceil(( (double)(numSteps))/ ((double)(2*numParams)) )); double acx,acy,acz; int x, y, z, m, n, p; int mx,my,mz; DAGetCorners(da, &x, &y, &z, &m, &n, &p); DAGetInfo(da,0, &mx, &my, &mz, 0,0,0,0,0,0,0); double hx = 1.0/(mx-1.0); for (int b=0; b<numParams; b++) { std::vector<Vec> tau; unsigned int tBegin = paramTimeSteps*b; unsigned int tEnd = tBegin + numSteps/2; // paramTimeSteps*(b+2); // std::cout << "For param " << b << ": Time step range is " << tBegin << " -> " << tEnd << std::endl; for (unsigned int t=0; t<numSteps+1; t++) { double newTime = (ti.step*(t-tBegin)*numSteps)/((double)(paramTimeSteps)); if ( (t>=tBegin) && (t<=tEnd)) { DAVecGetArray(da, forces[t], &tauArray); for (int k = z; k < z + p ; k++) { for (int j = y; j < y + n; j++) { for (int i = x; i < x + m; i++) { acx = (i)*hx; acy = (j)*hx; acz = (k)*hx; tauArray[k][j][i] += pVec[b]*sin(M_PI*newTime)*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz); } } } DAVecRestoreArray ( da, forces[t], &tauArray ) ; } } } VecRestoreArray(params, &pVec); #ifdef __DEBUG__ // Get the norms of the forces ... just to be safe .. double fNorm1, fNorm2; for (unsigned int i=0; i<forces.size(); i++) { VecNorm(forces[i], NORM_INFINITY, &fNorm1); VecNorm(forces[i], NORM_2, &fNorm2); PetscPrintf(0, "Force Norms at timestep %d are %g and %g\n", i, fNorm1, fNorm2); } #endif #ifdef __DEBUG__ std::cout << GRN"Leaving "NRM << __func__ << std::endl; #endif }
int main(int argc, char **argv) { PetscInitialize(&argc, &argv, "wave.opt", help); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); double startTime, endTime; int Ns = 32; unsigned int dof = 1; // double dtratio = 1.0; DA da; // Underlying DA Vec rho; // density - elemental scalar Vec nu; // Lame parameter - lambda - elemental scalar std::vector < std::vector<Vec> > fBasis; // the scalar activation - nodal scalar // std::vector<Vec> truth; // the ground truth. // Initial conditions Vec initialDisplacement; Vec initialVelocity; timeInfo ti; // get Ns CHKERRQ ( PetscOptionsGetInt(0,"-Ns", &Ns,0) ); double t0 = 0.0; double dt = 1.0/(Ns); double t1 = 1.0; double nuVal = 1.0; double beta = 0.0001; int numParams = 5; CHKERRQ ( PetscOptionsGetInt(0,"-nump",&numParams,0) ); CHKERRQ ( PetscOptionsGetScalar(0,"-t0",&t0,0) ); CHKERRQ ( PetscOptionsGetScalar(0,"-t1",&t1,0) ); CHKERRQ ( PetscOptionsGetScalar(0,"-dt",&dt,0) ); CHKERRQ ( PetscOptionsGetScalar(0,"-nu",&nuVal,0) ); CHKERRQ ( PetscOptionsGetScalar(0,"-beta",&beta,0) ); // CHKERRQ ( PetscOptionsGetString(PETSC_NULL, "-pn", problemName, PETSC_MAX_PATH_LEN-1, PETSC_NULL)); // Time info for timestepping ti.start = t0; ti.stop = t1; ti.step = dt; if (!rank) { std::cout << "Problem size is " << Ns+1 << " spatially and NT = " << (int)ceil(1.0/dt) << std::endl << std::endl; std::cout << "Number of parameters is " << numParams << std::endl; } // create DA CHKERRQ ( DACreate3d ( PETSC_COMM_WORLD, DA_NONPERIODIC, DA_STENCIL_BOX, Ns+1, Ns+1, Ns+1, PETSC_DECIDE, PETSC_DECIDE, PETSC_DECIDE, 1, 1, 0, 0, 0, &da) ); massMatrix *Mass = new massMatrix(feMat::PETSC); // Mass Matrix stiffnessMatrix *Stiffness = new stiffnessMatrix(feMat::PETSC); // Stiffness matrix waveDamping *Damping = new waveDamping(feMat::PETSC); // Damping Matrix fdynamicVector *Force = new fdynamicVector(feVec::PETSC); // Force Vector // create vectors CHKERRQ( DACreateGlobalVector(da, &rho) ); CHKERRQ( DACreateGlobalVector(da, &nu) ); CHKERRQ( DACreateGlobalVector(da, &initialDisplacement) ); CHKERRQ( DACreateGlobalVector(da, &initialVelocity) ); // Set initial conditions CHKERRQ( VecSet ( initialDisplacement, 0.0) ); CHKERRQ( VecSet ( initialVelocity, 0.0) ); VecZeroEntries( nu ); VecZeroEntries( rho ); CHKERRQ( VecSet ( nu, nuVal) ); CHKERRQ( VecSet ( rho, 1.0) ); int x, y, z, m, n, p; int mx,my,mz; CHKERRQ( DAGetCorners(da, &x, &y, &z, &m, &n, &p) ); CHKERRQ( DAGetInfo(da,0, &mx, &my, &mz, 0,0,0,0,0,0,0) ); double acx,acy,acz; double hx = 1.0/((double)Ns); // allocate for temporary buffers ... // unsigned int elemSize = Ns*Ns*Ns; // std::cout << "Elem size is " << elemSize << std::endl; // unsigned int nodeSize = (Ns+1)*(Ns+1)*(Ns+1); // Now set the activation ... unsigned int numSteps = (unsigned int)(ceil(( ti.stop - ti.start)/ti.step)); // Vec tauVec; // PetscScalar ***tauArray; unsigned int paramTimeSteps = (unsigned int)(ceil(( (double)(numSteps))/ ((double)(2*numParams)) )); /* for (int b=0; b<numParams; b++) { std::vector<Vec> tau; unsigned int tBegin = paramTimeSteps*b; unsigned int tEnd = tBegin + numSteps/2; // paramTimeSteps*(b+2); // std::cout << "For param " << b << ": Time step range is " << tBegin << " -> " << tEnd << std::endl; for (unsigned int t=0; t<numSteps+1; t++) { double newTime = (dt*(t-tBegin)*numSteps)/((double)(paramTimeSteps)); // double fff = 0.0; CHKERRQ( DACreateGlobalVector(da, &tauVec) ); CHKERRQ( VecSet( tauVec, 0.0)); if ( (t>=tBegin) && (t<=tEnd)) { CHKERRQ(DAVecGetArray(da, tauVec, &tauArray)); for (int k = z; k < z + p ; k++) { for (int j = y; j < y + n; j++) { for (int i = x; i < x + m; i++) { acx = (i)*hx; acy = (j)*hx; acz = (k)*hx; tauArray[k][j][i] = sin(M_PI*newTime)*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz); } } } CHKERRQ( DAVecRestoreArray ( da, tauVec, &tauArray ) ); } tau.push_back(tauVec); } fBasis.push_back(tau); } */ // std::cout << "Finished setting basis" << std::endl; /* // Set initial velocity ... CHKERRQ(DAVecGetArray(da, initialVelocity, &solArray)); for (int k = z; k < z + p ; k++) { for (int j = y; j < y + n; j++) { for (int i = x; i < x + m; i++) { acx = (i)*hx; acy = (j)*hx; acz = (k)*hx; solArray[k][j][i] = M_PI*cos(2*M_PI*acx)*cos(2*M_PI*acy)*cos(2*M_PI*acz); } } } CHKERRQ( DAVecRestoreArray ( da, initialVelocity, &solArray ) ); */ std::vector<Vec> newF; Vec alpha; PetscScalar *avec; VecCreateSeq(PETSC_COMM_SELF, numParams, &alpha); /* VecCreate(PETSC_COMM_WORLD, &alpha); VecSetSizes(alpha, numParams, PETSC_DECIDE); VecSetFromOptions(alpha); */ VecGetArray(alpha, &avec); for (int j=0; j<numParams; j++) avec[j] = 0.5 + 0.5*j; VecRestoreArray(alpha, &avec); // getForces(alpha, fBasis, newF); getForces(alpha, newF, da, ti, numParams); // Setup Matrices and Force Vector ... Mass->setProblemDimensions(1.0, 1.0, 1.0); Mass->setDA(da); Mass->setDof(dof); Mass->setNuVec(rho); Stiffness->setProblemDimensions(1.0, 1.0, 1.0); Stiffness->setDA(da); Stiffness->setDof(dof); Stiffness->setNuVec(nu); Damping->setAlpha(0.0); Damping->setBeta(0.00075); Damping->setMassMatrix(Mass); Damping->setStiffnessMatrix(Stiffness); Damping->setDA(da); Damping->setDof(dof); // Force Vector Force->setProblemDimensions(1.0,1.0,1.0); Force->setDA(da); Force->setFDynamic(newF); Force->setTimeInfo(&ti); // Newmark time stepper ... newmark *ts = new newmark; ts->setMassMatrix(Mass); ts->setDampingMatrix(Damping); ts->setStiffnessMatrix(Stiffness); ts->damp(false); ts->setTimeFrames(1); ts->storeVec(true); ts->setAdjoint(false); ts->setForceVector(Force); ts->setInitialDisplacement(initialDisplacement); ts->setInitialVelocity(initialVelocity); ts->setTimeInfo(&ti); ts->setAdjoint(false); // set if adjoint or forward ts->init(); // initialize IMPORTANT // if (!rank) // std::cout << RED"Starting initial forward solve"NRM << std::endl; ts->solve();// solve // if (!rank) // std::cout << GRN"Finished with initial forward solve"NRM << std::endl; std::vector<Vec> solvec = ts->getSolution(); // Now lets check the error ... // Vec nr; // concatenateVecs(solvec, nr); // VecDestroy(nr); // VecDestroy(gt); // std::cout << std::endl; /************* * INVERSE * *************/ // True solution is tau ... we want to recover it. // The observations in this case are, solvec /* Set very initial guess for the inverse problem*/ // Now can clear memory ... /* for (int i=0; i<newF.size(); i++) { if (newF[i] != NULL) { VecDestroy(newF[i]); } } newF.clear(); for (int i=0; i<solvec.size(); i++) { if (solvec[i] != NULL) { VecDestroy(solvec[i]); } } solvec.clear(); ts->destroy(); VecDestroy(rho); VecDestroy(nu); VecDestroy(initialDisplacement); VecDestroy(initialVelocity); VecDestroy(alpha); DADestroy(da); PetscFinalize(); return 0; */ Vec gt, nr; concatenateVecs(solvec, gt); Vec guess; VecDuplicate(alpha, &guess); VecZeroEntries(guess); // VecDuplicate(guess, &Out); // VecZeroEntries(Out); // double norm; /* PetscRandom rctx; PetscRandomCreate(PETSC_COMM_WORLD, &rctx); PetscRandomSetFromOptions(rctx); VecSetRandom(guess, rctx); VecNorm(guess, NORM_2, &norm); PetscPrintf(0, "guess norm = %g\n", norm); */ // double errnorm; // double exsolnorm; // Inverse solver set up // std::cout << RED"Setting up Inverse Solver"NRM << std::endl; parametricWaveInverse* hyperInv = new parametricWaveInverse; // std::cout << GRN"Finished setting up Inverse Solver"NRM << std::endl; hyperInv->setTimeStepper(ts); // set the timestepper hyperInv->setForwardInitialConditions(initialDisplacement, initialVelocity); // std::cout << RED"Setting initial guess"NRM << std::endl; // hyperInv->setInitialGuess(truth);// set the initial guess hyperInv->setInitialGuess(guess);// set the initial guess // std::cout << GRN"Done setting initial guess"NRM << std::endl; hyperInv->setRegularizationParameter(beta); // set the regularization paramter hyperInv->setAdjoints(solvec); // set the data for the problem // hyperInv->setForceBasis(fBasis); hyperInv->setNumberOfParameter(numParams); // std::cout << RED"Initializing Inverse Solver"NRM << std::endl; hyperInv->init(); // initialize the inverse solver // if (!rank) // std::cout << RED"Starting Inverse Solve"NRM << std::endl; startTime = MPI_Wtime(); hyperInv->solve(); // solve endTime = MPI_Wtime(); // if (!rank) // std::cout << GRN"FINISHED HESSIAN SOLVE"NRM << std::endl; hyperInv->getCurrentControl(guess); // get the solution hyperInv->destroy(); /* for (int i=0; i<solvec.size(); i++) { if (solvec[i] != NULL) { VecDestroy(solvec[i]); } } solvec.clear(); */ // VecView(guess, 0); if (!rank) std::cout << std::endl << "Error Norms " << std::endl; Vec Err; double gtNorm, solNorm, errNorm; VecDuplicate(guess, &Err); VecWAXPY(Err, -1.0, guess, alpha); VecNorm(alpha, NORM_2, >Norm); VecNorm(guess, NORM_2, &solNorm); VecNorm(Err, NORM_2, &errNorm); if (!rank) { std::cout << "The norms are " << gtNorm << ", " << solNorm << ", " << errNorm << std::endl; std::cout << "Relative error is " << errNorm/gtNorm << std::endl; } // Now we shall do another forward solve ... getForces(guess, newF, da, ti, numParams); Force->setFDynamic(newF); ts->setInitialDisplacement(initialDisplacement); ts->setInitialVelocity(initialVelocity); ts->setAdjoint(false); ts->clearMonitor(); ts->solve(); std::vector<Vec> solvec2 = ts->getSolution(); ts->destroy(); concatenateVecs(solvec2, nr); // Now can clear memory ... for (int i=0; i<solvec2.size(); i++) { if (solvec2[i] != NULL) { VecDestroy(solvec2[i]); } } solvec2.clear(); // Now can clear memory ... for (int i=0; i<newF.size(); i++) { if (newF[i] != NULL) { VecDestroy(newF[i]); } } newF.clear(); /* for (unsigned int i=0; i<truth.size(); i++) { VecNorm(truth[i], NORM_2, >Norm); VecNorm(solvec[i], NORM_2, &solNorm); VecAXPY(solvec[i], -1.0, truth[i]); VecNorm(solvec[i], NORM_2, &errNorm); PetscPrintf(0, "Ground truth at timestep %d is %g, %g, %g\n", i, gtNorm, solNorm, errNorm); // PetscPrintf(0, "Relative Error at timestep %d is %g\n", i, errNorm/gtNorm); } */ VecNorm(gt, NORM_2, >Norm); VecAXPY(nr, -1.0, gt); VecNorm(nr, NORM_2, &errNorm); if (!rank) std::cout << "Total Relative error on state is " << errNorm/gtNorm << std::endl; if (!rank) std::cout << "Wall time is " << endTime - startTime << std::endl; VecDestroy(gt); VecDestroy(nr); VecDestroy(Err); VecDestroy(alpha); VecDestroy(guess); VecDestroy(rho); VecDestroy(nu); VecDestroy(initialDisplacement); VecDestroy(initialVelocity); DADestroy(da); PetscFinalize(); }
PetscErrorCode ComputeMatrix(DA da,Mat B) { PetscErrorCode ierr; PetscInt i,j,k,mx,my,mz,xm,ym,zm,xs,ys,zs,dof,k1,k2,k3; PetscScalar *v,*v_neighbor,Hx,Hy,Hz,HxHydHz,HyHzdHx,HxHzdHy; MatStencil row,col; PetscFunctionBegin; ierr = DAGetInfo(da,0,&mx,&my,&mz,0,0,0,&dof,0,0,0);CHKERRQ(ierr); /* For simplicity, this example only works on mx=my=mz */ if ( mx != my || mx != mz) SETERRQ3(1,"This example only works with mx %d = my %d = mz %d\n",mx,my,mz); Hx = 1.0 / (PetscReal)(mx-1); Hy = 1.0 / (PetscReal)(my-1); Hz = 1.0 / (PetscReal)(mz-1); HxHydHz = Hx*Hy/Hz; HxHzdHy = Hx*Hz/Hy; HyHzdHx = Hy*Hz/Hx; ierr = PetscMalloc((2*dof*dof+1)*sizeof(PetscScalar),&v);CHKERRQ(ierr); v_neighbor = v + dof*dof; ierr = PetscMemzero(v,(2*dof*dof+1)*sizeof(PetscScalar));CHKERRQ(ierr); k3 = 0; for (k1=0; k1<dof; k1++){ for (k2=0; k2<dof; k2++){ if (k1 == k2){ v[k3] = 2.0*(HxHydHz + HxHzdHy + HyHzdHx); v_neighbor[k3] = -HxHydHz; } else { v[k3] = k1/(dof*dof); ; v_neighbor[k3] = k2/(dof*dof); } k3++; } } ierr = DAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm);CHKERRQ(ierr); for (k=zs; k<zs+zm; k++){ for (j=ys; j<ys+ym; j++){ for(i=xs; i<xs+xm; i++){ row.i = i; row.j = j; row.k = k; if (i==0 || j==0 || k==0 || i==mx-1 || j==my-1 || k==mz-1){ /* boudary points */ ierr = MatSetValuesBlockedStencil(B,1,&row,1,&row,v,INSERT_VALUES);CHKERRQ(ierr); } else { /* interior points */ /* center */ col.i = i; col.j = j; col.k = k; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v,INSERT_VALUES);CHKERRQ(ierr); /* x neighbors */ col.i = i-1; col.j = j; col.k = k; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); col.i = i+1; col.j = j; col.k = k; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); /* y neighbors */ col.i = i; col.j = j-1; col.k = k; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); col.i = i; col.j = j+1; col.k = k; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); /* z neighbors */ col.i = i; col.j = j; col.k = k-1; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); col.i = i; col.j = j; col.k = k+1; ierr = MatSetValuesBlockedStencil(B,1,&row,1,&col,v_neighbor,INSERT_VALUES);CHKERRQ(ierr); } } } } ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscFree(v);CHKERRQ(ierr); PetscFunctionReturn(0); }
/* MSA_BoundaryConditions - Calculates the boundary conditions for the region. Input Parameter: . user - user-defined application context Output Parameter: . user - user-defined application context */ static int MSA_BoundaryConditions(AppCtx * user) { int info; PetscInt i,j,k,limit=0,maxits=5; PetscInt xs,ys,xm,ym,gxs,gys,gxm,gym; PetscInt mx=user->mx,my=user->my; PetscInt bsize=0, lsize=0, tsize=0, rsize=0; double one=1.0, two=2.0, three=3.0, tol=1e-10; double fnorm,det,hx,hy,xt=0,yt=0; double u1,u2,nf1,nf2,njac11,njac12,njac21,njac22; double b=-0.5, t=0.5, l=-0.5, r=0.5; double *boundary; PetscTruth flg; /* Get local mesh boundaries */ info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); bsize=xm+2; lsize=ym+2; rsize=ym+2; tsize=xm+2; info = PetscMalloc(bsize*sizeof(double),&user->bottom); CHKERRQ(info); info = PetscMalloc(tsize*sizeof(double),&user->top); CHKERRQ(info); info = PetscMalloc(lsize*sizeof(double),&user->left); CHKERRQ(info); info = PetscMalloc(rsize*sizeof(double),&user->right); CHKERRQ(info); hx= (r-l)/(mx+1); hy=(t-b)/(my+1); for (j=0; j<4; j++){ if (j==0){ yt=b; xt=l+hx*xs; limit=bsize; boundary=user->bottom; } else if (j==1){ yt=t; xt=l+hx*xs; limit=tsize; boundary=user->top; } else if (j==2){ yt=b+hy*ys; xt=l; limit=lsize; boundary=user->left; } else { //if (j==3) yt=b+hy*ys; xt=r; limit=rsize; boundary=user->right; } for (i=0; i<limit; i++){ u1=xt; u2=-yt; for (k=0; k<maxits; k++){ nf1=u1 + u1*u2*u2 - u1*u1*u1/three-xt; nf2=-u2 - u1*u1*u2 + u2*u2*u2/three-yt; fnorm=sqrt(nf1*nf1+nf2*nf2); if (fnorm <= tol) break; njac11=one+u2*u2-u1*u1; njac12=two*u1*u2; njac21=-two*u1*u2; njac22=-one - u1*u1 + u2*u2; det = njac11*njac22-njac21*njac12; u1 = u1-(njac22*nf1-njac12*nf2)/det; u2 = u2-(njac11*nf2-njac21*nf1)/det; } boundary[i]=u1*u1-u2*u2; if (j==0 || j==1) { xt=xt+hx; } else { // if (j==2 || j==3) yt=yt+hy; } } } /* Scale the boundary if desired */ if (1==1){ PetscReal scl = 1.0; info = PetscOptionsGetReal(PETSC_NULL,"-bottom",&scl,&flg); CHKERRQ(info); if (flg){ for (i=0;i<bsize;i++) user->bottom[i]*=scl; } info = PetscOptionsGetReal(PETSC_NULL,"-top",&scl,&flg); CHKERRQ(info); if (flg){ for (i=0;i<tsize;i++) user->top[i]*=scl; } info = PetscOptionsGetReal(PETSC_NULL,"-right",&scl,&flg); CHKERRQ(info); if (flg){ for (i=0;i<rsize;i++) user->right[i]*=scl; } info = PetscOptionsGetReal(PETSC_NULL,"-left",&scl,&flg); CHKERRQ(info); if (flg){ for (i=0;i<lsize;i++) user->left[i]*=scl; } } return 0; }
/* QuadraticH - Evaluates Hessian matrix. Input Parameters: . user - user-defined context, as set by TaoSetHessian() . X - input vector Output Parameter: . H - Hessian matrix */ int QuadraticH(AppCtx *user, Vec X, Mat Hessian) { int info; PetscInt i,j,k; PetscInt mx=user->mx, my=user->my; PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym; double hx=1.0/(mx+1), hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy; double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; double hl,hr,ht,hb,hc,htl,hbr; PetscScalar **x, v[7]; MatStencil col[7],row; Vec localX; PetscTruth assembled; /* Get local mesh boundaries */ info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Scatter ghost points to local vector */ info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointers to vector data */ info = DAVecGetArray(user->da,localX,(void**)&x); /* Initialize matrix entries to zero */ info = MatAssembled(Hessian,&assembled); CHKERRQ(info); if (assembled){info = MatZeroEntries(Hessian); CHKERRQ(info);} /* Set various matrix options */ info = MatSetOption(Hessian,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE); CHKERRQ(info); /* Compute Hessian over the locally owned part of the mesh */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ xc = x[j][i]; xlt=xrb=xl=xr=xb=xt=xc; /* Left side */ if (i==0){ xl = user->left[j-ys+1]; xlt = user->left[j-ys+2]; } else { xl = x[j][i-1]; } if (j==0){ xb = user->bottom[i-xs+1]; xrb = user->bottom[i-xs+2]; } else { xb = x[j-1][i]; } if (i+1 == mx){ xr = user->right[j-ys+1]; xrb = user->right[j-ys]; } else { xr = x[j][i+1]; } if (j+1==my){ xt = user->top[i-xs+1]; xlt = user->top[i-xs]; }else { xt = x[j+1][i]; } if (i>0 && j+1<my){ xlt = x[j+1][i-1]; } if (j>0 && i+1<mx){ xrb = x[j-1][i+1]; } d1 = (xc-xl)/hx; d2 = (xc-xr)/hx; d3 = (xc-xt)/hy; d4 = (xc-xb)/hy; d5 = (xrb-xr)/hy; d6 = (xrb-xb)/hx; d7 = (xlt-xl)/hy; d8 = (xlt-xt)/hx; f1 = sqrt( 1.0 + d1*d1 + d7*d7); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f3 = sqrt( 1.0 + d3*d3 + d8*d8); f4 = sqrt( 1.0 + d3*d3 + d2*d2); f5 = sqrt( 1.0 + d2*d2 + d5*d5); f6 = sqrt( 1.0 + d4*d4 + d6*d6); hl = (-hydhx*(1.0+d7*d7)+d1*d7)/(f1*f1*f1)+ (-hydhx*(1.0+d4*d4)+d1*d4)/(f2*f2*f2); hr = (-hydhx*(1.0+d5*d5)+d2*d5)/(f5*f5*f5)+ (-hydhx*(1.0+d3*d3)+d2*d3)/(f4*f4*f4); ht = (-hxdhy*(1.0+d8*d8)+d3*d8)/(f3*f3*f3)+ (-hxdhy*(1.0+d2*d2)+d2*d3)/(f4*f4*f4); hb = (-hxdhy*(1.0+d6*d6)+d4*d6)/(f6*f6*f6)+ (-hxdhy*(1.0+d1*d1)+d1*d4)/(f2*f2*f2); hbr = -d2*d5/(f5*f5*f5) - d4*d6/(f6*f6*f6); htl = -d1*d7/(f1*f1*f1) - d3*d8/(f3*f3*f3); hc = hydhx*(1.0+d7*d7)/(f1*f1*f1) + hxdhy*(1.0+d8*d8)/(f3*f3*f3) + hydhx*(1.0+d5*d5)/(f5*f5*f5) + hxdhy*(1.0+d6*d6)/(f6*f6*f6) + (hxdhy*(1.0+d1*d1)+hydhx*(1.0+d4*d4)-2*d1*d4)/(f2*f2*f2) + (hxdhy*(1.0+d2*d2)+hydhx*(1.0+d3*d3)-2*d2*d3)/(f4*f4*f4); hl/=2.0; hr/=2.0; ht/=2.0; hb/=2.0; hbr/=2.0; htl/=2.0; hc/=2.0; row.j = j; row.i = i; k=0; if (j>0){ v[k]=hb; col[k].j = j - 1; col[k].i = i; k++; } if (j>0 && i < mx -1){ v[k]=hbr; col[k].j = j - 1; col[k].i = i+1; k++; } if (i>0){ v[k]= hl; col[k].j = j; col[k].i = i-1; k++; } v[k]= hc; col[k].j = j; col[k].i = i; k++; if (i < mx-1 ){ v[k]= hr; col[k].j = j; col[k].i = i+1; k++; } if (i>0 && j < my-1 ){ v[k]= htl; col[k].j = j+1; col[k].i = i-1; k++; } if (j < my-1 ){ v[k]= ht; col[k].j = j+1; col[k].i = i; k++; } /* Set matrix values using local numbering, which was defined earlier, in the main routine. */ info = MatSetValuesStencil(Hessian,1,&row,k,col,v,INSERT_VALUES); CHKERRQ(info); } } /* Restore vectors */ info = DAVecRestoreArray(user->da,localX,(void**)&x); info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); /* Assemble the matrix */ info = MatAssemblyBegin(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = MatAssemblyEnd(Hessian,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = PetscLogFlops(199*xm*ym); CHKERRQ(info); return 0; }
/* FormFunctionGradient - Evaluates the function and corresponding gradient. Input Parameters: . taoapp - the TAO_APPLICATION context . XX - input vector . userCtx - optional user-defined context, as set by TaoSetFunctionGradient() Output Parameters: . fcn - the newly evaluated function . GG - vector containing the newly evaluated gradient */ int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *userCtx){ AppCtx * user = (AppCtx *) userCtx; int info; PetscInt i,j; PetscInt mx=user->mx, my=user->my; PetscInt xs,xm,gxs,gxm,ys,ym,gys,gym; double ft=0; double hx=1.0/(mx+1),hy=1.0/(my+1), hydhx=hy/hx, hxdhy=hx/hy, area=0.5*hx*hy; double rhx=mx+1, rhy=my+1; double f1,f2,f3,f4,f5,f6,d1,d2,d3,d4,d5,d6,d7,d8,xc,xl,xr,xt,xb,xlt,xrb; double df1dxc,df2dxc,df3dxc,df4dxc,df5dxc,df6dxc; PetscScalar **g, **x; Vec localX; /* Get local mesh boundaries */ info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGetCorners(user->da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,PETSC_NULL,&gxm,&gym,PETSC_NULL); CHKERRQ(info); /* Scatter ghost points to local vector */ info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); /* Get pointers to vector data */ info = DAVecGetArray(user->da,localX,(void**)&x); info = DAVecGetArray(user->da,G,(void**)&g); /* Compute function and gradient over the locally owned part of the mesh */ for (j=ys; j<ys+ym; j++){ for (i=xs; i< xs+xm; i++){ xc = x[j][i]; xlt=xrb=xl=xr=xb=xt=xc; if (i==0){ /* left side */ xl= user->left[j-ys+1]; xlt = user->left[j-ys+2]; } else { xl = x[j][i-1]; } if (j==0){ /* bottom side */ xb=user->bottom[i-xs+1]; xrb =user->bottom[i-xs+2]; } else { xb = x[j-1][i]; } if (i+1 == gxs+gxm){ /* right side */ xr=user->right[j-ys+1]; xrb = user->right[j-ys]; } else { xr = x[j][i+1]; } if (j+1==gys+gym){ /* top side */ xt=user->top[i-xs+1]; xlt = user->top[i-xs]; }else { xt = x[j+1][i]; } if (i>gxs && j+1<gys+gym){ xlt = x[j+1][i-1]; } if (j>gys && i+1<gxs+gxm){ xrb = x[j-1][i+1]; } d1 = (xc-xl); d2 = (xc-xr); d3 = (xc-xt); d4 = (xc-xb); d5 = (xr-xrb); d6 = (xrb-xb); d7 = (xlt-xl); d8 = (xt-xlt); df1dxc = d1*hydhx; df2dxc = ( d1*hydhx + d4*hxdhy ); df3dxc = d3*hxdhy; df4dxc = ( d2*hydhx + d3*hxdhy ); df5dxc = d2*hydhx; df6dxc = d4*hxdhy; d1 *= rhx; d2 *= rhx; d3 *= rhy; d4 *= rhy; d5 *= rhy; d6 *= rhx; d7 *= rhy; d8 *= rhx; f1 = sqrt( 1.0 + d1*d1 + d7*d7); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f3 = sqrt( 1.0 + d3*d3 + d8*d8); f4 = sqrt( 1.0 + d3*d3 + d2*d2); f5 = sqrt( 1.0 + d2*d2 + d5*d5); f6 = sqrt( 1.0 + d4*d4 + d6*d6); f2 = sqrt( 1.0 + d1*d1 + d4*d4); f4 = sqrt( 1.0 + d3*d3 + d2*d2); ft = ft + (f2 + f4); df1dxc /= f1; df2dxc /= f2; df3dxc /= f3; df4dxc /= f4; df5dxc /= f5; df6dxc /= f6; g[j][i] = (df1dxc+df2dxc+df3dxc+df4dxc+df5dxc+df6dxc ) * 0.5; } } /* Compute triangular areas along the border of the domain. */ if (xs==0){ /* left side */ for (j=ys; j<ys+ym; j++){ d3=(user->left[j-ys+1] - user->left[j-ys+2])*rhy; d2=(user->left[j-ys+1] - x[j][0]) *rhx; ft = ft+sqrt( 1.0 + d3*d3 + d2*d2); } } if (ys==0){ /* bottom side */ for (i=xs; i<xs+xm; i++){ d2=(user->bottom[i+1-xs]-user->bottom[i-xs+2])*rhx; d3=(user->bottom[i-xs+1]-x[0][i])*rhy; ft = ft+sqrt( 1.0 + d3*d3 + d2*d2); } } if (xs+xm==mx){ /* right side */ for (j=ys; j< ys+ym; j++){ d1=(x[j][mx-1] - user->right[j-ys+1])*rhx; d4=(user->right[j-ys]-user->right[j-ys+1])*rhy; ft = ft+sqrt( 1.0 + d1*d1 + d4*d4); } } if (ys+ym==my){ /* top side */ for (i=xs; i<xs+xm; i++){ d1=(x[my-1][i] - user->top[i-xs+1])*rhy; d4=(user->top[i-xs+1] - user->top[i-xs])*rhx; ft = ft+sqrt( 1.0 + d1*d1 + d4*d4); } } if (ys==0 && xs==0){ d1=(user->left[0]-user->left[1])/hy; d2=(user->bottom[0]-user->bottom[1])*rhx; ft +=sqrt( 1.0 + d1*d1 + d2*d2); } if (ys+ym == my && xs+xm == mx){ d1=(user->right[ym+1] - user->right[ym])*rhy; d2=(user->top[xm+1] - user->top[xm])*rhx; ft +=sqrt( 1.0 + d1*d1 + d2*d2); } ft=ft*area; info = MPI_Allreduce(&ft,fcn,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);CHKERRQ(info); /* Restore vectors */ info = DAVecRestoreArray(user->da,localX,(void**)&x); info = DAVecRestoreArray(user->da,G,(void**)&g); /* Scatter values to global vector */ info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); info = PetscLogFlops(67*xm*ym); CHKERRQ(info); return 0; }
/* FormHessian computes the quadratic term in the quadratic objective function Notice that the objective function in this problem is quadratic (therefore a constant hessian). If using a nonquadratic solver, then you might want to reconsider this function */ int FormHessian(TAO_APPLICATION taoapp,Vec X,Mat *H, Mat *Hpre, MatStructure *flg, void *ptr) { AppCtx* user=(AppCtx*)ptr; int info; PetscInt i,j,k; PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0); PetscReal hx,hy,hxhy,hxhx,hyhy; PetscReal xi,v[5]; PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6; PetscReal vmiddle, vup, vdown, vleft, vright; Mat hes=*H; PetscTruth assembled; nx=user->nx; ny=user->ny; hx=two*pi/(nx+1.0); hy=two*user->b/(ny+1.0); hxhy=hx*hy; hxhx=one/(hx*hx); hyhy=one/(hy*hy); *flg=SAME_NONZERO_PATTERN; /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info); info = MatAssembled(hes,&assembled); CHKERRQ(info); if (assembled){info = MatZeroEntries(hes); CHKERRQ(info);} for (i=xs; i< xs+xm; i++){ xi=(i+1)*hx; trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */ trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */ trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */ trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */ trule5=trule1; /* L(i,j-1) */ trule6=trule2; /* U(i,j+1) */ vdown=-(trule5+trule2)*hyhy; vleft=-hxhx*(trule2+trule4); vright= -hxhx*(trule1+trule3); vup=-hyhy*(trule1+trule6); vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6); v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0; for (j=ys; j<ys+ym; j++){ row=(j-gys)*gxm + (i-gxs); k=0; if (j>gys){ v[k]=vdown; col[k]=row - gxm; k++; } if (i>gxs){ v[k]= vleft; col[k]=row - 1; k++; } v[k]= vmiddle; col[k]=row; k++; if (i+1 < gxs+gxm){ v[k]= vright; col[k]=row+1; k++; } if (j+1 <gys+gym){ v[k]= vup; col[k] = row+gxm; k++; } info = MatSetValuesLocal(hes,1,&row,k,col,v,INSERT_VALUES); CHKERRQ(info); } } /* Assemble matrix, using the 2-step process: MatAssemblyBegin(), MatAssemblyEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ info = MatAssemblyBegin(hes,MAT_FINAL_ASSEMBLY); CHKERRQ(info); info = MatAssemblyEnd(hes,MAT_FINAL_ASSEMBLY); CHKERRQ(info); /* Tell the matrix we will never add a new nonzero location to the matrix. If we do it will generate an error. */ info = MatSetOption(hes,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE); CHKERRQ(info); info = MatSetOption(hes,MAT_SYMMETRIC,PETSC_TRUE); CHKERRQ(info); info = PetscLogFlops(9*xm*ym+49*xm); CHKERRQ(info); return 0; }
int FormFunctionGradient(TAO_APPLICATION taoapp, Vec X, double *fcn,Vec G,void *ptr) { AppCtx* user=(AppCtx*)ptr; int info; PetscInt i,j,k,kk; PetscInt col[5],row,nx,ny,xs,xm,gxs,gxm,ys,ym,gys,gym; PetscReal one=1.0, two=2.0, six=6.0,pi=4.0*atan(1.0); PetscReal hx,hy,hxhy,hxhx,hyhy; PetscReal xi,v[5]; PetscReal ecc=user->ecc, trule1,trule2,trule3,trule4,trule5,trule6; PetscReal vmiddle, vup, vdown, vleft, vright; PetscReal tt,f1,f2; PetscReal *x,*g,zero=0.0; Vec localX; nx=user->nx; ny=user->ny; hx=two*pi/(nx+1.0); hy=two*user->b/(ny+1.0); hxhy=hx*hy; hxhx=one/(hx*hx); hyhy=one/(hy*hy); info = DAGetLocalVector(user->da,&localX);CHKERRQ(info); info = DAGlobalToLocalBegin(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = DAGlobalToLocalEnd(user->da,X,INSERT_VALUES,localX); CHKERRQ(info); info = VecSet(G, zero); CHKERRQ(info); /* Get local grid boundaries */ info = DAGetCorners(user->da,&xs,&ys,TAO_NULL,&xm,&ym,TAO_NULL); CHKERRQ(info); info = DAGetGhostCorners(user->da,&gxs,&gys,TAO_NULL,&gxm,&gym,TAO_NULL); CHKERRQ(info); info = VecGetArray(localX,&x); CHKERRQ(info); info = VecGetArray(G,&g); CHKERRQ(info); for (i=xs; i< xs+xm; i++){ xi=(i+1)*hx; trule1=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi,ecc) ) / six; /* L(i,j) */ trule2=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi,ecc) ) / six; /* U(i,j) */ trule3=hxhy*( p(xi,ecc) + p(xi+hx,ecc) + p(xi+hx,ecc) ) / six; /* U(i+1,j) */ trule4=hxhy*( p(xi,ecc) + p(xi-hx,ecc) + p(xi-hx,ecc) ) / six; /* L(i-1,j) */ trule5=trule1; /* L(i,j-1) */ trule6=trule2; /* U(i,j+1) */ vdown=-(trule5+trule2)*hyhy; vleft=-hxhx*(trule2+trule4); vright= -hxhx*(trule1+trule3); vup=-hyhy*(trule1+trule6); vmiddle=(hxhx)*(trule1+trule2+trule3+trule4)+hyhy*(trule1+trule2+trule5+trule6); for (j=ys; j<ys+ym; j++){ row=(j-gys)*gxm + (i-gxs); v[0]=0; v[1]=0; v[2]=0; v[3]=0; v[4]=0; k=0; if (j>gys){ v[k]=vdown; col[k]=row - gxm; k++; } if (i>gxs){ v[k]= vleft; col[k]=row - 1; k++; } v[k]= vmiddle; col[k]=row; k++; if (i+1 < gxs+gxm){ v[k]= vright; col[k]=row+1; k++; } if (j+1 <gys+gym){ v[k]= vup; col[k] = row+gxm; k++; } tt=0; for (kk=0;kk<k;kk++){ tt+=v[kk]*x[col[kk]]; } row=(j-ys)*xm + (i-xs); g[row]=tt; } } info = VecRestoreArray(localX,&x); CHKERRQ(info); info = VecRestoreArray(G,&g); CHKERRQ(info); info = DARestoreLocalVector(user->da,&localX); CHKERRQ(info); info = VecDot(X,G,&f1); CHKERRQ(info); info = VecDot(user->B,X,&f2); CHKERRQ(info); info = VecAXPY(G, one, user->B); CHKERRQ(info); *fcn = f1/2.0 + f2; info = PetscLogFlops((91 + 10*ym) * xm); CHKERRQ(info); return 0; }
/* Visualize solutions */ PetscErrorCode MySolutionView(MPI_Comm comm,PetscInt phy_num,void *ctx) { PetscErrorCode ierr; AppCtx *user = (AppCtx*)ctx; DMMG *dmmg = user->dmmg; DA da=DMMGGetDA(dmmg); Field **x = user->x; Field1 **x1 = user->x1; PetscInt i,j,mx,xs,ys,xm,ym; PetscMPIInt size; PetscFunctionBegin; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); ierr = DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);CHKERRQ(ierr); switch (phy_num){ case 0: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"Original Physics %d U,V,Omega,Temp: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"-----------------------------------\n"); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x[j][i].u,x[j][i].v,x[j][i].omega,x[j][i].temp); } } } break; case 1: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: U,V,Omega: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------\n"); DMMG *dmmg1=user->dmmg1; Vec solu_true = DMMGGetx(dmmg1); DA da=DMMGGetDA(dmmg1); Field1 **x1; ierr = DAVecGetArray(da,solu_true,&x1);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega); } } ierr = DAVecRestoreArray(da,solu_true,&x1);CHKERRQ(ierr); } break; case 2: if (size == 1){ ierr = PetscPrintf(PETSC_COMM_SELF,"SubPhysics %d: Temperature: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"--------------------------\n"); DMMG *dmmg2=user->dmmg2; Vec solu_true = DMMGGetx(dmmg2); DA da=DMMGGetDA(dmmg2); Field2 **x2; ierr = DAVecGetArray(da,solu_true,&x2);CHKERRQ(ierr); for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g\n",j,i,x2[j][i].temp); } } ierr = DAVecRestoreArray(da,solu_true,&x2);CHKERRQ(ierr); } break; default: if (size == 1){ DMMG *dmmg_comp=user->dmmg_comp; DA da1,da2,da=DMMGGetDA(dmmg); Vec X1,X2,solu_true = DMMGGetx(dmmg); Field **x; Field1 **x1; Field2 **x2; DMComposite dm = (DMComposite)(*dmmg_comp)->dm; PetscReal err,err_tmp; if (phy_num == 3){ ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics %d, U,V,Omega,Temp: \n",phy_num); ierr = PetscPrintf(PETSC_COMM_SELF,"------------------------------------\n"); ierr = PetscPrintf(PETSC_COMM_SELF,"Composite physics, U,V,Omega,Temp: \n");CHKERRQ(ierr); } ierr = DAVecGetArray(da,solu_true,&x);CHKERRQ(ierr); ierr = DMCompositeGetEntries(dm,&da1,&da2);CHKERRQ(ierr); ierr = DMCompositeGetLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DAVecGetArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecGetArray(da2,X2,(void**)&x2);CHKERRQ(ierr); err = 0.0; for (j=ys; j<ys+ym; j++) { for (i=xs; i<xs+xm; i++) { err_tmp = PetscAbs(x[j][i].u-x1[j][i].u) + PetscAbs(x[j][i].v-x1[j][i].v) + PetscAbs(x[j][i].omega-x1[j][i].omega); err_tmp += PetscAbs(x[j][i].temp-x2[j][i].temp); if (err < err_tmp) err = err_tmp; if (phy_num == 3){ ierr = PetscPrintf(PETSC_COMM_SELF,"x[%d,%d] = %g, %g, %g, %g\n",j,i,x1[j][i].u,x1[j][i].v,x1[j][i].omega,x2[j][i].temp); } } } ierr = PetscPrintf(PETSC_COMM_SELF,"|solu - solu_comp| = %g\n",err);CHKERRQ(ierr); ierr = DAVecRestoreArray(da1,X1,(void**)&x1);CHKERRQ(ierr); ierr = DAVecRestoreArray(da2,X2,(void**)&x2);CHKERRQ(ierr); ierr = DMCompositeRestoreLocalVectors(dm,&X1,&X2);CHKERRQ(ierr); ierr = DAVecRestoreArray(da,solu_true,&x);CHKERRQ(ierr); } } PetscFunctionReturn(0); }
extern PetscErrorCode DefiantBlackOilComputePerfIndicesSyncPerfs(BlackOilReservoirSimulation* MySim) { PetscErrorCode ierr; PetscInt mx, my, mz, xm, ym, zm, xs, ys, zs; PetscInt i, rank; /* Well handling variables */ PetscInt PerfIDMine, WellID; PetscInt MyI, MyJ, MyK; PetscScalar re; /* Local values for variables*/ PetscScalar ***Localx1, ***Localx2, ***Localx3; PetscScalar ***Localh1, ***Localh2, ***Localh3; PetscScalar ***LocalSo, ***LocalSw, ***LocalSg; PetscScalar ***LocalPo, ***LocalPw, ***LocalPg; PetscScalar ***LocalMuo, ***LocalMuw, ***LocalMug; PetscScalar ***LocalRhoo, ***LocalRhow, ***LocalRhog; PetscScalar ***LocalK11, ***LocalK22, ***LocalK33; PetscScalar ***LocalKro, ***LocalKrw, ***LocalKrg; PetscScalar ***LocalBo, ***LocalBw, ***LocalBg; PetscScalar ***LocalPcow, ***LocalPcog; /* temporary array */ PetscScalar *InBuffer; PetscFunctionBegin; /* Allocate the In and out Buffers, we have 27 doubles at each perforation */ ierr = PetscMalloc(sizeof(PetscScalar)*27, &InBuffer);CHKERRQ(ierr);CHKMEMQ; /* Get dimensions and extents of the local vectors */ ierr = DAGetInfo(MySim->SimDA, 0, &mx, &my, &mz, 0, 0, 0, 0, 0, 0, 0);CHKERRQ(ierr); ierr = DAGetCorners(MySim->SimDA, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); /* Grab the local coordiantes */ ierr = DAVecGetArray(MySim->SimDA, MySim->x1, &Localx1);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->x2, &Localx2);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->x3, &Localx3);CHKERRQ(ierr);CHKMEMQ; /* Grab the local geometry */ ierr = DAVecGetArray(MySim->SimDA, MySim->h1, &Localh1);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->h2, &Localh2);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->h3, &Localh3);CHKERRQ(ierr);CHKMEMQ; /* Grab the Saturations */ ierr = DAVecGetArray(MySim->SimDA, MySim->So, &LocalSo);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Sw, &LocalSw);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Sg, &LocalSg);CHKERRQ(ierr);CHKMEMQ; /* Grab the Pressures */ ierr = DAVecGetArray(MySim->SimDA, MySim->Po, &LocalPo);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Pw, &LocalPw);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Pg, &LocalPg);CHKERRQ(ierr);CHKMEMQ; /* Grab the Densities */ ierr = DAVecGetArray(MySim->SimDA, MySim->Rhoo, &LocalRhoo);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Rhow, &LocalRhow);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Rhog, &LocalRhog);CHKERRQ(ierr);CHKMEMQ; /* Grab the local viscosities*/ ierr = DAVecGetArray(MySim->SimDA, MySim->Muo, &LocalMuo);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Muw, &LocalMuw);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Mug, &LocalMug);CHKERRQ(ierr);CHKMEMQ; /* Grab the local permeabilities */ ierr = DAVecGetArray(MySim->SimDA, MySim->K11, &LocalK11);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->K22, &LocalK22);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->K33, &LocalK33);CHKERRQ(ierr);CHKMEMQ; /* Grab the local permeabilities */ ierr = DAVecGetArray(MySim->SimDA, MySim->Kro, &LocalKro);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Krw, &LocalKrw);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Krg, &LocalKrg);CHKERRQ(ierr);CHKMEMQ; /* Grab the local capillary pressure */ ierr = DAVecGetArray(MySim->SimDA, MySim->Pcow, &LocalPcow);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Pcog, &LocalPcog);CHKERRQ(ierr);CHKMEMQ; /* Grab the local data for volume factors at the cell centers */ ierr = DAVecGetArray(MySim->SimDA, MySim->Bo, &LocalBo);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Bw, &LocalBw);CHKERRQ(ierr);CHKMEMQ; ierr = DAVecGetArray(MySim->SimDA, MySim->Bg, &LocalBg);CHKERRQ(ierr);CHKMEMQ; /* Get the current rank */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);CHKMEMQ; /* Now we sync all the flow rates and BHP's across all perforations */ /* At the end of this loop, all information across all wells is uniform and up-to-date */ for (WellID = 0; WellID < MySim->NumberOfWells; WellID++) { for (PerfIDMine = 0; PerfIDMine < (MySim->Wells[WellID]).NumberOfPerforations; PerfIDMine++) { MyI = (MySim->Wells[WellID]).Perforations[PerfIDMine].I;CHKMEMQ; MyJ = (MySim->Wells[WellID]).Perforations[PerfIDMine].J;CHKMEMQ; MyK = (MySim->Wells[WellID]).Perforations[PerfIDMine].K;CHKMEMQ; if (MyI >= xs && MyI < xs+xm && MyJ >= ys && MyJ < ys+ym && MyK >= zs && MyK < zs+zm) { MySim->Wells[WellID].Perforations[PerfIDMine].So = LocalSo[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Sw = LocalSw[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Sg = LocalSg[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Po = LocalPo[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Pw = LocalPw[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Pg = LocalPg[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Kro = LocalKro[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Krw = LocalKrw[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Krg = LocalKrg[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Muo = LocalMuo[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Muw = LocalMuw[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Mug = LocalMug[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo = LocalRhoo[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Rhow = LocalRhow[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Rhog = LocalRhog[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Pcow = LocalPcow[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Pcog = LocalPcog[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Bo = LocalBo[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Bw = LocalBw[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].Bg = LocalBg[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].x1 = Localx1[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].x2 = Localx2[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].x3 = Localx3[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].h1 = Localh1[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].h2 = Localh2[MyK][MyJ][MyI];CHKMEMQ; MySim->Wells[WellID].Perforations[PerfIDMine].h3 = Localh3[MyK][MyJ][MyI];CHKMEMQ; /* we also compute the well indices */ if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation == PERF_ORIENTATION_X1X1) { re = 0.14 / 0.5 * sqrt((sqrt(LocalK33[MyK][MyJ][MyI] / LocalK22[MyK][MyJ][MyI]) * Localh2[MyK][MyJ][MyI] * Localh2[MyK][MyJ][MyI] + sqrt(LocalK22[MyK][MyJ][MyI] / LocalK33[MyK][MyJ][MyI]) * Localh3[MyK][MyJ][MyI] * Localh3[MyK][MyJ][MyI])) / (pow(LocalK33[MyK][MyJ][MyI] / LocalK22[MyK][MyJ][MyI], 0.25) + pow(LocalK22[MyK][MyJ][MyI] / LocalK33[MyK][MyJ][MyI], 0.25)); MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI * Localh1[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI] * LocalK33[MyK][MyJ][MyI]) / (log(re / MySim->Wells[WellID].Perforations[PerfIDMine].Rw) + MySim->Wells[WellID].Perforations[PerfIDMine].S); } else if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation == PERF_ORIENTATION_X2X2) { re = 0.14 / 0.5 * sqrt((sqrt(LocalK33[MyK][MyJ][MyI] / LocalK11[MyK][MyJ][MyI]) * Localh1[MyK][MyJ][MyI] * Localh1[MyK][MyJ][MyI] + sqrt(LocalK11[MyK][MyJ][MyI] / LocalK33[MyK][MyJ][MyI]) * Localh3[MyK][MyJ][MyI] * Localh3[MyK][MyJ][MyI])) / (pow(LocalK33[MyK][MyJ][MyI] / LocalK11[MyK][MyJ][MyI], 0.25) + pow(LocalK11[MyK][MyJ][MyI] / LocalK33[MyK][MyJ][MyI], 0.25)); MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI * Localh2[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI] * LocalK33[MyK][MyJ][MyI]) / (log(re / MySim->Wells[WellID].Perforations[PerfIDMine].Rw) + MySim->Wells[WellID].Perforations[PerfIDMine].S); } else if ((MySim->Wells[WellID]).Perforations[PerfIDMine].Orientation == PERF_ORIENTATION_X3X3) { re = 0.14 / 0.5 * sqrt((sqrt(LocalK22[MyK][MyJ][MyI] / LocalK11[MyK][MyJ][MyI]) * Localh1[MyK][MyJ][MyI] * Localh1[MyK][MyJ][MyI] + sqrt(LocalK11[MyK][MyJ][MyI] / LocalK22[MyK][MyJ][MyI]) * Localh2[MyK][MyJ][MyI] * Localh2[MyK][MyJ][MyI])) / (pow(LocalK22[MyK][MyJ][MyI] / LocalK11[MyK][MyJ][MyI], 0.25) + pow(LocalK11[MyK][MyJ][MyI] / LocalK22[MyK][MyJ][MyI], 0.25)); MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = 2.0 * PI * Localh3[MyK][MyJ][MyI] * sqrt(LocalK11[MyK][MyJ][MyI] * LocalK22[MyK][MyJ][MyI]) / (log(re / MySim->Wells[WellID].Perforations[PerfIDMine].Rw) + MySim->Wells[WellID].Perforations[PerfIDMine].S); } } i = 0; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Po;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pw;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pg;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].So;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Sw;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Sg;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhow;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Rhog;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bo;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bw;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Bg;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Kro;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Krw;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Krg;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Muo;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Muw;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Mug;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x1;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x2;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].x3;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h1;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h2;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].h3;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pcow;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].Pcog;i++; InBuffer[i] = MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex; /* Sync properties at the perforation locations */ ierr = MPI_Bcast(InBuffer, 27, MPI_DOUBLE, MySim->Wells[WellID].Perforations[PerfIDMine].OwnerRank, PETSC_COMM_WORLD);CHKERRQ(ierr);CHKMEMQ; /* and now unpack the data */ i = 0; MySim->Wells[WellID].Perforations[PerfIDMine].Po = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Pw = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Pg = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].So = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Sw = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Sg = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Rhoo = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Rhow = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Rhog = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Bo = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Bw = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Bg = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Kro = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Krw = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Krg = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Muo = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Muw = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Mug = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].x1 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].x2 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].x3 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].h1 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].h2 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].h3 = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Pcow = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].Pcog = InBuffer[i];i++; MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex = InBuffer[i]; PetscPrintf(PETSC_COMM_WORLD, "\n At well: %d Value of WellIndex is:%g", WellID,MySim->Wells[WellID].Perforations[PerfIDMine].WellIndex); } } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; SNES snes; /* nonlinear solver */ Vec Hu,r; /* solution, residual vectors */ Mat J; /* Jacobian matrix */ AppCtx user; /* user-defined work context */ PetscInt its, i, tmpxs, tmpxm; /* iteration count, index, etc. */ PetscReal tmp1, tmp2, tmp3, tmp4, tmp5, errnorms[2], descaleNode[2]; PetscTruth eps_set = PETSC_FALSE, dump = PETSC_FALSE, exactinitial = PETSC_FALSE, snes_mf_set, snes_fd_set; MatFDColoring matfdcoloring = 0; ISColoring iscoloring; SNESConvergedReason reason; /* Check convergence */ PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &user.rank); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "BODVARDSSON solves for thickness and velocity in 1D, steady ice stream\n" " [run with -help for info and options]\n");CHKERRQ(ierr); user.n = 3.0; /* Glen flow law exponent */ user.secpera = 31556926.0; user.rho = 910.0; /* kg m^-3 */ user.rhow = 1028.0; /* kg m^-3 */ user.g = 9.81; /* m s^-2 */ /* ask Test N for its parameters, but only those we need to solve */ ierr = params_exactN(&(user.H0), &tmp1, &(user.xc), &tmp2, &tmp3, &tmp4, &tmp5, &(user.Txc)); CHKERRQ(ierr); /* regularize using strain rate of 1/xc per year */ user.epsilon = (1.0 / user.secpera) / user.xc; /* tools for non-dimensionalizing to improve equation scaling */ user.scaleNode[0] = 1000.0; user.scaleNode[1] = 100.0 / user.secpera; ierr = PetscOptionsTruth("-snes_mf","","",PETSC_FALSE,&snes_mf_set,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-snes_fd","","",PETSC_FALSE,&snes_fd_set,NULL);CHKERRQ(ierr); if (!snes_mf_set && !snes_fd_set) { PetscPrintf(PETSC_COMM_WORLD, "\n***ERROR: bodvardsson needs one or zero of '-snes_mf', '-snes_fd'***\n\n" "USAGE FOLLOWS ...\n\n%s",help); PetscEnd(); } if (snes_fd_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " using approximate Jacobian; finite-differencing using coloring\n"); CHKERRQ(ierr); } else if (snes_mf_set) { ierr = PetscPrintf(PETSC_COMM_WORLD, " matrix free; no preconditioner\n"); CHKERRQ(ierr); } else { ierr = PetscPrintf(PETSC_COMM_WORLD, " true Jacobian\n"); CHKERRQ(ierr); } ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL, "bodvardsson program options",__FILE__);CHKERRQ(ierr); { ierr = PetscOptionsTruth("-bod_up_one","","",PETSC_FALSE,&user.upwind1,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-bod_exact_init","","",PETSC_FALSE,&exactinitial,NULL);CHKERRQ(ierr); ierr = PetscOptionsTruth("-bod_dump", "dump out exact and approximate solution and residual, as asci","", dump,&dump,NULL);CHKERRQ(ierr); ierr = PetscOptionsReal("-bod_epsilon","regularization (a strain rate in units of 1/a)","", user.epsilon * user.secpera,&user.epsilon,&eps_set);CHKERRQ(ierr); if (eps_set) user.epsilon *= 1.0 / user.secpera; } ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Create machinery for parallel grid management (DA), nonlinear solver (SNES), and Vecs for fields (solution, RHS). Note default Mx=46 grid points means dx=10 km. Also degrees of freedom = 2 (thickness and velocity at each point) and stencil radius = ghost width = 2 for 2nd-order upwinding. */ user.solnghostwidth = 2; ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,-46,2,user.solnghostwidth,PETSC_NULL,&user.da); CHKERRQ(ierr); ierr = DASetUniformCoordinates(user.da,0.0,user.xc, PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); ierr = DASetFieldName(user.da,0,"ice thickness [non-dimensional]"); CHKERRQ(ierr); ierr = DASetFieldName(user.da,1,"ice velocity [non-dimensional]"); CHKERRQ(ierr); ierr = DAGetInfo(user.da,PETSC_IGNORE,&user.Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE, PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE); ierr = DAGetCorners(user.da,&user.xs,PETSC_NULL,PETSC_NULL,&user.xm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); user.dx = user.xc / (PetscReal)(user.Mx-1); /* another DA for scalar parameters, with same length */ ierr = DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,user.Mx,1,1,PETSC_NULL,&user.scalarda);CHKERRQ(ierr); ierr = DASetUniformCoordinates(user.scalarda,0.0,user.xc, PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); /* check that parallel layout of scalar DA is same as dof=2 DA */ ierr = DAGetCorners(user.scalarda,&tmpxs,PETSC_NULL,PETSC_NULL,&tmpxm,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); if ((tmpxs != user.xs) || (tmpxm != user.xm)) { PetscPrintf(PETSC_COMM_SELF, "\n***ERROR: rank %d gets different ownership range for the two DAs! ENDING ...***\n\n", user.rank); PetscEnd(); } ierr = PetscPrintf(PETSC_COMM_WORLD, " Mx = %D points, dx = %.3f m\n H0 = %.2f m, xc = %.2f km, Txc = %.5e Pa m\n", user.Mx, user.dx, user.H0, user.xc/1000.0, user.Txc);CHKERRQ(ierr); /* Extract/allocate global vectors from DAs and duplicate for remaining same types */ ierr = DACreateGlobalVector(user.da,&Hu);CHKERRQ(ierr); ierr = VecSetBlockSize(Hu,2);CHKERRQ(ierr); ierr = VecDuplicate(Hu,&r);CHKERRQ(ierr); /* inherits block size */ ierr = VecDuplicate(Hu,&user.Huexact);CHKERRQ(ierr); /* ditto */ ierr = DACreateGlobalVector(user.scalarda,&user.M);CHKERRQ(ierr); ierr = VecDuplicate(user.M,&user.Bstag);CHKERRQ(ierr); ierr = VecDuplicate(user.M,&user.beta);CHKERRQ(ierr); ierr = DASetLocalFunction(user.da,(DALocalFunction1)scshell);CHKERRQ(ierr); ierr = DASetLocalJacobian(user.da,(DALocalFunction1)BodJacobianMatrixLocal);CHKERRQ(ierr); ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,SNESDAFormFunction,&user);CHKERRQ(ierr); /* setting up a matrix is only actually needed for -snes_fd case */ ierr = DAGetMatrix(user.da,MATAIJ,&J);CHKERRQ(ierr); if (snes_fd_set) { /* tools needed so DA can use sparse matrix for its F.D. Jacobian approx */ ierr = DAGetColoring(user.da,IS_COLORING_GLOBAL,MATAIJ,&iscoloring);CHKERRQ(ierr); ierr = MatFDColoringCreate(J,iscoloring,&matfdcoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(iscoloring);CHKERRQ(ierr); ierr = MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode (*)(void))SNESDAFormFunction,&user);CHKERRQ(ierr); ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,matfdcoloring);CHKERRQ(ierr); } else { ierr = SNESSetJacobian(snes,J,J,SNESDAComputeJacobian,&user);CHKERRQ(ierr); } ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); /* the the Bodvardsson (1955) exact solution allows setting M(x), B(x), beta(x), T(xc) */ ierr = FillDistributedParams(&user);CHKERRQ(ierr); /* the exact thickness and exact ice velocity (user.uHexact) are known from Bodvardsson (1955) */ ierr = FillExactSoln(&user); CHKERRQ(ierr); if (exactinitial) { ierr = PetscPrintf(PETSC_COMM_WORLD," using exact solution as initial guess\n"); CHKERRQ(ierr); /* the initial guess is the exact continuum solution */ ierr = VecCopy(user.Huexact,Hu); CHKERRQ(ierr); } else { ierr = FillInitial(&user, &Hu); CHKERRQ(ierr); } /************ SOLVE NONLINEAR SYSTEM ************/ /* recall that RHS r is used internally by KSP, and is set by the SNES */ for (i = 0; i < 2; i++) descaleNode[i] = 1.0 / user.scaleNode[i]; ierr = VecStrideScaleAll(Hu,descaleNode); CHKERRQ(ierr); /* de-dimensionalize initial guess */ ierr = SNESSolve(snes,PETSC_NULL,Hu);CHKERRQ(ierr); ierr = VecStrideScaleAll(Hu,user.scaleNode); CHKERRQ(ierr); /* put back in "real" scale */ ierr = SNESGetIterationNumber(snes,&its);CHKERRQ(ierr); ierr = SNESGetConvergedReason(snes,&reason);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " %s Number of Newton iterations = %D\n", SNESConvergedReasons[reason],its);CHKERRQ(ierr); if (dump) { ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing combined result Hu\n");CHKERRQ(ierr); ierr = VecView(Hu,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing combined exact result Huexact\n");CHKERRQ(ierr); ierr = VecView(user.Huexact,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, " viewing final combined residual at Hu\n");CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_WORLD); CHKERRQ(ierr); } /* evaluate error relative to exact solution */ ierr = VecAXPY(Hu,-1.0,user.Huexact); CHKERRQ(ierr); /* Hu = - Huexact + Hu */ ierr = VecStrideNormAll(Hu,NORM_INFINITY,errnorms); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD, "(dx,errHinf,erruinf) %.3f %.4e %.4e\n", user.dx,errnorms[0],errnorms[1]*user.secpera);CHKERRQ(ierr); ierr = VecDestroy(Hu);CHKERRQ(ierr); ierr = VecDestroy(r);CHKERRQ(ierr); ierr = VecDestroy(user.Huexact);CHKERRQ(ierr); ierr = VecDestroy(user.M);CHKERRQ(ierr); ierr = VecDestroy(user.Bstag);CHKERRQ(ierr); ierr = VecDestroy(user.beta);CHKERRQ(ierr); ierr = MatDestroy(J); CHKERRQ(ierr); ierr = SNESDestroy(snes);CHKERRQ(ierr); ierr = DADestroy(user.da);CHKERRQ(ierr); ierr = DADestroy(user.scalarda);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int main(int argc,char **args) { PetscInt rank,size,npt; PetscScalar dx,dy,cx,cy; PetscErrorCode ierr; Vec x,x0,tempvec, *vinda,*vindb,*vindc; PetscInt i,j,k,n,n2,pmax,puse,Istart,Iend,localsize,niter; PetscScalar **x0array, **aarray,**barray; PetscInt *cacheInt; PetscScalar *cacheScalar; DA myDA; PetscScalar *Mixnorm; PetscInt iter,*iterind,*nind; FILE *fidoutput, *fidtimelog; char fname[50],ftimelog[50]; PetscViewer socketviewer; PetscInt withMatlab, doFFT, doSmoothing; PetscTruth Matlabflag, FFTflag, Smoothingflag; PetscInt timelogcount; MPI_Status status; PetscLogDouble v1,v2,elapsed_time; timelogcount = 0; PetscInitialize(&argc,&args,(char *)0,help); MPI_Comm_size(PETSC_COMM_WORLD,&size); MPI_Comm_rank(PETSC_COMM_WORLD,&rank); ierr = PetscPrintf(PETSC_COMM_WORLD,"\nPETSC: Petsc Initializes successfully! \n"); ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: comm_size is %d \n", size); ierr = PetscOptionsGetInt(PETSC_NULL,"-withMatlab",&withMatlab,&Matlabflag);CHKERRQ(ierr); if (Matlabflag == PETSC_FALSE){withMatlab = 0;}else{withMatlab = 1;} ierr = PetscOptionsGetInt(PETSC_NULL,"-doFFT",&doFFT,&FFTflag);CHKERRQ(ierr); if (FFTflag == PETSC_FALSE){doFFT = 0;}else{doFFT = 1;} ierr = PetscOptionsGetInt(PETSC_NULL,"-doSmoothing",&doSmoothing,&Smoothingflag);CHKERRQ(ierr); if (Smoothingflag == PETSC_FALSE){doSmoothing = 0;}else{doSmoothing = 1;} if(withMatlab==1){ // Rank 0 connects to socket, use default socket PetscViewerSocketOpen(PETSC_COMM_WORLD,0,PETSC_DEFAULT,&socketviewer); ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: socket opened! \n");CHKERRQ(ierr); // Receive n from Matlab IntReceive(socketviewer, &nind); n = *nind; // Receive iter from Matlab IntReceive(socketviewer, &iterind); iter = *iterind; }else{ ierr = PetscOptionsGetInt(PETSC_NULL,"-ngrid",&n,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-niter",&iter,PETSC_NULL);CHKERRQ(ierr); } ///////////////////////////////////////////////////////////////////////////////////// ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: number of grid is %d \n", n); ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: number of iteration is %d \n", iter); Mixnorm = malloc(iter*sizeof(PetscScalar)); dx = 1.0/n; dy = 1.0/n; n2 = (PetscInt)(n*0.5); npt = 5; pmax = 5e5; puse = pmax; PetscInt logmax = 1000; PetscScalar Timelog[logmax]; PetscLogDouble t1,t2; ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: estimated buffer size (per processer) %f Mbytes \n", pmax*1.0/1e6*8*17 ); ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: estimated variable size %f Mbytes\n", 1.0*n*n/1e6*8*1); ///////////////////////////////////////////////////////////////////////////////////// // ierr = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE ,n,&tempvec);CHKERRQ(ierr); // ierr = VecGetOwnershipRange(tempvec,&Istart,&Iend);CHKERRQ(ierr); // localsize = Iend-Istart; // ierr = VecDestroy(tempvec);CHKERRQ(ierr); ///////////////////////////////////////////////////////////////////////////////////// if(doSmoothing==1){ ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: Now Do DACreate2d \n\n\n\n" ); ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: %d %d %d\n\n\n\n",n2,n,size); DACreate2d(MPI_COMM_WORLD,DA_XYPERIODIC,DA_STENCIL_BOX,n2,n,1,size,1,2,PETSC_NULL,PETSC_NULL,&myDA); DACreateGlobalVector(myDA,&x0); DAGetCorners(myDA,PETSC_NULL,&Istart,PETSC_NULL,PETSC_NULL,&localsize,PETSC_NULL); Iend = Istart+localsize; }else{ ierr = VecCreateMPI(PETSC_COMM_WORLD,PETSC_DECIDE ,n,&tempvec);CHKERRQ(ierr); ierr = VecGetOwnershipRange(tempvec,&Istart,&Iend);CHKERRQ(ierr); localsize = Iend-Istart; ierr = VecDestroy(tempvec);CHKERRQ(ierr); VecCreateMPI(PETSC_COMM_WORLD,localsize*n2,PETSC_DETERMINE ,&x0); } //ierr = PetscPrintf(PETSC_COMM_WORLD,"\n\n\n\n\nPETSC: So far so good\n\n\n\n"); VecGetArray2d(x0,n2,localsize,0,0,&x0array); // Create initial vector for(j=0;j<localsize;j++){ for(i=0;i<n2;i++){ cx = (Istart+j+0.5)*dx; x0array[i][j] = cos(2*M_PI*cx); } } VecRestoreArray2d(x0,n2,localsize,0,0,&x0array); ierr = VecDuplicate(x0,&x);CHKERRQ(ierr); ierr = VecNorm(x0,NORM_2,Mixnorm); CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"PETSC: initial norm= %f \n",*(Mixnorm+0)/n ); vinda = &x0; vindb = &x; sprintf(fname, "mixnorm_%d_%d",n,iter); ierr =PetscPrintf(PETSC_COMM_WORLD,"\n iter norm time unit time\n");CHKERRQ(ierr); ierr =PetscFOpen(PETSC_COMM_WORLD,fname,"w",&fidoutput);CHKERRQ(ierr); /////////////////////////////////////////////////////////////////////////////////////////////////// // Memory allocation for the iteration scheme // cacheInt = malloc(1*pmax*sizeof(PetscInt)); // cacheScalar = malloc(2*pmax*sizeof(PetscScalar)); cacheInt = malloc(2*pmax*sizeof(PetscInt)); cacheScalar = malloc(2*pmax*sizeof(PetscScalar)); /////////////////////////////////////////////////////////////////////////////////////////////////// // Iteration here! for(niter=0;niter<iter;niter++){ ierr = PetscGetTime(&v1);CHKERRQ(ierr); // BackwardAverage(vinda, vindb, cacheInt, cacheScalar, n, npt, pmax, Istart,Iend); // BackwardAverageR(vinda, vindb, cacheInt, cacheScalar, n, npt, pmax, Istart,Iend); BackwardAverageRL(vinda, vindb, cacheInt, cacheScalar, n, npt, pmax, Istart,Iend); vindc = vindb; vindb = vinda; vinda = vindc; // if(doSmoothing==1){Smoothing(vinda, vindb,n, myDA, Istart,Iend);} ierr = PetscGetTime(&v2);CHKERRQ(ierr); //vindc = vindb; //vindb = vinda; //vinda = vindc; ierr = VecNorm(*vinda,NORM_2,Mixnorm+niter); CHKERRQ(ierr); *(Mixnorm+niter) = *(Mixnorm+niter)/n; elapsed_time = v2 - v1; PetscPrintf(PETSC_COMM_WORLD," %d %f %f %f \n",niter,*(Mixnorm+niter),elapsed_time,elapsed_time/n/n*1e6 ); PetscFPrintf(PETSC_COMM_WORLD,fidoutput," %d %f %f %f\n" ,niter,*(Mixnorm+niter),elapsed_time,elapsed_time/n/n*1e6 ); } //////////////////////////////////////////////////////////////////////////////////////////////////// //Change oremtation of vector VecGetArray2d(*vinda,n2,localsize,0,0,&aarray); VecGetArray2d(*vindb,localsize,n2,0,0,&barray); for(j=0;j<localsize;j++){ for(i=0;i<n2;i++){ barray[j][i] = aarray[i][j]; } } VecRestoreArray2d(*vinda,n2,localsize,0,0,&aarray); VecRestoreArray2d(*vindb,localsize,n2,0,0,&barray); vindc = vindb; vindb = vinda; vinda = vindc; //////////////////////////////////////////////////////////////////////////////////////////////////// // FFT part if(doFFT==1){FFT2D(*vinda,*vindb, localsize, n, Istart,Iend, iter,doSmoothing);} //////////////////////////////////////////////////////////////////////////////////////////////////// /* if(rank==0){ sprintf(ftimelog, "timelog_%d_%d",n,iter); fidtimelog = fopen(ftimelog,"w"); for(i=0;i<timelogcount;i++){ fprintf(fidtimelog,"%f ",Timelog[i]); } fprintf(fidtimelog,"\n "); for(j = 1;j<size;j++){ MPI_Recv(Timelog,timelogcount,MPI_DOUBLE,j,j,PETSC_COMM_WORLD,&status); for(i=0;i<timelogcount;i++){ fprintf(fidtimelog,"%f ",Timelog[i]); } fprintf(fidtimelog,"\n "); } fclose(fidtimelog); }else{ MPI_Send(Timelog ,timelogcount,MPI_DOUBLE,0,rank,PETSC_COMM_WORLD); } PetscFClose(PETSC_COMM_WORLD,fidoutput); */ /////////////////////////////////////////////////////////////////////////// if(withMatlab==1){ VecView(*vinda,socketviewer); PetscScalarView(iter,Mixnorm,socketviewer); } // free(x0array); free(Mixnorm); free(cacheInt); free(cacheScalar); ierr = VecDestroy(x0);CHKERRQ(ierr); ierr = VecDestroy(x);CHKERRQ(ierr); PetscPrintf(PETSC_COMM_WORLD,"Done!"); ////////////////////////////////////////////////////////////////////////////////////// ierr = PetscFinalize();CHKERRQ(ierr);