Пример #1
0
void MonodomainProblem<ELEMENT_DIM, SPACE_DIM>::WriteInfo(double time)
{
    if (PetscTools::AmMaster())
    {
        std::cout << "Solved to time " << time << "\n" << std::flush;
    }

    double v_max, v_min;

    VecMax( this->mSolution, PETSC_NULL, &v_max );
    VecMin( this->mSolution, PETSC_NULL, &v_min );

    if (PetscTools::AmMaster())
    {
        std::cout << " V = " << "[" <<v_min << ", " << v_max << "]" << "\n" << std::flush;
    }
}
Пример #2
0
PetscErrorCode MyTSMonitor(TS ts,PetscInt step,PetscReal ptime,Vec v,void *ptr)
{
  PetscErrorCode ierr;
  PetscReal      norm,vmax,vmin;
  MPI_Comm       comm;
  MonitorCtx     *user = (MonitorCtx*)ptr;

  PetscFunctionBegin;
  ierr = VecNorm(v,NORM_1,&norm);CHKERRQ(ierr);
  ierr = VecMax(v,PETSC_NULL,&vmax);CHKERRQ(ierr);
  ierr = VecMin(v,PETSC_NULL,&vmin);CHKERRQ(ierr);
  ierr = PetscObjectGetComm((PetscObject)ts,&comm);CHKERRQ(ierr);
  ierr = PetscPrintf(comm,"timestep %D: time %G, solution norm %G, max %G, min %G\n",step,ptime,norm,vmax,vmin);CHKERRQ(ierr);

  if (user->drawcontours){
    ierr = VecView(v,PETSC_VIEWER_DRAW_WORLD);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Пример #3
0
PetscErrorCode VecMax_MultiVec(Vec x, PetscInt* p, PetscScalar* val)
{
#if !defined(NDEBUG)
    TBOX_ASSERT(x);
#endif
    Vec_MultiVec* mx = static_cast<Vec_MultiVec*>(x->data);
#if !defined(NDEBUG)
    TBOX_ASSERT(mx);
#endif
    PetscErrorCode ierr;
    *p = -1;
    *val = PETSC_MIN_REAL;
    for (PetscInt k = 0; k < mx->n; ++k)
    {
        PetscInt component_p;
        PetscScalar component_val;
        ierr = VecMax(mx->array[k], &component_p, &component_val);
        CHKERRQ(ierr);
        *val = std::max(*val, component_val);
    }
    PetscFunctionReturn(0);
} // VecMax_MultiVec
Пример #4
0
  -n <length> : vector length\n\n";

#include <petscvec.h>

int main(int argc,char **argv)
{
  PetscErrorCode ierr;
  PetscInt       n = 5,idx;
  PetscReal      value;
  Vec            x;
  PetscScalar    one = 1.0;

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
  ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr);

  /* create vector */
  ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr);
  ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr);
  ierr = VecSetFromOptions(x);CHKERRQ(ierr);


  ierr = VecSet(x,one);CHKERRQ(ierr);
  ierr = VecSetValue(x,0,0.0,INSERT_VALUES);CHKERRQ(ierr);
  ierr = VecSetValue(x,n-1,2.0,INSERT_VALUES);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(x);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(x);CHKERRQ(ierr);

  ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
  ierr = VecMax(x,&idx,&value);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"Maximum value %g index %D\n",(double)value,idx);CHKERRQ(ierr);
  ierr = VecMin(x,&idx,&value);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"Minimum value %g index %D\n",(double)value,idx);CHKERRQ(ierr);

  ierr = VecDestroy(&x);CHKERRQ(ierr);

  ierr = PetscFinalize();
  return ierr;
}
void _Stokes_SLE_PenaltySolver_Solve( void* solver,void* stokesSLE ) {
    Stokes_SLE_PenaltySolver* self            = (Stokes_SLE_PenaltySolver*)solver;
    Stokes_SLE*             sle             = (Stokes_SLE*)stokesSLE;
    /* Create shortcuts to stuff needed on sle */
    Mat                     kMatrix         = sle->kStiffMat->matrix;
    Mat                     gradMat         = sle->gStiffMat->matrix;
    Mat                     divMat          = NULL;
    Mat                     C_Mat           = sle->cStiffMat->matrix;
    Vec                     uVec            = sle->uSolnVec->vector;
    Vec                     pVec            = sle->pSolnVec->vector;
    Vec                     fVec            = sle->fForceVec->vector;
    Vec                     hVec            = sle->hForceVec->vector;
    Vec     		hTempVec;
    Vec    			fTempVec;
    Vec                     penalty;
    Mat    			GTrans, kHat;
    KSP			ksp_v;
    double	 		negOne=-1.0;
    double	 		one=1.0;
    Mat    			C_InvMat;
    Vec    			diagC;
    PC			pc;
    int                 rank;

    MPI_Comm_rank( MPI_COMM_WORLD, &rank );

    Journal_DPrintf( self->debug, "In %s():\n", __func__ );

    VecDuplicate( hVec, &hTempVec );
    VecDuplicate( fVec, &fTempVec );
    VecDuplicate( pVec, &diagC );

    if( sle->dStiffMat == NULL ) {
        Journal_DPrintf( self->debug, "Div matrix == NULL : Problem is assumed to be symmetric. ie Div = GTrans \n");
#if( PETSC_VERSION_MAJOR <= 2 )
        MatTranspose( gradMat, &GTrans );
#else
        MatTranspose( gradMat, MAT_INITIAL_MATRIX, &GTrans );
#endif
        divMat = GTrans;
    }
    else {

       MatType type;
       PetscInt size[2];

        MatGetType( sle->dStiffMat->matrix, &type );
        MatGetLocalSize( sle->dStiffMat->matrix, size + 0, size + 1 );

        /* make a copy we can play with */
        MatCreate( sle->comm, &GTrans );
        MatSetSizes( GTrans, size[0], size[1], PETSC_DECIDE, PETSC_DECIDE );
        MatSetType( GTrans, type );
#if (((PETSC_VERSION_MAJOR==3) && (PETSC_VERSION_MINOR>=3)) || (PETSC_VERSION_MAJOR>3) )
        MatSetUp(GTrans);
#endif
        MatCopy( sle->dStiffMat->matrix, GTrans, DIFFERENT_NONZERO_PATTERN );
        divMat = GTrans;

    }

    Stokes_SLE_PenaltySolver_MakePenalty( self, sle, &penalty );

    /* Create CInv */
    MatGetDiagonal( C_Mat, diagC );
    VecReciprocal( diagC );
    VecPointwiseMult( diagC, penalty, diagC );
    { /* Print the maximum and minimum penalties in my system. */
        PetscInt idx;
        PetscReal min, max;

        VecMin( diagC, &idx, &min );
        VecMax( diagC, &idx, &max );
        if( rank == 0 ) {
           printf( "PENALTY RANGE:\n" );
           printf( "  MIN: %e\n", min );
           printf( "  MAX: %e\n", max );
        }
    }
    MatDiagonalSet( C_Mat, diagC, INSERT_VALUES );
    C_InvMat = C_Mat;				/* Use pointer CInv since C has been inverted */

    /* Build RHS : rhs = f - GCInv h */
    MatMult( C_InvMat, hVec, hTempVec ); /* hTempVec = C_InvMat * hVec */
    VecScale( hTempVec, -1.0 );
    MatMult( gradMat, hTempVec, fTempVec );
#if 0
    VecPointwiseMult( fTempVec, penalty, fTempVec );
    { /* Print the maximum and minimum penalties in my system. */
        PetscInt idx;
        PetscReal min, max;

        VecMin( fTempVec, &idx, &min );
        VecMax( fTempVec, &idx, &max );
        printf( "PENALTY RANGE:\n" );
        printf( "  MIN: %e\n", min );
        printf( "  MAX: %e\n", max );
    }
#endif
    VecAXPY( fTempVec, 1.0, fVec );
    /*MatMultAdd( gradMat, hTempVec, fVec, fTempVec );*/

    /* Build G CInv GTrans */
/* 	MatTranspose( gradMat, &GTrans ); */
/* 	 since CInv is diagonal we can just scale mat entries by the diag vector */
    MatDiagonalScale( divMat, diagC, PETSC_NULL );  /*  Div = CInve Div */
    MatMatMult( gradMat, divMat, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &kHat );
    /*MatDiagonalScale( kHat, penalty, PETSC_NULL );*/
    MatScale( kHat, -1.0 );
    MatAXPY( kMatrix, 1.0, kHat, SAME_NONZERO_PATTERN );

    /* Setup solver context and make sure that it uses a direct solver */
    KSPCreate( sle->comm, &ksp_v );
    Stg_KSPSetOperators( ksp_v, kMatrix, kMatrix, DIFFERENT_NONZERO_PATTERN );
    KSPSetType( ksp_v, KSPPREONLY );
    KSPGetPC( ksp_v, &pc );
    PCSetType( pc, PCLU );
    KSPSetFromOptions( ksp_v );

    KSPSolve( ksp_v, fTempVec, uVec );

    /* Recover p */
    if( sle->dStiffMat == NULL ) {

/* 		 since Div was modified when C is diagonal, re build the transpose */
        if( GTrans != PETSC_NULL )
            Stg_MatDestroy(&GTrans );

#if( PETSC_VERSION_MAJOR <= 2 )
        MatTranspose( gradMat, &GTrans );
#else
        MatTranspose( gradMat, MAT_INITIAL_MATRIX, &GTrans );
#endif
        divMat = GTrans;
    }
    else {
/* 		 never modified Div_null so set divMat to point back to it */
        divMat = sle->dStiffMat->matrix;
    }

    MatMult( divMat, uVec, hTempVec );    /* hTemp = Div v */
    VecAYPX( hTempVec, negOne, hVec );    /* hTemp = H - hTemp   : hTemp = H - Div v */
    MatMult( C_InvMat, hTempVec, pVec );  /* p = CInv hTemp      : p = CInv ( H - Div v ) */

    Stg_MatDestroy(&kHat );
    if( fTempVec != PETSC_NULL ) Stg_VecDestroy(&fTempVec );
    if( hTempVec != PETSC_NULL ) Stg_VecDestroy(&hTempVec );
    if( diagC != PETSC_NULL )    Stg_VecDestroy(&diagC );
    if( ksp_v != PETSC_NULL )   Stg_KSPDestroy(&ksp_v );
    if( GTrans != PETSC_NULL )   Stg_MatDestroy(&GTrans );
}
Пример #6
0
PetscErrorCode port_lsd_bfbt(void)
{
  Mat            A;
  Vec            x,b;
  KSP            ksp_A;
  PC             pc_A;
  IS             isu,isp;
  PetscErrorCode ierr;

  PetscFunctionBeginUser;
  ierr = LoadTestMatrices(&A,&x,&b,&isu,&isp);CHKERRQ(ierr);

  ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_A);CHKERRQ(ierr);
  ierr = KSPSetOptionsPrefix(ksp_A,"fc_");CHKERRQ(ierr);
  ierr = KSPSetOperators(ksp_A,A,A);CHKERRQ(ierr);

  ierr = KSPGetPC(ksp_A,&pc_A);CHKERRQ(ierr);
  ierr = PCSetType(pc_A,PCFIELDSPLIT);CHKERRQ(ierr);
  ierr = PCFieldSplitSetBlockSize(pc_A,2);CHKERRQ(ierr);
  ierr = PCFieldSplitSetIS(pc_A,"velocity",isu);CHKERRQ(ierr);
  ierr = PCFieldSplitSetIS(pc_A,"pressure",isp);CHKERRQ(ierr);

  ierr = KSPSetFromOptions(ksp_A);CHKERRQ(ierr);
  ierr = KSPSolve(ksp_A,b,x);CHKERRQ(ierr);

  /* Pull u,p out of x */
  {
    PetscInt    loc;
    PetscReal   max,norm;
    PetscScalar sum;
    Vec         uvec,pvec;
    VecScatter  uscat,pscat;
    Mat         A11,A22;

    /* grab matrices and create the compatable u,p vectors */
    ierr = MatGetSubMatrix(A,isu,isu,MAT_INITIAL_MATRIX,&A11);CHKERRQ(ierr);
    ierr = MatGetSubMatrix(A,isp,isp,MAT_INITIAL_MATRIX,&A22);CHKERRQ(ierr);

    ierr = MatCreateVecs(A11,&uvec,NULL);CHKERRQ(ierr);
    ierr = MatCreateVecs(A22,&pvec,NULL);CHKERRQ(ierr);

    /* perform the scatter from x -> (u,p) */
    ierr = VecScatterCreate(x,isu,uvec,NULL,&uscat);CHKERRQ(ierr);
    ierr = VecScatterBegin(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
    ierr = VecScatterEnd(uscat,x,uvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);

    ierr = VecScatterCreate(x,isp,pvec,NULL,&pscat);CHKERRQ(ierr);
    ierr = VecScatterBegin(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
    ierr = VecScatterEnd(pscat,x,pvec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);

    PetscPrintf(PETSC_COMM_WORLD,"-- vector vector values --\n");
    ierr = VecMin(uvec,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Min(u)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecMax(uvec,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Max(u)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecNorm(uvec,NORM_2,&norm);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Norm(u) = %1.6f \n",(double)norm);CHKERRQ(ierr);
    ierr = VecSum(uvec,&sum);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Sum(u)  = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr);

    PetscPrintf(PETSC_COMM_WORLD,"-- pressure vector values --\n");
    ierr = VecMin(pvec,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Min(p)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecMax(pvec,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Max(p)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecNorm(pvec,NORM_2,&norm);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Norm(p) = %1.6f \n",(double)norm);CHKERRQ(ierr);
    ierr = VecSum(pvec,&sum);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Sum(p)  = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr);

    PetscPrintf(PETSC_COMM_WORLD,"-- Full vector values --\n");
    ierr = VecMin(x,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Min(u,p)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecMax(x,&loc,&max);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Max(u,p)  = %1.6f [loc=%D]\n",(double)max,loc);CHKERRQ(ierr);
    ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Norm(u,p) = %1.6f \n",(double)norm);CHKERRQ(ierr);
    ierr = VecSum(x,&sum);CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"  Sum(u,p)  = %1.6f \n",(double)PetscRealPart(sum));CHKERRQ(ierr);

    ierr = VecScatterDestroy(&uscat);CHKERRQ(ierr);
    ierr = VecScatterDestroy(&pscat);CHKERRQ(ierr);
    ierr = VecDestroy(&uvec);CHKERRQ(ierr);
    ierr = VecDestroy(&pvec);CHKERRQ(ierr);
    ierr = MatDestroy(&A11);CHKERRQ(ierr);
    ierr = MatDestroy(&A22);CHKERRQ(ierr);
  }

  ierr = KSPDestroy(&ksp_A);CHKERRQ(ierr);
  ierr = MatDestroy(&A);CHKERRQ(ierr);
  ierr = VecDestroy(&x);CHKERRQ(ierr);
  ierr = VecDestroy(&b);CHKERRQ(ierr);
  ierr = ISDestroy(&isu);CHKERRQ(ierr);
  ierr = ISDestroy(&isp);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Пример #7
0
int main(int argc,char *argv[])
{
  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  //VARIABLE DEFINITION
  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  float cp,S,sigma,gamma,pp,Topt;
  float q,Ab,Aw,Agf,grad_T,fi,mm,nn,Pmax,EVPmax;
  float Ec,Es,deltat,t_integracion,t_modelacion;
  float Lini,Lfin,deltaL;
  int niter,niterL,nzc;
  Vector zc_vector;
  int zczc,ii;
  float Ac,L,zc;
  float aclouds,awhite,ablack,Ts,d;
  float t,xx,As;
  float k1,k2,k3,k4;
  int j;
  float Tc,Tlb,Tlw,Tanual,I,a,EVP,E;
  float P;
  float k1c,k2c,k3c,k4c;
  float k1w,k2w,k3w,k4w;
  float k1b,k2b,k3b,k4b;
  float Bw,Bb;
  int it;
  Vector time,temperature,white_temperature,
    black_temperature,white_area,black_area,clouds_area,evap,prec;
  Matrix resultados;
  FILE *fl;
  char fname[1000];

  float k1p1,k1p2,k1p3,k1p4,k1p5;

  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  //PARAMETERS
  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  cp = 3.e13;	//erg*cm-2*K-1
  S = 2.89e13;	//erg*cm-2*año-1
  sigma = 1789.;	//erg*cm-2*año-1*K-4
  gamma = 0.3;	//año-1
  pp = 1.;	//adimensional
  Topt = 295.5;	//K
  q = 20.;	//K
  Ab = 0.25;	//adimensinal
  Aw = 0.75;	//adimensinal
  Agf = 0.50;	//adimensinal
  grad_T = (-0.0065);	//K*m-1, Trenberth 95, p.10
  
  fi = 0.1;
  mm = 0.35;
  nn = 0.1;
  Pmax = pow((1./mm),(1/nn)); //=36251 [mm/año], cuando ac=1.0
  EVPmax = Pmax;
  //EVPmax = 1511.; //[mm/año] corresponde a Ts=26 grados centígrados
  //Pmax = EVPmax;	//[mm/año]
  //ac_crit = mm*Pmax^nn;

  //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  //experimento otro: cambiando estos parámetros
  Ec=1.;	//emisividad de las nubes
  Es=1.;	//emisividad de la superficie
  //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

  deltat = 0.01; //[años] tamaño de paso temporal para dTsdt y dadt
  t_integracion = 1; //[año] cada cuanto se guardan valores de las variables
  t_modelacion = 10000;	//[años] período de modelación por cada L
  niter = t_integracion/deltat;	//# de iteraciones en los RK4

  /*
    Lini = 1.992;
    Lfin = 4.004;
    deltaL = 0.004;
  */
  Lini = 1.000;
  Lfin = 1.000;
  deltaL = 0.004;
  niterL = (Lfin-Lini)/deltaL;

  ////zc_vector = [1000.,2000.,3000.,4000.,5000.,6000.,7000.,8000.]
  zc_vector=VecAlloc(1);
  VecSet(zc_vector,0,6000.);
  nzc=1;
    
  //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  //LOOP IN HEIGHTS
  //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  FILE *ft=fopen("hdw-legacy.dat","w");
  for(zczc=0;zczc<=nzc-1;zczc++){
    zc=VecGet(zc_vector,zczc);
    //Ac=1.-fi*(zc/1000.);
    Ac=0.6;
    resultados=MatAlloc(niterL+1,19);

    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
    //LOOP IN SOLAR FORCING
    //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
    for(ii=0;ii<=niterL;ii++){
      L = deltaL*ii+Lini;
      printf("%d de %d, L = %.4lf\n",ii,niterL,L);
      
      //valores iniciales
      aclouds = 0.01	;//adimensional, 0 para reproducir modelo original, 0.01 para iniciar con area de nubes
      awhite = 0.01	;//adimensional
      ablack = 0.01	;//adimensional
      Ts=295.5	;//temperatura en la superficie, valor inicial para rk4

      d = t_modelacion ;//numero de años en el eje de las abscisas - iteraciones de t - dimension de los vectores de resultados

      //printf("Tam:%d\n",(int)(d+1)/2);
      time=VecAlloc((d+1)/2);
      temperature=VecAlloc((d+1)/2);
      white_temperature=VecAlloc((d+1)/2);
      black_temperature=VecAlloc((d+1)/2);
      white_area=VecAlloc((d+1)/2);
      black_area=VecAlloc((d+1)/2);
      clouds_area=VecAlloc((d+1)/2);
      evap=VecAlloc((d+1)/2);
      prec=VecAlloc((d+1)/2);

      it=0;
      
      //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      //LOOP IN MODELLING TIME
      //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      for(t=0;t<=t_modelacion;t+=t_integracion){

	//if(it>5000){
	if(it>-1){
	  fprintf(ft,"%e %e %e %e %e\n",
		  t,Ts,aclouds,awhite,ablack);

	}

	xx = pp - awhite - ablack;
	As = xx*Agf + ablack*Ab + awhite*Aw;

	//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	//TIME INTEGRATION
	//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	for(j=1;j<=niter;j++){
	  
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  //TEMPERATURE
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  k1=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int((Ts+grad_T*zc),4)-sigma*Es*gsl_pow_int(Ts,4));
	  k2=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k1/2)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k1/2),4));
	  k3=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k2/2)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k2/2),4));
	  k4=(1/cp)*(S*L*((1-Ac)*aclouds+(1-aclouds))*(1-As)+sigma*Ec*aclouds*gsl_pow_int(((Ts+k3)+grad_T*zc),4)-sigma*Es*gsl_pow_int((Ts+k3),4));
	  Ts = Ts+deltat*(k1/6+k2/3+k3/3+k4/6);

	  //CLOUD TEMPERATURE
	  Tc=Ts+zc*grad_T;
	  Tlb=q*(As-Ab)+Ts;
	  Tlw=q*(As-Aw)+Ts;
	  
	  //EVAPORATION
	  if(Ts>277){
	    Tanual = Ts - 273.	;//(°C)
	    I = 12.*pow((Tanual/5.),1.5);
	    a = (6.7e-7)*gsl_pow_int(I,3) - (7.7e-5)*PowInt(I,2) + (1.8e-2)*I + 0.49;
	    EVP = 12.*16*pow((10.*(Ts - 273.)/I),a);
	    E = Min(1.,EVP/EVPmax);
	  }else{
	    E = 0.;
	  }

	  //PRECIPITATION
	  P = (1./Pmax)*pow((aclouds/mm),(1./nn));

	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  //CLOUD COVERING
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  k1c=(1-aclouds)*E-aclouds*P;
	  k2c=(1-(aclouds+k1c/2))*E-(aclouds+k1c/2)*P;
	  k3c=(1-(aclouds+k2c/2))*E-(aclouds+k2c/2)*P;
	  k4c=(1-(aclouds+k3c))*E-(aclouds+k3c)*P;
	  aclouds=aclouds+deltat*(k1c/6+k2c/3+k3c/3+k4c/6);

	  //REPRODUCTIVE FITNESS
	  //WHITE DAISIES
	  if((Tlw>278)&&(Tlw<313))
	    Bw=1-0.003265*PowInt((Topt-Tlw),2);
	  else Bw=0;
	  //BLACK DAISIES
	  if((Tlb>278)&&(Tlb<313)) 
	    Bb=1-0.003265*PowInt((Topt-Tlb),2);
	  else Bb=0;
	  
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  //WHITE AREA
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  k1w=awhite*(xx*Bw-gamma);
	  k2w=(awhite+k1w/2)*(xx*Bw-gamma);
	  k3w=(awhite+k2w/2)*(xx*Bw-gamma);
	  k4w=(awhite+k3w)*(xx*Bw-gamma);
	  awhite=awhite+deltat*(k1w/6+k2w/3+k3w/3+k4w/6);

	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  //BLACK AREA
	  //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	  k1b=ablack*(xx*Bb-gamma);
	  k2b=(ablack+k1b/2)*(xx*Bb-gamma);
	  k3b=(ablack+k2b/2)*(xx*Bb-gamma);
	  k4b=(ablack+k3b)*(xx*Bb-gamma);
	  ablack=ablack+deltat*(k1b/6+k2b/3+k3b/3+k4b/6);

	  xx = pp - awhite - ablack;
	  As = xx*Agf + ablack*Ab + awhite*Aw;
	  
	}//end for time integration
	
	if(it>5000){
	  VecSet(time,it-5001,t);
	  VecSet(temperature,it-5001,Ts-273);
	  VecSet(white_temperature,it-5001,Tlw-273);
	  VecSet(black_temperature,it-5001,Tlb-273);
	  VecSet(white_area,it-5001,awhite);
	  VecSet(black_area,it-5001,ablack);
	  VecSet(clouds_area,it-5001,aclouds);
	  VecSet(evap,it-5001,E*(1-aclouds));
	  VecSet(prec,it-5001,P*aclouds);
	}
	
	it++;
	
      }//end for modelling time t
      

      if(VERBOSE){
	fprintf(stdout,"Valor %s = %.6e\n",VARS[0],L);
	fprintf(stdout,"Valor %s = %.6e\n",VARS[1],VecMin(temperature))	;//Ts
	fprintf(stdout,"Valor %s = %.6e\n",VARS[2],VecMean(temperature))	;//Ts
	fprintf(stdout,"Valor %s = %.6e\n",VARS[3],VecMax(temperature))	;//Ts
	fprintf(stdout,"Valor %s = %.6e\n",VARS[4],VecMin(white_area))	;//aw
	fprintf(stdout,"Valor %s = %.6e\n",VARS[5],VecMean(white_area))	;//aw
	fprintf(stdout,"Valor %s = %.6e\n",VARS[6],VecMax(white_area))	;//aw
	fprintf(stdout,"Valor %s = %.6e\n",VARS[7],VecMin(black_area))	;//ab
	fprintf(stdout,"Valor %s = %.6e\n",VARS[8],VecMean(black_area))	;//ab
	fprintf(stdout,"Valor %s = %.6e\n",VARS[9],VecMax(black_area))	;//ab
	fprintf(stdout,"Valor %s = %.6e\n",VARS[10],VecMin(clouds_area))	;//ac
	fprintf(stdout,"Valor %s = %.6e\n",VARS[11],VecMean(clouds_area))	;//ac
	fprintf(stdout,"Valor %s = %.6e\n",VARS[12],VecMax(clouds_area))	;//ac
	fprintf(stdout,"Valor %s = %.6e\n",VARS[13],VecMin(evap))	;//E
	fprintf(stdout,"Valor %s = %.6e\n",VARS[14],VecMean(evap))	;//E
	fprintf(stdout,"Valor %s = %.6e\n",VARS[15],VecMax(evap))	;//E
	fprintf(stdout,"Valor %s = %.6e\n",VARS[16],VecMin(prec))	;//P
	fprintf(stdout,"Valor %s = %.6e\n",VARS[17],VecMean(prec))	;//P
	fprintf(stdout,"Valor %s = %.6e\n",VARS[18],VecMax(prec))	;//P
      }
 
      //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      //RESULTADOS
      //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
      MatSet(resultados,ii,0,L);
      MatSet(resultados,ii,1,VecMin(temperature))	;//Ts
      MatSet(resultados,ii,2,VecMean(temperature))	;//Ts
      MatSet(resultados,ii,3,VecMax(temperature))	;//Ts
      MatSet(resultados,ii,4,VecMin(white_area))	;//aw
      MatSet(resultados,ii,5,VecMean(white_area))	;//aw
      MatSet(resultados,ii,6,VecMax(white_area))	;//aw
      MatSet(resultados,ii,7,VecMin(black_area))	;//ab
      MatSet(resultados,ii,8,VecMean(black_area))	;//ab
      MatSet(resultados,ii,9,VecMax(black_area))	;//ab
      MatSet(resultados,ii,10,VecMin(clouds_area))	;//ac
      MatSet(resultados,ii,11,VecMean(clouds_area))	;//ac
      MatSet(resultados,ii,12,VecMax(clouds_area))	;//ac
      MatSet(resultados,ii,13,VecMin(evap))	;//E
      MatSet(resultados,ii,14,VecMean(evap))	;//E
      MatSet(resultados,ii,15,VecMax(evap))	;//E
      MatSet(resultados,ii,16,VecMin(prec))	;//P
      MatSet(resultados,ii,17,VecMean(prec))	;//P
      MatSet(resultados,ii,18,VecMax(prec))	;//P

      VecFree(time);
      VecFree(temperature);
      VecFree(white_temperature);
      VecFree(black_temperature);
      VecFree(white_area);
      VecFree(black_area);
      VecFree(clouds_area);
      VecFree(evap);
      VecFree(prec);

    }//end for ii

    sprintf(fname,"DAWHYC2_EXP2_L0416_%.2f_%d_activa.txt",Ac,(int)zc/1000);
    fl=fopen(fname,"w");
    fprintf(fl,"zc= %.0lf\n",zc);
    fprintf(fl,"Ac= %.2lf\n",Ac);

    for(j=0;j<NVARS;j++)
      fprintf(fl,"%10s ",VARS[j]);

    MatrixFprintf(fl,resultados,"%10.4f ");
    fclose(fl);
    
    MatFree(resultados);

  }//end for heights
  fclose(ft);
  
}//end program
Пример #8
0
int main(int argc,char **args)
{

  Vec            sol,x0,y0,z0; 

  PetscInt       rank,size,Istart,Iend,Lsize;
  Mat            Dy,Dz,MarkovA,dAdy,dAdz;
 
  PetscErrorCode ierr;
  PetscViewer    socketviewer;
  CoordInfo      *cdinfo;

  // for streamline calculation
  PetscScalar *xarray, *yarray,*zarray;    
  PetscScalar  *x,*y,*z;
  PetscInt     n, withMatlab; 
  PetscTruth      Matlabflag,flg;
  PetscInt     ny,nz;
  PetscInt     solmaxp;
  PetscScalar  solmax; 

   n          = 5500;
   withMatlab = 0;
   ny         = 2;
   nz         = 2;


  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);
 

//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// Use Matlab as output 
    ierr = PetscOptionsGetInt(PETSC_NULL,"-withMatlab",&withMatlab,&Matlabflag);CHKERRQ(ierr); 
    ierr = PetscOptionsGetInt(PETSC_NULL,"-ngridy",&ny,&flg);CHKERRQ(ierr);
    ierr = PetscOptionsGetInt(PETSC_NULL,"-ngridz",&nz,&flg);CHKERRQ(ierr);

 
    if (Matlabflag == PETSC_FALSE){withMatlab = 0;}else{withMatlab = 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 cdinfo from Matlab
          ierr = CdinfoReceive(socketviewer, &cdinfo);

       // receive the velocity field from matlab.
          ierr = VecReceive(socketviewer,VECSEQ,&sol);CHKERRQ(ierr); 
          ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: sol is received from Matlab \n");CHKERRQ(ierr); 

          //test
          ierr =  VecLoadfromFile(PETSC_COMM_WORLD,"sol",VECSEQ,&sol);CHKERRQ(ierr);
          ierr = CdinfoLoad(PETSC_COMM_WORLD,"cdinfofiled", &cdinfo);CHKERRQ(ierr);

          ierr = VecReceive(socketviewer,VECMPI,&x0);CHKERRQ(ierr); 
          ierr = VecReceive(socketviewer,VECMPI,&y0);CHKERRQ(ierr); 
          ierr = VecReceive(socketviewer,VECMPI,&z0);CHKERRQ(ierr); 
          ierr = PetscPrintf(PETSC_COMM_WORLD,"PETSC: x0,y0 and z0 are received from Matlab \n");CHKERRQ(ierr);   
 
     }else{

           // Load cdinfo
           ierr = CdinfoLoad(PETSC_COMM_WORLD,"cdinfofiled", &cdinfo);CHKERRQ(ierr);
    
           ierr =  VecLoadfromFile(PETSC_COMM_WORLD,"sol",VECSEQ,&sol);CHKERRQ(ierr);
           // Load x0, y0, z0 as initial points for streamlines  
           ierr =  VecLoadfromFile(PETSC_COMM_WORLD,"x0filed",VECMPI,&x0);CHKERRQ(ierr);
           ierr =  VecLoadfromFile(PETSC_COMM_WORLD,"y0filed",VECMPI,&y0);CHKERRQ(ierr);
           ierr =  VecLoadfromFile(PETSC_COMM_WORLD,"z0filed",VECMPI,&z0);CHKERRQ(ierr);

     }

   ierr = VecMax(sol,&solmaxp,&solmax);CHKERRQ(ierr);

   StreamlineMap(x0, y0, z0, sol, cdinfo, &Dy, &Dz,0.01/solmax, n ,10,&x,&y,&z);
   MarkovMap2d(sol, ny, nz, cdinfo,&MarkovA,&dAdy,&dAdz);   

   ierr = VecGetOwnershipRange(x0,&Istart,&Iend);CHKERRQ(ierr); 
   Lsize = Iend - Istart;

 if(withMatlab==1){

  	 VecView(x0,socketviewer);
         VecView(y0,socketviewer);
   	 VecView(z0,socketviewer);
 	 VecSave(x0,"xefilew");
         VecSave(y0,"yefilew");
   	 VecSave(z0,"zefilew");
 
 	 PetscScalarView(Lsize*n,x,socketviewer);
 	 PetscScalarView(Lsize*n,y,socketviewer);
  	 PetscScalarView(Lsize*n,z,socketviewer);


  	 SparseView(Dy,socketviewer);
  	 SparseView(Dz,socketviewer);
  }else{

         SparseSave(MarkovA,"A");

 	 VecSave(x0,"xefilew");
         VecSave(y0,"yefilew");
   	 VecSave(z0,"zefilew");
   
         Vec vx,vy,vz;

        ierr =  VecCreateMPIWithArray(PETSC_COMM_WORLD,Lsize*n,PETSC_DECIDE,x,&vx);CHKERRQ(ierr); 
        ierr =  VecCreateMPIWithArray(PETSC_COMM_WORLD,Lsize*n,PETSC_DECIDE,y,&vy);CHKERRQ(ierr); 
        ierr =  VecCreateMPIWithArray(PETSC_COMM_WORLD,Lsize*n,PETSC_DECIDE,z,&vz);CHKERRQ(ierr); 

 	VecSave(vx,"xeallfilew");
 	VecSave(vy,"yeallfilew");
  	VecSave(vz,"zeallfilew");

	ierr = VecDestroy(vx);CHKERRQ(ierr);
        ierr = VecDestroy(vy);CHKERRQ(ierr);
	ierr = VecDestroy(vz);CHKERRQ(ierr);


   }



   ierr = VecRestoreArray(x0,&xarray);CHKERRQ(ierr);
   ierr = VecRestoreArray(y0,&yarray);CHKERRQ(ierr);
   ierr = VecRestoreArray(z0,&zarray);CHKERRQ(ierr);

   ierr = VecDestroy(x0);CHKERRQ(ierr);
   ierr = VecDestroy(y0);CHKERRQ(ierr);
   ierr = VecDestroy(z0);CHKERRQ(ierr);



   ierr = MatDestroy(Dy);CHKERRQ(ierr);
   ierr = MatDestroy(Dz);CHKERRQ(ierr);
   ierr = MatDestroy(dAdy);CHKERRQ(ierr);
   ierr = MatDestroy(dAdz);CHKERRQ(ierr);
   ierr = MatDestroy(MarkovA);CHKERRQ(ierr);
  


  ierr = PetscFinalize();CHKERRQ(ierr);
  return 0;
}
Пример #9
0
/*

Stokes output:
  ---------------------------------
  Operator summary:
    K
    G
    f,
    h
    u
    p
  ---------------------------------
  Solution summary:
    max_u
    min_u
    average_u


    |r_1|
    |r_2|
---------------------------------
  Solver summary:
    name


---------------------------------
  Petsc build summary:

*/
PetscErrorCode BSSCR_stokes_output( PetscViewer v, Mat stokes_A, Vec stokes_b, Vec stokes_x, KSP ksp, PetscInt monitor_index )
{
    Mat K,G,D,C;
    Vec f,h, u,p;


    K = G = D = C = PETSC_NULL;
    f = h = PETSC_NULL;
    u = p = PETSC_NULL;

    MatNestGetSubMat( stokes_A, 0,0, &K );
    MatNestGetSubMat( stokes_A, 0,1, &G );
    MatNestGetSubMat( stokes_A, 1,0, &D );
    MatNestGetSubMat( stokes_A, 1,1, &C );

    VecNestGetSubVec( stokes_x, 0, &u );
    VecNestGetSubVec( stokes_x, 1, &p );

    VecNestGetSubVec( stokes_b, 0, &f );
    VecNestGetSubVec( stokes_b, 1, &h );


    PetscViewerASCIIPrintf( v, "Stokes Output:\n");
    PetscViewerASCIIPushTab( v );
    /*--------------------------------------------------------------------------------------------*/
    PetscViewerASCIIPrintf( v, "--------------------------------------------------\n");
    PetscViewerASCIIPrintf( v, "Operator summary:\n");
    PetscViewerASCIIPushTab( v );

    if (K) {
        BSSCR_MatInfoLog(v,K, "stokes_A11");
        PetscViewerASCIIPrintf( v, "\n");
    }
    if (G) {
        BSSCR_MatInfoLog(v,G, "stokes_A12");
        PetscViewerASCIIPrintf( v, "\n");
    }
    if (D) {
        BSSCR_MatInfoLog(v,D, "stokes_A21");
        PetscViewerASCIIPrintf( v, "\n");
    }
    if (C) {
        BSSCR_MatInfoLog(v,C, "stokes_A22");
        PetscViewerASCIIPrintf( v, "\n");
    }

    if (f) {
        BSSCR_VecInfoLog(v,f,"stokes_b1");
        PetscViewerASCIIPrintf( v, "\n");
    }
    if (h) {
        BSSCR_VecInfoLog(v,h,"stokes_b2");
        PetscViewerASCIIPrintf( v, "\n");
    }

    PetscViewerASCIIPopTab( v );


    /*--------------------------------------------------------------------------------------------*/
    PetscViewerASCIIPrintf( v, "--------------------------------------------------\n");
    PetscViewerASCIIPrintf( v, "Solution summary:\n");
    PetscViewerASCIIPushTab( v );

    if (u) {
        BSSCR_VecInfoLog(v,u,"x1");
        PetscViewerASCIIPrintf( v, "\n");
    }
    if (p) {
        BSSCR_VecInfoLog(v,p,"x2");
        PetscViewerASCIIPrintf( v, "\n");
    }

    {
        PetscScalar s,sum;
        PetscReal r,max,min;
        PetscInt N, loc;
        double r1,r2;
        Vec K_d;
        PetscInt loc_max, loc_min;


        VecGetSize( u, &N );
        VecMax( u, &loc, &r );
        PetscViewerASCIIPrintf( v, "u_max: %1.12e [%d] \n", r, loc );
        VecMin( u, &loc, &r );
        PetscViewerASCIIPrintf( v, "u_min: %1.12e [%d] \n", r, loc );

        VecDot( u,u, &s );
        PetscViewerASCIIPrintf( v, "u_rms: %1.12e \n", sqrt( PetscRealPart(s) )/N );

        VecDuplicate( u, &K_d );
        MatGetDiagonal( K, K_d );
        VecMax( K_d, &loc_max, &max );
        VecMin( K_d, &loc_min, &min );
        PetscViewerASCIIPrintf( v,"Algebraic contrast: max(K_d)=%.3e [%d] , min(K_d)=%.3e [%d] , max(K_d)/min(K_d) = %.8e \n", max,loc_max, min,loc_min, max/min );

        MatGetRowMax( K, K_d, PETSC_NULL );
        VecMax( K_d, &loc_max, &max );
        MatGetRowMin( K, K_d, PETSC_NULL );
        VecAbs( K_d );
        VecMin( K_d, &loc_min, &min );
        PetscViewerASCIIPrintf( v,"Algebraic contrast:   max(K)=%.3e [%d] , |min(K)|=%.3e [%d]  ,   max(K)/|min(K)| = %.8e \n", max,loc_max, min,loc_min, max/min );
        Stg_VecDestroy(&K_d );

        PetscViewerASCIIPrintf( v, "\n");

        VecGetSize( p, &N );
        VecMax( p, &loc, &r );
        PetscViewerASCIIPrintf( v, "p_max:  %1.12e [%d] \n", r, loc );
        VecMin( p, &loc, &r );
        PetscViewerASCIIPrintf( v, "p_min:  %1.12e [%d] \n", r, loc );

        VecDot( p,p, &s );
        PetscViewerASCIIPrintf( v, "p_rms:  %1.12e \n", sqrt( PetscRealPart(s) )/N );

        VecSum( p, &sum );
        PetscViewerASCIIPrintf( v, "sum(p): %1.12e \n", sum );

        PetscViewerASCIIPrintf( v, "\n");

        r1 = BSSCR_StokesMomentumResidual( K,G,f, u,p );
        PetscViewerASCIIPrintf( v, "|r1| = %1.12e <momentum> \n", r1 );
        r2 = BSSCR_StokesContinuityResidual( G,C,h, u,p );
        PetscViewerASCIIPrintf( v, "|r2| = %1.12e <continuity> \n", r2 );
        PetscViewerASCIIPrintf( v, "\n");
    }
    PetscViewerASCIIPopTab( v );


    /*--------------------------------------------------------------------------------------------*/
    if (ksp) {
        PetscViewerASCIIPrintf( v, "--------------------------------------------------\n");
        PetscViewerASCIIPrintf( v, "Solver summary:\n");
        PetscViewerASCIIPushTab( v );

        BSSCR_KSPLogSolve( v, monitor_index, ksp );
        BSSCR_BSSCR_KSPLogSolveSummary( v, monitor_index, ksp );
        PetscViewerASCIIPrintf( v, "\n");
        PetscViewerASCIIPopTab( v );
    }

    /*--------------------------------------------------------------------------------------------*/
    PetscViewerASCIIPrintf( v, "--------------------------------------------------\n");
    PetscViewerASCIIPrintf( v, "Petsc build summary:\n");
    PetscViewerASCIIPushTab( v );

    BSSCR_GeneratePetscHeader_for_viewer( v );
    PetscViewerASCIIPrintf( v, "\n");

    PetscViewerASCIIPopTab( v );
    /*--------------------------------------------------------------------------------------------*/


    PetscViewerASCIIPopTab(v);

    PetscFunctionReturn(0);
}
Пример #10
0
PetscErrorCode test_view( void )
{
  Vec            X, a,b;
  Vec            c,d,e,f;
  Vec            tmp_buf[2];
  IS             tmp_is[2];
  PetscInt       index;
  PetscReal      val;
  PetscInt       list[]={0,1,2};
  PetscScalar    vals[]={0.720032,0.061794,0.0100223};
  PetscErrorCode ierr;
  PetscBool      explcit = PETSC_FALSE;

  PetscFunctionBegin;
  PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME );

  ierr = VecCreate( PETSC_COMM_WORLD, &c );CHKERRQ(ierr);
  ierr = VecSetSizes( c, PETSC_DECIDE, 3 );CHKERRQ(ierr);
  ierr = VecSetFromOptions( c );CHKERRQ(ierr);
  ierr = VecDuplicate( c, &d );CHKERRQ(ierr);
  ierr = VecDuplicate( c, &e );CHKERRQ(ierr);
  ierr = VecDuplicate( c, &f );CHKERRQ(ierr);

  ierr = VecSet( c, 1.0 );CHKERRQ(ierr);
  ierr = VecSet( d, 2.0 );CHKERRQ(ierr);
  ierr = VecSet( e, 3.0 );CHKERRQ(ierr);
  ierr = VecSetValues(f,3,list,vals,INSERT_VALUES);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(f);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(f);CHKERRQ(ierr);
  ierr = VecScale( f, 10.0 );CHKERRQ(ierr);

  tmp_buf[0] = e;
  tmp_buf[1] = f;
  ierr = PetscOptionsGetBool(0,"-explicit_is",&explcit,0);CHKERRQ(ierr);
  ierr = GetISs(tmp_buf,tmp_is);CHKERRQ(ierr);
  ierr = VecCreateNest(PETSC_COMM_WORLD,2,explcit?tmp_is:PETSC_NULL,tmp_buf,&b);CHKERRQ(ierr);
  ierr = VecDestroy(&e);CHKERRQ(ierr);
  ierr = VecDestroy(&f);CHKERRQ(ierr);
  ierr = ISDestroy(&tmp_is[0]);CHKERRQ(ierr);
  ierr = ISDestroy(&tmp_is[1]);CHKERRQ(ierr);

  tmp_buf[0] = c;
  tmp_buf[1] = d;
  ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&a);CHKERRQ(ierr);
  ierr = VecDestroy(&c);CHKERRQ(ierr);   ierr = VecDestroy(&d);CHKERRQ(ierr);

  tmp_buf[0] = a;
  tmp_buf[1] = b;
  ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr);
  ierr = VecDestroy(&a);CHKERRQ(ierr);

  ierr = VecAssemblyBegin(X);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(X);CHKERRQ(ierr);

  ierr = VecMax( b, &index, &val );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(max-b) = %f : index = %d \n", val, index );

  ierr = VecMin( b, &index, &val );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(min-b) = %f : index = %d \n", val, index );

  ierr = VecDestroy(&b);CHKERRQ(ierr);

  ierr = VecMax( X, &index, &val );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", val, index );
  ierr = VecMin( X, &index, &val );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", val, index );

  ierr = VecView( X, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr);

  ierr = VecDestroy(&X);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
void _Stokes_SLE_UzawaSolver_Solve( void* solver, void* stokesSLE ) {
	Stokes_SLE_UzawaSolver* self            = (Stokes_SLE_UzawaSolver*)solver;	
	Stokes_SLE*             sle             = (Stokes_SLE*)stokesSLE;
	
	/* Create shortcuts to stuff needed on sle */
	Mat                     K_Mat           = sle->kStiffMat->matrix;
	Mat                     G_Mat           = sle->gStiffMat->matrix;
	Mat                     D_Mat           = NULL;
	Mat                     M_Mat           = NULL;
	Vec                     uVec            = sle->uSolnVec->vector;
	Vec                     qVec            = sle->pSolnVec->vector;
	Vec                     fVec            = sle->fForceVec->vector;
	Vec                     hVec            = sle->hForceVec->vector;
	
	/* Create shortcuts to solver related stuff */
	Vec                     qTempVec        = self->pTempVec;  
	Vec                     rVec            = self->rVec;
	Vec                     sVec            = self->sVec;
	Vec                     fTempVec        = self->fTempVec;
	Vec                     vStarVec        = self->vStarVec; 
	KSP                     velSolver       = self->velSolver;	/*  Inner velocity solver */
	KSP                     pcSolver        = self->pcSolver;   /*  Preconditioner  */

	Iteration_Index         maxIterations   = self->maxUzawaIterations;
	Iteration_Index         minIterations   = self->minUzawaIterations;
	Iteration_Index         iteration_I     = 0;
	Iteration_Index         outputInterval  = 1;
	
	double                  zdotr_current	= 0.0;
	double                  zdotr_previous 	= 1.0;
	double                  sdotGTrans_v;
	double                  alpha, beta;
	double                  absResidual;  
	double                  relResidual;
	double*                 chosenResidual;	  /* We can opt to use either the absolute or relative residual in termination condition */
    	double                  uzawaRhsScale;      
	double                  divU;
	double                  weightedResidual;
	double                  weightedVelocityScale;
	double                  momentumEquationResidual;
	
	Iteration_Index         innerLoopIterations;
	Stream*                 errorStream     = Journal_Register( Error_Type, (Name)Stokes_SLE_UzawaSolver_Type  );
	
	PetscInt		fVecSize, qTempVecSize, uVecSize, qVecSize;
	PetscScalar		fVecNorm, qTempVecNorm, uVecNorm, rVecNorm, fTempVecNorm, uVecNormInf, qVecNorm, qVecNormInf;

	double                  qGlobalProblemScale;
	double                  qReciprocalGlobalProblemScale;
	int			init_info_stream_rank;	
	PetscScalar p_sum;
	/* Bool nullsp_present; */
	Bool uzawa_summary;
	double time,t0,rnorm0;

	PetscTruth     flg;
	double        ksptime;

	VecGetSize( qTempVec, &qTempVecSize );
	qGlobalProblemScale = sqrt( (double) qTempVecSize );
	qReciprocalGlobalProblemScale = 1.0 / qGlobalProblemScale;
	init_info_stream_rank = Stream_GetPrintingRank( self->info );
	Stream_SetPrintingRank( self->info, 0 ); 

	/*	DEFINITIONS:
					See accompanying documentation
					u - the displacement / velocity solution (to which constraints are applied)
					q - the pressure-like variable which constrains the divergence displacement / velocity	(= pressure for incompressible)	
					F - standard FE force vector
					Fhat - Uzawa RHS = K^{-1} G F  - h 
					K - standard FE stiffness matrix
					Khat - Uzawa transformed stiffness matrix = G^T K^{-1} G
					G matrix - discrete gradient operator
					D matrix - discrete divergence operator = G^T for this particular algorithm
					C matrix - Mass matrix (M) for compressibility 
					
		LM & DAM			
	*/

	/* CHOICE OF RESIDUAL: 
					we may opt to converge on the absolute value (self->useAbsoluteTolerance == True ... default)
					or the relative value of the residual (self->useAbsoluteTolerance == False) 
			 		(another possibility would be always to improve the residual by a given tolerance)
					The Moresi & Solomatov (Phys Fluids, 1995) approach is to use the relative tolerance	
	*/ 

	VecNorm( fVec, NORM_2, &fVecNorm );
	VecGetSize( fVec, &fVecSize );
	if ( fVecNorm / sqrt( (double)fVecSize ) <= 1e-99 ) {
		Journal_Printf( errorStream,
			"Error in func %s: The momentum force vector \"%s\" is zero. "
			"The force vector should be non-zero either because of your chosen boundary "
			"conditions, or because of the element force vector assembly. You have %d "
			"element force vectors attached.\n",
			__func__, sle->fForceVec->name, sle->fForceVec->assembleForceVector->hooks->count );
		if ( sle->fForceVec->assembleForceVector->hooks->count > 0 ) {
			Journal_Printf( errorStream, "You used the following force vector assembly terms:\n" );
			EntryPoint_PrintConcise( sle->fForceVec->assembleForceVector, errorStream );
/* 			 TODO : need to print the elementForceVector assembly, not the global guy!! */
		}	
		Journal_Printf( errorStream,
			"Please check values for building the force vector.\n" );
		Journal_Firewall( 0, errorStream, "Exiting.\n" ); 	
	}
	
					
 	Journal_DPrintf( self->debug, "In %s:\n", __func__ );
	Journal_RPrintfL( self->debug, 2, "Conjugate Gradient Uzawa solver with:\n");
	
	Stream_IndentBranch( StgFEM_Debug );
	
	Journal_RPrintfL( self->debug, 2, "Compressibility %s\n", (sle->cStiffMat)? "on" : "off");
	Journal_RPrintfL( self->debug, 2, "Preconditioning %s\n", (pcSolver)? "on" : "off" );   
	
	
	
	if ( sle->cStiffMat ) {
		Journal_DPrintfL( self->debug, 2, "(compressibility active)\n" );
		M_Mat = sle->cStiffMat->matrix;   
	}
	else {
		Journal_DPrintfL( self->debug, 2, "(compressibility inactive)\n" );
	}
	if ( sle->dStiffMat ) {
		Journal_DPrintfL( self->debug, 2, "(asymmetric geometry: handling D Matrix [incorrectly - will be ignored])\n" );
		D_Mat = sle->dStiffMat->matrix;
	}
	else {
		Journal_DPrintfL( self->debug, 2, "(No D -> symmetric geometry: D = Gt)\n" );
	}
	
	#if DEBUG
	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
		Journal_DPrintf( self->debug, "Matrices and Vectors to solve are:\n" );
		Journal_DPrintf( self->debug, "K Matrix:\n" );
		/* No nice way of viewing Matrices, so commented out as incompatible with
		 * new 3D decomp at present --Kathleen Humble 30-04-07 
		 * Matrix_View( sle->kStiffMat->matrix, self->debug ); */
		Journal_DPrintf( self->debug, "G Matrix:\n" );
		if ( D_Mat ) {
			Journal_DPrintf( self->debug, "D Matrix:\n" );
		}	
		if ( M_Mat ) {
			Journal_DPrintf( self->debug, "M Matrix:\n" );
		}	
		Journal_DPrintf( self->debug, "Z (preconditioner) Matrix:\n" );
		Journal_DPrintf( self->debug, "f Vector:\n" );
		_SLE_VectorView( fVec, self->debug );
		Journal_DPrintf( self->debug, "h Vector:\n" );
		_SLE_VectorView( hVec, self->debug );
	}
	#endif
	
	/* STEP 1: Estimate the magnitude of the RHS for the transformed problem
			   we compute (usually to lower accuracy than elsewhere) the RHS (Fhat - h) 
	         and store the result in qTempVec.
		LM & DAM			
	*/
	
	Journal_DPrintfL( self->debug, 2, "Building Fhat - h.\n" );
	PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg);
	KSPSetTolerances( velSolver, self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
	if (flg) {
	    ksptime = MPI_Wtime();
	}
	KSPSolve( velSolver, fVec, vStarVec );
	if (flg) {
	    ksptime = MPI_Wtime() - ksptime;
	    PetscPrintf( PETSC_COMM_WORLD,  "KSP on velSolver took %lf seconds in Building Fhat step\n", ksptime);
	}
	KSPGetIterationNumber( velSolver, &innerLoopIterations );
	
	Journal_DPrintfL( self->debug, 2, "Fhat inner solution: Number of iterations: %d\n", innerLoopIterations );
	
        if ( D_Mat ) {
          MatMult( D_Mat, vStarVec, qTempVec );
        }
        else {
          MatMultTranspose( G_Mat, vStarVec, qTempVec );
        }
	VecAXPY( qTempVec, -1.0, hVec );
	
	/*  WARNING:
			If D != G^T then the resulting \hat{K} is not likely to be symmetric, positive definite as
			required by this implementation of the Uzawa iteration.  This next piece of code
			is VERY unlikely to work properly so it's in the sin bin for the time being - LM.
			
			if ( D_Mat ) {
				MatrixMultiply( D_Mat, vStarVec, qTempVec );
			}
			else {
				MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
			}
		LM & DAM			
	*/	

	
	/* STEP 2: The problem scaling - optionally normalize the uzawa residual by the magnitude of the RHS (use a relative tolerance)
			For the inner velocity solver,  Citcom uses a relative tolerance equal to that used for the Uzawa iteration as a whole
		LM & DAM			
	*/
	
	if (self->useAbsoluteTolerance) {
		chosenResidual = &absResidual;
		Journal_PrintfL( self->info, 2, "Absolute residual < %g for Uzawa stopping condition\n", self->tolerance);
		/* We should calculate the effective relative tolerance and insert that here !! */
		KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
	}
	else {  /* The CITCOM compatible choice */
		chosenResidual = &relResidual;
		Journal_PrintfL( self->info, 2, "Relative residual < %g for Uzawa stopping condition\n", self->tolerance);	
		KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
	}
	
	Journal_DPrintfL( self->debug, 2, "Determining scaling factor for residual:\n" );
	VecNorm( qTempVec, NORM_2, &qTempVecNorm );
	uzawaRhsScale = ((double)qTempVecNorm) * qReciprocalGlobalProblemScale;
	
	Journal_DPrintfL( self->debug, 2, "uzawaRhsScale = %f\n", uzawaRhsScale );	
	Journal_Firewall( isGoodNumber( uzawaRhsScale ), errorStream, 
			"Error in func '%s' for %s '%s' - uzawaRhsScale has illegal value '%g'.\n", __func__, self->type, self->name, uzawaRhsScale );
	
	/* STEP 3: Calculate initial residual for transformed equation  (\hat{F} - h - \hat{K} q_0)
	    Compute the solution to K u_0 = F - G q_0  (u_0 unknown)
		  Then G^T u* = \hat{F} - \hat{K} q_0 
	    u_0 is also the initial velocity solution to which the constraint is applied by the subsequent iteration
		LM & DAM			
	*/
	
	Journal_DPrintfL( self->debug, 2, "Solving for transformed Uzawa RHS.\n" );
	
	VecCopy( fVec, fTempVec );
	VecScale( fTempVec, -1.0 );
	MatMultAdd( G_Mat, qVec, fTempVec, fTempVec );
	VecScale( fTempVec, -1.0 );
	KSPSolve( velSolver, fTempVec, uVec );

	/* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) LM & DAM */
        if ( D_Mat ) {
           MatMult( D_Mat, uVec, rVec );
        }
        else {
           MatMultTranspose( G_Mat, uVec, rVec );
        }
	VecNorm( rVec, NORM_2, &rnorm0 );
	VecNorm( uVec, NORM_2, &uVecNorm );
	divU = rnorm0 / uVecNorm;
	
	Journal_PrintfL( self->info, 2, "Initial l2Norm( Div u ) / l2Norm( u ) = %f \n", divU);
	
	Journal_Firewall( isGoodNumber( divU ), errorStream, 
			"Error in func '%s' for %s '%s' - l2Norm( Div u ) has illegal value '%g'.\n",
			__func__, self->type, self->name, divU );
	
	
	Journal_DPrintfL( self->debug, 2, "Adding compressibility and prescribed divergence terms.\n" );
	
	if ( M_Mat ) {
		MatMultAdd( M_Mat, qVec, rVec, rVec );
	}	
	VecAXPY( rVec, -1.0, hVec );
			
	/* Check for existence of constant null space */
#if 0
	nullsp_present = _check_if_constant_nullsp_present( self, K_Mat,G_Mat,M_Mat, fTempVec,vStarVec,qTempVec,sVec, velSolver );
#endif
			
	/* STEP 4: Preconditioned conjugate gradient iteration loop */	
		
	Journal_DPrintfL( self->debug, 1, "Beginning main Uzawa conjugate gradient loop:\n" );	

	iteration_I = 0;

        /* outer_it, residual, time */
        uzawa_summary = self->monitor;
	time = 0.0;
	t0 = MPI_Wtime();
//	Journal_PrintfL( self->info, 1, "  |r0| = %.8e \n", rnorm0 );

	do{	
		/* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
		self->outeritsinitialtime = 0;
		self->outeritsendtime = 0;
		//BEGINNING OF OUTER ITERATIONS!!!!!
		/*get wall time for start of outer loop*/
		self->outeritsinitialtime = MPI_Wtime();
		
		Journal_DPrintfL( self->debug, 2, "Beginning solve '%u'.\n", iteration_I );
		Stream_IndentBranch( StgFEM_Debug );
		
		/* STEP 4.1: Preconditioner
			Solve:
				Q_\hat{K} z_1 =  r_1
				Q_\hat{K} is an approximation to \hat{K} which is simple / trivial / quick to invert
			LM & DAM			
		*/
		
		if ( pcSolver ) {
		    PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg);
		    if (flg) {
			ksptime = MPI_Wtime();
		    }
		    KSPSolve( pcSolver, rVec, qTempVec );
		    if (flg) {
			ksptime = MPI_Wtime() - ksptime;
			PetscPrintf( PETSC_COMM_WORLD,  "KSP on pcSolver took %lf seconds\n", ksptime);
		    }
		}
		else {
			VecCopy( rVec, qTempVec );
		}

		/* Remove the constant null space, but only if NOT compressible */
#if 0
		if( nullsp_present == True ) {
			_remove_constant_nullsp( qTempVec );
		}
#endif
				
		/* STEP 4.2: Calculate s_I, the pressure search direction
				z_{I-1} . r_{I-1}  
				\beta = (z_{I-1} . r_{I-1}) / (z_{I-2} . r_{I-2})  
					\beta = 0 for the first iteration
		      s_I = z_(I-1) + \beta * s_(I-1) 
			LM & DAM			
		*/ 
		
		VecDot( qTempVec, rVec, &zdotr_current );
	
		VecNorm( qTempVec, NORM_2, &qTempVecNorm );
		VecNorm( rVec, NORM_2, &rVecNorm );	
		Journal_DPrintfL( self->debug, 2, "l2Norm (qTempVec) %g; (rVec) %g \n", 
			qTempVecNorm * qReciprocalGlobalProblemScale,
			rVecNorm * qReciprocalGlobalProblemScale );
		
		if ( iteration_I == 0 ) {
			VecCopy( qTempVec, sVec );
		}
		else {
			beta = zdotr_current/zdotr_previous;
			VecAYPX( sVec, beta, qTempVec );
		}
		
		/* STEP 4.3: Velocity search direction corresponding to s_I is found by solving
				K u* = G s_I
			LM & DAM			
		*/
			
		MatMult( G_Mat, sVec, fTempVec );
		
		Journal_DPrintfL( self->debug, 2, "Uzawa inner iteration step\n");
		
		//START OF INNER ITERATIONS!!!!
		PetscOptionsHasName(PETSC_NULL,"-uzawa_printksptimes",&flg);
		/*get initial wall time for inner loop*/
		self->inneritsinitialtime = MPI_Wtime();
		if (flg) {
		    ksptime = MPI_Wtime();
		}
		KSPSolve( velSolver, fTempVec, vStarVec );
		if (flg) {
		    ksptime = MPI_Wtime() - ksptime;
		    PetscPrintf( PETSC_COMM_WORLD,  "KSP on velSolver took %lf seconds in Uzawa inner iteration step\n", ksptime);
		}
		/*get end wall time for inner loop*/
		self->inneritsendtime = MPI_Wtime();
		
		/* add time to total time inner its: */
		self->totalinneritstime = self->totalinneritstime + (-self->inneritsinitialtime + self->inneritsendtime);
		/* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
		self->inneritsinitialtime = 0;
		self->inneritsendtime = 0;
		
		KSPGetIterationNumber( velSolver, &innerLoopIterations );
		/* add the inner loop iterations to the total inner iterations */
		self->totalnuminnerits = self->totalnuminnerits + innerLoopIterations;
		
		Journal_DPrintfL( self->debug, 2, "Completed Uzawa inner iteration in '%u' iterations \n", innerLoopIterations );
				
		/* STEP 4.4: Calculate the step size ( \alpha = z_{I-1} . r_{I-1} / (s_I . \hat{K} s_I) )
				 \hat{K} s_I = G^T u* - M s_I (u* from step 4.3) 	
			LM & DAM			
		*/ 
		
                if ( D_Mat ) {
                   MatMult( D_Mat, vStarVec, qTempVec );
                }
                else {
                   MatMultTranspose( G_Mat, vStarVec, qTempVec );
                }
		
		/* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) 
		
			if ( D_Mat ) {
				MatrixMultiply( D_Mat, vStarVec, qTempVec );
			}
			else {
				MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
			}
			LM & DAM			
		*/

		if ( M_Mat ) {
			Journal_DPrintfL( self->debug, 2, "Correcting for Compressibility\n" );
			VecScale( qTempVec, -1.0 );
			MatMultAdd( M_Mat, sVec, qTempVec, qTempVec );
			VecScale( qTempVec, -1.0 );
		}

		VecDot( sVec, qTempVec, &sdotGTrans_v );
		
		alpha = zdotr_current/sdotGTrans_v;
		
		/* STEP 4.5: Update pressure, velocity and value of residual
				 by \alpha times corresponding search direction 
			LM & DAM			
		*/
		
		Journal_DPrintfL( self->debug, 2, "zdotr_current = %g \n", zdotr_current);
		Journal_DPrintfL( self->debug, 2, "sdotGTrans_v = %g \n", sdotGTrans_v);
		Journal_DPrintfL( self->debug, 2, "alpha = %g \n", alpha);
	
		Journal_Firewall( 
				isGoodNumber( zdotr_current ) && isGoodNumber( sdotGTrans_v ) && isGoodNumber( alpha ), 
				errorStream, 
				"Error in func '%s' for %s '%s' - zdotr_current, sdotGTrans_v or alpha has an illegal value: '%g','%g' or '%g'\n",
				__func__, self->type, self->name, zdotr_current, sdotGTrans_v, alpha );
		
		VecAXPY( qVec, alpha, sVec );
		VecAXPY( uVec, -alpha, vStarVec );
		VecAXPY( rVec, -alpha, qTempVec );
		
		/* STEP 4.6: store the value of z_{I-1} . r_{I-1} for the next iteration
		 LM & DAM
		*/
		
		zdotr_previous = zdotr_current; 
		
		VecNorm( rVec, NORM_2, &rVecNorm );
		absResidual = rVecNorm * qReciprocalGlobalProblemScale;
		relResidual = absResidual / uzawaRhsScale;
		
		Stream_UnIndentBranch( StgFEM_Debug );
		
		if( iteration_I % outputInterval == 0 ) {
			Journal_PrintfL( self->info, 2, "\tLoop = %u, absResidual = %.8e, relResidual = %.8e\n", 
				iteration_I, absResidual, relResidual );
		}
		
		Journal_Firewall( isGoodNumber( absResidual ), errorStream, 
				"Error in func '%s' for %s '%s' - absResidual has an illegal value: '%g'\n",
				__func__, self->type, self->name, absResidual );
		
		Journal_Firewall( iteration_I < maxIterations, 
				errorStream, "In func %s: Reached maximum number of iterations %u without converging; absResidual = %.5g, relResidual = %.5g \n",
				__func__, iteration_I, absResidual, relResidual );

/* 		 TODO: test for small change in 10 iterations and if so restart? */

		time = MPI_Wtime()-t0;
		if (uzawa_summary) {
                	Journal_PrintfL( self->info, 1, "  %1.4d uzawa residual norm %12.13e, cpu time %5.5e\n", iteration_I+1,*chosenResidual,time );
        	}
			
	iteration_I++;  
	//END OF OUTER ITERATION LOOP!!!
		/*get wall time for end of outer loop*/
		self->outeritsendtime = MPI_Wtime();
		/* add time to total time inner its: */
		self->totalouteritstime = self->totalouteritstime + (-self->outeritsinitialtime + self->outeritsendtime);
		/* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
		self->outeritsinitialtime = 0;
		self->outeritsendtime = 0;
		/* add the outer loop iterations to the total outer iterations */
		self->totalnumouterits++; 
	}  while ( (*chosenResidual > self->tolerance) || (iteration_I<minIterations) );  
//	}  while ( *chosenResidual > self->tolerance );

	Journal_DPrintfL( self->debug, 1, "Pressure solution converged. Exiting uzawa \n ");
	
	/* STEP 5:  Check all the relevant residuals and report back */
	
	if (Stream_IsEnable( self->info ) ) {
	
	/* This information should be in an info stream */
	Journal_PrintfL( self->info, 1, "Summary:\n");
	Journal_PrintfL( self->info, 1, "  Uzawa its. = %04d , Uzawa residual = %12.13e\n", iteration_I, relResidual );
	MatMultTranspose( G_Mat, uVec, rVec );
	VecNorm( rVec, NORM_2, &rVecNorm );
	VecNorm( uVec, NORM_2, &uVecNorm );
	divU = rVecNorm / uVecNorm;
	Journal_PrintfL( self->info, 1, "  |G^T u|/|u|               = %.8e\n", divU);
	
	/* Residual for the momentum equation 
		Compute r = || F - Ku - Gp || / || F ||
	*/
	
	MatMult( G_Mat, qVec, vStarVec );
	MatMultAdd( K_Mat, uVec, vStarVec, fTempVec );
	VecAYPX( fTempVec, -1.0, fVec );
	
	VecNorm( fTempVec, NORM_2, &fTempVecNorm );
	VecNorm( fVec, NORM_2, &fVecNorm );
	momentumEquationResidual = fTempVecNorm / fVecNorm;
	Journal_PrintfL( self->info, 1, "  |f - K u - G p|/|f|       = %.8e\n", momentumEquationResidual );
	Journal_Firewall( isGoodNumber( momentumEquationResidual ), errorStream, 
			"Bad residual for the momentum equation (|| F - Ku - Gp || / || F || = %g):\n"
			"\tCheck to see if forcing term is zero or nan - \n\t|| F - Ku - Gp || = %g \n\t|| F || = %g.\n", 
			momentumEquationResidual,
			fTempVecNorm, fVecNorm );
		
	/* "Preconditioned"	residual for the momentum equation 
	 		r_{w} = || Q_{K}(r) || / || Q_{K}(F)
			fTempVec contains the residual but is overwritten once used
			vStarVec is used to hold the diagonal preconditioner Q_{K} 
	*/
	
	MatGetDiagonal( K_Mat, vStarVec );
	VecReciprocal( vStarVec );
	VecPointwiseMult( vStarVec, fTempVec, fTempVec );
	VecNorm( fTempVec, NORM_2, &weightedResidual );
	VecPointwiseMult( vStarVec, fVec, fTempVec );
	VecNorm( fTempVec, NORM_2, &weightedVelocityScale );
		
	Journal_PrintfL( self->info, 1, "  |f - K u - G p|_w/|f|_w   = %.8e\n", weightedResidual / weightedVelocityScale );	
		
	/* Report back on the solution - velocity and pressure 
	 Note - correction for dof in Vrms ??
	*/

	VecNorm( uVec, NORM_INFINITY, &uVecNormInf );
	VecNorm( uVec, NORM_2, &uVecNorm );
	VecGetSize( uVec, &uVecSize );
	VecNorm( qVec, NORM_INFINITY, &qVecNormInf );
	VecNorm( qVec, NORM_2, &qVecNorm );
	VecGetSize( qVec, &qVecSize );
        Journal_PrintfL( self->info, 1, "  |u|_{\\infty} = %.8e , u_rms = %.8e\n", 
		uVecNormInf, uVecNorm / sqrt( (double)uVecSize ) );
	Journal_PrintfL( self->info, 1, "  |p|_{\\infty} = %.8e , p_rms = %.8e\n",
               	qVecNormInf, qVecNorm / sqrt( (double)qVecSize ) );

	{	PetscInt lmin,lmax;
		PetscReal min,max;
		VecMax( uVec, &lmax, &max );
		VecMin( uVec, &lmin, &min );
		Journal_PrintfL( self->info, 1, "  min/max(u) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
                VecMax( qVec, &lmax, &max );
                VecMin( qVec, &lmin, &min );
                Journal_PrintfL( self->info, 1, "  min/max(p) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
        }
	VecSum( qVec, &p_sum );
	Journal_PrintfL( self->info, 1, "  \\sum_i p_i = %.8e \n", p_sum );

	} /* journal stream enabled */

	#if DEBUG
	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
		Journal_DPrintf( self->debug, "Velocity solution:\n" );
		_SLE_VectorView( uVec, self->debug );
		Journal_DPrintf( self->debug, "Pressure solution:\n" );
		_SLE_VectorView( qVec, self->debug );
	}
	#endif
	Stream_UnIndentBranch( StgFEM_Debug );

        Stream_SetPrintingRank( self->info, init_info_stream_rank );
		/* Now gather up data for printing out to FrequentOutput file: */
	
	
	/*!!! if non-linear need to divide by number of nonlinear iterations and we do this in SystemLinearEquations */
	if((sle->isNonLinear != True)){
		self->avgnuminnerits = self->totalnuminnerits/self->totalnumouterits;
		self->avgnumouterits = self->totalnumouterits;
		self->avgtimeouterits = (self->totalouteritstime - self->totalinneritstime)/self->totalnumouterits;
		self->avgtimeinnerits = self->totalinneritstime/self->totalnuminnerits;
	}	
}
Пример #12
0
int main(int argc, char ** argv )
{
  PetscInitialize(&argc,&argv,"options","DENDRO example\n");
  ot::RegisterEvents();

  ot::DAMG_Initialize(MPI_COMM_WORLD);

  int size, rank;
  MPI_Comm_size(MPI_COMM_WORLD,&size);
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  if (argc<2) 
  {
    std::cout<<"Usage: mpirun -np <numProcs> "<<argv[0]<<" <filePrefix>"<<std::endl;
    return(-1);
  }

  std::ostringstream fName;
  fName<<argv[1]<<rank<<"_"<<size<<".pts";

  std::vector<double> pts;
  ot::readPtsFromFile(const_cast<char*>(fName.str().c_str()), pts);
  
  Vec sol;
  ot::DAMG * damg;
  
  // This function pointer will be called while setting up the solver on the coarsest grid if not all processes are active on the coarse grid 
  ot::getPrivateMatricesForKSP_Shell = getPrivateMatricesForKSP_Shell_Jac2;

  solve_neumann(
    /* input parameters: */
     pts,
     CalcVarCoef,
     CalcVarRHS,
     30, /* upper bound */

     /* output parameters */
     sol,
     damg
    );
 
  // compare solution with the exact one
  unsigned numMultigridLevels = damg[0]->totalLevels;
  ot::DA* da=damg[numMultigridLevels-1]->da;
  PetscScalar *solArray;
  da->vecGetBuffer(sol,solArray,false,false,true,1);
  double maxDiff = 0;
  unsigned maxDepth=da->getMaxDepth()-1;

  if(da->iAmActive())
  { 
    // first loop over those octants which do not contain ghost nodes.
    for(da->init<ot::DA_FLAGS::INDEPENDENT>(); da->curr() < da->end<ot::DA_FLAGS::INDEPENDENT>(); da->next<ot::DA_FLAGS::INDEPENDENT>())  
    {
      Point pt = da->getCurrentOffset();
      unsigned levelhere = da->getLevel(da->curr()) - 1;
      double hxOct = ldexp(1.0,-levelhere);
      double x = ldexp(pt.x(),-maxDepth );
      double y = ldexp(pt.y(),-maxDepth );
      double z = ldexp(pt.z(),-maxDepth );

      unsigned int indices[8];
      da->getNodeIndices(indices); 

      double coord[8][3] = {
	{0.0,0.0,0.0},
	{1.0,0.0,0.0},
	{0.0,1.0,0.0},
	{1.0,1.0,0.0},
	{0.0,0.0,1.0},
	{1.0,0.0,1.0},
	{0.0,1.0,1.0},
	{1.0,1.0,1.0}
      };

      unsigned char hn = da->getHangingNodeIndex(da->curr());

      for(int i = 0; i < 8; i++)
	if (!(hn & (1 << i)))
	{
	  double xhere, yhere, zhere;
	  xhere = x + coord[i][0]*hxOct; 
	  yhere = y + coord[i][1]*hxOct; 
	  zhere = z + coord[i][2]*hxOct; 

	  double currDiff = fabs ( solArray[indices[i]] - cos(w*M_PI*xhere)*cos(w*M_PI*yhere)*cos(w*M_PI*zhere) );	
	  if (maxDiff < currDiff)
	    maxDiff=currDiff;
	}
    }  
    
    // now loop over those octants which DO contain ghost nodes; now we need to  check if the node is ghost, and skip it if it is
    size_t myFirstNode = da->getIdxElementBegin();
    size_t postFirstNode = da->getIdxPostGhostBegin();
    for(da->init<ot::DA_FLAGS::DEPENDENT>(); da->curr() < da->end<ot::DA_FLAGS::DEPENDENT>(); da->next<ot::DA_FLAGS::DEPENDENT>())  
    {
      Point pt = da->getCurrentOffset();
      unsigned levelhere = da->getLevel(da->curr()) - 1;
      double hxOct = ldexp(1.0,-levelhere);
      double x = ldexp(pt.x(),-maxDepth );
      double y = ldexp(pt.y(),-maxDepth );
      double z = ldexp(pt.z(),-maxDepth );

      unsigned int indices[8];
      da->getNodeIndices(indices); 

      double coord[8][3] = {
	{0.0,0.0,0.0},
	{1.0,0.0,0.0},
	{0.0,1.0,0.0},
	{1.0,1.0,0.0},
	{0.0,0.0,1.0},
	{1.0,0.0,1.0},
	{0.0,1.0,1.0},
	{1.0,1.0,1.0}
      };

      unsigned char hn = da->getHangingNodeIndex(da->curr());

      for(int i = 0; i < 8; i++)
	if ( indices[i]>=myFirstNode && indices[i]<postFirstNode && !(hn & (1 << i)) )
	{
	  double xhere, yhere, zhere;
	  xhere = x + coord[i][0]*hxOct; 
	  yhere = y + coord[i][1]*hxOct; 
	  zhere = z + coord[i][2]*hxOct; 

	  double currDiff = fabs ( solArray[indices[i]] - cos(w*M_PI*xhere)*cos(w*M_PI*yhere)*cos(w*M_PI*zhere) );	
	  if (maxDiff < currDiff)
	     maxDiff=currDiff;
	}
    }  
  }
  da->vecRestoreBuffer(sol,solArray,false,false,true,1); 

    double gMaxDiff;
    par::Mpi_Reduce<double>(&maxDiff, &gMaxDiff, 1, MPI_MAX, 0, MPI_COMM_WORLD);  
  if (!rank)
  {
    std::cout<<"Maximum difference: "<<gMaxDiff<<std::endl;
  }
    
  double solmax,solmin;
  VecMax(sol,NULL,&solmax);
  VecMin(sol,NULL,&solmin);

  if (!rank)
    std::cout<<"solution min: " << solmin << "; solution max: " << solmax << std::endl;

  // destroy multigrid context; this destroys the solution as well 
  DAMGDestroy(damg);
  
  ot::DAMG_Finalize();
  PetscFinalize();
  return 0;
}
Пример #13
0
void bsscr_summary(KSP_BSSCR * bsscrp_self, KSP ksp_S, KSP ksp_inner,
		   Mat K,Mat K2,Mat D,Mat G,Mat C,Vec u,Vec p,Vec f,Vec h,Vec t,
		   double penaltyNumber,PetscTruth KisJustK,double mgSetupTime,double scrSolveTime,double a11SingleSolveTime){
    PetscTruth flg, found;
    PetscInt   uSize, pSize, lmax, lmin, iterations;
    PetscReal  rNorm, fNorm, uNorm, uNormInf, pNorm, pNormInf, p_sum, min, max;
    Vec q, qq, t2, t3;
    double solutionAnalysisTime;

      PetscPrintf( PETSC_COMM_WORLD,  "\n\nSCR Solver Summary:\n\n");
      if(bsscrp_self->mg)
	    PetscPrintf( PETSC_COMM_WORLD, "  Multigrid setup:        = %.4g secs \n", mgSetupTime);

      KSPGetIterationNumber( ksp_S, &iterations);
      bsscrp_self->solver->stats.pressure_its = iterations;
      PetscPrintf( PETSC_COMM_WORLD,     "  Pressure Solve:         = %.4g secs / %d its\n", scrSolveTime, iterations);
      KSPGetIterationNumber( ksp_inner, &iterations);
      bsscrp_self->solver->stats.velocity_backsolve_its = iterations;
      PetscPrintf( PETSC_COMM_WORLD,     "  Final V Solve:          = %.4g secs / %d its\n\n", a11SingleSolveTime, iterations);

      /***************************************************************************************************************/

      flg = PETSC_FALSE; /* Off by default */
	  PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_solution_summary", &flg, &found );

      if(flg) {
	    PetscScalar KuNorm;
	    solutionAnalysisTime = MPI_Wtime();
	    VecGetSize( u, &uSize );
	    VecGetSize( p, &pSize );
	    VecDuplicate( u, &t2 );
	    VecDuplicate( u, &t3 );
	    MatMult( K, u, t3); VecNorm( t3, NORM_2, &KuNorm );
	    double angle, kdot;
	    if(penaltyNumber > 1e-10){/* should change this to ifK2built maybe */
          MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm );
          VecDot(t2,t3,&kdot);
          angle = (kdot/(rNorm*KuNorm));
          PetscPrintf( PETSC_COMM_WORLD,  "  <K u, K2 u>/(|K u| |K2 u|)    = %.6e\n", angle);
	    }
	    VecNorm( t, NORM_2, &rNorm ); /* t = f- G p  should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c */
	    VecDot(t3,t,&kdot);
	    angle = (kdot/(rNorm*KuNorm));
            PetscPrintf( PETSC_COMM_WORLD,  "  <K u, (f-G p)>/(|K u| |f- G p|)    = %.6e\n\n", angle);

	    MatMult( K, u, t2); VecNorm(t2, NORM_2, &KuNorm);
	    VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t  : t = f- G p  should be the formal residual vector, calculated on line 267 in auglag-driver-DGTGD.c*/
	    VecNorm( t2, NORM_2, &rNorm );
	    VecNorm( f,  NORM_2, &fNorm );
	    if(KisJustK){
          PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with original K matrix\n");
          PetscPrintf( PETSC_COMM_WORLD,"Solved    K u = G p -f\n");
          PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n");
          PetscPrintf( PETSC_COMM_WORLD,  "  |f - K u - G p|                       = %.12e\n", rNorm);
          PetscPrintf( PETSC_COMM_WORLD,  "  |f - K u - G p|/|f|                   = %.12e\n", rNorm/fNorm);
          if(penaltyNumber > 1e-10){/* means the restore_K flag was used */
            //if(K2 && f2){
            MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */
            //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */
            KisJustK=PETSC_FALSE;
            MatMult( K, u, t2);
            MatMult( G, p, t);
            VecAYPX( t, -1.0, f ); /* t <- -t + f */
            VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t */
            VecNorm( t2, NORM_2, &rNorm );
            PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n");
            PetscPrintf( PETSC_COMM_WORLD,  "  |(f) - (K + K2) u - G p|         = %.12e\n", rNorm);
            //}
          }
	    }
	    else{
          PetscPrintf( PETSC_COMM_WORLD,"Velocity back-solve with K+K2 matrix\n");
          PetscPrintf( PETSC_COMM_WORLD,"Solved    (K + K2) u = G p - (f)\n");
          PetscPrintf( PETSC_COMM_WORLD,"Residual with K+K2 matrix and f rhs vector\n");
          PetscPrintf( PETSC_COMM_WORLD,  "  |(f) - (K + K2) u - G p|         = %.12e\n", rNorm);
          PetscReal KK2Norm,KK2Normf;
          MatNorm(K,NORM_1,&KK2Norm);
          MatNorm(K,NORM_FROBENIUS,&KK2Normf);
          penaltyNumber = -penaltyNumber;
          MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */
          //VecAXPY(f,penaltyNumber,f2); /* f = penaltyNumber*f2 + f */
          KisJustK=PETSC_FALSE;
          MatMult( K, u, t2);    /* t2 = K*u  */
          MatMult( G, p, t);     /* t  = G*p  */
          VecAYPX( t, -1.0, f ); /* t <- f - t ; t = f - G*p  */
          VecAYPX( t2, -1.0, t ); /* t2 <- t - t2; t2 = f - G*p - K*u  */
          VecNorm( t2, NORM_2, &rNorm );
          PetscPrintf( PETSC_COMM_WORLD,"Residual with original K matrix\n");
          PetscPrintf( PETSC_COMM_WORLD,  "  |f - K u - G p|                       = %.12e\n", rNorm);
          PetscPrintf( PETSC_COMM_WORLD,  "  |f - K u - G p|/|f|                   = %.12e\n", rNorm/fNorm);
          PetscReal KNorm, K2Norm;
          MatNorm(K,NORM_1,&KNorm);	  MatNorm(K2,NORM_1,&K2Norm);
          PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_1    %.12e %.12e   ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm);
          MatNorm(K,NORM_INFINITY,&KNorm);  MatNorm(K2,NORM_INFINITY,&K2Norm);
          PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_inf  %.12e %.12e   ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm);
          MatNorm(K,NORM_FROBENIUS,&KNorm); MatNorm(K2,NORM_FROBENIUS,&K2Norm);
          PetscPrintf( PETSC_COMM_WORLD,"K and K2 norm_frob %.12e %.12e   ratio %.12e\n",KNorm,K2Norm,K2Norm/KNorm);
          PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_1    %.12e\n",KK2Norm);
          PetscPrintf( PETSC_COMM_WORLD,"K+r*K2 norm_frob %.12e\n",KK2Normf);
          penaltyNumber = -penaltyNumber;
          MatAXPY(K,penaltyNumber,K2,DIFFERENT_NONZERO_PATTERN);/* Computes K = penaltyNumber*K2 + K */
        }
        PetscPrintf( PETSC_COMM_WORLD,"\n");
        PetscPrintf( PETSC_COMM_WORLD,  "  |K u|    = %.12e\n", KuNorm);
        if(penaltyNumber > 1e-10){
          MatMult( K2, u, t2); VecNorm( t2, NORM_2, &rNorm );
          PetscPrintf( PETSC_COMM_WORLD,  "  |K2 u|   = %.12e\n", rNorm);
          PetscPrintf( PETSC_COMM_WORLD,"\n");
	    }



	    VecDuplicate( p, &q );
	    MatMult( D, u, q );   /* q = G'*u = D*u */
	    VecNorm( u, NORM_2, &uNorm );
	    VecNorm( q, NORM_2, &rNorm );

	    PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|_2               = %.6e\n", rNorm );
	    PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|_2/|u|_2         = %.6e\n", sqrt( (double) uSize / (double) pSize ) * rNorm / uNorm);

	    VecDuplicate( p, &qq );
	    MatMultTranspose( G, u, qq );
	    VecNorm( qq, NORM_2, &rNorm );
	    PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|/|u|             = %.8e\n", rNorm/uNorm ); /* to compare directly with Uzawa */

	    VecNorm( q, NORM_INFINITY, &rNorm );
	    PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|_infty/|u|_2     = %.6e\n", sqrt( (double) uSize ) * rNorm / uNorm);
	    /* create G'*u+C*p-h to check on this constraint */
	    /* already have q = D*u */
	    VecZeroEntries(qq);
	    if(C){
          MatMult( C, p, qq );
	    }
	    VecAYPX( q, 1.0, qq ); /* q = q+qq; G'*u + C*p*/
	    VecAXPY( q, -1.0, h ); /* q = q-h;  G'*u + C*p - h  */
	    VecNorm( q, NORM_2, &rNorm );
	    PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u + C p - h|        = %.8e  :constraint\n", rNorm );

	    VecNorm( u, NORM_INFINITY, &uNormInf );
	    VecNorm( u, NORM_2,        &uNorm );
	    VecGetSize( u, &uSize );

	    VecNorm( p, NORM_INFINITY, &pNormInf );
	    VecNorm( p, NORM_2,        &pNorm );

	    PetscPrintf( PETSC_COMM_WORLD,  "  |u|_{\\infty}  = %.6e , u_rms = %.6e\n",
	                 uNormInf, uNorm / sqrt( (double) uSize ) );

	    PetscPrintf( PETSC_COMM_WORLD,  "  |p|_{\\infty}  = %.6e , p_rms = %.6e\n",
	                 pNormInf, pNorm / sqrt( (double) pSize ) );

	    VecMax( u, &lmax, &max );
	    VecMin( u, &lmin, &min );
	    PetscPrintf( PETSC_COMM_WORLD,  "  min/max(u)    = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax);
        bsscrp_self->solver->stats.vmin = min;
        bsscrp_self->solver->stats.vmax = max;

	    VecMax( p, &lmax, &max );
	    VecMin( p, &lmin, &min );
	    PetscPrintf( PETSC_COMM_WORLD,  "  min/max(p)    = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax);
        bsscrp_self->solver->stats.pmin = min;
        bsscrp_self->solver->stats.pmax = max;

	    VecSum( p, &p_sum );
	    PetscPrintf( PETSC_COMM_WORLD,  "  \\sum_i p_i    = %.6e \n", p_sum );
        bsscrp_self->solver->stats.p_sum=p_sum;

	    solutionAnalysisTime = MPI_Wtime() - solutionAnalysisTime;

	    PetscPrintf( PETSC_COMM_WORLD,  "\n  Time for this analysis  = %.4g secs\n\n",solutionAnalysisTime);

	    Stg_VecDestroy(&t2 );
	    Stg_VecDestroy(&t3 );
	    Stg_VecDestroy(&q );
	    Stg_VecDestroy(&qq );
      }

}
Пример #14
0
int Brusselator(int argc,char **argv,PetscInt cycle)
{
  TS                ts;         /* nonlinear solver */
  Vec               X;          /* solution, residual vectors */
  Mat               J;          /* Jacobian matrix */
  PetscInt          steps,maxsteps,mx;
  PetscErrorCode    ierr;
  DM                da;
  PetscReal         ftime,hx,dt,xmax,xmin;
  struct _User      user;       /* user-defined work context */
  TSConvergedReason reason;

  PetscInitialize(&argc,&argv,(char*)0,help);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create distributed array (DMDA) to manage parallel grid and vectors
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMDACreate1d(PETSC_COMM_WORLD,DM_BOUNDARY_NONE,-11,2,2,NULL,&da);CHKERRQ(ierr);

  /*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Extract global vectors from DMDA;
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = DMCreateGlobalVector(da,&X);CHKERRQ(ierr);

  /* Initialize user application context */
  ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Advection-reaction options","");
  {
    user.A      = 1;
    user.B      = 3;
    user.alpha  = 0.1;
    user.uleft  = 1;
    user.uright = 1;
    user.vleft  = 3;
    user.vright = 3;
    ierr        = PetscOptionsReal("-A","Reaction rate","",user.A,&user.A,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-B","Reaction rate","",user.B,&user.B,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-alpha","Diffusion coefficient","",user.alpha,&user.alpha,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-uleft","Dirichlet boundary condition","",user.uleft,&user.uleft,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-uright","Dirichlet boundary condition","",user.uright,&user.uright,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-vleft","Dirichlet boundary condition","",user.vleft,&user.vleft,NULL);CHKERRQ(ierr);
    ierr        = PetscOptionsReal("-vright","Dirichlet boundary condition","",user.vright,&user.vright,NULL);CHKERRQ(ierr);
  }
  ierr = PetscOptionsEnd();CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Create timestepping solver context
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr);
  ierr = TSSetDM(ts,da);CHKERRQ(ierr);
  ierr = TSSetType(ts,TSARKIMEX);CHKERRQ(ierr);
  ierr = TSSetRHSFunction(ts,NULL,FormRHSFunction,&user);CHKERRQ(ierr);
  ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);CHKERRQ(ierr);
  ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr);
  ierr = DMCreateMatrix(da,&J);CHKERRQ(ierr);
  ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);CHKERRQ(ierr);

  ftime    = 1.0;
  maxsteps = 10000;
  ierr     = TSSetDuration(ts,maxsteps,ftime);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set initial conditions
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = FormInitialSolution(ts,X,&user);CHKERRQ(ierr);
  ierr = TSSetSolution(ts,X);CHKERRQ(ierr);
  ierr = VecGetSize(X,&mx);CHKERRQ(ierr);
  hx = 1.0/(PetscReal)(mx/2-1);
  dt = 0.4 * PetscSqr(hx) / user.alpha; /* Diffusive stability limit */
  dt *= PetscPowRealInt(0.2,cycle);     /* Shrink the time step in convergence study. */
  ierr = TSSetInitialTimeStep(ts,0.0,dt);CHKERRQ(ierr);
  ierr = TSSetTolerances(ts,1e-3*PetscPowRealInt(0.5,cycle),NULL,1e-3*PetscPowRealInt(0.5,cycle),NULL);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Set runtime options
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSetFromOptions(ts);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Solve nonlinear system
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = TSSolve(ts,X);CHKERRQ(ierr);
  ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr);
  ierr = TSGetTimeStepNumber(ts,&steps);CHKERRQ(ierr);
  ierr = TSGetConvergedReason(ts,&reason);CHKERRQ(ierr);
  ierr = VecMin(X,NULL,&xmin);CHKERRQ(ierr);
  ierr = VecMax(X,NULL,&xmax);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"%s at time %g after % 3D steps. Range [%6.4f,%6.4f]\n",TSConvergedReasons[reason],(double)ftime,steps,(double)xmin,(double)xmax);CHKERRQ(ierr);

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Free work space.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  ierr = MatDestroy(&J);CHKERRQ(ierr);
  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = TSDestroy(&ts);CHKERRQ(ierr);
  ierr = DMDestroy(&da);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return 0;
}
Пример #15
0
void Stokes_SLE_PenaltySolver_MakePenalty( Stokes_SLE_PenaltySolver* self, Stokes_SLE* sle, Vec* _penalty ) {
    Vec fVec = sle->fForceVec->vector, hVec = sle->hForceVec->vector, penalty, lambda;
    Mat kMat = sle->kStiffMat->matrix;
    FeMesh *mesh = sle->kStiffMat->rowVariable->feMesh;
    FeVariable *velField = sle->kStiffMat->rowVariable;
    SolutionVector* uVec = sle->uSolnVec;
    FeEquationNumber *eqNum = uVec->eqNum;
    IArray *inc;
    PetscScalar *lambdaVals, lambdaMin, *penaltyVals;
    int numDofs, numLocalElems, nodeCur, numLocalNodes, rank, eq;
    SolutionVector *solVec = sle->uSolnVec;
    double *velBackup;
    Vec vecBackup;
    int ii, jj, kk;

    MPI_Comm_rank( MPI_COMM_WORLD, &rank );

    numDofs = Mesh_GetDimSize( mesh );
    numLocalElems = FeMesh_GetElementLocalSize( mesh );
    numLocalNodes = FeMesh_GetNodeLocalSize( mesh );

    velBackup = (double*)malloc( numLocalNodes*numDofs*sizeof(double) );
    for( ii = 0; ii < numLocalNodes; ii++ )
        FeVariable_GetValueAtNode( velField, ii, velBackup + ii*numDofs );

    VecDuplicate( hVec, &penalty );
    VecGetArray( penalty, &penaltyVals );

    VecDuplicate( fVec, &lambda );
    MatGetDiagonal( kMat, lambda );
    {
        PetscInt idx;
        PetscReal min, max;

        VecMin( lambda, &idx, &min );
        VecMax( lambda, &idx, &max );
        if( rank == 0 ) {
           printf( "LAMBDA RANGE:\n" );
           printf( "  MIN: %e\n", min );
           printf( "  MAX: %e\n", max );
        }
    }

    vecBackup = solVec->vector;
    solVec->vector = lambda;
    SolutionVector_UpdateSolutionOntoNodes( solVec );

    inc = IArray_New();
    lambdaVals = (double*)malloc( numDofs*sizeof(double) );

    for( ii = 0; ii < numLocalElems; ii++ ) {

        lambdaMin = DBL_MAX;

        FeMesh_GetElementNodes( mesh, ii, inc );
        for( jj = 0; jj < inc->size; jj++ ) {

            nodeCur = inc->ptr[jj];
            FeVariable_GetValueAtNode( velField, nodeCur, lambdaVals );

            for( kk = 0; kk < numDofs; kk++ ) {

                eq = eqNum->mapNodeDof2Eq[nodeCur][kk];
                if( eq == -1 )
                    continue;

/*
                eq = *(int*)STreeMap_Map( eqNum->ownedMap, &eq );

                VecGetValues( lambda, 1, &eq, &lambdaVal );
*/

                if( lambdaVals[kk] < 0.0 )
                    printf( "%g\n",  lambdaVals[kk] );
                if( lambdaVals[kk] < lambdaMin )
                    lambdaMin = lambdaVals[kk];

            }
        }

        penaltyVals[ii] = lambdaMin;

    }

    if( lambdaVals ) free( lambdaVals );
    Stg_Class_Delete( inc );

    solVec->vector = vecBackup;

    for( ii = 0; ii < numLocalNodes; ii++ )
        FeVariable_SetValueAtNode( velField, ii, velBackup + ii*numDofs );
    if( velBackup ) free( velBackup );
    FeVariable_SyncShadowValues( velField );

    Stg_VecDestroy(&lambda );

    VecRestoreArray( penalty, &penaltyVals );
    VecAssemblyBegin( penalty );
    VecAssemblyEnd( penalty );

    {
        PetscInt idx;
        PetscReal min, max;

        VecMin( penalty, &idx, &min );
        VecMax( penalty, &idx, &max );
        if( rank == 0 ) {
           printf( "SEMI-PENALTY RANGE:\n" );
           printf( "  MIN: %e\n", min );
           printf( "  MAX: %e\n", max );
        }
    }

    *_penalty = penalty;
}
Пример #16
0
PetscErrorCode bsscr_buildK2(KSP ksp){
    KSP_BSSCR  *bsscr = (KSP_BSSCR *)ksp->data;
    Mat K,G,M, K2=0;
    Vec f2=0;
    PetscReal minD,maxD;


    //MatStokesBlockScaling BA=bsscr->BA;
    Stokes_SLE*  stokesSLE  = (Stokes_SLE*)bsscr->solver->st_sle;
    StokesBlockKSPInterface* Solver = bsscr->solver;
    //PetscErrorCode ierr;

    PetscFunctionBegin;
    K = stokesSLE->kStiffMat->matrix;
    G = stokesSLE->gStiffMat->matrix;
    if(bsscr->K2){
	Stg_MatDestroy(&bsscr->K2);
	bsscr->K2 =  PETSC_NULL;
    }
    switch (bsscr->k2type) {
    case (K2_DGMGD):
    {/* Should only do this one if scaling is turned off. */
	      Vec D=0;
          Vec MD = 0;
          Mat GKG = 0;
          Mat KG = 0;
          Mat Mscale = 0;

	  //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle;

	  if (Solver->mStiffMat){

         MatMatMult(K, G, MAT_INITIAL_MATRIX, PETSC_DEFAULT , &KG);
         MatTransposeMatMult(G, KG, MAT_INITIAL_MATRIX, PETSC_DEFAULT ,&GKG);
         MatGetVecs( GKG, PETSC_NULL, &MD );
         MatGetDiagonal( GKG, MD );

	      M = Solver->mStiffMat->matrix;
          MatDuplicate(M, MAT_COPY_VALUES, &Mscale );
          MatDiagonalScale(Mscale, NULL, MD );

          VecMin(MD, PETSC_NULL, &minD);
          VecMax(MD, PETSC_NULL, &maxD);
          VecScale(MD, 1.0/maxD);
          VecMin(MD, PETSC_NULL, &minD);
          VecMax(MD, PETSC_NULL, &maxD);

	      bsscr_GMiGt(&K2,K,G,Mscale);      /* K2 created */

	      Stg_VecDestroy(&D);
          Stg_VecDestroy(&MD);
          Stg_MatDestroy(&GKG);
          Stg_MatDestroy(&KG);


	      PetscPrintf( PETSC_COMM_WORLD,  "\n\n-----  K2_DGMGD  ------");
          PetscPrintf( PETSC_COMM_WORLD,  "    min %f, max %f \n\n", minD, maxD);

      }
	  else{
	      PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method DGMGD was specified but the SLE has no mStiffMat on it.\n");
	      PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n");  }
    }
    break;
    case (K2_GMG):
    {
	  //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle;
	  if (Solver->mStiffMat){
	      M = Solver->mStiffMat->matrix;
	      bsscr_GMiGt(&K2,K,G,M);      /* K2 created */
	      PetscPrintf( PETSC_COMM_WORLD,  "\n\n-----  K2_GMG  ------\n\n");
	  }else{
	      PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method GMG was specified but the SLE has no mStiffMat on it.\n");
	      PetscPrintf( PETSC_COMM_WORLD,"You need to use the AugLagStokes_SLE class.\n");
	  }
    }
    break;
    case (K2_GG):
    {
	  bsscr_GGt(&K2,K,G);      /* K2 created */
	  PetscPrintf( PETSC_COMM_WORLD,  "\n\n-----  K2_GG  ------\n\n");
    }
    break;
    case (K2_SLE):
    {
	  //AugLagStokes_SLE * stokesSLE = (AugLagStokes_SLE*)bsscr->st_sle;
	  if (Solver->mStiffMat){
	      K2 = Solver->mStiffMat->matrix;
	      if(Solver->jForceVec){ f2 = Solver->jForceVec->vector; }
	      PetscPrintf( PETSC_COMM_WORLD,  "\n\n-----  K2_SLE  ------\n\n");
	  }else{
	      PetscPrintf( PETSC_COMM_WORLD,"The Augmented Lagrangian Method SLE was specified but the Solver has no Matrix on it.\n");
	      PetscPrintf( PETSC_COMM_WORLD,"You need to set the K2 matrix on the StokesBlockKSPInterface class.\n");
	  }
    }
    break;
    default:
	  PetscPrintf( PETSC_COMM_WORLD,  "\n\n-----  NO K2  ------\n\n");
    }
    bsscr->f2 = f2;
    bsscr->K2 = K2;
    PetscFunctionReturn(0);
}
Пример #17
0
void AABB::Extend(const vec3& v)
{
	m_min = VecMin(m_min, v);
	m_max = VecMax(m_max, v);
}
Пример #18
0
int main(int argc,char **argv)
{
  Vec            x,y,w;               /* vectors */
  Vec            *z;                    /* array of vectors */
  PetscReal      norm,v,v1,v2,maxval;
  PetscInt       n = 20,maxind;
  PetscErrorCode ierr;
  PetscScalar    one = 1.0,two = 2.0,three = 3.0,dots[3],dot;

  ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;
  ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr);

  /*
     Create a vector, specifying only its global dimension.
     When using VecCreate(), VecSetSizes() and VecSetFromOptions(), the vector format
     (currently parallel, shared, or sequential) is determined at runtime.  Also, the
     parallel partitioning of the vector is determined by PETSc at runtime.

     Routines for creating particular vector types directly are:
        VecCreateSeq() - uniprocessor vector
        VecCreateMPI() - distributed vector, where the user can
                         determine the parallel partitioning
        VecCreateShared() - parallel vector that uses shared memory
                            (available only on the SGI); otherwise,
                            is the same as VecCreateMPI()

     With VecCreate(), VecSetSizes() and VecSetFromOptions() the option -vec_type mpi or
     -vec_type shared causes the particular type of vector to be formed.

  */

  ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr);
  ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr);
  ierr = VecSetFromOptions(x);CHKERRQ(ierr);
  /*
     Duplicate some work vectors (of the same format and
     partitioning as the initial vector).
  */
  ierr = VecDuplicate(x,&y);CHKERRQ(ierr);
  ierr = VecDuplicate(x,&w);CHKERRQ(ierr);

  /*
     Duplicate more work vectors (of the same format and
     partitioning as the initial vector).  Here we duplicate
     an array of vectors, which is often more convenient than
     duplicating individual ones.
  */
  ierr = VecDuplicateVecs(x,3,&z);CHKERRQ(ierr);
  /*
     Set the vectors to entries to a constant value.
  */
  ierr = VecSet(x,one);CHKERRQ(ierr);
  ierr = VecSet(y,two);CHKERRQ(ierr);
  ierr = VecSet(z[0],one);CHKERRQ(ierr);
  ierr = VecSet(z[1],two);CHKERRQ(ierr);
  ierr = VecSet(z[2],three);CHKERRQ(ierr);
  /*
     Demonstrate various basic vector routines.
  */
  ierr = VecDot(x,y,&dot);CHKERRQ(ierr);
  ierr = VecMDot(x,3,z,dots);CHKERRQ(ierr);

  /*
     Note: If using a complex numbers version of PETSc, then
     PETSC_USE_COMPLEX is defined in the makefiles; otherwise,
     (when using real numbers) it is undefined.
  */

  ierr = PetscPrintf(PETSC_COMM_WORLD,"Vector length %D\n",n);CHKERRQ(ierr);
  ierr = VecMax(x,&maxind,&maxval);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMax %g, VecInd %D\n",(double)maxval,maxind);CHKERRQ(ierr);

  ierr = VecMin(x,&maxind,&maxval);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMin %g, VecInd %D\n",(double)maxval,maxind);CHKERRQ(ierr);
  ierr = PetscPrintf(PETSC_COMM_WORLD,"All other values should be near zero\n");CHKERRQ(ierr);


  ierr = VecScale(x,two);CHKERRQ(ierr);
  ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecScale %g\n",(double)v);CHKERRQ(ierr);


  ierr = VecCopy(x,w);CHKERRQ(ierr);
  ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecCopy  %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecAXPY(y,three,x);CHKERRQ(ierr);
  ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-8.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecAXPY %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecAYPX(y,two,x);CHKERRQ(ierr);
  ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-18.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecAYPX %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecSwap(x,y);CHKERRQ(ierr);
  ierr = VecNorm(y,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-2.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecSwap  %g\n",(double)v);CHKERRQ(ierr);
  ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
  v = norm-18.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecSwap  %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecWAXPY(w,two,x,y);CHKERRQ(ierr);
  ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-38.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecWAXPY %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecPointwiseMult(w,y,x);CHKERRQ(ierr);
  ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-36.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecPointwiseMult %g\n",(double)v);CHKERRQ(ierr);

  ierr = VecPointwiseDivide(w,x,y);CHKERRQ(ierr);
  ierr = VecNorm(w,NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-9.0*PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecPointwiseDivide %g\n",(double)v);CHKERRQ(ierr);

  dots[0] = one;
  dots[1] = three;
  dots[2] = two;

  ierr = VecSet(x,one);CHKERRQ(ierr);
  ierr = VecMAXPY(x,3,dots,z);CHKERRQ(ierr);
  ierr = VecNorm(z[0],NORM_2,&norm);CHKERRQ(ierr);
  v    = norm-PetscSqrtReal((PetscReal)n); if (v > -PETSC_SMALL && v < PETSC_SMALL) v = 0.0;
  ierr = VecNorm(z[1],NORM_2,&norm);CHKERRQ(ierr);
  v1   = norm-2.0*PetscSqrtReal((PetscReal)n); if (v1 > -PETSC_SMALL && v1 < PETSC_SMALL) v1 = 0.0;
  ierr = VecNorm(z[2],NORM_2,&norm);CHKERRQ(ierr);
  v2   = norm-3.0*PetscSqrtReal((PetscReal)n); if (v2 > -PETSC_SMALL && v2 < PETSC_SMALL) v2 = 0.0;
  ierr = PetscPrintf(PETSC_COMM_WORLD,"VecMAXPY %g %g %g \n",(double)v,(double)v1,(double)v2);CHKERRQ(ierr);

  /*
     Free work space.  All PETSc objects should be destroyed when they
     are no longer needed.
  */
  ierr = VecDestroy(&x);CHKERRQ(ierr);
  ierr = VecDestroy(&y);CHKERRQ(ierr);
  ierr = VecDestroy(&w);CHKERRQ(ierr);
  ierr = VecDestroyVecs(3,&z);CHKERRQ(ierr);
  ierr = PetscFinalize();
  return ierr;
}
Пример #19
0
PetscErrorCode test_axpy_dot_max( void )
{
  Vec            x1,y1, x2,y2;
  Vec            tmp_buf[2];
  Vec            X, Y;
  PetscReal      real,real2;
  PetscScalar    scalar;
  PetscInt       index;
  PetscErrorCode ierr;

  PetscFunctionBegin;
  PetscPrintf( PETSC_COMM_WORLD, "\n\n============== %s ==============\n", PETSC_FUNCTION_NAME );

  gen_test_vector( PETSC_COMM_WORLD, 4, 0, 1, &x1 );
  gen_test_vector( PETSC_COMM_WORLD, 5, 10, 2, &x2 );

  gen_test_vector( PETSC_COMM_WORLD, 4, 4, 3, &y1 );
  gen_test_vector( PETSC_COMM_WORLD, 5, 5, 1, &y2 );

  tmp_buf[0] = x1;
  tmp_buf[1] = x2;
  ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&X);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(X);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(X);CHKERRQ(ierr);
  ierr = VecDestroy(&x1);CHKERRQ(ierr);
  ierr = VecDestroy(&x2);CHKERRQ(ierr);


  tmp_buf[0] = y1;
  tmp_buf[1] = y2;
  ierr = VecCreateNest(PETSC_COMM_WORLD,2,PETSC_NULL,tmp_buf,&Y);CHKERRQ(ierr);
  ierr = VecAssemblyBegin(Y);CHKERRQ(ierr);
  ierr = VecAssemblyEnd(Y);CHKERRQ(ierr);
  ierr = VecDestroy(&y1);CHKERRQ(ierr);
  ierr = VecDestroy(&y2);CHKERRQ(ierr);


  PetscPrintf( PETSC_COMM_WORLD, "VecAXPY \n");
  ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */
  ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr);
  ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(1) y1 = \n" ); 
  ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(1) y2 = \n" ); 
  ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr);
  ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr);

  PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) );

  ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi     norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2);


  ierr = VecAXPY( Y, 1.0, X ); /* Y <- a X + Y */
  ierr = VecNestGetSubVec( Y, 0, &y1 );CHKERRQ(ierr);
  ierr = VecNestGetSubVec( Y, 1, &y2 );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(2) y1 = \n" );
  ierr = VecView( y1, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(2) y2 = \n" );
  ierr = VecView( y2, PETSC_VIEWER_STDOUT_WORLD );CHKERRQ(ierr);
  ierr = VecDot( X,Y, &scalar );CHKERRQ(ierr);

  PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi \n", PetscRealPart(scalar), PetscImaginaryPart(scalar) );
  ierr = VecDotNorm2( X,Y, &scalar, &real2 );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "X.Y = %lf + %lfi     norm2(Y) = %lf\n", PetscRealPart(scalar), PetscImaginaryPart(scalar), real2);


  ierr = VecMax( X, &index, &real );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(max-X) = %f : index = %d \n", real, index );
  ierr = VecMin( X, &index, &real );CHKERRQ(ierr);
  PetscPrintf( PETSC_COMM_WORLD, "(min-X) = %f : index = %d \n", real, index );

  ierr = VecDestroy(&X);CHKERRQ(ierr);
  ierr = VecDestroy(&Y);CHKERRQ(ierr);

  PetscFunctionReturn(0);
}
PetscErrorCode BSSCR_MatStokesMVBlockReportOperatorScales( Mat A, PetscTruth sym )
{
	Vec rA, rG;
	PetscInt loc,M,N;
	PetscReal min, max;
	Mat K,G,D,C;
	PetscTruth is_block;
	
	
	/* check A is 2x2 block matrix */
	Stg_PetscObjectTypeCompare( (PetscObject)A, "block", &is_block );
	if (is_block==PETSC_FALSE) {
		Stg_SETERRQ( PETSC_ERR_SUP, "Only valid for MatType = block" );
	}
	MatGetSize( A, &M, &N );
	if ( (M!=2) || (N!=2) ) {
		Stg_SETERRQ2( PETSC_ERR_SUP, "Only valid for 2x2 block. Yours has dimension %Dx%D", M,N );
	}
	
	
	MatNestGetSubMat( A, 0,0, &K );
	MatNestGetSubMat( A, 0,1, &G );
	MatNestGetSubMat( A, 1,0, &D );
	MatNestGetSubMat( A, 1,1, &C );
	
	
	MatGetVecs( K, PETSC_NULL, &rA );
	VecDuplicate( rA, &rG );
	
	/* Report the row max and mins */
	if (K!=PETSC_NULL) {
		MatGetRowMax( K, rA, PETSC_NULL );
		VecMax( rA, &loc, &max );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_max(K) = %g \n", max );
		
		MatGetRowMinAbs( K, rA, PETSC_NULL );
		VecMin( rA, &loc, &min );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_min(K) = %g \n\n", min );
	}
	
	if( G != PETSC_NULL ) {       
		MatGetRowMax( G, rG, PETSC_NULL );
		VecMax( rG, &loc, &max );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_max(G) = %g \n", max );
		
		MatGetRowMinAbs( G, rG, PETSC_NULL );
		VecMin( rG, &loc, &min );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_min(G) = %g \n", min );
	}
	
	if( D != PETSC_NULL && !sym ) {
                Vec rD;

                MatGetVecs( D, PETSC_NULL, &rD );
		MatGetRowMax( D, rD, PETSC_NULL );
		VecMax( rD, &loc, &max );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_max(D) = %g \n", max );
		
		MatGetRowMinAbs( D, rD, PETSC_NULL );
		VecMin( rD, &loc, &min );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_min(D) = %g \n", min );

                Stg_VecDestroy(&rD );
	}
	
	if( C != PETSC_NULL ) {
		Vec cG;

		MatGetVecs( G, &cG, PETSC_NULL );
		MatGetRowMax( C, cG, PETSC_NULL );
		VecMax( cG, &loc, &max );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_max(C) = %g \n", max );
		
		MatGetRowMin( C, cG, PETSC_NULL );
		VecMin( cG, &loc, &min );
		PetscPrintf( PETSC_COMM_WORLD, "Sup_min(C) = %g \n\n", min );
	
		Stg_VecDestroy(&cG);
	}
	
	
	Stg_VecDestroy(&rA );
	Stg_VecDestroy(&rG );
	
	
	PetscFunctionReturn(0);
}
Пример #21
0
static PetscErrorCode  KSPSolve_CGS(KSP ksp)
{
  PetscErrorCode ierr;
  PetscInt       i;
  PetscScalar    rho,rhoold,a,s,b;
  Vec            X,B,V,P,R,RP,T,Q,U,AUQ;
  PetscReal      dp = 0.0;
  PetscBool      diagonalscale;

  PetscFunctionBegin;
  /* not sure what residual norm it does use, should use for right preconditioning */

  ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr);
  if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name);

  X   = ksp->vec_sol;
  B   = ksp->vec_rhs;
  R   = ksp->work[0];
  RP  = ksp->work[1];
  V   = ksp->work[2];
  T   = ksp->work[3];
  Q   = ksp->work[4];
  P   = ksp->work[5];
  U   = ksp->work[6];
  AUQ = V;

  /* Compute initial preconditioned residual */
  ierr = KSPInitialResidual(ksp,X,V,T,R,B);CHKERRQ(ierr);

  /* Test for nothing to do */
  ierr = VecNorm(R,NORM_2,&dp);CHKERRQ(ierr);
  if (ksp->normtype == KSP_NORM_NATURAL) dp *= dp;
  ierr       = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
  ksp->its   = 0;
  ksp->rnorm = dp;
  ierr       = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
  ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr);
  ierr = KSPMonitor(ksp,0,dp);CHKERRQ(ierr);
  ierr = (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
  if (ksp->reason) PetscFunctionReturn(0);

  /* Make the initial Rp == R */
  ierr = VecCopy(R,RP);CHKERRQ(ierr);
  /*  added for Fidap */
  /* Penalize Startup - Isaac Hasbani Trick for CGS
     Since most initial conditions result in a mostly 0 residual,
     we change all the 0 values in the vector RP to the maximum.
  */
  if (ksp->normtype == KSP_NORM_NATURAL) {
    PetscReal   vr0max;
    PetscScalar *tmp_RP=0;
    PetscInt    numnp  =0, *max_pos=0;
    ierr = VecMax(RP, max_pos, &vr0max);CHKERRQ(ierr);
    ierr = VecGetArray(RP, &tmp_RP);CHKERRQ(ierr);
    ierr = VecGetLocalSize(RP, &numnp);CHKERRQ(ierr);
    for (i=0; i<numnp; i++) {
      if (tmp_RP[i] == 0.0) tmp_RP[i] = vr0max;
    }
    ierr = VecRestoreArray(RP, &tmp_RP);CHKERRQ(ierr);
  }
  /*  end of addition for Fidap */

  /* Set the initial conditions */
  ierr = VecDot(R,RP,&rhoold);CHKERRQ(ierr);        /* rhoold = (r,rp)      */
  ierr = VecCopy(R,U);CHKERRQ(ierr);
  ierr = VecCopy(R,P);CHKERRQ(ierr);
  ierr = KSP_PCApplyBAorAB(ksp,P,V,T);CHKERRQ(ierr);

  i = 0;
  do {

    ierr = VecDot(V,RP,&s);CHKERRQ(ierr);           /* s <- (v,rp)          */
    a    = rhoold / s;                               /* a <- rho / s         */
    ierr = VecWAXPY(Q,-a,V,U);CHKERRQ(ierr);      /* q <- u - a v         */
    ierr = VecWAXPY(T,1.0,U,Q);CHKERRQ(ierr);      /* t <- u + q           */
    ierr = VecAXPY(X,a,T);CHKERRQ(ierr);           /* x <- x + a (u + q)   */
    ierr = KSP_PCApplyBAorAB(ksp,T,AUQ,U);CHKERRQ(ierr);
    ierr = VecAXPY(R,-a,AUQ);CHKERRQ(ierr);       /* r <- r - a K (u + q) */
    ierr = VecDot(R,RP,&rho);CHKERRQ(ierr);         /* rho <- (r,rp)        */
    if (ksp->normtype == KSP_NORM_NATURAL) {
      dp = PetscAbsScalar(rho);
    } else {
      ierr = VecNorm(R,NORM_2,&dp);CHKERRQ(ierr);
    }

    ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
    ksp->its++;
    ksp->rnorm = dp;
    ierr       = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
    ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr);
    ierr = KSPMonitor(ksp,i+1,dp);CHKERRQ(ierr);
    ierr = (*ksp->converged)(ksp,i+1,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
    if (ksp->reason) break;

    b      = rho / rhoold;                           /* b <- rho / rhoold    */
    ierr   = VecWAXPY(U,b,Q,R);CHKERRQ(ierr);       /* u <- r + b q         */
    ierr   = VecAXPY(Q,b,P);CHKERRQ(ierr);
    ierr   = VecWAXPY(P,b,Q,U);CHKERRQ(ierr);       /* p <- u + b(q + b p)  */
    ierr   = KSP_PCApplyBAorAB(ksp,P,V,Q);CHKERRQ(ierr);    /* v <- K p    */
    rhoold = rho;
    i++;
  } while (i<ksp->max_it);
  if (i >= ksp->max_it) ksp->reason = KSP_DIVERGED_ITS;

  ierr = KSPUnwindPreconditioner(ksp,X,T);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
PetscErrorCode BSSCR_DRIVER_flex( KSP ksp, Mat stokes_A, Vec stokes_x, Vec stokes_b, Mat approxS, KSP ksp_K,
                                  MatStokesBlockScaling BA, PetscTruth sym, KSP_BSSCR * bsscrp_self )
{
    char name[PETSC_MAX_PATH_LEN];
    char ubefore[100];
    char uafter[100];
    char pbefore[100];
    char pafter[100];
    PetscTruth flg, flg2, truth, useAcceleratingSmoothingMG, useFancySmoothingMG;
    PetscTruth usePreviousGuess, useNormInfStoppingConditions, useNormInfMonitor, found, extractMats;
    Mat K,G,D,C;
    Vec u,p,f,h;
    Mat S;
    Vec h_hat,t,t2,q,v;

    KSP ksp_inner;
    KSP ksp_S;
    KSP ksp_cleaner;
    KSPType ksp_inner_type;
        
    PetscTruth has_cnst_nullspace;
    PC pc_S, pc_MG, pcInner;
    PetscInt monitor_index,max_it,min_it;
    Vec nsp_vec = PETSC_NULL; 
        
    PetscReal scr_rtol;
    PetscReal inner_rtol;
    PetscReal vSolver_rtol;
        
    PetscScalar uNormInf, pNormInf;
    PetscScalar uNorm, pNorm, rNorm, fNorm;
    PetscInt  uSize, pSize;
    PetscInt    lmin,lmax;
    PetscInt  iterations;
    PetscReal   min,max;
    PetscReal p_sum;

    MGContext mgCtx;
    PC shellPC;

    double t0, t1;
    double mgSetupTime, scrSolveTime, a11SingleSolveTime, solutionAnalysisTime;
    Index nx,ny,nz;
    PetscInt j,start,end;

    static int been_here = 0;  /* Ha Ha Ha !! */

    /* get sub matrix / vector objects */
    MatNestGetSubMat( stokes_A, 0,0, &K );
    MatNestGetSubMat( stokes_A, 0,1, &G );
    MatNestGetSubMat( stokes_A, 1,0, &D );
    MatNestGetSubMat( stokes_A, 1,1, &C );
        
    VecNestGetSubVec( stokes_x, 0, &u );
    VecNestGetSubVec( stokes_x, 1, &p );
        
    VecNestGetSubVec( stokes_b, 0, &f );
    VecNestGetSubVec( stokes_b, 1, &h );

    /* PetscPrintf( PETSC_COMM_WORLD,  "\t Adress of stokes_x is %p\n", stokes_x); */
    /* VecNorm( u, NORM_2, &uNorm ); */
    /* PetscPrintf( PETSC_COMM_WORLD,  "\t u Norm is %.6e in %s: address is %p\n",uNorm,__func__,u); */
    /* VecNorm( p, NORM_2, &pNorm ); */
    /* PetscPrintf( PETSC_COMM_WORLD,  "\t p Norm is %.6e in %s: addres is %p\n",pNorm,__func__,p); */
    /* Create Schur complement matrix */
        
    //MatCreateSchurFromBlock( stokes_A, 0.0, "MatSchur_A11", &S );
    MatCreateSchurComplement(K,K,G,D,C, &S);
    /* configure inner solver */
    if (ksp_K!=PETSC_NULL) {
        MatSchurComplementSetKSP( S, ksp_K );
        MatSchurComplementGetKSP( S, &ksp_inner );
    }
    else {
        abort();
        MatSchurComplementGetKSP( S, &ksp_inner );
        KSPSetType( ksp_inner, "cg" );
    }
    KSPGetPC( ksp_inner, &pcInner );

    /* If we're using multigrid, replace the preconditioner here
       so we get the same options prefix. */

    if(bsscrp_self->mg) {
        mgSetupTime=setupMG( bsscrp_self, ksp_inner, pcInner, K, &mgCtx );
    }

    /* SETFROMOPTIONS MIGHT F**K MG UP */
    KSPSetOptionsPrefix( ksp_inner, "A11_" );
    KSPSetFromOptions( ksp_inner );

    useNormInfStoppingConditions = PETSC_FALSE;
    PetscOptionsGetTruth( PETSC_NULL ,"-A11_use_norm_inf_stopping_condition", &useNormInfStoppingConditions, &found );
    if(useNormInfStoppingConditions) 
        BSSCR_KSPSetNormInfConvergenceTest( ksp_inner ); 

    useNormInfMonitor = PETSC_FALSE; 
    PetscOptionsGetTruth( PETSC_NULL, "-A11_ksp_norm_inf_monitor", &useNormInfMonitor, &found );
    if(useNormInfMonitor) 
        KSPMonitorSet( ksp_inner, BSSCR_KSPNormInfMonitor, PETSC_NULL, PETSC_NULL );
        
    useNormInfMonitor = PETSC_FALSE; 
    PetscOptionsGetTruth( PETSC_NULL, "-A11_ksp_norm_inf_to_norm_2_monitor", &useNormInfMonitor, &found );
    if(useNormInfMonitor) 
        KSPMonitorSet( ksp_inner, BSSCR_KSPNormInfToNorm2Monitor, PETSC_NULL, PETSC_NULL );

    /* create right hand side */
    /* h_hat = G'*inv(K)*f - h */
    MatGetVecs(K,PETSC_NULL,&t);
    MatGetVecs( S, PETSC_NULL, &h_hat );

    KSPSetOptionsPrefix( ksp_inner, "A11_" );
    KSPSetFromOptions( ksp_inner );

    KSPSolve(ksp_inner,f,t);/* t=f/K */
    //bsscr_writeVec( t, "ts", "Writing t vector");
    MatMult(D,t,h_hat);/* G'*t */
    VecAXPY(h_hat, -1.0, h);/* h_hat = h_hat - h */
    Stg_VecDestroy(&t);
    //bsscr_writeVec( h_hat, "h_hat", "Writing h_hat Vector in Solver");
    //MatSchurApplyReductionToVecFromBlock( S, stokes_b, h_hat );
        
    /* create solver for S p = h_hat */

    KSPCreate( PETSC_COMM_WORLD, &ksp_S );
    KSPSetOptionsPrefix( ksp_S, "scr_");
    Stg_KSPSetOperators( ksp_S, S,S, SAME_NONZERO_PATTERN );
    KSPSetType( ksp_S, "cg" );
        
    /* Build preconditioner for S */
    KSPGetPC( ksp_S, &pc_S );
    BSSCR_BSSCR_StokesCreatePCSchur2( K,G,D,C,approxS,pc_S,sym, bsscrp_self );

    KSPSetFromOptions(ksp_S);

    /* Set specific monitor test */
    KSPGetTolerances( ksp_S, PETSC_NULL, PETSC_NULL, PETSC_NULL, &max_it );
    //BSSCR_KSPLogSetMonitor( ksp_S, max_it, &monitor_index );
        
    /* Pressure / Velocity Solve */   
    scrSolveTime = MPI_Wtime();
    PetscPrintf( PETSC_COMM_WORLD, "\t* Pressure / Velocity Solve \n");

    usePreviousGuess = PETSC_FALSE; 
    if(been_here)
        PetscOptionsGetTruth( PETSC_NULL, "-scr_use_previous_guess", &usePreviousGuess, &found );
    
    if(usePreviousGuess) {   /* Note this should actually look at checkpoint information */
        KSPSetInitialGuessNonzero( ksp_S, PETSC_TRUE );
    }
    else {
        KSPSetInitialGuessNonzero( ksp_S, PETSC_FALSE );
    }
    
    //KSPSetRelativeRhsConvergenceTest( ksp_S );

    useNormInfStoppingConditions = PETSC_FALSE;
    PetscOptionsGetTruth( PETSC_NULL ,"-scr_use_norm_inf_stopping_condition", &useNormInfStoppingConditions, &found );
    if(useNormInfStoppingConditions) 
        BSSCR_KSPSetNormInfConvergenceTest(ksp_S); 

    useNormInfMonitor = PETSC_FALSE; 
    PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_norm_inf_monitor", &useNormInfMonitor, &found );
    if(useNormInfMonitor) 
        KSPMonitorSet( ksp_S, BSSCR_KSPNormInfToNorm2Monitor, PETSC_NULL, PETSC_NULL );


    PetscPrintf( PETSC_COMM_WORLD, "\t* KSPSolve( ksp_S, h_hat, p )\n");
    /* if h_hat needs to be fixed up ..take out any nullspace vectors here */
    /* we want to check that there is no "noise" in the null-space in the h vector */
    /* this causes problems when we are trying to solve a Jacobian system when the Residual is almost converged */
    if(bsscrp_self->check_pressureNS){
        bsscrp_self->buildPNS(ksp);/* build and set nullspace vectors on bsscr - which is on ksp (function pointer is set in KSPSetUp_BSSCR */
    }

    PetscScalar norm, a, a1, a2, hnorm, pnorm, gnorm;
    MatNorm(G,NORM_INFINITY,&gnorm);
    VecNorm(h_hat, NORM_2, &hnorm);
    hnorm=hnorm/gnorm;

    if((hnorm < 1e-6) && (hnorm > 1e-20)){
        VecScale(h_hat,1.0/hnorm);
    }
    /* test to see if v or t are in nullspace of G and orthogonalize wrt h_hat if needed */
    KSPRemovePressureNullspace_BSSCR(ksp, h_hat);
    /***************************************/
    /* set convergence test to use min_it */
    found = PETSC_FALSE;
    min_it = 0;
    PetscOptionsGetInt( PETSC_NULL,"-scr_ksp_set_min_it_converge", &min_it, &found);
    if(found && min_it > 0){
        BSSCR_KSPSetConvergenceMinIts(ksp_S, min_it, bsscrp_self);
    }
    KSPSolve( ksp_S, h_hat, p );
    sprintf(pafter,"psafter_%d",been_here);
    bsscr_writeVec( p, pafter, "Writing p Vector in Solver");
    /***************************************/
    if((hnorm < 1e-6) && (hnorm > 1e-20)){
        VecScale(h_hat,hnorm);
        VecScale(p,hnorm);
    }
    KSPRemovePressureNullspace_BSSCR(ksp, p);


    scrSolveTime =  MPI_Wtime() - scrSolveTime;
    PetscPrintf( PETSC_COMM_WORLD, "\n\t* KSPSolve( ksp_S, h_hat, p )  Solve  Finished in time: %lf seconds\n\n", scrSolveTime);
    /* Resolve with this pressure to obtain solution for u */
        
    /* obtain solution for u */       
    VecDuplicate( u, &t );
    MatMult( G, p, t);
    VecAYPX( t, -1.0, f ); /* t <- -t + f */
    MatSchurComplementGetKSP( S, &ksp_inner );
        
 
    a11SingleSolveTime = MPI_Wtime();         /* ----------------------------------  Final V Solve */
        
    if(usePreviousGuess)      
        KSPSetInitialGuessNonzero( ksp_inner, PETSC_TRUE ); 

    KSPSetOptionsPrefix( ksp_inner, "backsolveA11_" );
    KSPSetFromOptions( ksp_inner );
    KSPSolve( ksp_inner, t, u );       /* Solve, then restore default tolerance and initial guess */          


    a11SingleSolveTime = MPI_Wtime() - a11SingleSolveTime;            /* ------------------ Final V Solve */

        
    PetscPrintf( PETSC_COMM_WORLD,  "\n\nSCR Solver Summary:\n\n");
  
    if(bsscrp_self->mg)
        PetscPrintf( PETSC_COMM_WORLD, "  Multigrid setup:        = %.4g secs \n", mgSetupTime);

    KSPGetIterationNumber( ksp_S, &iterations);
    PetscPrintf( PETSC_COMM_WORLD,     "  Pressure Solve:         = %.4g secs / %d its\n", scrSolveTime, iterations);
    KSPGetIterationNumber( ksp_inner, &iterations);
    PetscPrintf( PETSC_COMM_WORLD,     "  Final V Solve:          = %.4g secs / %d its\n\n", a11SingleSolveTime, iterations);
    
    /* Analysis of solution:
       This can be somewhat time consuming as it requires allocation / de-allocation, 
       computing vector norms etc. So we make it optional..
       This should be put into a proper KSP  monitor now?
    */        
    flg = PETSC_TRUE;
    PetscOptionsGetTruth( PETSC_NULL, "-scr_ksp_solution_summary", &flg, &found );
        
    if(flg) {
        
        solutionAnalysisTime = MPI_Wtime();
        
        VecGetSize( u, &uSize ); 
        VecGetSize( p, &pSize );
        
        VecDuplicate( u, &t2 );
        MatMult( K, u, t2);
        VecAYPX( t2, -1.0, t ); /* t2 <- -t2 + t  ... should be the formal residual vector */
        
        VecNorm( t2, NORM_2, &rNorm );      
        VecNorm( f,  NORM_2, &fNorm );      
        
        PetscPrintf( PETSC_COMM_WORLD,  "  |f - K u - G p|/|f|     = %.6e\n", rNorm/fNorm );
                
        VecDuplicate( p, &q );
        MatMult( D, u, q );
        VecNorm( u, NORM_2, &uNorm );       
        VecNorm( q, NORM_2, &rNorm );       
        
        PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|_2/|u|_2         = %.6e\n", sqrt( (double) uSize / (double) pSize ) * rNorm / uNorm);
        
        VecNorm( q, NORM_INFINITY, &rNorm );
        
        PetscPrintf( PETSC_COMM_WORLD,  "  |G^T u|_infty/|u|_2     = %.6e\n", sqrt( (double) uSize ) * rNorm / uNorm);

        VecNorm( u, NORM_INFINITY, &uNormInf );
        VecNorm( u, NORM_2,        &uNorm );
        VecGetSize( u, &uSize );
        
        VecNorm( p, NORM_INFINITY, &pNormInf );
        VecNorm( p, NORM_2,        &pNorm );
        
        PetscPrintf( PETSC_COMM_WORLD,  "  |u|_{\\infty}  = %.6e , u_rms = %.6e\n", 
                     uNormInf, uNorm / sqrt( (double) uSize ) );
                
        PetscPrintf( PETSC_COMM_WORLD,  "  |p|_{\\infty}  = %.6e , p_rms = %.6e\n",
                     pNormInf, pNorm / sqrt( (double) pSize ) );

        VecMax( u, &lmax, &max );
        VecMin( u, &lmin, &min );
        PetscPrintf( PETSC_COMM_WORLD,  "  min/max(u)    = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax);

        VecMax( p, &lmax, &max );
        VecMin( p, &lmin, &min );
        PetscPrintf( PETSC_COMM_WORLD,  "  min/max(p)    = %.6e [%d] / %.6e [%d]\n",min,lmin,max,lmax);
       
        VecSum( p, &p_sum );
        PetscPrintf( PETSC_COMM_WORLD,  "  \\sum_i p_i    = %.6e \n", p_sum );
        
        solutionAnalysisTime = MPI_Wtime() - solutionAnalysisTime;
        
        PetscPrintf( PETSC_COMM_WORLD,  "\n  Time for this analysis  = %.4g secs\n\n",solutionAnalysisTime);
        
        Stg_VecDestroy(&t2 );
        Stg_VecDestroy(&q );
            
    }
                
    if(bsscrp_self->mg) {
        //MG_inner_solver_pcmg_shutdown( pcInner );
    }

    Stg_VecDestroy(&t );

        
//      KSPLogDestroyMonitor( ksp_S );
        
    Stg_KSPDestroy(&ksp_S );
    //Stg_KSPDestroy(&ksp_inner );
    Stg_VecDestroy(&h_hat );
    Stg_MatDestroy(&S );

    /* Destroy nullspace vector if it exists. */
    if(nsp_vec)
        Stg_VecDestroy(&nsp_vec);
       
    //been_here = 1;
    been_here++;
    PetscFunctionReturn(0);
}
Пример #23
0
PetscErrorCode TaoPounders_solvequadratic(Tao tao,PetscReal *gnorm, PetscReal *qmin)
{
    PetscErrorCode ierr;
#if defined(PETSC_USE_REAL_SINGLE)
    PetscReal      atol=1.0e-5;
#else
    PetscReal      atol=1.0e-10;
#endif
    PetscInt       info,its;
    TAO_POUNDERS   *mfqP = (TAO_POUNDERS*)tao->data;
    PetscReal      maxval;
    PetscInt       i,j;

    PetscFunctionBegin;

    ierr = VecCopy(mfqP->Gres, mfqP->subb);CHKERRQ(ierr);

    ierr = VecSet(mfqP->subx,0.0);CHKERRQ(ierr);

    ierr = VecSet(mfqP->subndel,-mfqP->delta);CHKERRQ(ierr);
    ierr = VecSet(mfqP->subpdel,mfqP->delta);CHKERRQ(ierr);

    ierr = MatCopy(mfqP->Hres,mfqP->subH,SAME_NONZERO_PATTERN);CHKERRQ(ierr);

    ierr = TaoResetStatistics(mfqP->subtao);CHKERRQ(ierr);
    ierr = TaoSetTolerances(mfqP->subtao,NULL,NULL,*gnorm,*gnorm,NULL);CHKERRQ(ierr);
    /* enforce bound constraints -- experimental */
    if (tao->XU && tao->XL) {
      ierr = VecCopy(tao->XU,mfqP->subxu);CHKERRQ(ierr);
      ierr = VecAXPY(mfqP->subxu,-1.0,tao->solution);CHKERRQ(ierr);
      ierr = VecScale(mfqP->subxu,1.0/mfqP->delta);CHKERRQ(ierr);
      ierr = VecCopy(tao->XL,mfqP->subxl);CHKERRQ(ierr);
      ierr = VecAXPY(mfqP->subxl,-1.0,tao->solution);CHKERRQ(ierr);
      ierr = VecScale(mfqP->subxl,1.0/mfqP->delta);CHKERRQ(ierr);

      ierr = VecPointwiseMin(mfqP->subxu,mfqP->subxu,mfqP->subpdel);CHKERRQ(ierr);
      ierr = VecPointwiseMax(mfqP->subxl,mfqP->subxl,mfqP->subndel);CHKERRQ(ierr);
    } else {
      ierr = VecCopy(mfqP->subpdel,mfqP->subxu);CHKERRQ(ierr);
      ierr = VecCopy(mfqP->subndel,mfqP->subxl);CHKERRQ(ierr);
    }
    /* Make sure xu > xl */
    ierr = VecCopy(mfqP->subxl,mfqP->subpdel);CHKERRQ(ierr);
    ierr = VecAXPY(mfqP->subpdel,-1.0,mfqP->subxu); CHKERRQ(ierr);
    ierr = VecMax(mfqP->subpdel,NULL,&maxval);CHKERRQ(ierr);
    if (maxval > 1e-10) {
      SETERRQ(PETSC_COMM_WORLD,1,"upper bound < lower bound in subproblem");
    }
    /* Make sure xu > tao->solution > xl */
    ierr = VecCopy(mfqP->subxl,mfqP->subpdel);CHKERRQ(ierr);
    ierr = VecAXPY(mfqP->subpdel,-1.0,mfqP->subx); CHKERRQ(ierr);
    ierr = VecMax(mfqP->subpdel,NULL,&maxval);CHKERRQ(ierr);
    if (maxval > 1e-10) {
      SETERRQ(PETSC_COMM_WORLD,1,"initial guess < lower bound in subproblem");
    }

    ierr = VecCopy(mfqP->subx,mfqP->subpdel);CHKERRQ(ierr);
    ierr = VecAXPY(mfqP->subpdel,-1.0,mfqP->subxu); CHKERRQ(ierr);
    ierr = VecMax(mfqP->subpdel,NULL,&maxval);CHKERRQ(ierr);
    if (maxval > 1e-10) {
      SETERRQ(PETSC_COMM_WORLD,1,"initial guess > upper bound in subproblem");
    }


    ierr = TaoSolve(mfqP->subtao);CHKERRQ(ierr);
    ierr = TaoGetSolutionStatus(mfqP->subtao,NULL,qmin,NULL,NULL,NULL,NULL);CHKERRQ(ierr);

    /* test bounds post-solution*/
    ierr = VecCopy(mfqP->subxl,mfqP->subpdel);CHKERRQ(ierr);
    ierr = VecAXPY(mfqP->subpdel,-1.0,mfqP->subx); CHKERRQ(ierr);
    ierr = VecMax(mfqP->subpdel,NULL,&maxval);CHKERRQ(ierr);
    if (maxval > 1e-5) {
      ierr = PetscInfo(tao,"subproblem solution < lower bound");CHKERRQ(ierr);
      tao->reason = TAO_DIVERGED_TR_REDUCTION;
    }

    ierr = VecCopy(mfqP->subx,mfqP->subpdel);CHKERRQ(ierr);
    ierr = VecAXPY(mfqP->subpdel,-1.0,mfqP->subxu); CHKERRQ(ierr);
    ierr = VecMax(mfqP->subpdel,NULL,&maxval);CHKERRQ(ierr);
    if (maxval > 1e-5) {
      ierr = PetscInfo(tao,"subproblem solution > upper bound");
      tao->reason = TAO_DIVERGED_TR_REDUCTION;
    }


    *qmin *= -1;
    PetscFunctionReturn(0);
}
Пример #24
0
int main(int argc,char **argv)
{
    TS             ts;                   /* nonlinear solver */
    Vec            u;                    /* solution, residual vectors */
    Mat            J;                    /* Jacobian matrix */
    PetscInt       maxsteps = 1000;     /* iterations for convergence */
    PetscInt       nsteps;
    PetscReal      vmin,vmax,norm;
    PetscErrorCode ierr;
    DM             da;
    PetscReal      ftime,dt;
    AppCtx         user;              /* user-defined work context */
    JacobianType   jacType;

    PetscInitialize(&argc,&argv,(char*)0,help);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Create distributed array (DMDA) to manage parallel grid and vectors
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = DMDACreate1d(PETSC_COMM_WORLD,DMDA_BOUNDARY_NONE,-11,1,1,NULL,&da);
    CHKERRQ(ierr);

    /*  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Extract global vectors from DMDA;
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = DMCreateGlobalVector(da,&u);
    CHKERRQ(ierr);

    /* Initialize user application context */
    user.c            = -30.0;
    user.boundary     = 0;  /* 0: Dirichlet BC; 1: Neumann BC */
    user.viewJacobian = PETSC_FALSE;

    ierr = PetscOptionsGetInt(NULL,"-boundary",&user.boundary,NULL);
    CHKERRQ(ierr);
    ierr = PetscOptionsHasName(NULL,"-viewJacobian",&user.viewJacobian);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Create timestepping solver context
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = TSCreate(PETSC_COMM_WORLD,&ts);
    CHKERRQ(ierr);
    ierr = TSSetProblemType(ts,TS_NONLINEAR);
    CHKERRQ(ierr);
    ierr = TSSetType(ts,TSTHETA);
    CHKERRQ(ierr);
    ierr = TSThetaSetTheta(ts,1.0);
    CHKERRQ(ierr); /* Make the Theta method behave like backward Euler */
    ierr = TSSetIFunction(ts,NULL,FormIFunction,&user);
    CHKERRQ(ierr);

    ierr = DMSetMatType(da,MATAIJ);
    CHKERRQ(ierr);
    ierr = DMCreateMatrix(da,&J);
    CHKERRQ(ierr);
    jacType = JACOBIAN_ANALYTIC; /* use user-provide Jacobian */

    ierr = TSSetDM(ts,da);
    CHKERRQ(ierr); /* Use TSGetDM() to access. Setting here allows easy use of geometric multigrid. */

    ftime = 1.0;
    ierr = TSSetDuration(ts,maxsteps,ftime);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Set initial conditions
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = FormInitialSolution(ts,u,&user);
    CHKERRQ(ierr);
    ierr = TSSetSolution(ts,u);
    CHKERRQ(ierr);
    dt   = .01;
    ierr = TSSetInitialTimeStep(ts,0.0,dt);
    CHKERRQ(ierr);


    /* Use slow fd Jacobian or fast fd Jacobian with colorings.
       Note: this requirs snes which is not created until TSSetUp()/TSSetFromOptions() is called */
    ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Options for Jacobian evaluation",NULL);
    CHKERRQ(ierr);
    ierr = PetscOptionsEnum("-jac_type","Type of Jacobian","",JacobianTypes,(PetscEnum)jacType,(PetscEnum*)&jacType,0);
    CHKERRQ(ierr);
    ierr = PetscOptionsEnd();
    CHKERRQ(ierr);
    if (jacType == JACOBIAN_ANALYTIC) {
        ierr = TSSetIJacobian(ts,J,J,FormIJacobian,&user);
        CHKERRQ(ierr);
    } else if (jacType == JACOBIAN_FD_COLORING) {
        SNES snes;
        ierr = TSGetSNES(ts,&snes);
        CHKERRQ(ierr);
        ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,0);
        CHKERRQ(ierr);
    } else if (jacType == JACOBIAN_FD_FULL) {
        SNES snes;
        ierr = TSGetSNES(ts,&snes);
        CHKERRQ(ierr);
        ierr = SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,&user);
        CHKERRQ(ierr);
    }

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Set runtime options
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = TSSetFromOptions(ts);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Integrate ODE system
       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = TSSolve(ts,u);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     Compute diagnostics of the solution
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = VecNorm(u,NORM_1,&norm);
    CHKERRQ(ierr);
    ierr = VecMax(u,NULL,&vmax);
    CHKERRQ(ierr);
    ierr = VecMin(u,NULL,&vmin);
    CHKERRQ(ierr);
    ierr = TSGetTimeStepNumber(ts,&nsteps);
    CHKERRQ(ierr);
    ierr = TSGetTime(ts,&ftime);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"timestep %D: time %G, solution norm %G, max %G, min %G\n",nsteps,ftime,norm,vmax,vmin);
    CHKERRQ(ierr);

    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       Free work space.
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    ierr = MatDestroy(&J);
    CHKERRQ(ierr);
    ierr = VecDestroy(&u);
    CHKERRQ(ierr);
    ierr = TSDestroy(&ts);
    CHKERRQ(ierr);
    ierr = DMDestroy(&da);
    CHKERRQ(ierr);
    ierr = PetscFinalize();
    PetscFunctionReturn(0);
}