Esempio n. 1
0
static PetscErrorCode PCBDDCScalingSetUp_Deluxe_Private(PC pc)
{
  PC_BDDC                *pcbddc=(PC_BDDC*)pc->data;
  PCBDDCDeluxeScaling    deluxe_ctx=pcbddc->deluxe_ctx;
  PCBDDCSubSchurs        sub_schurs = pcbddc->sub_schurs;
  PetscErrorCode         ierr;

  PetscFunctionBegin;
  if (!sub_schurs->n_subs) {
    PetscFunctionReturn(0);
  }

  /* Create work vectors for sequential part of deluxe */
  ierr = MatCreateVecs(sub_schurs->S_Ej_all,&deluxe_ctx->seq_work1,&deluxe_ctx->seq_work2);CHKERRQ(ierr);

  /* Compute deluxe sequential scatter */
  if (sub_schurs->reuse_mumps && !sub_schurs->is_dir) {
    PCBDDCReuseMumps reuse_mumps = sub_schurs->reuse_mumps;
    ierr = PetscObjectReference((PetscObject)reuse_mumps->correction_scatter_B);CHKERRQ(ierr);
    deluxe_ctx->seq_scctx = reuse_mumps->correction_scatter_B;
  } else {
    ierr = VecScatterCreate(pcbddc->work_scaling,sub_schurs->is_Ej_all,deluxe_ctx->seq_work1,NULL,&deluxe_ctx->seq_scctx);CHKERRQ(ierr);
  }

  /* Create Mat object for deluxe scaling */
  ierr = PetscObjectReference((PetscObject)sub_schurs->S_Ej_all);CHKERRQ(ierr);
  deluxe_ctx->seq_mat = sub_schurs->S_Ej_all;
  if (sub_schurs->sum_S_Ej_all) { /* if this matrix is present, then we need to create the KSP object to invert it */
    PC               pc_temp;
    MatSolverPackage solver=NULL;
    char             ksp_prefix[256];
    size_t           len;

    ierr = KSPCreate(PETSC_COMM_SELF,&deluxe_ctx->seq_ksp);CHKERRQ(ierr);
    ierr = KSPSetOperators(deluxe_ctx->seq_ksp,sub_schurs->sum_S_Ej_all,sub_schurs->sum_S_Ej_all);CHKERRQ(ierr);
    ierr = KSPSetType(deluxe_ctx->seq_ksp,KSPPREONLY);CHKERRQ(ierr);
    ierr = KSPGetPC(deluxe_ctx->seq_ksp,&pc_temp);CHKERRQ(ierr);
    ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr);
    ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr);
    ierr = PCFactorGetMatSolverPackage(pc_temp,(const MatSolverPackage*)&solver);CHKERRQ(ierr);
    if (solver) {
      PC     new_pc;
      PCType type;

      ierr = PCGetType(pc_temp,&type);CHKERRQ(ierr);
      ierr = KSPGetPC(deluxe_ctx->seq_ksp,&new_pc);CHKERRQ(ierr);
      ierr = PCSetType(new_pc,type);CHKERRQ(ierr);
      ierr = PCFactorSetMatSolverPackage(new_pc,solver);CHKERRQ(ierr);
    }
    ierr = PetscStrlen(((PetscObject)(pcbddc->ksp_D))->prefix,&len);CHKERRQ(ierr);
    len -= 10; /* remove "dirichlet_" */
    ierr = PetscStrncpy(ksp_prefix,((PetscObject)(pcbddc->ksp_D))->prefix,len+1);CHKERRQ(ierr);
    ierr = PetscStrcat(ksp_prefix,"deluxe_");CHKERRQ(ierr);
    ierr = KSPSetOptionsPrefix(deluxe_ctx->seq_ksp,ksp_prefix);CHKERRQ(ierr);
    ierr = KSPSetFromOptions(deluxe_ctx->seq_ksp);CHKERRQ(ierr);
    ierr = KSPSetUp(deluxe_ctx->seq_ksp);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Esempio n. 2
0
PetscErrorCode  PCSetFromOptions_Factor(PC pc)
{
  PC_Factor         *factor = (PC_Factor*)pc->data;
  PetscErrorCode    ierr;
  PetscBool         flg = PETSC_FALSE,set;
  char              tname[256], solvertype[64];
  PetscFunctionList ordlist;
  PetscEnum         etmp;

  PetscFunctionBegin;
  if (!MatOrderingRegisterAllCalled) {ierr = MatOrderingRegisterAll();CHKERRQ(ierr);}
  ierr = PetscOptionsBool("-pc_factor_in_place","Form factored matrix in the same memory as the matrix","PCFactorSetUseInPlace",flg,&flg,NULL);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetUseInPlace(pc);CHKERRQ(ierr);
  }
  ierr = PetscOptionsReal("-pc_factor_fill","Expected non-zeros in factored matrix","PCFactorSetFill",((PC_Factor*)factor)->info.fill,&((PC_Factor*)factor)->info.fill,0);CHKERRQ(ierr);

  ierr = PetscOptionsEnum("-pc_factor_shift_type","Type of shift to add to diagonal","PCFactorSetShiftType",
                          MatFactorShiftTypes,(PetscEnum)(int)((PC_Factor*)factor)->info.shifttype,&etmp,&flg);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetShiftType(pc,(MatFactorShiftType)etmp);CHKERRQ(ierr);
  }
  ierr = PetscOptionsReal("-pc_factor_shift_amount","Shift added to diagonal","PCFactorSetShiftAmount",((PC_Factor*)factor)->info.shiftamount,&((PC_Factor*)factor)->info.shiftamount,0);CHKERRQ(ierr);

  ierr = PetscOptionsReal("-pc_factor_zeropivot","Pivot is considered zero if less than","PCFactorSetZeroPivot",((PC_Factor*)factor)->info.zeropivot,&((PC_Factor*)factor)->info.zeropivot,0);CHKERRQ(ierr);
  ierr = PetscOptionsReal("-pc_factor_column_pivot","Column pivot tolerance (used only for some factorization)","PCFactorSetColumnPivot",((PC_Factor*)factor)->info.dtcol,&((PC_Factor*)factor)->info.dtcol,&flg);CHKERRQ(ierr);

  flg  = ((PC_Factor*)factor)->info.pivotinblocks ? PETSC_TRUE : PETSC_FALSE;
  ierr = PetscOptionsBool("-pc_factor_pivot_in_blocks","Pivot inside matrix dense blocks for BAIJ and SBAIJ","PCFactorSetPivotInBlocks",flg,&flg,&set);CHKERRQ(ierr);
  if (set) {
    ierr = PCFactorSetPivotInBlocks(pc,flg);CHKERRQ(ierr);
  }

  flg  = PETSC_FALSE;
  ierr = PetscOptionsBool("-pc_factor_reuse_fill","Use fill from previous factorization","PCFactorSetReuseFill",flg,&flg,NULL);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetReuseFill(pc,PETSC_TRUE);CHKERRQ(ierr);
  }
  flg  = PETSC_FALSE;
  ierr = PetscOptionsBool("-pc_factor_reuse_ordering","Reuse ordering from previous factorization","PCFactorSetReuseOrdering",flg,&flg,NULL);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetReuseOrdering(pc,PETSC_TRUE);CHKERRQ(ierr);
  }

  ierr = MatGetOrderingList(&ordlist);CHKERRQ(ierr);
  ierr = PetscOptionsList("-pc_factor_mat_ordering_type","Reordering to reduce nonzeros in factored matrix","PCFactorSetMatOrderingType",ordlist,((PC_Factor*)factor)->ordering,tname,256,&flg);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetMatOrderingType(pc,tname);CHKERRQ(ierr);
  }

  /* maybe should have MatGetSolverTypes(Mat,&list) like the ordering list */
  ierr = PetscOptionsString("-pc_factor_mat_solver_package","Specific direct solver to use","MatGetFactor",((PC_Factor*)factor)->solvertype,solvertype,64,&flg);CHKERRQ(ierr);
  if (flg) {
    ierr = PCFactorSetMatSolverPackage(pc,solvertype);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Esempio n. 3
0
static PetscErrorCode PCSetUp_ILU(PC pc)
{
  PetscErrorCode         ierr;
  PC_ILU                 *ilu = (PC_ILU*)pc->data;
  MatInfo                info;
  PetscBool              flg;
  const MatSolverPackage stype;
  MatFactorError         err;

  PetscFunctionBegin;
  pc->failedreason = PC_NOERROR;
  /* ugly hack to change default, since it is not support by some matrix types */
  if (((PC_Factor*)ilu)->info.shifttype == (PetscReal)MAT_SHIFT_NONZERO) {
    ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATSEQAIJ,&flg);CHKERRQ(ierr);
    if (!flg) {
      ierr = PetscObjectTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&flg);CHKERRQ(ierr);
      if (!flg) {
        ((PC_Factor*)ilu)->info.shifttype = (PetscReal)MAT_SHIFT_INBLOCKS;
        PetscInfo(pc,"Changing shift type from NONZERO to INBLOCKS because block matrices do not support NONZERO\n");CHKERRQ(ierr);
      }
    }
  }

  ierr = MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);CHKERRQ(ierr);
  if (ilu->hdr.inplace) {
    if (!pc->setupcalled) {

      /* In-place factorization only makes sense with the natural ordering,
         so we only need to get the ordering once, even if nonzero structure changes */
      ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
      if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
      if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
    }

    /* In place ILU only makes sense with fill factor of 1.0 because
       cannot have levels of fill */
    ((PC_Factor*)ilu)->info.fill          = 1.0;
    ((PC_Factor*)ilu)->info.diagonal_fill = 0.0;

    ierr = MatILUFactor(pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);CHKERRQ(ierr);
    ierr = MatFactorGetError(pc->pmat,&err);CHKERRQ(ierr);
    if (err) { /* Factor() fails */
      pc->failedreason = (PCFailedReason)err;
      PetscFunctionReturn(0);
    }

    ((PC_Factor*)ilu)->fact = pc->pmat;
    /* must update the pc record of the matrix state or the PC will attempt to run PCSetUp() yet again */
    ierr = PetscObjectStateGet((PetscObject)pc->pmat,&pc->matstate);CHKERRQ(ierr);
  } else {
    if (!pc->setupcalled) {
      /* first time in so compute reordering and symbolic factorization */
      ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
      if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
      if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
      /*  Remove zeros along diagonal?     */
      if (ilu->nonzerosalongdiagonal) {
        ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr);
      }
      if (!((PC_Factor*)ilu)->fact) {
        ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      }
      ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
      ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
      ilu->hdr.actualfill = info.fill_ratio_needed;

      ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
    } else if (pc->flag != SAME_NONZERO_PATTERN) {
      if (!ilu->hdr.reuseordering) {
        /* compute a new ordering for the ILU */
        ierr = ISDestroy(&ilu->row);CHKERRQ(ierr);
        ierr = ISDestroy(&ilu->col);CHKERRQ(ierr);
        ierr = MatGetOrdering(pc->pmat,((PC_Factor*)ilu)->ordering,&ilu->row,&ilu->col);CHKERRQ(ierr);
        if (ilu->row) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->row);CHKERRQ(ierr);}
        if (ilu->col) {ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)ilu->col);CHKERRQ(ierr);}
        /*  Remove zeros along diagonal?     */
        if (ilu->nonzerosalongdiagonal) {
          ierr = MatReorderForNonzeroDiagonal(pc->pmat,ilu->nonzerosalongdiagonaltol,ilu->row,ilu->col);CHKERRQ(ierr);
        }
      }
      ierr = MatDestroy(&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      ierr = MatGetFactor(pc->pmat,((PC_Factor*)ilu)->solvertype,MAT_FACTOR_ILU,&((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
      ierr = MatILUFactorSymbolic(((PC_Factor*)ilu)->fact,pc->pmat,ilu->row,ilu->col,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
      ierr = MatGetInfo(((PC_Factor*)ilu)->fact,MAT_LOCAL,&info);CHKERRQ(ierr);
      ilu->hdr.actualfill = info.fill_ratio_needed;

      ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)ilu)->fact);CHKERRQ(ierr);
    }
    ierr = MatFactorGetError(((PC_Factor*)ilu)->fact,&err);CHKERRQ(ierr);
    if (err) { /* FactorSymbolic() fails */
      pc->failedreason = (PCFailedReason)err;
      PetscFunctionReturn(0);
    }

    ierr = MatLUFactorNumeric(((PC_Factor*)ilu)->fact,pc->pmat,&((PC_Factor*)ilu)->info);CHKERRQ(ierr);
    ierr = MatFactorGetError(((PC_Factor*)ilu)->fact,&err);CHKERRQ(ierr);
    if (err) { /* FactorNumeric() fails */
      pc->failedreason = (PCFailedReason)err;
    }
  }

  ierr = PCFactorGetMatSolverPackage(pc,&stype);CHKERRQ(ierr);
  if (!stype) {
    const MatSolverPackage solverpackage;
    ierr = MatFactorGetSolverPackage(((PC_Factor*)ilu)->fact,&solverpackage);CHKERRQ(ierr);
    ierr = PCFactorSetMatSolverPackage(pc,solverpackage);CHKERRQ(ierr);
  }
  PetscFunctionReturn(0);
}
Esempio n. 4
0
int main(int argc, char **argv)
{
  /* -------Initialize and Get the parameters from command line ------*/
  PetscInitialize(&argc, &argv, PETSC_NULL, PETSC_NULL);
  PetscPrintf(PETSC_COMM_WORLD,"--------Initializing------ \n");
  PetscErrorCode ierr;

  PetscBool flg;

  int myrank;
  MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
  if(myrank==0) 
    mma_verbose=1;
    
  /*-------------------------------------------------*/
  int Mx,My,Mz,Mzslab, Npmlx,Npmly,Npmlz,DegFree, anisotropic;

  PetscOptionsGetInt(PETSC_NULL,"-Nx",&Nx,&flg);  MyCheckAndOutputInt(flg,Nx,"Nx","Nx");
  PetscOptionsGetInt(PETSC_NULL,"-Ny",&Ny,&flg);  MyCheckAndOutputInt(flg,Ny,"Ny","Nx");
  PetscOptionsGetInt(PETSC_NULL,"-Nz",&Nz,&flg);  MyCheckAndOutputInt(flg,Nz,"Nz","Nz");
  PetscOptionsGetInt(PETSC_NULL,"-Mx",&Mx,&flg);  MyCheckAndOutputInt(flg,Mx,"Mx","Mx");
  PetscOptionsGetInt(PETSC_NULL,"-My",&My,&flg);  MyCheckAndOutputInt(flg,My,"My","My");
  PetscOptionsGetInt(PETSC_NULL,"-Mz",&Mz,&flg);  MyCheckAndOutputInt(flg,Mz,"Mz","Mz");
  PetscOptionsGetInt(PETSC_NULL,"-Mzslab",&Mzslab,&flg);  MyCheckAndOutputInt(flg,Mzslab,"Mzslab","Mzslab");
  PetscOptionsGetInt(PETSC_NULL,"-Npmlx",&Npmlx,&flg);  MyCheckAndOutputInt(flg,Npmlx,"Npmlx","Npmlx");
  PetscOptionsGetInt(PETSC_NULL,"-Npmly",&Npmly,&flg);  MyCheckAndOutputInt(flg,Npmly,"Npmly","Npmly");
  PetscOptionsGetInt(PETSC_NULL,"-Npmlz",&Npmlz,&flg);  MyCheckAndOutputInt(flg,Npmlz,"Npmlz","Npmlz");

  Nxyz = Nx*Ny*Nz;

  // if anisotropic !=0, Degree of Freedom = 3*Mx*My*Mz; else DegFree = Mx*My*Mz;
  PetscOptionsGetInt(PETSC_NULL,"-anisotropic",&anisotropic,&flg);
  if(!flg) anisotropic = 0; // by default, it is isotropc.
  DegFree = (anisotropic ? 3 : 1 )*Mx*My*((Mzslab==0)?Mz:1); 
  PetscPrintf(PETSC_COMM_WORLD," the Degree of Freedoms is %d \n ", DegFree);
  
  int DegFreeAll=DegFree+1;
  PetscPrintf(PETSC_COMM_WORLD," the Degree of Freedoms ALL is %d \n ", DegFreeAll);

  int BCPeriod, Jdirection, Jdirectiontwo, LowerPML;
  int bx[2], by[2], bz[2];
  PetscOptionsGetInt(PETSC_NULL,"-BCPeriod",&BCPeriod,&flg);  MyCheckAndOutputInt(flg,BCPeriod,"BCPeriod","BCPeriod given");
  PetscOptionsGetInt(PETSC_NULL,"-Jdirection",&Jdirection,&flg);  MyCheckAndOutputInt(flg,Jdirection,"Jdirection","Diapole current direction");
  PetscOptionsGetInt(PETSC_NULL,"-Jdirectiontwo",&Jdirectiontwo,&flg);  MyCheckAndOutputInt(flg,Jdirectiontwo,"Jdirectiontwo","Diapole current direction for source two");
  PetscOptionsGetInt(PETSC_NULL,"-LowerPML",&LowerPML,&flg);  MyCheckAndOutputInt(flg,LowerPML,"LowerPML","PML in the lower xyz boundary");
  PetscOptionsGetInt(PETSC_NULL,"-bxl",bx,&flg);  MyCheckAndOutputInt(flg,bx[0],"bxl","BC at x lower");
  PetscOptionsGetInt(PETSC_NULL,"-bxu",bx+1,&flg);  MyCheckAndOutputInt(flg,bx[1],"bxu","BC at x upper");
  PetscOptionsGetInt(PETSC_NULL,"-byl",by,&flg);  MyCheckAndOutputInt(flg,by[0],"byl","BC at y lower");
  PetscOptionsGetInt(PETSC_NULL,"-byu",by+1,&flg);  MyCheckAndOutputInt(flg,by[1],"byu","BC at y upper");
  PetscOptionsGetInt(PETSC_NULL,"-bzl",bz,&flg);  MyCheckAndOutputInt(flg,bz[0],"bzl","BC at z lower");
  PetscOptionsGetInt(PETSC_NULL,"-bzu",bz+1,&flg);  MyCheckAndOutputInt(flg,bz[1],"bzu","BC at z upper");


  double  epssub, RRT, sigmax, sigmay, sigmaz ;
   
  PetscOptionsGetReal(PETSC_NULL,"-hx",&hx,&flg);  MyCheckAndOutputDouble(flg,hx,"hx","hx");
  hy = hx;
  hz = hx;
  hxyz = (Nz==1)*hx*hy + (Nz>1)*hx*hy*hz;  

  double omega, omegaone, omegatwo, wratio;
  PetscOptionsGetReal(PETSC_NULL,"-omega",&omega,&flg);  MyCheckAndOutputDouble(flg,omega,"omega","omega");
   PetscOptionsGetReal(PETSC_NULL,"-wratio",&wratio,&flg);  MyCheckAndOutputDouble(flg,wratio,"wratio","wratio");
  omegaone=omega;
  omegatwo=wratio*omega;
  PetscPrintf(PETSC_COMM_WORLD,"---omegaone is %.16e and omegatwo is %.16e ---\n",omegaone, omegatwo);

  PetscOptionsGetReal(PETSC_NULL,"-Qabs",&Qabs,&flg); 
  if (flg && Qabs>1e+15)
    Qabs=1.0/0.0;
  MyCheckAndOutputDouble(flg,Qabs,"Qabs","Qabs");
  PetscOptionsGetReal(PETSC_NULL,"-epsair",&epsair,&flg);  MyCheckAndOutputDouble(flg,epsair,"epsair","epsair");
  PetscOptionsGetReal(PETSC_NULL,"-epssub",&epssub,&flg);  MyCheckAndOutputDouble(flg,epssub,"epssub","epssub");
  PetscOptionsGetReal(PETSC_NULL,"-RRT",&RRT,&flg);  MyCheckAndOutputDouble(flg,RRT,"RRT","RRT given");
  sigmax = pmlsigma(RRT,Npmlx*hx);
  sigmay = pmlsigma(RRT,Npmly*hy);
  sigmaz = pmlsigma(RRT,Npmlz*hz);  
  PetscPrintf(PETSC_COMM_WORLD,"----sigmax is %.12e \n",sigmax);
  PetscPrintf(PETSC_COMM_WORLD,"----sigmay is %.12e \n",sigmay);
  PetscPrintf(PETSC_COMM_WORLD,"----sigmaz is %.12e \n",sigmaz);

  char initialdata[PETSC_MAX_PATH_LEN]; //filenameComm[PETSC_MAX_PATH_LEN];
  PetscOptionsGetString(PETSC_NULL,"-initialdata",initialdata,PETSC_MAX_PATH_LEN,&flg); MyCheckAndOutputChar(flg,initialdata,"initialdata","Inputdata file");
  PetscOptionsGetString(PETSC_NULL,"-filenameComm",filenameComm,PETSC_MAX_PATH_LEN,&flg); MyCheckAndOutputChar(flg,filenameComm,"filenameComm","Output filenameComm");


  // add cx, cy, cz to indicate where the diapole current is;

  int cx, cy, cz;
  PetscOptionsGetInt(PETSC_NULL,"-cx",&cx,&flg); 
  if (!flg)
    {cx=(LowerPML)*floor(Nx/2); PetscPrintf(PETSC_COMM_WORLD,"cx is %d by default \n",cx);}
  else
    {PetscPrintf(PETSC_COMM_WORLD,"the current poisiont cx is %d \n",cx);}
  

  PetscOptionsGetInt(PETSC_NULL,"-cy",&cy,&flg); 
  if (!flg)
    {cy=(LowerPML)*floor(Ny/2); PetscPrintf(PETSC_COMM_WORLD,"cy is %d by default \n",cy);}
 else
    {PetscPrintf(PETSC_COMM_WORLD,"the current poisiont cy is %d \n",cy);}
  

  PetscOptionsGetInt(PETSC_NULL,"-cz",&cz,&flg); 
  if (!flg)
    {cz=(LowerPML)*floor(Nz/2); PetscPrintf(PETSC_COMM_WORLD,"cz is %d by default \n",cz);}
  else
    {PetscPrintf(PETSC_COMM_WORLD,"the current poisiont cz is %d \n",cz);}
    
  posj = (cx*Ny+ cy)*Nz + cz;
  PetscPrintf(PETSC_COMM_WORLD,"the posj is %d \n. ", posj);

  int fixpteps;
  PetscOptionsGetInt(PETSC_NULL,"-fixpteps",&fixpteps,&flg);  MyCheckAndOutputInt(flg,fixpteps,"fixpteps","fixpteps");

  // Get minapproach;
  PetscOptionsGetInt(PETSC_NULL,"-minapproach",&minapproach,&flg);  MyCheckAndOutputInt(flg,minapproach,"minapproach","minapproach");
   
  // Get withepsinldos;
  PetscOptionsGetInt(PETSC_NULL,"-withepsinldos",&withepsinldos,&flg);  MyCheckAndOutputInt(flg,withepsinldos,"withepsinldos","withepsinldos");
  
  // Get outputbase;
  PetscOptionsGetInt(PETSC_NULL,"-outputbase",&outputbase,&flg);  MyCheckAndOutputInt(flg,outputbase,"outputbase","outputbase");
  // Get cavityverbose;
  PetscOptionsGetInt(PETSC_NULL,"-cavityverbose",&cavityverbose,&flg);
  if(!flg) cavityverbose=0;
  PetscPrintf(PETSC_COMM_WORLD,"the cavity verbose is set as %d \n", cavityverbose); 
  // Get refinedldos;
  PetscOptionsGetInt(PETSC_NULL,"-refinedldos",&refinedldos,&flg);
  if(!flg) refinedldos=0;
  PetscPrintf(PETSC_COMM_WORLD,"the refinedldos is set as %d \n", refinedldos);
  // Get cmpwrhs;
  int cmpwrhs;
   PetscOptionsGetInt(PETSC_NULL,"-cmpwrhs",&cmpwrhs,&flg);
  if(!flg) cmpwrhs=0;
  PetscPrintf(PETSC_COMM_WORLD,"the cmpwrhs is set as %d \n", cmpwrhs);
  // Get lrzsqr;
   PetscOptionsGetInt(PETSC_NULL,"-lrzsqr",&lrzsqr,&flg);
  if(!flg) lrzsqr=0;
  PetscPrintf(PETSC_COMM_WORLD,"the lrzsqr is set as %d \n", lrzsqr);
  // Get newQdef;
   PetscOptionsGetInt(PETSC_NULL,"-newQdef",&newQdef,&flg);
  if(!flg) newQdef=0;
  PetscPrintf(PETSC_COMM_WORLD,"the newQdef is set as %d \n", newQdef);
  /*--------------------------------------------------------*/

  /*--------------------------------------------------------*/


  /*---------- Set the current source---------*/
  //Mat D; //ImaginaryIMatrix;
  ImagIMat(PETSC_COMM_WORLD, &D,6*Nxyz);

  Vec J;
  ierr = VecCreateMPI(PETSC_COMM_WORLD, PETSC_DECIDE, 6*Nxyz, &J);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) J, "Source");CHKERRQ(ierr);
  VecSet(J,0.0); //initialization;

  if (Jdirection == 1)
    SourceSingleSetX(PETSC_COMM_WORLD, J, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else if (Jdirection ==2)
    SourceSingleSetY(PETSC_COMM_WORLD, J, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else if (Jdirection == 3)
    SourceSingleSetZ(PETSC_COMM_WORLD, J, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else
    PetscPrintf(PETSC_COMM_WORLD," Please specify correct direction of current: x (1) , y (2) or z (3)\n "); 

  Vec Jtwo;
  ierr = VecDuplicate(J, &Jtwo);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) Jtwo, "Sourcetwo");CHKERRQ(ierr);
  VecSet(Jtwo,0.0); //initialization;

  if (Jdirectiontwo == 1)
    SourceSingleSetX(PETSC_COMM_WORLD, Jtwo, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else if (Jdirectiontwo ==2)
    SourceSingleSetY(PETSC_COMM_WORLD, Jtwo, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else if (Jdirectiontwo == 3)
    SourceSingleSetZ(PETSC_COMM_WORLD, Jtwo, Nx, Ny, Nz, cx, cy, cz,1.0/hxyz);
  else
    PetscPrintf(PETSC_COMM_WORLD," Please specify correct direction of current two: x (1) , y (2) or z (3)\n "); 


  //Vec b; // b= i*omega*J;
  Vec bone, btwo;

  ierr = VecDuplicate(J,&b);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) b, "rhsone");CHKERRQ(ierr);

  ierr = VecDuplicate(J,&bone);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) bone, "rhsone");CHKERRQ(ierr);

  ierr = VecDuplicate(Jtwo,&btwo);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) btwo, "rhstwo");CHKERRQ(ierr);

  if (cmpwrhs==0)
    {
      ierr = MatMult(D,J,b);CHKERRQ(ierr);
      ierr = MatMult(D,Jtwo,btwo);CHKERRQ(ierr);
      
      VecCopy(b,bone);
      VecScale(bone,omegaone);

      VecScale(btwo,omegatwo);

      VecScale(b,omega);      
    }
  else
    {
      double complex cmpiomega;
      cmpiomega = cpow(1+I/Qabs,newQdef+1);
      double sqrtiomegaR = -omega*cimag(csqrt(cmpiomega));
      double sqrtiomegaI = omega*creal(csqrt(cmpiomega));
      PetscPrintf(PETSC_COMM_WORLD,"the real part of sqrt cmpomega is %g and imag sqrt is % g ", sqrtiomegaR, sqrtiomegaI);
      Vec tmpi;
      ierr = VecDuplicate(J,&tmpi);
      VecSet(b,0.0);
      VecSet(tmpi,0.0);
      CmpVecScale(J,b,sqrtiomegaR,sqrtiomegaI,D,tmpi);
      VecDestroy(&tmpi);
    }

  /*-------Get the weight vector ------------------*/
  //Vec weight;
  ierr = VecDuplicate(J,&weight); CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) weight, "weight");CHKERRQ(ierr);

  if(LowerPML==0)
    GetWeightVec(weight, Nx, Ny,Nz); // new code handles both 3D and 2D;
  else
    VecSet(weight,1.0);

  Vec weightedJ;
  ierr = VecDuplicate(J,&weightedJ); CHKERRQ(ierr);
  ierr = VecPointwiseMult(weightedJ,J,weight);
  ierr = PetscObjectSetName((PetscObject) weightedJ, "weightedJ");CHKERRQ(ierr);

  Vec weightedJtwo;
  ierr = VecDuplicate(Jtwo,&weightedJtwo); CHKERRQ(ierr);
  ierr = VecPointwiseMult(weightedJtwo,Jtwo,weight);
  ierr = PetscObjectSetName((PetscObject) weightedJtwo, "weightedJtwo");CHKERRQ(ierr);

  //Vec vR;
  ierr = VecDuplicate(J,&vR); CHKERRQ(ierr);
  GetRealPartVec(vR, 6*Nxyz);

  // VecFReal;
  if (lrzsqr)
    { ierr = VecDuplicate(J,&epsFReal); CHKERRQ(ierr); 
      ierr = PetscObjectSetName((PetscObject) epsFReal, "epsFReal");CHKERRQ(ierr);

      if (newQdef==0)
	{
	  sqrtomegaI = omega*cimag(csqrt(1+I/Qabs));
	  PetscPrintf(PETSC_COMM_WORLD,"the real part of sqrt cmpomega is %g and imag sqrt is % g ", omega*creal(csqrt(1+I/Qabs)), sqrtomegaI);
	  betar = 2*sqrtomegaI;
	  betai = betar/Qabs;
	}
      else
	{
	  double gamma;
	  gamma = omega/Qabs;
	  betar = 2*gamma*(1-1.0/pow(Qabs,2));
	  betai = 2*gamma*(2.0/Qabs);
	}

      ierr = VecDuplicate(J,&nb); CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) nb, "nb"); CHKERRQ(ierr);
      
      ierr = VecDuplicate(J,&y); CHKERRQ(ierr);
      ierr = PetscObjectSetName((PetscObject) y, "y"); CHKERRQ(ierr);
      
      ierr = VecDuplicate(J,&xsqr); CHKERRQ(ierr); // xsqr = x*x;
      ierr = PetscObjectSetName((PetscObject) xsqr, "xsqr"); CHKERRQ(ierr);
      CongMat(PETSC_COMM_WORLD, &C, 6*Nxyz);
}
  /*----------- Define PML muinv vectors  */
 
  Vec muinvpml;
  MuinvPMLFull(PETSC_COMM_SELF, &muinvpml,Nx,Ny,Nz,Npmlx,Npmly,Npmlz,sigmax,sigmay,sigmaz,omega, LowerPML); 

  //double *muinv;
  muinv = (double *) malloc(sizeof(double)*6*Nxyz);
  int add=0;
  AddMuAbsorption(muinv,muinvpml,Qabs,add);
  ierr = VecDestroy(&muinvpml); CHKERRQ(ierr);  

  /*---------- Define PML eps vectors: epspml---------- */  
  Vec epspml; //epspmlQ, epscoef;
  ierr = VecDuplicate(J,&epspml);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) epspml,"EpsPMLFull"); CHKERRQ(ierr);
  EpsPMLFull(PETSC_COMM_WORLD, epspml,Nx,Ny,Nz,Npmlx,Npmly,Npmlz,sigmax,sigmay,sigmaz,omega, LowerPML);

  ierr = VecDuplicate(J,&epspmlQ);CHKERRQ(ierr);


  Vec epscoefone, epscoeftwo;
  ierr = VecDuplicate(J,&epscoefone);CHKERRQ(ierr);
  ierr = VecDuplicate(J,&epscoeftwo);CHKERRQ(ierr);
 
  // compute epspmlQ,epscoef;
  EpsCombine(D, weight, epspml, epspmlQ, epscoefone, Qabs, omegaone);
  EpsCombine(D, weight, epspml, epspmlQ, epscoeftwo, Qabs, omegatwo);
  /*--------- Setup the interp matrix ----------------------- */
  /* for a samll eps block, interp it into yee-lattice. The interp matrix A and PML epspml only need to generated once;*/
  

  //Mat A; 
  //new routine for myinterp;
  myinterp(PETSC_COMM_WORLD, &A, Nx,Ny,Nz, LowerPML*floor((Nx-Mx)/2),LowerPML*floor((Ny-My)/2),LowerPML*floor((Nz-Mz)/2), Mx,My,Mz,Mzslab, anisotropic); // LoweerPML*Npmlx,..,.., specify where the interp starts;  

  //Vec epsSReal, epsgrad, vgrad; // create compatiable vectors with A.
  ierr = MatGetVecs(A,&epsSReal, &epsgrad); CHKERRQ(ierr);  
  ierr = PetscObjectSetName((PetscObject) epsgrad, "epsgrad");CHKERRQ(ierr);
  ierr = VecDuplicate(epsSReal, &vgrad); CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) epsSReal, "epsSReal");CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) vgrad, "vgrad");CHKERRQ(ierr);
  
  /*---------Setup the epsmedium vector----------------*/
  //Vec epsmedium;
  ierr = VecDuplicate(J,&epsmedium); CHKERRQ(ierr);
  GetMediumVec(epsmedium,Nz,Mz,epsair,epssub);
 
  /*--------- Setup the finitie difference matrix-------------*/
  //Mat M;
  MoperatorGeneral(PETSC_COMM_WORLD, &M, Nx,Ny,Nz,hx,hy,hz, bx, by, bz,muinv,BCPeriod);
  free(muinv);

  /*--------Setup the KSP variables ---------------*/
  
  KSP kspone;
  PC pcone; 
  ierr = KSPCreate(PETSC_COMM_WORLD,&kspone);CHKERRQ(ierr);
  //ierr = KSPSetType(ksp, KSPPREONLY);CHKERRQ(ierr);
  ierr = KSPSetType(kspone, KSPGMRES);CHKERRQ(ierr);
  ierr = KSPGetPC(kspone,&pcone);CHKERRQ(ierr);
  ierr = PCSetType(pcone,PCLU);CHKERRQ(ierr);
  ierr = PCFactorSetMatSolverPackage(pcone,MATSOLVERPASTIX);CHKERRQ(ierr);
  ierr = PCSetFromOptions(pcone);
  int maxkspit = 20;
  ierr = KSPSetTolerances(kspone,1e-14,PETSC_DEFAULT,PETSC_DEFAULT,maxkspit);CHKERRQ(ierr);
  ierr = KSPSetFromOptions(kspone);CHKERRQ(ierr);

  KSP ksptwo;
  PC pctwo;
   ierr = KSPCreate(PETSC_COMM_WORLD,&ksptwo);CHKERRQ(ierr);
  //ierr = KSPSetType(ksp, KSPPREONLY);CHKERRQ(ierr);
  ierr = KSPSetType(ksptwo, KSPGMRES);CHKERRQ(ierr);
  ierr = KSPGetPC(ksptwo,&pctwo);CHKERRQ(ierr);
  ierr = PCSetType(pctwo,PCLU);CHKERRQ(ierr);
  ierr = PCFactorSetMatSolverPackage(pctwo,MATSOLVERPASTIX);CHKERRQ(ierr);
  ierr = PCSetFromOptions(pctwo);
  ierr = KSPSetTolerances(ksptwo,1e-14,PETSC_DEFAULT,PETSC_DEFAULT,maxkspit);CHKERRQ(ierr);
  ierr = KSPSetFromOptions(ksptwo);CHKERRQ(ierr);

  /*--------- Create the space for solution vector -------------*/
  //Vec x;
  ierr = VecDuplicate(J,&x);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) x, "Solution");CHKERRQ(ierr); 
  
  /*----------- Create the space for final eps -------------*/

  //Vec epsC, epsCi, epsP;
  ierr = VecDuplicate(J,&epsC);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) epsC, "EpsC");CHKERRQ(ierr);
  ierr = VecDuplicate(J,&epsCi);CHKERRQ(ierr);
  ierr = VecDuplicate(J,&epsP);CHKERRQ(ierr);

  ierr = VecSet(epsP,0.0); CHKERRQ(ierr);
  ierr = VecAssemblyBegin(epsP); CHKERRQ(ierr);
  ierr = VecAssemblyEnd(epsP); CHKERRQ(ierr); 

  /*------------ Create space used in the solver ------------*/
  //Vec vgradlocal,tmp, tmpa,tmpb;
  ierr = VecCreateSeq(PETSC_COMM_SELF, DegFree, &vgradlocal); CHKERRQ(ierr);
  ierr = VecDuplicate(J,&tmp); CHKERRQ(ierr);
  ierr = VecDuplicate(J,&tmpa); CHKERRQ(ierr);
  ierr = VecDuplicate(J,&tmpb); CHKERRQ(ierr);
 
  // Vec pickposvec; this vector is zero except that first entry is one;
  if (withepsinldos)
    { ierr = VecDuplicate(J,&pickposvec); CHKERRQ(ierr);
      ierr = VecSet(pickposvec,0.0); CHKERRQ(ierr);
      ierr = VecSetValue(pickposvec,posj+Jdirection*Nxyz,1.0,INSERT_VALUES);
      VecAssemblyBegin(pickposvec);
      VecAssemblyEnd(pickposvec);
    }
  /*------------ Create scatter used in the solver -----------*/
  //VecScatter scatter;
  //IS from, to;
  ierr =ISCreateStride(PETSC_COMM_SELF,DegFree,0,1,&from); CHKERRQ(ierr);
  ierr =ISCreateStride(PETSC_COMM_SELF,DegFree,0,1,&to); CHKERRQ(ierr);

  /*-------------Read the input file -------------------------*/

  double *epsoptAll;
  epsoptAll = (double *) malloc(DegFreeAll*sizeof(double));

  FILE *ptf;
  ptf = fopen(initialdata,"r");
  PetscPrintf(PETSC_COMM_WORLD,"reading from input files \n");

  int i;
  // set the dielectric at the center is fixed, and alwyas high
  //epsopt[0]=myub; is defined below near lb and ub;
  for (i=0;i<DegFree;i++)
    { //PetscPrintf(PETSC_COMM_WORLD,"current eps reading is %lf \n",epsopt[i]);
      fscanf(ptf,"%lf",&epsoptAll[i]);
    }
  epsoptAll[DegFreeAll-1]=0; //initialize auxiliary variable;
  fclose(ptf);



  /*----declare these data types, althought they may not be used for job 2 -----------------*/
 
  double mylb,myub, *lb=NULL, *ub=NULL;
  int maxeval, maxtime, mynloptalg;
  double maxf;
  nlopt_opt  opt;
  nlopt_result result;
  /*--------------------------------------------------------------*/
  /*----Now based on Command Line, Do the corresponding job----*/
  /*----------------------------------------------------------------*/


  //int Job; set Job to be gloabl variables;
  PetscOptionsGetInt(PETSC_NULL,"-Job",&Job,&flg);  MyCheckAndOutputInt(flg,Job,"Job","The Job indicator you set");
  
  int numofvar=(Job==1)*DegFreeAll + (Job==3);

  /*--------   convert the epsopt array to epsSReal (if job!=optmization) --------*/
  if (Job==2 || Job ==3)
    {
      // copy epsilon from file to epsSReal; (different from FindOpt.c, because epsilon is not degree-of-freedoms in computeQ.
      // i) create a array to read file (done above in epsopt); ii) convert the array to epsSReal;
      int ns, ne;
      ierr = VecGetOwnershipRange(epsSReal,&ns,&ne);
      for(i=ns;i<ne;i++)
	{ ierr=VecSetValue(epsSReal,i,epsoptAll[i],INSERT_VALUES); 
	  CHKERRQ(ierr); }      
      if(withepsinldos)
	{ epsatinterest = epsoptAll[cx*Ny*Nz + cy*Nz + cz]  + epsair;
	  PetscPrintf(PETSC_COMM_WORLD, " the relative permitivity at the point of current is %.16e \n ",epsatinterest);}
      ierr = VecAssemblyBegin(epsSReal); CHKERRQ(ierr);
      ierr = VecAssemblyEnd(epsSReal);  CHKERRQ(ierr);
    }

  if (Job==1 || Job==3)  // optimization bounds setup;
    {      
      PetscOptionsGetInt(PETSC_NULL,"-maxeval",&maxeval,&flg);  MyCheckAndOutputInt(flg,maxeval,"maxeval","max number of evaluation");
      PetscOptionsGetInt(PETSC_NULL,"-maxtime",&maxtime,&flg);  MyCheckAndOutputInt(flg,maxtime,"maxtime","max time of evaluation");
      PetscOptionsGetInt(PETSC_NULL,"-mynloptalg",&mynloptalg,&flg);  MyCheckAndOutputInt(flg,mynloptalg,"mynloptalg","The algorithm used ");

      PetscOptionsGetReal(PETSC_NULL,"-mylb",&mylb,&flg);  MyCheckAndOutputDouble(flg,mylb,"mylb","optimization lb");
      PetscOptionsGetReal(PETSC_NULL,"-myub",&myub,&flg);  MyCheckAndOutputDouble(flg,myub,"myub","optimization ub");

      
 
      lb = (double *) malloc(numofvar*sizeof(double));
      ub = (double *) malloc(numofvar*sizeof(double));

      // the dielectric constant at center is fixed!
      for(i=0;i<numofvar;i++)
	{
	  lb[i] = mylb;
	  ub[i] = myub;
	}  //initial guess, lower bounds, upper bounds;

      // set lower and upper bounds for auxiliary variable;
      lb[numofvar-1]=0;
      ub[numofvar-1]=1.0/0.0;

      //fix the dielectric at the center to be high for topology optimization;
      if (Job==1 && fixpteps==1)
	{
	  epsoptAll[0]=myub;
	  lb[0]=myub;
	  ub[0]=myub;
	}



      opt = nlopt_create(mynloptalg, numofvar);
      
      myfundatatypeshg data[2] = {{omegaone, bone, weightedJ, epscoefone,kspone},{omegatwo, btwo, weightedJtwo, epscoeftwo,ksptwo}};

      nlopt_add_inequality_constraint(opt,ldosconstraint, &data[0], 1e-8);
      nlopt_add_inequality_constraint(opt,ldosconstraint, &data[1], 1e-8);

      nlopt_set_lower_bounds(opt,lb);
      nlopt_set_upper_bounds(opt,ub);
      nlopt_set_maxeval(opt,maxeval);
      nlopt_set_maxtime(opt,maxtime);


      /*add functionality to choose local optimizer; */
      int mynloptlocalalg;
      nlopt_opt local_opt;
      PetscOptionsGetInt(PETSC_NULL,"-mynloptlocalalg",&mynloptlocalalg,&flg);  MyCheckAndOutputInt(flg,mynloptlocalalg,"mynloptlocalalg","The local optimization algorithm used ");
      if (mynloptlocalalg)
	{ 
	  local_opt=nlopt_create(mynloptlocalalg,numofvar);
	  nlopt_set_ftol_rel(local_opt, 1e-14);
	  nlopt_set_maxeval(local_opt,100000);
	  nlopt_set_local_optimizer(opt,local_opt);
	}
    }

  switch (Job)
    {
    case 1:
      {
	if (minapproach)
	  nlopt_set_min_objective(opt,maxminobjfun,NULL);// NULL: no data to be passed because of global variables;
	else
	  nlopt_set_max_objective(opt,maxminobjfun,NULL);

	result = nlopt_optimize(opt,epsoptAll,&maxf);
      }      
      break;
    case 2 :  //AnalyzeStructure
      { 
	int Linear, Eig, maxeigit;
	PetscOptionsGetInt(PETSC_NULL,"-Linear",&Linear,&flg);  MyCheckAndOutputInt(flg,Linear,"Linear","Linear solver indicator");
	PetscOptionsGetInt(PETSC_NULL,"-Eig",&Eig,&flg);  MyCheckAndOutputInt(flg,Eig,"Eig","Eig solver indicator");
	PetscOptionsGetInt(PETSC_NULL,"-maxeigit",&maxeigit,&flg);  MyCheckAndOutputInt(flg,maxeigit,"maxeigit","maximum number of Eig solver iterations is");

	/*----------------------------------*/
	//EigenSolver(Linear, Eig, maxeigit);
	/*----------------------------------*/

	OutputVec(PETSC_COMM_WORLD, weight,filenameComm, "weight.m");
      }
      break;   
    default:
      PetscPrintf(PETSC_COMM_WORLD,"--------Interesting! You're doing nothing!--------\n ");
 }


  if(Job==1 || Job==3)
    {
      /* print the optimization parameters */
#if 0
      double xrel, frel, fabs;
      // double *xabs;
      frel=nlopt_get_ftol_rel(opt);
      fabs=nlopt_get_ftol_abs(opt);
      xrel=nlopt_get_xtol_rel(opt);
      PetscPrintf(PETSC_COMM_WORLD,"nlopt frel is %g \n",frel);
      PetscPrintf(PETSC_COMM_WORLD,"nlopt fabs is %g \n",fabs);
      PetscPrintf(PETSC_COMM_WORLD,"nlopt xrel is %g \n",xrel);
      //nlopt_result nlopt_get_xtol_abs(const nlopt_opt opt, double *tol);
#endif
      /*--------------*/

      if (result < 0) {
	PetscPrintf(PETSC_COMM_WORLD,"nlopt failed! \n", result);
      }
      else {
	PetscPrintf(PETSC_COMM_WORLD,"found extremum  %0.16e\n", minapproach?1.0/maxf:maxf); 
      }

      PetscPrintf(PETSC_COMM_WORLD,"nlopt returned value is %d \n", result);


      if(Job==1)
	{ //OutputVec(PETSC_COMM_WORLD, epsopt,filenameComm, "epsopt.m");
	  //OutputVec(PETSC_COMM_WORLD, epsgrad,filenameComm, "epsgrad.m");
	  //OutputVec(PETSC_COMM_WORLD, vgrad,filenameComm, "vgrad.m");
	  //OutputVec(PETSC_COMM_WORLD, x,filenameComm, "x.m");
	  int rankA;
	  MPI_Comm_rank(PETSC_COMM_WORLD, &rankA);

	  if(rankA==0)
	    {
	      ptf = fopen(strcat(filenameComm,"epsopt.txt"),"w");
	      for (i=0;i<DegFree;i++)
		fprintf(ptf,"%0.16e \n",epsoptAll[i]);
	      fclose(ptf);
	      PetscPrintf(PETSC_COMM_WORLD,"the t parameter is %.8e \n",epsoptAll[DegFreeAll-1]);
	    }  
	}

      nlopt_destroy(opt);
    }
     


  ierr = PetscPrintf(PETSC_COMM_WORLD,"--------Done!--------\n ");CHKERRQ(ierr);

  /*------------------------------------*/
 

  /* ----------------------Destroy Vecs and Mats----------------------------*/ 

  free(epsoptAll);
  free(lb);
  free(ub);
  ierr = VecDestroy(&J); CHKERRQ(ierr);
  ierr = VecDestroy(&b); CHKERRQ(ierr);
  ierr = VecDestroy(&weight); CHKERRQ(ierr);
  ierr = VecDestroy(&weightedJ); CHKERRQ(ierr);
  ierr = VecDestroy(&vR); CHKERRQ(ierr);
  ierr = VecDestroy(&epspml); CHKERRQ(ierr);
  ierr = VecDestroy(&epspmlQ); CHKERRQ(ierr);
  ierr = VecDestroy(&epsSReal); CHKERRQ(ierr);
  ierr = VecDestroy(&epsgrad); CHKERRQ(ierr);
  ierr = VecDestroy(&vgrad); CHKERRQ(ierr);  
  ierr = VecDestroy(&epsmedium); CHKERRQ(ierr);
  ierr = VecDestroy(&epsC); CHKERRQ(ierr);
  ierr = VecDestroy(&epsCi); CHKERRQ(ierr);
  ierr = VecDestroy(&epsP); CHKERRQ(ierr);
  ierr = VecDestroy(&x); CHKERRQ(ierr);
  ierr = VecDestroy(&vgradlocal);CHKERRQ(ierr);
  ierr = VecDestroy(&tmp); CHKERRQ(ierr);
  ierr = VecDestroy(&tmpa); CHKERRQ(ierr);
  ierr = VecDestroy(&tmpb); CHKERRQ(ierr);
  ierr = MatDestroy(&A); CHKERRQ(ierr);  
  ierr = MatDestroy(&D); CHKERRQ(ierr);
  ierr = MatDestroy(&M); CHKERRQ(ierr);  
 

  ierr = VecDestroy(&epscoefone); CHKERRQ(ierr);
  ierr = VecDestroy(&epscoeftwo); CHKERRQ(ierr);
  ierr = KSPDestroy(&kspone);CHKERRQ(ierr);
  ierr = KSPDestroy(&ksptwo);CHKERRQ(ierr);

  ISDestroy(&from);
  ISDestroy(&to);

  if (withepsinldos)
    {ierr=VecDestroy(&pickposvec); CHKERRQ(ierr);}

  if (lrzsqr)
    {
      ierr=VecDestroy(&epsFReal); CHKERRQ(ierr);
      ierr=VecDestroy(&xsqr); CHKERRQ(ierr);
      ierr=VecDestroy(&y); CHKERRQ(ierr);
      ierr=VecDestroy(&nb); CHKERRQ(ierr);
      ierr=MatDestroy(&C); CHKERRQ(ierr);
    }

  ierr = VecDestroy(&bone); CHKERRQ(ierr);
  ierr = VecDestroy(&btwo); CHKERRQ(ierr);
  ierr = VecDestroy(&Jtwo); CHKERRQ(ierr);
  

  /*------------ finalize the program -------------*/

  {
    int rank;
    MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
    //if (rank == 0) fgetc(stdin);
    MPI_Barrier(PETSC_COMM_WORLD);
  }
  
  ierr = PetscFinalize(); CHKERRQ(ierr);

  return 0;
}
Esempio n. 5
0
PetscErrorCode main(int argc,char **argv)
{
  PetscErrorCode     ierr;                /* used to check for functions returning nonzeros */
  PetscMPIInt        size;
  Vec                x;                   /* solution */
  KSP                ksp;
  PC                 pc;
  Vec                ceq,cin;
  PetscBool          flg;                 /* A return value when checking for use options */
  Tao                tao;                 /* Tao solver context */
  TaoConvergedReason reason;
  AppCtx             user;                /* application context */

  /* Initialize TAO,PETSc */
  ierr = PetscInitialize(&argc,&argv,(char *)0,help);CHKERRQ(ierr);
  ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
  /* Specify default parameters for the problem, check for command-line overrides */
  ierr = PetscStrncpy(user.name,"HS21",8);CHKERRQ(ierr);
  ierr = PetscOptionsGetString(NULL,NULL,"-cutername",user.name,24,&flg);CHKERRQ(ierr);

  ierr = PetscPrintf(PETSC_COMM_WORLD,"\n---- MAROS Problem %s -----\n",user.name);CHKERRQ(ierr);
  ierr = InitializeProblem(&user);CHKERRQ(ierr);
  ierr = VecDuplicate(user.d,&x);CHKERRQ(ierr);
  ierr = VecDuplicate(user.beq,&ceq);CHKERRQ(ierr);
  ierr = VecDuplicate(user.bin,&cin);CHKERRQ(ierr);
  ierr = VecSet(x,1.0);CHKERRQ(ierr);

  ierr = TaoCreate(PETSC_COMM_WORLD,&tao);CHKERRQ(ierr);
  ierr = TaoSetType(tao,TAOIPM);CHKERRQ(ierr);
  ierr = TaoSetInitialVector(tao,x);CHKERRQ(ierr);
  ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetEqualityConstraintsRoutine(tao,ceq,FormEqualityConstraints,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetInequalityConstraintsRoutine(tao,cin,FormInequalityConstraints,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetInequalityBounds(tao,user.bin,NULL);CHKERRQ(ierr);
  ierr = TaoSetJacobianEqualityRoutine(tao,user.Aeq,user.Aeq,FormEqualityJacobian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetJacobianInequalityRoutine(tao,user.Ain,user.Ain,FormInequalityJacobian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void*)&user);CHKERRQ(ierr);
  ierr = TaoGetKSP(tao,&ksp);CHKERRQ(ierr);
  ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
  ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
  /*
      This algorithm produces matrices with zeros along the diagonal therefore we need to use
    SuperLU which does partial pivoting
  */
  ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERSUPERLU);CHKERRQ(ierr);
  ierr = KSPSetType(ksp,KSPPREONLY);CHKERRQ(ierr);
  ierr = TaoSetTolerances(tao,0,0,0);CHKERRQ(ierr);

  ierr = TaoSetFromOptions(tao);CHKERRQ(ierr);
  ierr = TaoSolve(tao);CHKERRQ(ierr);
  ierr = TaoGetConvergedReason(tao,&reason);CHKERRQ(ierr);
  if (reason < 0) {
    ierr = PetscPrintf(MPI_COMM_WORLD, "TAO failed to converge due to %s.\n",TaoConvergedReasons[reason]);CHKERRQ(ierr);
  } else {
    ierr = PetscPrintf(MPI_COMM_WORLD, "Optimization completed with status %s.\n",TaoConvergedReasons[reason]);CHKERRQ(ierr);
  }

  ierr = DestroyProblem(&user);CHKERRQ(ierr);
  ierr = VecDestroy(&x);CHKERRQ(ierr);
  ierr = VecDestroy(&ceq);CHKERRQ(ierr);
  ierr = VecDestroy(&cin);CHKERRQ(ierr);
  ierr = TaoDestroy(&tao);CHKERRQ(ierr);

  ierr = PetscFinalize();
  return ierr;
}
Esempio n. 6
0
                      Written as requested by [petsc-maint #63875] \n\n";

#include <petscksp.h>

#undef __FUNCT__
#define __FUNCT__ "main"
int main(int argc,char **args)
{
  Vec            x,x2,b,u;     /* approx solution, RHS, exact solution */
  Mat            A;            /* linear system matrix */
  KSP            ksp;          /* linear solver context */
  PC             pc;           /* preconditioner context */
  PetscReal      norm,tol=1.e-14; /* norm of solution error */
  PetscErrorCode ierr;
  PetscInt       i,n = 10,col[3],its;
  PetscMPIInt    rank;
  PetscScalar    neg_one = -1.0,one = 1.0,value[3];

  PetscInitialize(&argc,&args,(char*)0,help);
  ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
  ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr);

  /* Create vectors.*/
  ierr = VecCreate(PETSC_COMM_WORLD,&x);CHKERRQ(ierr);
  ierr = PetscObjectSetName((PetscObject) x, "Solution");CHKERRQ(ierr);
  ierr = VecSetSizes(x,PETSC_DECIDE,n);CHKERRQ(ierr);
  ierr = VecSetFromOptions(x);CHKERRQ(ierr);
  ierr = VecDuplicate(x,&b);CHKERRQ(ierr);
  ierr = VecDuplicate(x,&u);CHKERRQ(ierr);
  ierr = VecDuplicate(x,&x2);CHKERRQ(ierr);

  /* Create matrix. Only proc[0] sets values - not efficient for parallel processing!
     See ex23.c for efficient parallel assembly matrix */
  ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
  ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr);
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
  ierr = MatSetUp(A);CHKERRQ(ierr);

  if (!rank) {
    value[0] = -1.0; value[1] = 2.0; value[2] = -1.0;
    for (i=1; i<n-1; i++) {
      col[0] = i-1; col[1] = i; col[2] = i+1;
      ierr   = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr);
    }
    i    = n - 1; col[0] = n - 2; col[1] = n - 1;
    ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);
    i    = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0;
    ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr);

    i    = 0; col[0] = n-1; value[0] = 0.5; /* make A non-symmetric */
    ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr);
  }
  ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  /* Set exact solution */
  ierr = VecSet(u,one);CHKERRQ(ierr);

  /* Create linear solver context */
  ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr);
  ierr = KSPSetOperators(ksp,A,A,SAME_PRECONDITIONER);CHKERRQ(ierr);
  ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
  ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
#if defined(PETSC_HAVE_MUMPS)
  ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERMUMPS);CHKERRQ(ierr);
#endif
  ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);

  /* 1. Solve linear system A x = b */
  ierr = MatMult(A,u,b);CHKERRQ(ierr);
  ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);

  /* Check the error */
  ierr = VecAXPY(x,neg_one,u);CHKERRQ(ierr);
  ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
  ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr);
  if (norm > tol) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"1. Norm of error for Ax=b: %G, Iterations %D\n",
                       norm,its);CHKERRQ(ierr);
  }

  /* 2. Solve linear system A^T x = b*/
  ierr = MatMultTranspose(A,u,b);CHKERRQ(ierr);
  ierr = KSPSolveTranspose(ksp,b,x2);CHKERRQ(ierr);

  /* Check the error */
  ierr = VecAXPY(x2,neg_one,u);CHKERRQ(ierr);
  ierr = VecNorm(x2,NORM_2,&norm);CHKERRQ(ierr);
  ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr);
  if (norm > tol) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"2. Norm of error for A^T x=b: %G, Iterations %D\n",
                       norm,its);CHKERRQ(ierr);
  }

  /* 3. Change A and solve A x = b with an iterative solver using A=LU as a preconditioner*/
  if (!rank) {
    i    = 0; col[0] = n-1; value[0] = 1.e-2;
    ierr = MatSetValues(A,1,&i,1,col,value,ADD_VALUES);CHKERRQ(ierr);
  }
  ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
  ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);

  ierr = MatMult(A,u,b);CHKERRQ(ierr);
  ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);

  /* Check the error */
  ierr = VecAXPY(x,neg_one,u);CHKERRQ(ierr);
  ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr);
  ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr);
  if (norm > tol) {
    ierr = PetscPrintf(PETSC_COMM_WORLD,"3. Norm of error for (A+Delta) x=b: %G, Iterations %D\n",norm,its);CHKERRQ(ierr);
  }

  /* Free work space. */
  ierr = VecDestroy(&x);CHKERRQ(ierr);
  ierr = VecDestroy(&u);CHKERRQ(ierr);
  ierr = VecDestroy(&x2);CHKERRQ(ierr);
  ierr = VecDestroy(&b);CHKERRQ(ierr);
  ierr = MatDestroy(&A);CHKERRQ(ierr);
  ierr = KSPDestroy(&ksp);CHKERRQ(ierr);

  ierr = PetscFinalize();
  return 0;
}
Esempio n. 7
0
PetscErrorCode GetH(MPI_Comm comm, Mat *Hout, int mx, int my, int mz, double s, double nR, int dim, KSP *kspHout, PC *pcHout)
{
  PetscErrorCode ierr;
  Mat H;
  int i,ns,ne;
  int N=mx*my*mz;

  MatCreate(comm, &H);
  MatSetType(H,MATMPIAIJ);
  MatSetSizes(H,PETSC_DECIDE, PETSC_DECIDE, N, N);
  MatMPIAIJSetPreallocation(H, 3, PETSC_NULL, 3, PETSC_NULL);


  if (dim==1){ 
		double value[3];
  		int col[3];
		
		ierr = MatGetOwnershipRange(H, &ns, &ne); CHKERRQ(ierr);

  		for (i = ns; i < ne; ++i) {
    			if (i==0){ 
				col[0]= 0, value[0]= s*nR*nR*(-2.0)+1;
				col[1]= 1, value[1]= s*nR*nR*2.0;
		 		col[2]= 2, value[2]= 0;}
    			else if (i==N-1){ 
				col[0]= N-3, value[0]= 0;
				col[1]= N-2, value[1]= s*nR*nR*2.0;
		 		col[2]= N-1, value[2]= s*nR*nR*(-2.0)+1;}
			else{
				col[0]= i-1, value[0]= s*nR*nR;
				col[1]= i,   value[1]= s*nR*nR*(-2.0)+1;
		 		col[2]= i+1, value[2]= s*nR*nR;}

    			ierr = MatSetValues(H,1,&i,3,col,value,INSERT_VALUES); CHKERRQ(ierr);
  		}

		ierr = MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
		ierr = MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
  
  }

  if (dim==2) {
    PetscPrintf(comm,"2D Helmholtz filter is not implemented yet!\n");
    MatShift(H,1.0);}

  if (dim==3) {
    PetscPrintf(comm,"3D Helmholtz filter is not implemented yet!\n");
    MatShift(H,1.0);}

  ierr = PetscObjectSetName((PetscObject) H,"Hop"); CHKERRQ(ierr);

  KSP ksp;
  PC pc; 
  
  ierr = KSPCreate(comm,&ksp);CHKERRQ(ierr);
  ierr = KSPSetType(ksp, KSPGMRES);CHKERRQ(ierr);
  ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
  ierr = PCSetType(pc,PCLU);CHKERRQ(ierr);
  ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERMUMPS);CHKERRQ(ierr);
  ierr = KSPSetTolerances(ksp,1e-14,PETSC_DEFAULT,PETSC_DEFAULT,maxit);CHKERRQ(ierr);

  ierr = PCSetFromOptions(pc);
  ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);

  *Hout=H;
  *kspHout=ksp;
  *pcHout=pc;

  PetscFunctionReturn(0);

}
std::pair<std::string,std::string>
RBConstructionBase<Base>::set_alternative_solver
(AutoPtr<LinearSolver<Number> >&
#ifdef LIBMESH_HAVE_PETSC
 ls
#endif
 )
{
  // It seems that setting it this generic way has no effect...
  // PreconditionerType orig_pc = this->linear_solver->preconditioner_type();
  // this->linear_solver->set_preconditioner_type(AMG_PRECOND);
  // so we do it the "hard" way.
  std::string orig_petsc_pc_type_string, orig_petsc_ksp_type_string;

#ifdef LIBMESH_HAVE_PETSC
  // ... but we can set it the "hard" way
  PetscLinearSolver<Number>* petsc_linear_solver =
    libmesh_cast_ptr<PetscLinearSolver<Number>*>(ls.get());

  // Note: #define PCType char*, and PCGetType just sets a pointer.  We'll use
  // the string below to make a real copy, and set the PC back to its original
  // type at the end of the function.
#if PETSC_VERSION_LESS_THAN(3,0,0) || !PETSC_VERSION_LESS_THAN(3,4,0)
  // Pre-3.0 and petsc-dev (as of October 2012) use non-const versions
  PCType orig_petsc_pc_type;
  KSPType orig_petsc_ksp_type;
#else
  const PCType orig_petsc_pc_type;
  const KSPType orig_petsc_ksp_type;
#endif

  if (petsc_linear_solver)
    {
      PC pc = petsc_linear_solver->pc();
      int ierr = PCGetType(pc, &orig_petsc_pc_type);
      LIBMESH_CHKERRABORT(ierr);

      KSP ksp = petsc_linear_solver->ksp();
      ierr = KSPGetType(ksp, &orig_petsc_ksp_type);
      LIBMESH_CHKERRABORT(ierr);

      // libMesh::out << "orig_petsc_pc_type (before)=" << orig_petsc_pc_type << std::endl;
      // Make actual copies of the original PC and KSP types
      orig_petsc_pc_type_string = orig_petsc_pc_type;
      orig_petsc_ksp_type_string = orig_petsc_ksp_type;

#ifdef LIBMESH_HAVE_PETSC_HYPRE
      // Set solver/PC combo specified in input file...
      if (this->alternative_solver == "amg")
        {
          // Set HYPRE and boomeramg PC types
          ierr = PCSetType(pc, PCHYPRE);
          LIBMESH_CHKERRABORT(ierr);
          ierr = PCHYPRESetType(pc, "boomeramg");
          LIBMESH_CHKERRABORT(ierr);
        }
#endif // LIBMESH_HAVE_PETSC_HYPRE
      if (this->alternative_solver == "mumps")
        {
          // We'll use MUMPS... TODO: configure libmesh to detect
          // when MUMPS is available via PETSc.

          // No initial guesses can be specified with KSPPREONLY.  We
          // can leave the solver as gmres or whatever and it should
          // converge in 1 iteration.  Otherwise, to use KSPPREONLY,
          // you may need to do:
          // KSPSetInitialGuessNonzero(ksp, PETSC_FALSE);
          // ierr = KSPSetType(ksp, KSPPREONLY);
          // LIBMESH_CHKERRABORT(ierr);

          // Need to call the equivalent for the command line options:
          // -ksp_type preonly -pc_type lu -pc_factor_mat_solver_package mumps
          ierr = PCSetType(pc, PCLU);
          LIBMESH_CHKERRABORT(ierr);
#if !(PETSC_VERSION_LESS_THAN(3,0,0))
          ierr = PCFactorSetMatSolverPackage(pc,"mumps");
          LIBMESH_CHKERRABORT(ierr);
#endif
        }
    }
  else
    {
      // Otherwise, the cast failed and we are not using PETSc...
      libMesh::out << "You are not using PETSc, so don't know how to set AMG PC." << std::endl;
      libMesh::out << "Returning empty string!" << std::endl;
    }
#endif // LIBMESH_HAVE_PETSC

  return std::make_pair(orig_petsc_pc_type_string, orig_petsc_ksp_type_string);
}
Esempio n. 9
0
static PetscErrorCode PCSetUp_Cholesky(PC pc)
{
    PetscErrorCode         ierr;
    PetscBool              flg;
    PC_Cholesky            *dir = (PC_Cholesky*)pc->data;
    const MatSolverPackage stype;
    MatFactorError         err;

    PetscFunctionBegin;
    pc->failedreason = PC_NOERROR;
    if (dir->hdr.reusefill && pc->setupcalled) ((PC_Factor*)dir)->info.fill = dir->hdr.actualfill;

    ierr = MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
    CHKERRQ(ierr);
    if (dir->hdr.inplace) {
        if (dir->row && dir->col && (dir->row != dir->col)) {
            ierr = ISDestroy(&dir->row);
            CHKERRQ(ierr);
        }
        ierr = ISDestroy(&dir->col);
        CHKERRQ(ierr);
        ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
        CHKERRQ(ierr);
        if (dir->col && (dir->row != dir->col)) {  /* only use row ordering for SBAIJ */
            ierr = ISDestroy(&dir->col);
            CHKERRQ(ierr);
        }
        if (dir->row) {
            ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
            CHKERRQ(ierr);
        }
        ierr = MatCholeskyFactor(pc->pmat,dir->row,&((PC_Factor*)dir)->info);
        CHKERRQ(ierr);
        ierr = MatFactorGetError(pc->pmat,&err);
        CHKERRQ(ierr);
        if (err) { /* Factor() fails */
            pc->failedreason = (PCFailedReason)err;
            PetscFunctionReturn(0);
        }

        ((PC_Factor*)dir)->fact = pc->pmat;
    } else {
        MatInfo info;

        if (!pc->setupcalled) {
            ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
            CHKERRQ(ierr);
            /* check if dir->row == dir->col */
            ierr = ISEqual(dir->row,dir->col,&flg);
            CHKERRQ(ierr);
            if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"row and column permutations must equal");
            ierr = ISDestroy(&dir->col);
            CHKERRQ(ierr); /* only pass one ordering into CholeskyFactor */

            flg  = PETSC_FALSE;
            ierr = PetscOptionsGetBool(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg,NULL);
            CHKERRQ(ierr);
            if (flg) {
                PetscReal tol = 1.e-10;
                ierr = PetscOptionsGetReal(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,NULL);
                CHKERRQ(ierr);
                ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);
                CHKERRQ(ierr);
            }
            if (dir->row) {
                ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
                CHKERRQ(ierr);
            }
            if (!((PC_Factor*)dir)->fact) {
                ierr = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);
                CHKERRQ(ierr);
            }
            ierr                = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);
            CHKERRQ(ierr);
            ierr                = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
            CHKERRQ(ierr);
            dir->hdr.actualfill = info.fill_ratio_needed;
            ierr                = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
        } else if (pc->flag != SAME_NONZERO_PATTERN) {
            if (!dir->hdr.reuseordering) {
                ierr = ISDestroy(&dir->row);
                CHKERRQ(ierr);
                ierr = MatGetOrdering(pc->pmat,((PC_Factor*)dir)->ordering,&dir->row,&dir->col);
                CHKERRQ(ierr);
                ierr = ISDestroy(&dir->col);
                CHKERRQ(ierr); /* only use dir->row ordering in CholeskyFactor */

                flg  = PETSC_FALSE;
                ierr = PetscOptionsGetBool(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&flg,NULL);
                CHKERRQ(ierr);
                if (flg) {
                    PetscReal tol = 1.e-10;
                    ierr = PetscOptionsGetReal(((PetscObject)pc)->options,((PetscObject)pc)->prefix,"-pc_factor_nonzeros_along_diagonal",&tol,NULL);
                    CHKERRQ(ierr);
                    ierr = MatReorderForNonzeroDiagonal(pc->pmat,tol,dir->row,dir->row);
                    CHKERRQ(ierr);
                }
                if (dir->row) {
                    ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)dir->row);
                    CHKERRQ(ierr);
                }
            }
            ierr                = MatDestroy(&((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
            ierr                = MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_CHOLESKY,&((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
            ierr                = MatCholeskyFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->row,&((PC_Factor*)dir)->info);
            CHKERRQ(ierr);
            ierr                = MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
            CHKERRQ(ierr);
            dir->hdr.actualfill = info.fill_ratio_needed;
            ierr                = PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
            CHKERRQ(ierr);
        } else {
            ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
            CHKERRQ(ierr);
            if (err == MAT_FACTOR_NUMERIC_ZEROPIVOT) {
                ierr = MatFactorClearError(((PC_Factor*)dir)->fact);
                CHKERRQ(ierr);
                pc->failedreason = PC_NOERROR;
            }
        }
        ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
        CHKERRQ(ierr);
        if (err) { /* FactorSymbolic() fails */
            pc->failedreason = (PCFailedReason)err;
            PetscFunctionReturn(0);
        }

        ierr = MatCholeskyFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);
        CHKERRQ(ierr);
        ierr = MatFactorGetError(((PC_Factor*)dir)->fact,&err);
        CHKERRQ(ierr);
        if (err) { /* FactorNumeric() fails */
            pc->failedreason = (PCFailedReason)err;
        }
    }

    ierr = PCFactorGetMatSolverPackage(pc,&stype);
    CHKERRQ(ierr);
    if (!stype) {
        const MatSolverPackage solverpackage;
        ierr = MatFactorGetSolverPackage(((PC_Factor*)dir)->fact,&solverpackage);
        CHKERRQ(ierr);
        ierr = PCFactorSetMatSolverPackage(pc,solverpackage);
        CHKERRQ(ierr);
    }
    PetscFunctionReturn(0);
}
Esempio n. 10
0
// =====================================================
  void PetscPreconditioner::set_petsc_preconditioner_type
  (const PreconditionerType & preconditioner_type, PC & pc,  const int &parallelOverlapping) {
    int ierr = 0;
    switch(preconditioner_type)  {

      case IDENTITY_PRECOND:
        ierr = PCSetType(pc, (char*) PCNONE);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case CHOLESKY_PRECOND:
        ierr = PCSetType(pc, (char*) PCCHOLESKY);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case ICC_PRECOND:
        ierr = PCSetType(pc, (char*) PCICC);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;


      case ILU_PRECOND:
      {
        int nprocs;
        MPI_Comm_size(MPI_COMM_WORLD, &nprocs); //TODO
        // In serial, just set the ILU preconditioner type
        if(nprocs == 1)
        {
          ierr = PCSetType(pc, (char*) PCILU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        else
        {
//        But PETSc has no truly parallel ILU, instead you have to set
//        an actual parallel preconditioner (e.g. block Jacobi (parlleloverlapping 0) or ASM (parlleloverlapping >0))
//	  and then assign ILU sub-preconditioners.

          set_petsc_preconditioner_type(ASM_PRECOND, pc);
          PCASMSetOverlap(pc, parallelOverlapping);
          PCSetUp(pc);

          // Set ILU as the sub preconditioner type
          set_petsc_subpreconditioner_type(PCILU, pc);
        }
        break;
      }
      case LU_PRECOND: {
        int nprocs;
        MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
        if(nprocs == 1) {
          ierr = PCSetType(pc, (char*) PCLU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        else {
          ierr = PCSetType(pc, (char*) PCLU);
          CHKERRABORT(MPI_COMM_WORLD, ierr);

          ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          ierr = PCFactorSetUpMatSolverPackage(pc);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          Mat       F;
          ierr = PCFactorGetMatrix(pc, &F);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
          ierr = MatMumpsSetIcntl(F, 14, 30);
          CHKERRABORT(MPI_COMM_WORLD, ierr);
        }
        break;
      }

      case SLU_PRECOND:
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERSUPERLU_DIST);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;    //here we set the SuperLU_dist solver package

      case MLU_PRECOND: //here we set the MUMPS parallel direct solver package
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);

        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetUpMatSolverPackage(pc);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        Mat       F;
        ierr = PCFactorGetMatrix(pc, &F);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = MatMumpsSetIcntl(F, 14, 30);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case ULU_PRECOND: //here we set the Umfpack serial direct solver package
        ierr = PCSetType(pc, (char*) PCLU);
        CHKERRABORT(MPI_COMM_WORLD, ierr);

        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERUMFPACK);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetUpMatSolverPackage(pc);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case MCC_PRECOND:
        ierr = PCSetType(pc, (char*) PCCHOLESKY);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        ierr = PCFactorSetMatSolverPackage(pc, MATSOLVERMUMPS);
        CHKERRABORT(MPI_COMM_WORLD, ierr);                   //here we set the MUMPS parallel direct solver package
        break;

      case ASM_PRECOND:
        ierr = PCSetType(pc, (char*) PCASM);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case FIELDSPLIT_PRECOND:
        ierr = PCSetType(pc, (char*) PCFIELDSPLIT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case JACOBI_PRECOND:
        ierr = PCSetType(pc, (char*) PCJACOBI);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case BLOCK_JACOBI_PRECOND:
        ierr = PCSetType(pc, (char*) PCBJACOBI);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case SOR_PRECOND:
        ierr = PCSetType(pc, (char*) PCSOR);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case EISENSTAT_PRECOND:
        ierr = PCSetType(pc, (char*) PCEISENSTAT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case AMG_PRECOND:
        ierr = PCSetType(pc, (char*) PCHYPRE);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case MG_PRECOND:
        ierr = PCSetType(pc, (char*) PCMG);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      case LSC_PRECOND:
        ierr = PCSetType(pc, (char*) PCLSC);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

#if !(PETSC_VERSION_LESS_THAN(2,1,2))
        // Only available for PETSC >= 2.1.2
      case USER_PRECOND:
        ierr = PCSetType(pc, (char*) PCMAT);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;
#endif

      case SHELL_PRECOND:
        ierr = PCSetType(pc, (char*) PCSHELL);
        CHKERRABORT(MPI_COMM_WORLD, ierr);
        break;

      default:
        std::cerr << "ERROR:  Unsupported PETSC Preconditioner: "
                  << preconditioner_type << std::endl
                  << "Continuing with PETSC defaults" << std::endl;
    }

    //Let the commandline override stuff
    if(preconditioner_type != AMG_PRECOND && preconditioner_type != MG_PRECOND)   PCSetFromOptions(pc);   //!!!!!!
  }
Esempio n. 11
0
void
SolverLinearPetsc<T>::setPetscPreconditionerType()
{

    int ierr = 0;
#if (PETSC_VERSION_MAJOR == 3) && (PETSC_VERSION_MINOR >= 2)
    ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERUMFPACK );

    if ( ierr )
    {
        ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERSUPERLU );

        if ( ierr )
        {
            ierr = PCFactorSetMatSolverPackage( M_pc,MATSOLVERPETSC );
        }
    }

#elif (PETSC_VERSION_MAJOR >= 3)
    ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_UMFPACK );

    if ( ierr )
    {
        ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_SUPERLU );

        if ( ierr )
        {
            ierr = PCFactorSetMatSolverPackage( M_pc,MAT_SOLVER_PETSC );
        }
    }

#endif
    DVLOG(2) << "[SolverLinearPetsc] preconditioner type:  " << this->preconditionerType() << "\n";

    switch ( this->preconditionerType() )
    {
    case IDENTITY_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCNONE );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case CHOLESKY_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCCHOLESKY );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case ICC_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCICC );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case ILU_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCILU );
        CHKERRABORT( this->worldComm().globalComm(),ierr );

        if ( this->vm().count( "pc-factor-levels" ) )
        {
            PCFactorSetLevels( M_pc,this->vm()["pc-factor-levels"].template as<int>() );
        }

        else
            PCFactorSetLevels( M_pc,3 );

        if ( this->vm().count( "pc-factor-fill" ) )
        {
            PCFactorSetFill( M_pc,this->vm()["pc-factor-fill"].template as<double>() );
        }

        else
            PCFactorSetFill( M_pc,40 );

        return;

    case LU_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCLU );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case ASM_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCASM );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

#if PETSC_VERSION_GREATER_OR_EQUAL_THAN( 3,2,0 )
    case GASM_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCGASM );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;
#endif

    case JACOBI_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCJACOBI );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case BLOCK_JACOBI_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCBJACOBI );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case SOR_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCSOR );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case EISENSTAT_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCEISENSTAT );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

#if !((PETSC_VERSION_MAJOR == 2) && (PETSC_VERSION_MINOR <= 1) && (PETSC_VERSION_SUBMINOR <= 1))

    case USER_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCMAT );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;
#endif

    case SHELL_PRECOND:
        ierr = PCSetType ( M_pc, ( char* ) PCSHELL );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case FIELDSPLIT_PRECOND:
        ierr = PCSetType( M_pc,( char* ) PCFIELDSPLIT );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        ierr = PCFieldSplitSetType( M_pc,PC_COMPOSITE_SCHUR );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    case ML_PRECOND:
        ierr = PCSetType( M_pc,( char* ) PCML );
        CHKERRABORT( this->worldComm().globalComm(),ierr );
        return;

    default:
        std::cerr << "ERROR:  Unsupported PETSC Preconditioner: "
                  << this->preconditionerType()       << std::endl
                  << "Continuing with PETSC defaults" << std::endl;
    }

}
Esempio n. 12
0
PetscErrorCode PCBDDCSubSchursSetUp(PCBDDCSubSchurs sub_schurs, Mat S, IS is_A_I, IS is_A_B, PetscInt ncc, IS is_cc[], PetscInt xadj[], PetscInt adjncy[], PetscInt nlayers)
{
  Mat                    A_II,A_IB,A_BI,A_BB;
  ISLocalToGlobalMapping BtoNmap,ItoNmap;
  PetscBT                touched;
  PetscInt               i,n_I,n_B,n_local,*local_numbering;
  PetscBool              is_sorted;
  PetscErrorCode         ierr;

  PetscFunctionBegin;
  ierr = ISSorted(is_A_I,&is_sorted);CHKERRQ(ierr);
  if (!is_sorted) {
    SETERRQ(PetscObjectComm((PetscObject)is_A_I),PETSC_ERR_PLIB,"IS for I dofs should be shorted");
  }
  ierr = ISSorted(is_A_B,&is_sorted);CHKERRQ(ierr);
  if (!is_sorted) {
    SETERRQ(PetscObjectComm((PetscObject)is_A_B),PETSC_ERR_PLIB,"IS for B dofs should be shorted");
  }

  /* get sizes */
  ierr = ISGetLocalSize(is_A_I,&n_I);CHKERRQ(ierr);
  ierr = ISGetLocalSize(is_A_B,&n_B);CHKERRQ(ierr);
  n_local = n_I+n_B;

  /* maps */
  ierr = ISLocalToGlobalMappingCreateIS(is_A_B,&BtoNmap);CHKERRQ(ierr);
  if (nlayers >= 0 && xadj != NULL && adjncy != NULL) { /* I problems have a different size of the original ones */
    ierr = ISLocalToGlobalMappingCreateIS(is_A_I,&ItoNmap);CHKERRQ(ierr);
    /* allocate some auxiliary space */
    ierr = PetscMalloc1(n_local,&local_numbering);CHKERRQ(ierr);
    ierr = PetscBTCreate(n_local,&touched);CHKERRQ(ierr);
  } else {
    ItoNmap = 0;
    local_numbering = 0;
    touched = 0;
  }

  /* get Schur complement matrices */
  ierr = MatSchurComplementGetSubMatrices(S,&A_II,NULL,&A_IB,&A_BI,&A_BB);CHKERRQ(ierr);

  /* allocate space for schur complements */
  ierr = PetscMalloc5(ncc,&sub_schurs->is_AEj_I,ncc,&sub_schurs->is_AEj_B,ncc,&sub_schurs->S_Ej,ncc,&sub_schurs->work1,ncc,&sub_schurs->work2);CHKERRQ(ierr);
  sub_schurs->n_subs = ncc;

  /* cycle on subsets and extract schur complements */
  for (i=0;i<sub_schurs->n_subs;i++) {
    Mat      AE_II,AE_IE,AE_EI,AE_EE;
    IS       is_I,is_subset_B;

    /* get IS for subsets in B numbering */
    ierr = ISDuplicate(is_cc[i],&sub_schurs->is_AEj_B[i]);CHKERRQ(ierr);
    ierr = ISSort(sub_schurs->is_AEj_B[i]);CHKERRQ(ierr);
    ierr = ISGlobalToLocalMappingApplyIS(BtoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_B[i],&is_subset_B);CHKERRQ(ierr);

    /* BB block on subset */
    ierr = MatGetSubMatrix(A_BB,is_subset_B,is_subset_B,MAT_INITIAL_MATRIX,&AE_EE);CHKERRQ(ierr);

    if (ItoNmap) { /* is ItoNmap has been computed, extracts only a part of I dofs */
      const PetscInt* idx_B;
      PetscInt        n_local_dofs,n_prev_added,j,layer,subset_size;

      /* all boundary dofs must be skipped when adding layers */
      ierr = PetscBTMemzero(n_local,touched);CHKERRQ(ierr);
      ierr = ISGetIndices(is_A_B,&idx_B);CHKERRQ(ierr);
      for (j=0;j<n_B;j++) {
        ierr = PetscBTSet(touched,idx_B[j]);CHKERRQ(ierr);
      }
      ierr = ISRestoreIndices(is_A_B,&idx_B);CHKERRQ(ierr);

      /* add next layers of dofs */
      ierr = ISGetLocalSize(is_cc[i],&subset_size);CHKERRQ(ierr);
      ierr = ISGetIndices(is_cc[i],&idx_B);CHKERRQ(ierr);
      ierr = PetscMemcpy(local_numbering,idx_B,subset_size*sizeof(PetscInt));CHKERRQ(ierr);
      ierr = ISRestoreIndices(is_cc[i],&idx_B);CHKERRQ(ierr);
      n_local_dofs = subset_size;
      n_prev_added = subset_size;
      for (layer=0;layer<nlayers;layer++) {
        PetscInt n_added;
        if (n_local_dofs == n_I+subset_size) break;
        if (n_local_dofs > n_I+subset_size) {
          SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error querying layer %d. Out of bound access (%d > %d)",layer,n_local_dofs,n_I+subset_size);
        }
        ierr = PCBDDCAdjGetNextLayer_Private(local_numbering+n_local_dofs,n_prev_added,touched,xadj,adjncy,&n_added);CHKERRQ(ierr);
        n_prev_added = n_added;
        n_local_dofs += n_added;
        if (!n_added) break;
      }

      /* IS for I dofs in original numbering and in I numbering */
      ierr = ISCreateGeneral(PetscObjectComm((PetscObject)ItoNmap),n_local_dofs-subset_size,local_numbering+subset_size,PETSC_COPY_VALUES,&sub_schurs->is_AEj_I[i]);CHKERRQ(ierr);
      ierr = ISSort(sub_schurs->is_AEj_I[i]);CHKERRQ(ierr);
      ierr = ISGlobalToLocalMappingApplyIS(ItoNmap,IS_GTOLM_DROP,sub_schurs->is_AEj_I[i],&is_I);CHKERRQ(ierr);

      /* II block */
      ierr = MatGetSubMatrix(A_II,is_I,is_I,MAT_INITIAL_MATRIX,&AE_II);CHKERRQ(ierr);
    } else { /* in this case we can take references of already existing IS and matrices for I dofs */
      /* IS for I dofs in original numbering */
      ierr = PetscObjectReference((PetscObject)is_A_I);CHKERRQ(ierr);
      sub_schurs->is_AEj_I[i] = is_A_I;

      /* IS for I dofs in I numbering TODO: "first" argument of ISCreateStride is not general */
      ierr = ISCreateStride(PetscObjectComm((PetscObject)is_A_I),n_I,0,1,&is_I);CHKERRQ(ierr);

      /* II block is the same */
      ierr = PetscObjectReference((PetscObject)A_II);CHKERRQ(ierr);
      AE_II = A_II;
    }

    /* IE block */
    ierr = MatGetSubMatrix(A_IB,is_I,is_subset_B,MAT_INITIAL_MATRIX,&AE_IE);CHKERRQ(ierr);

    /* EI block */
    ierr = MatGetSubMatrix(A_BI,is_subset_B,is_I,MAT_INITIAL_MATRIX,&AE_EI);CHKERRQ(ierr);

    /* setup Schur complements on subset */
    ierr = MatCreateSchurComplement(AE_II,AE_II,AE_IE,AE_EI,AE_EE,&sub_schurs->S_Ej[i]);CHKERRQ(ierr);
    ierr = MatGetVecs(sub_schurs->S_Ej[i],&sub_schurs->work1[i],&sub_schurs->work2[i]);CHKERRQ(ierr);
    if (AE_II == A_II) { /* we can reuse the same ksp */
      KSP ksp;
      ierr = MatSchurComplementGetKSP(S,&ksp);CHKERRQ(ierr);
      ierr = MatSchurComplementSetKSP(sub_schurs->S_Ej[i],ksp);CHKERRQ(ierr);
    } else { /* build new ksp object which inherits ksp and pc types from the original one */
      KSP      origksp,schurksp;
      PC       origpc,schurpc;
      KSPType  ksp_type;
      PCType   pc_type;
      PetscInt n_internal;

      ierr = MatSchurComplementGetKSP(S,&origksp);CHKERRQ(ierr);
      ierr = MatSchurComplementGetKSP(sub_schurs->S_Ej[i],&schurksp);CHKERRQ(ierr);
      ierr = KSPGetType(origksp,&ksp_type);CHKERRQ(ierr);
      ierr = KSPSetType(schurksp,ksp_type);CHKERRQ(ierr);
      ierr = KSPGetPC(schurksp,&schurpc);CHKERRQ(ierr);
      ierr = KSPGetPC(origksp,&origpc);CHKERRQ(ierr);
      ierr = PCGetType(origpc,&pc_type);CHKERRQ(ierr);
      ierr = PCSetType(schurpc,pc_type);CHKERRQ(ierr);
      ierr = ISGetSize(is_I,&n_internal);CHKERRQ(ierr);
      if (n_internal) { /* UMFPACK gives error with 0 sized problems */
        MatSolverPackage solver=NULL;
        ierr = PCFactorGetMatSolverPackage(origpc,(const MatSolverPackage*)&solver);CHKERRQ(ierr);
        if (solver) {
          ierr = PCFactorSetMatSolverPackage(schurpc,solver);CHKERRQ(ierr);
        }
      }
      ierr = KSPSetUp(schurksp);CHKERRQ(ierr);
    }
    /* free */
    ierr = MatDestroy(&AE_II);CHKERRQ(ierr);
    ierr = MatDestroy(&AE_EE);CHKERRQ(ierr);
    ierr = MatDestroy(&AE_IE);CHKERRQ(ierr);
    ierr = MatDestroy(&AE_EI);CHKERRQ(ierr);
    ierr = ISDestroy(&is_I);CHKERRQ(ierr);
    ierr = ISDestroy(&is_subset_B);CHKERRQ(ierr);
  }
  /* free */
  ierr = ISLocalToGlobalMappingDestroy(&ItoNmap);CHKERRQ(ierr);
  ierr = ISLocalToGlobalMappingDestroy(&BtoNmap);CHKERRQ(ierr);
  ierr = PetscFree(local_numbering);CHKERRQ(ierr);
  ierr = PetscBTDestroy(&touched);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}
Esempio n. 13
0
PetscErrorCode main(int argc,char **argv)
{
    PetscErrorCode     ierr;                /* used to check for functions returning nonzeros */
    Tao                tao;
    KSP                ksp;
    PC                 pc;
    AppCtx             user;                /* application context */

    ierr = PetscInitialize(&argc,&argv,(char *)0,help);
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"\n---- TOY Problem -----\n");
    CHKERRQ(ierr);
    ierr = PetscPrintf(PETSC_COMM_WORLD,"Solution should be f(1,1)=-2\n");
    CHKERRQ(ierr);
    ierr = InitializeProblem(&user);
    CHKERRQ(ierr);
    ierr = TaoCreate(PETSC_COMM_WORLD,&tao);
    CHKERRQ(ierr);
    ierr = TaoSetType(tao,TAOIPM);
    CHKERRQ(ierr);
    ierr = TaoSetInitialVector(tao,user.x);
    CHKERRQ(ierr);
    ierr = TaoSetVariableBounds(tao,user.xl,user.xu);
    CHKERRQ(ierr);
    ierr = TaoSetObjectiveAndGradientRoutine(tao,FormFunctionGradient,(void*)&user);
    CHKERRQ(ierr);

    ierr = TaoSetEqualityConstraintsRoutine(tao,user.ce,FormEqualityConstraints,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetInequalityConstraintsRoutine(tao,user.ci,FormInequalityConstraints,(void*)&user);
    CHKERRQ(ierr);

    ierr = TaoSetJacobianEqualityRoutine(tao,user.Ae,user.Ae,FormEqualityJacobian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetJacobianInequalityRoutine(tao,user.Ai,user.Ai,FormInequalityJacobian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetHessianRoutine(tao,user.H,user.H,FormHessian,(void*)&user);
    CHKERRQ(ierr);
    ierr = TaoSetTolerances(tao,0,0,0);
    CHKERRQ(ierr);

    ierr = TaoSetFromOptions(tao);
    CHKERRQ(ierr);

    ierr = TaoGetKSP(tao,&ksp);
    CHKERRQ(ierr);
    ierr = KSPGetPC(ksp,&pc);
    CHKERRQ(ierr);
    ierr = PCSetType(pc,PCLU);
    CHKERRQ(ierr);
    /*
        This algorithm produces matrices with zeros along the diagonal therefore we need to use
      SuperLU which does partial pivoting
    */
    ierr = PCFactorSetMatSolverPackage(pc,MATSOLVERSUPERLU);
    CHKERRQ(ierr);
    ierr = KSPSetType(ksp,KSPPREONLY);
    CHKERRQ(ierr);
    ierr = KSPSetFromOptions(ksp);
    CHKERRQ(ierr);

    ierr = TaoSetTolerances(tao,0,0,0);
    CHKERRQ(ierr);
    ierr = TaoSolve(tao);
    CHKERRQ(ierr);

    ierr = DestroyProblem(&user);
    CHKERRQ(ierr);
    ierr = TaoDestroy(&tao);
    CHKERRQ(ierr);
    ierr = PetscFinalize();
    return ierr;
}