14 #include "../config/config.hpp"
20 #include "../fem/fem.hpp"
23 #if defined(PETSC_HAVE_HYPRE)
24 #include "petscmathypre.h"
28 #if PETSC_VERSION_LT(3,12,0)
29 #define MatComputeOperator(A,B,C) MatComputeExplicitOperator(A,C)
30 #define MatComputeOperatorTranspose(A,B,C) MatComputeExplicitOperatorTranspose(A,C)
43 #define PCHKERRQ(obj,err) do { \
46 PetscError(PetscObjectComm((PetscObject)(obj)),__LINE__,_MFEM_FUNC_NAME, \
47 __FILE__,(err),PETSC_ERROR_REPEAT,NULL); \
48 MFEM_ABORT("Error in PETSc. See stacktrace above."); \
51 #define CCHKERRQ(comm,err) do { \
54 PetscError(comm,__LINE__,_MFEM_FUNC_NAME, \
55 __FILE__,(err),PETSC_ERROR_REPEAT,NULL); \
56 MFEM_ABORT("Error in PETSc. See stacktrace above."); \
72 static PetscErrorCode __mfem_snes_jacobian(
SNES,
Vec,
Mat,
Mat,
void*);
73 static PetscErrorCode __mfem_snes_function(
SNES,
Vec,
Vec,
void*);
76 static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch,
Vec,
Vec,
Vec,
77 PetscBool*,PetscBool*,
void*);
79 static PetscErrorCode __mfem_pc_shell_apply(
PC,
Vec,
Vec);
80 static PetscErrorCode __mfem_pc_shell_apply_transpose(
PC,
Vec,
Vec);
81 static PetscErrorCode __mfem_pc_shell_setup(
PC);
82 static PetscErrorCode __mfem_pc_shell_destroy(
PC);
83 static PetscErrorCode __mfem_pc_shell_view(
PC,PetscViewer);
84 static PetscErrorCode __mfem_mat_shell_apply(
Mat,
Vec,
Vec);
85 static PetscErrorCode __mfem_mat_shell_apply_transpose(
Mat,
Vec,
Vec);
86 static PetscErrorCode __mfem_mat_shell_destroy(
Mat);
87 static PetscErrorCode __mfem_array_container_destroy(
void*);
88 static PetscErrorCode __mfem_matarray_container_destroy(
void*);
89 static PetscErrorCode __mfem_monitor_ctx_destroy(
void**);
92 static PetscErrorCode Convert_Array_IS(MPI_Comm,
bool,
const mfem::Array<int>*,
97 static PetscErrorCode MakeShellPCWithFactory(
PC,
103 #if !defined(PETSC_HAVE_HYPRE)
104 static PetscErrorCode MatConvert_hypreParCSR_AIJ(hypre_ParCSRMatrix*,
Mat*);
105 static PetscErrorCode MatConvert_hypreParCSR_IS(hypre_ParCSRMatrix*,
Mat*);
112 } __mfem_mat_shell_ctx;
119 unsigned long int numprec;
120 } __mfem_pc_shell_ctx;
131 void (*postcheck)(
mfem::Operator *op,
const mfem::Vector&, mfem::Vector&,
132 mfem::Vector&,
bool&,
bool&);
136 const mfem::Vector&,
const mfem::Vector&,
137 const mfem::Vector&,
const mfem::Vector&);
148 PetscObjectState cached_ijacstate;
149 PetscObjectState cached_rhsjacstate;
150 PetscObjectState cached_splits_xstate;
151 PetscObjectState cached_splits_xdotstate;
158 } __mfem_monitor_ctx;
161 static PetscErrorCode ierr;
181 ierr = PetscInitialize(argc,argv,rc_file,help);
182 MFEM_VERIFY(!ierr,
"Unable to initialize PETSc");
187 ierr = PetscFinalize();
188 MFEM_VERIFY(!ierr,
"Unable to finalize PETSc");
193 void PetscParVector::_SetDataAndSize_()
198 ierr = VecGetArrayRead(x,&array); PCHKERRQ(x,ierr);
199 ierr = VecGetLocalSize(x,&n); PCHKERRQ(x,ierr);
201 ierr = VecRestoreArrayRead(x,&array); PCHKERRQ(x,ierr);
207 ierr = VecGetSize(x,&N); PCHKERRQ(x,ierr);
211 PetscParVector::PetscParVector(MPI_Comm comm,
const Vector &_x,
214 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
215 ierr = VecSetSizes(
x,_x.
Size(),PETSC_DECIDE); PCHKERRQ(
x,ierr);
216 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
222 ierr = VecGetArray(
x,&array); PCHKERRQ(
x,ierr);
223 for (
int i = 0; i < _x.
Size(); i++) { array[i] = _x[i]; }
224 ierr = VecRestoreArray(
x,&array); PCHKERRQ(
x,ierr);
231 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
235 MPI_Comm_rank(comm, &myid);
236 ierr = VecSetSizes(
x,col[myid+1]-col[myid],PETSC_DECIDE); PCHKERRQ(
x,ierr);
240 ierr = VecSetSizes(
x,PETSC_DECIDE,glob_size); PCHKERRQ(
x,ierr);
242 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
249 ierr = VecDestroy(&x); CCHKERRQ(comm,ierr);
255 MFEM_VERIFY(col,
"Missing distribution");
257 MPI_Comm_rank(comm, &myid);
258 ierr = VecCreateMPIWithArray(comm,1,col[myid+1]-col[myid],glob_size,_data,
259 &
x); CCHKERRQ(comm,ierr)
265 ierr = VecDuplicate(y.
x,&
x); PCHKERRQ(
x,ierr);
270 bool transpose,
bool allocate) :
Vector()
275 ierr = VecCreate(comm,&
x);
277 ierr = VecSetSizes(
x,loc,PETSC_DECIDE);
279 ierr = VecSetType(
x,VECSTANDARD);
286 ierr = VecCreateMPIWithArray(comm,1,loc,PETSC_DECIDE,NULL,
287 &
x); CCHKERRQ(comm,ierr);
293 bool transpose,
bool allocate) :
Vector()
298 ierr = MatCreateVecs(pA,&
x,NULL); PCHKERRQ(pA,ierr);
302 ierr = MatCreateVecs(pA,NULL,&
x); PCHKERRQ(pA,ierr);
306 ierr = VecReplaceArray(
x,NULL); PCHKERRQ(
x,ierr);
315 ierr = PetscObjectReference((
PetscObject)y); PCHKERRQ(y,ierr);
325 MPI_Comm comm = pfes->
GetComm();
326 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
328 PetscMPIInt myid = 0;
329 if (!HYPRE_AssumedPartitionCheck())
331 MPI_Comm_rank(comm,&myid);
333 ierr = VecSetSizes(
x,offsets[myid+1]-offsets[myid],PETSC_DECIDE);
335 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
351 ierr = VecScatterCreateToAll(
x,&scctx,&vout); PCHKERRQ(
x,ierr);
352 ierr = VecScatterBegin(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
354 ierr = VecScatterEnd(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
356 ierr = VecScatterDestroy(&scctx); PCHKERRQ(
x,ierr);
357 ierr = VecGetArray(vout,&array); PCHKERRQ(
x,ierr);
358 ierr = VecGetLocalSize(vout,&size); PCHKERRQ(
x,ierr);
361 ierr = VecRestoreArray(vout,&array); PCHKERRQ(
x,ierr);
362 ierr = VecDestroy(&vout); PCHKERRQ(
x,ierr);
371 ierr = VecSet(
x,d); PCHKERRQ(
x,ierr);
378 MFEM_VERIFY(idx.
Size() == vals.
Size(),
379 "Size mismatch between indices and values");
383 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
384 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
391 MFEM_VERIFY(idx.
Size() == vals.
Size(),
392 "Size mismatch between indices and values");
396 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
397 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
403 ierr = VecCopy(y.
x,
x); PCHKERRQ(
x,ierr);
409 ierr = VecAXPY(
x,1.0,y.
x); PCHKERRQ(
x,ierr);
415 ierr = VecAXPY(
x,-1.0,y.
x); PCHKERRQ(
x,ierr);
421 ierr = VecScale(
x,s); PCHKERRQ(
x,ierr);
427 ierr = VecPlaceArray(
x,temp_data); PCHKERRQ(
x,ierr);
432 ierr = VecResetArray(
x); PCHKERRQ(
x,ierr);
437 PetscRandom rctx = NULL;
441 ierr = PetscRandomCreate(PetscObjectComm((
PetscObject)
x),&rctx);
443 ierr = PetscRandomSetSeed(rctx,(
unsigned long)seed); PCHKERRQ(x,ierr);
444 ierr = PetscRandomSeed(rctx); PCHKERRQ(x,ierr);
446 ierr = VecSetRandom(
x,rctx); PCHKERRQ(
x,ierr);
447 ierr = PetscRandomDestroy(&rctx); PCHKERRQ(
x,ierr);
458 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)
x),fname,
459 FILE_MODE_WRITE,&view);
463 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)
x),fname,&view);
466 ierr = VecView(
x,view); PCHKERRQ(
x,ierr);
467 ierr = PetscViewerDestroy(&view); PCHKERRQ(
x,ierr);
471 ierr = VecView(
x,NULL); PCHKERRQ(
x,ierr);
480 ierr = MatGetOwnershipRange(
A,&N,NULL); PCHKERRQ(
A,ierr);
487 ierr = MatGetOwnershipRangeColumn(
A,&N,NULL); PCHKERRQ(
A,ierr);
494 ierr = MatGetLocalSize(
A,&N,NULL); PCHKERRQ(
A,ierr);
501 ierr = MatGetLocalSize(
A,NULL,&N); PCHKERRQ(
A,ierr);
508 ierr = MatGetSize(
A,&N,NULL); PCHKERRQ(
A,ierr);
515 ierr = MatGetSize(
A,NULL,&N); PCHKERRQ(
A,ierr);
522 ierr = MatGetInfo(
A,MAT_GLOBAL_SUM,&info); PCHKERRQ(
A,ierr);
547 rows.
GetData(),PETSC_USE_POINTER,&isr); PCHKERRQ(B,ierr);
549 cols.
GetData(),PETSC_USE_POINTER,&isc); PCHKERRQ(B,ierr);
550 ierr = MatCreateSubMatrix(B,isr,isc,MAT_INITIAL_MATRIX,&
A); PCHKERRQ(B,ierr);
551 ierr = ISDestroy(&isr); PCHKERRQ(B,ierr);
552 ierr = ISDestroy(&isc); PCHKERRQ(B,ierr);
596 BlockDiagonalConstructor(comm,row_starts,row_starts,diag,
609 BlockDiagonalConstructor(comm,row_starts,col_starts,diag,
621 ierr = MatDestroy(&A); CCHKERRQ(comm,ierr);
628 #if defined(PETSC_HAVE_HYPRE)
629 ierr = MatCreateFromParCSR(B,MATAIJ,PETSC_USE_POINTER,&
A);
631 ierr = MatConvert_hypreParCSR_AIJ(B,&
A); CCHKERRQ(B.
GetComm(),ierr);
641 ierr = MatDestroy(&A); CCHKERRQ(comm,ierr);
648 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
656 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
660 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
661 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
662 ierr = MatAXPY(
A,1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
671 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
672 ierr = MatScale(
A,-1.0); PCHKERRQ(
A,ierr);
676 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
677 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
678 ierr = MatAXPY(
A,-1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
683 void PetscParMatrix::
684 BlockDiagonalConstructor(MPI_Comm comm,
689 PetscInt lrsize,lcsize,rstart,cstart;
690 PetscMPIInt myid = 0,commsize;
692 ierr = MPI_Comm_size(comm,&commsize); CCHKERRQ(comm,ierr);
693 if (!HYPRE_AssumedPartitionCheck())
695 ierr = MPI_Comm_rank(comm,&myid); CCHKERRQ(comm,ierr);
697 lrsize = row_starts[myid+1]-row_starts[myid];
698 rstart = row_starts[myid];
699 lcsize = col_starts[myid+1]-col_starts[myid];
700 cstart = col_starts[myid];
705 ierr = ISCreateStride(comm,diag->
Height(),rstart,1,&is); CCHKERRQ(comm,ierr);
706 ISLocalToGlobalMapping rl2g,cl2g;
707 ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g); PCHKERRQ(is,ierr);
708 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
709 if (row_starts != col_starts)
711 ierr = ISCreateStride(comm,diag->
Width(),cstart,1,&is);
713 ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g); PCHKERRQ(is,ierr);
714 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
718 ierr = PetscObjectReference((
PetscObject)rl2g); PCHKERRQ(rl2g,ierr);
723 ierr = MatCreate(comm,&A); CCHKERRQ(comm,ierr);
724 ierr = MatSetSizes(A,lrsize,lcsize,PETSC_DECIDE,PETSC_DECIDE);
726 ierr = MatSetType(A,MATIS); PCHKERRQ(A,ierr);
727 ierr = MatSetLocalToGlobalMapping(A,rl2g,cl2g); PCHKERRQ(A,ierr);
728 ierr = ISLocalToGlobalMappingDestroy(&rl2g); PCHKERRQ(A,ierr)
729 ierr = ISLocalToGlobalMappingDestroy(&cl2g); PCHKERRQ(A,ierr)
733 ierr = MatISGetLocalMat(A,&lA); PCHKERRQ(A,ierr);
734 int *II = diag->GetI();
735 int *JJ = diag->GetJ();
736 #if defined(PETSC_USE_64BIT_INDICES)
739 ierr = PetscMalloc2(m,&pII,nnz,&pJJ); PCHKERRQ(lA,ierr);
740 for (
int i = 0; i < m; i++) { pII[i] = II[i]; }
741 for (
int i = 0; i < nnz; i++) { pJJ[i] = JJ[i]; }
742 ierr = MatSeqAIJSetPreallocationCSR(lA,pII,pJJ,
743 diag->
GetData()); PCHKERRQ(lA,ierr);
744 ierr = PetscFree2(pII,pJJ); PCHKERRQ(lA,ierr);
746 ierr = MatSeqAIJSetPreallocationCSR(lA,II,JJ,
747 diag->
GetData()); PCHKERRQ(lA,ierr);
759 ierr = PetscMalloc1(m,&dii); CCHKERRQ(PETSC_COMM_SELF,ierr);
760 ierr = PetscMalloc1(nnz,&djj); CCHKERRQ(PETSC_COMM_SELF,ierr);
761 ierr = PetscMalloc1(nnz,&da); CCHKERRQ(PETSC_COMM_SELF,ierr);
762 if (
sizeof(
PetscInt) ==
sizeof(
int))
764 ierr = PetscMemcpy(dii,diag->
GetI(),m*
sizeof(
PetscInt));
765 CCHKERRQ(PETSC_COMM_SELF,ierr);
766 ierr = PetscMemcpy(djj,diag->
GetJ(),nnz*
sizeof(
PetscInt));
767 CCHKERRQ(PETSC_COMM_SELF,ierr);
771 int *iii = diag->
GetI();
772 int *jjj = diag->
GetJ();
773 for (
int i = 0; i < m; i++) { dii[i] = iii[i]; }
774 for (
int i = 0; i < nnz; i++) { djj[i] = jjj[i]; }
777 CCHKERRQ(PETSC_COMM_SELF,ierr);
778 ierr = PetscCalloc1(m,&oii);
779 CCHKERRQ(PETSC_COMM_SELF,ierr);
782 ierr = MatCreateMPIAIJWithSplitArrays(comm,lrsize,lcsize,PETSC_DECIDE,
784 dii,djj,da,oii,NULL,NULL,&A);
789 ierr = MatCreateSeqAIJWithArrays(comm,lrsize,lcsize,dii,djj,da,&A);
793 void *ptrs[4] = {dii,djj,da,oii};
794 const char *names[4] = {
"_mfem_csr_dii",
803 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
804 ierr = PetscContainerSetPointer(c,ptrs[i]); CCHKERRQ(comm,ierr);
805 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
809 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
814 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); PCHKERRQ(A,ierr);
815 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); PCHKERRQ(A,ierr);
822 return A ? PetscObjectComm((
PetscObject)A) : MPI_COMM_NULL;
835 __mfem_mat_shell_ctx *ctx =
new __mfem_mat_shell_ctx;
836 ierr = MatCreate(comm,A); CCHKERRQ(comm,ierr);
838 PETSC_DECIDE,PETSC_DECIDE); PCHKERRQ(A,ierr);
839 ierr = MatSetType(*A,MATSHELL); PCHKERRQ(A,ierr);
840 ierr = MatShellSetContext(*A,(
void *)ctx); PCHKERRQ(A,ierr);
841 ierr = MatShellSetOperation(*A,MATOP_MULT,
842 (
void (*)())__mfem_mat_shell_apply);
844 ierr = MatShellSetOperation(*A,MATOP_MULT_TRANSPOSE,
845 (
void (*)())__mfem_mat_shell_apply_transpose);
847 ierr = MatShellSetOperation(*A,MATOP_DESTROY,
848 (
void (*)())__mfem_mat_shell_destroy);
850 ierr = MatSetUp(*A); PCHKERRQ(*A,ierr);
851 ctx->op =
const_cast<Operator *
>(op);
876 PetscBool avoidmatconvert = PETSC_FALSE;
879 ierr = PetscObjectTypeCompareAny((
PetscObject)(pA->
A),&avoidmatconvert,MATMFFD,
883 if (pA && !avoidmatconvert)
887 #if PETSC_VERSION_LT(3,10,0)
891 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATTRANSPOSEMAT,&istrans);
902 #if PETSC_VERSION_LT(3,10,0)
903 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATIS,&ismatis);
909 ierr = MatTransposeGetMat(pA->
A,&At); CCHKERRQ(pA->
GetComm(),ierr);
910 #if PETSC_VERSION_LT(3,10,0)
911 ierr = PetscObjectTypeCompare((
PetscObject)(At),MATIS,&ismatis);
919 #if PETSC_VERSION_LT(3,10,0)
926 ierr = MatISGetMPIXAIJ(At,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
927 ierr = MatCreateTranspose(B,A); PCHKERRQ(pA->
A,ierr);
928 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
932 ierr = MatISGetMPIXAIJ(pA->
A,MAT_INITIAL_MATRIX,A);
933 PCHKERRQ(pA->
A,ierr);
940 ierr = MPI_Comm_size(comm,&size); CCHKERRQ(comm,ierr);
946 ierr = MatConvert(At,size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);
947 PCHKERRQ(pA->
A,ierr);
948 ierr = MatCreateTranspose(B,A); PCHKERRQ(pA->
A,ierr);
949 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
953 ierr = MatConvert(pA->
A, size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,A);
954 PCHKERRQ(pA->
A,ierr);
963 ierr = MatConvert(At,MATIS,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
964 ierr = MatCreateTranspose(B,A); PCHKERRQ(pA->
A,ierr);
965 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
969 ierr = MatConvert(pA->
A,MATIS,MAT_INITIAL_MATRIX,A); PCHKERRQ(pA->
A,ierr);
974 #if defined(PETSC_HAVE_HYPRE)
978 ierr = MatConvert(At,MATHYPRE,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
979 ierr = MatCreateTranspose(B,A); PCHKERRQ(pA->
A,ierr);
980 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
984 ierr = MatConvert(pA->
A,MATHYPRE,MAT_INITIAL_MATRIX,A); PCHKERRQ(pA->
A,ierr);
987 MFEM_ABORT(
"Reconfigure PETSc with --download-hypre or --with-hypre")
996 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1003 #if defined(PETSC_HAVE_HYPRE)
1004 ierr = MatCreateFromParCSR(const_cast<HypreParMatrix&>(*pH),MATAIJ,
1005 PETSC_USE_POINTER,A);
1007 ierr = MatConvert_hypreParCSR_AIJ(const_cast<HypreParMatrix&>(*pH),A);
1013 #if defined(PETSC_HAVE_HYPRE)
1014 ierr = MatCreateFromParCSR(const_cast<HypreParMatrix&>(*pH),MATIS,
1015 PETSC_USE_POINTER,A);
1017 ierr = MatConvert_hypreParCSR_IS(const_cast<HypreParMatrix&>(*pH),A);
1023 #if defined(PETSC_HAVE_HYPRE)
1024 ierr = MatCreateFromParCSR(const_cast<HypreParMatrix&>(*pH),MATHYPRE,
1025 PETSC_USE_POINTER,A);
1028 MFEM_ABORT(
"Reconfigure PETSc with --download-hypre or --with-hypre")
1037 MFEM_ABORT(
"Conversion from HypreParCSR to operator type = " << tid <<
1038 " is not implemented");
1043 Mat *mats,*matsl2l = NULL;
1048 ierr = PetscCalloc1(nr*nc,&mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1051 ierr = PetscCalloc1(nr,&matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1053 for (i=0; i<nr; i++)
1055 PetscBool needl2l = PETSC_TRUE;
1057 for (j=0; j<nc; j++)
1065 ierr = PetscObjectQuery((
PetscObject)mats[i*nc+j],
"_MatIS_PtAP_l2l",
1067 PCHKERRQ(mats[i*nc+j],ierr);
1075 ierr = PetscContainerGetPointer(c,(
void**)&l2l);
1077 MFEM_VERIFY(l2l->
Size() == 1,
"Unexpected size "
1078 << l2l->
Size() <<
" for block row " << i );
1079 ierr = PetscObjectReference((
PetscObject)(*l2l)[0]);
1081 matsl2l[i] = (*l2l)[0];
1082 needl2l = PETSC_FALSE;
1088 ierr = MatCreateNest(comm,nr,NULL,nc,NULL,mats,A); CCHKERRQ(comm,ierr);
1091 ierr = MatConvert(*A,MATIS,MAT_INPLACE_MATRIX,A); CCHKERRQ(comm,ierr);
1094 for (
int i=0; i<(int)nr; i++) { (*vmatsl2l)[i] = matsl2l[i]; }
1095 ierr = PetscFree(matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1098 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
1099 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
1100 ierr = PetscContainerSetUserDestroy(c,__mfem_matarray_container_destroy);
1103 PCHKERRQ((*A),ierr);
1104 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
1106 for (i=0; i<nr*nc; i++) { ierr = MatDestroy(&mats[i]); CCHKERRQ(comm,ierr); }
1107 ierr = PetscFree(mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1113 ierr = MatCreate(comm,A); CCHKERRQ(comm,ierr);
1114 ierr = MatSetSizes(*A,pI->
Height(),pI->
Width(),PETSC_DECIDE,PETSC_DECIDE);
1116 ierr = MatSetType(*A,MATAIJ); PCHKERRQ(*A,ierr);
1117 ierr = MatMPIAIJSetPreallocation(*A,1,NULL,0,NULL); PCHKERRQ(*A,ierr);
1118 ierr = MatSeqAIJSetPreallocation(*A,1,NULL); PCHKERRQ(*A,ierr);
1119 ierr = MatSetOption(*A,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE); PCHKERRQ(*A,ierr);
1120 ierr = MatGetOwnershipRange(*A,&rst,NULL); PCHKERRQ(*A,ierr);
1123 ierr = MatSetValue(*A,i,i,1.,INSERT_VALUES); PCHKERRQ(*A,ierr);
1125 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*A,ierr);
1126 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*A,ierr);
1141 int n = pS->
Width();
1142 int *ii = pS->
GetI();
1143 int *jj = pS->
GetJ();
1147 ierr = PetscMalloc1(m+1,&pii); CCHKERRQ(comm,ierr);
1148 ierr = PetscMalloc1(ii[m],&pjj); CCHKERRQ(comm,ierr);
1149 ierr = PetscMalloc1(ii[m],&pdata); CCHKERRQ(comm,ierr);
1151 for (
int i = 0; i < m; i++)
1154 for (
int j = ii[i]; j < ii[i+1]; j++)
1161 ierr = PetscSortIntWithScalarArray(pii[i+1]-pii[i],pjj,pdata);
1162 CCHKERRQ(comm,ierr);
1166 ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,m,n,pii,pjj,pdata,&B);
1167 CCHKERRQ(comm,ierr);
1169 void *ptrs[3] = {pii,pjj,pdata};
1170 const char *names[3] = {
"_mfem_csr_pii",
1174 for (
int i=0; i<3; i++)
1178 ierr = PetscContainerCreate(PETSC_COMM_SELF,&c); PCHKERRQ(B,ierr);
1179 ierr = PetscContainerSetPointer(c,ptrs[i]); PCHKERRQ(B,ierr);
1180 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
1184 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
1192 ierr = MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,A); PCHKERRQ(B,ierr);
1193 ierr = MatDestroy(&B); PCHKERRQ(*A,ierr);
1197 ierr = MatConvert(B,MATIS,MAT_INITIAL_MATRIX,A); PCHKERRQ(B,ierr);
1198 ierr = MatDestroy(&B); PCHKERRQ(*A,ierr);
1202 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1209 "Supported types are ANY_TYPE, PETSC_MATSHELL or PETSC_MATAIJ");
1216 ierr = MatComputeOperator(*A,MATMPIAIJ,&B); CCHKERRQ(comm,ierr);
1217 ierr = PetscObjectTypeCompare((
PetscObject)B,MATMPIAIJ,&isaij);
1218 CCHKERRQ(comm,ierr);
1219 ierr = MatDestroy(A); CCHKERRQ(comm,ierr);
1222 ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,A); CCHKERRQ(comm,ierr);
1223 ierr = MatDestroy(&B); CCHKERRQ(comm,ierr);
1237 MPI_Comm comm = MPI_COMM_NULL;
1238 ierr = PetscObjectGetComm((
PetscObject)A,&comm); PCHKERRQ(A,ierr);
1239 ierr = MatDestroy(&A); CCHKERRQ(comm,ierr);
1250 ierr = PetscObjectReference((
PetscObject)a); PCHKERRQ(a,ierr);
1260 if (_A == A) {
return; }
1262 ierr = PetscObjectReference((
PetscObject)_A); PCHKERRQ(_A,ierr);
1277 f = MatMultTranspose;
1278 fadd = MatMultTransposeAdd;
1289 ierr = VecScale(X,a); PCHKERRQ(A,ierr);
1290 ierr = (*fadd)(A,X,Y,Y); PCHKERRQ(A,ierr);
1291 ierr = VecScale(X,1./a); PCHKERRQ(A,ierr);
1295 ierr = VecScale(X,a); PCHKERRQ(A,ierr);
1296 ierr = VecScale(Y,b); PCHKERRQ(A,ierr);
1297 ierr = (*fadd)(A,X,Y,Y); PCHKERRQ(A,ierr);
1298 ierr = VecScale(X,1./a); PCHKERRQ(A,ierr);
1302 ierr = (*f)(A,X,Y); PCHKERRQ(A,ierr);
1305 ierr = VecScale(Y,a); PCHKERRQ(A,ierr);
1317 ierr = VecScale(Y,b); PCHKERRQ(A,ierr);
1321 ierr = VecSet(Y,0.); PCHKERRQ(A,ierr);
1328 ierr = PetscObjectReference((
PetscObject)master.
A); PCHKERRQ(master.
A,ierr);
1340 MFEM_VERIFY(A,
"Mat not present");
1350 MFEM_VERIFY(A,
"Mat not present");
1361 ierr = MatCreateTranspose(A,&B); PCHKERRQ(A,ierr);
1365 ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B); PCHKERRQ(A,ierr);
1372 ierr = MatScale(A,s); PCHKERRQ(A,ierr);
1377 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1378 <<
", expected size = " <<
Width());
1379 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1380 <<
", expected size = " <<
Height());
1386 MatMultKernel(A,a,XX->x,b,YY->
x,
false);
1394 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
1395 <<
", expected size = " <<
Height());
1396 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
1397 <<
", expected size = " <<
Width());
1403 MatMultKernel(A,a,YY->
x,b,XX->x,
true);
1416 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)A),fname,
1417 FILE_MODE_WRITE,&view);
1421 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)A),fname,&view);
1424 ierr = MatView(A,view); PCHKERRQ(A,ierr);
1425 ierr = PetscViewerDestroy(&view); PCHKERRQ(A,ierr);
1429 ierr = MatView(A,NULL); PCHKERRQ(A,ierr);
1435 MFEM_ASSERT(s.
Size() ==
Height(),
"invalid s.Size() = " << s.
Size()
1436 <<
", expected size = " <<
Height());
1440 ierr = MatDiagonalScale(A,*YY,NULL); PCHKERRQ(A,ierr);
1446 MFEM_ASSERT(s.
Size() ==
Width(),
"invalid s.Size() = " << s.
Size()
1447 <<
", expected size = " <<
Width());
1451 ierr = MatDiagonalScale(A,NULL,*XX); PCHKERRQ(A,ierr);
1457 ierr = MatShift(A,(
PetscScalar)s); PCHKERRQ(A,ierr);
1463 MFEM_ASSERT(s.
Size() ==
Height(),
"invalid s.Size() = " << s.
Size()
1464 <<
", expected size = " <<
Height());
1465 MFEM_ASSERT(s.
Size() ==
Width(),
"invalid s.Size() = " << s.
Size()
1466 <<
", expected size = " <<
Width());
1470 ierr = MatDiagonalSet(A,*XX,ADD_VALUES); PCHKERRQ(A,ierr);
1476 Mat pA = *A,pP = *P,pRt = *Rt;
1478 PetscBool Aismatis,Pismatis,Rtismatis;
1481 "Petsc RAP: Number of local cols of A " << A->
Width() <<
1482 " differs from number of local rows of P " << P->
Height());
1484 "Petsc RAP: Number of local rows of A " << A->
Height() <<
1485 " differs from number of local rows of Rt " << Rt->
Height());
1486 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&Aismatis);
1488 ierr = PetscObjectTypeCompare((
PetscObject)pP,MATIS,&Pismatis);
1490 ierr = PetscObjectTypeCompare((
PetscObject)pRt,MATIS,&Rtismatis);
1497 ISLocalToGlobalMapping cl2gP,cl2gRt;
1498 PetscInt rlsize,clsize,rsize,csize;
1500 ierr = MatGetLocalToGlobalMapping(pP,NULL,&cl2gP); PCHKERRQ(pA,ierr);
1501 ierr = MatGetLocalToGlobalMapping(pRt,NULL,&cl2gRt); PCHKERRQ(pA,ierr);
1502 ierr = MatGetLocalSize(pP,NULL,&clsize); PCHKERRQ(pP,ierr);
1503 ierr = MatGetLocalSize(pRt,NULL,&rlsize); PCHKERRQ(pRt,ierr);
1504 ierr = MatGetSize(pP,NULL,&csize); PCHKERRQ(pP,ierr);
1505 ierr = MatGetSize(pRt,NULL,&rsize); PCHKERRQ(pRt,ierr);
1506 ierr = MatCreate(A->
GetComm(),&B); PCHKERRQ(pA,ierr);
1507 ierr = MatSetSizes(B,rlsize,clsize,rsize,csize); PCHKERRQ(B,ierr);
1508 ierr = MatSetType(B,MATIS); PCHKERRQ(B,ierr);
1509 ierr = MatSetLocalToGlobalMapping(B,cl2gRt,cl2gP); PCHKERRQ(B,ierr);
1510 ierr = MatISGetLocalMat(pA,&lA); PCHKERRQ(pA,ierr);
1511 ierr = MatISGetLocalMat(pP,&lP); PCHKERRQ(pA,ierr);
1512 ierr = MatISGetLocalMat(pRt,&lRt); PCHKERRQ(pA,ierr);
1515 ierr = MatPtAP(lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
1521 ierr = MatTranspose(lRt,MAT_INITIAL_MATRIX,&lR); PCHKERRQ(lRt,ierr);
1522 ierr = MatMatMatMult(lR,lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
1524 ierr = MatDestroy(&lR); PCHKERRQ(lRt,ierr);
1532 ierr = PetscObjectReference((
PetscObject)lRt); PCHKERRQ(lRt,ierr);
1533 (*vmatsl2l)[0] = lRt;
1536 ierr = PetscContainerCreate(PetscObjectComm((
PetscObject)B),&c);
1538 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
1539 ierr = PetscContainerSetUserDestroy(c,__mfem_matarray_container_destroy);
1543 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
1547 ierr = MatISSetLocalMat(B,lB); PCHKERRQ(lB,ierr);
1548 ierr = MatDestroy(&lB); PCHKERRQ(lA,ierr);
1549 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
1550 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
1556 ierr = MatPtAP(pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
1562 ierr = MatTranspose(pRt,MAT_INITIAL_MATRIX,&pR); PCHKERRQ(Rt,ierr);
1563 ierr = MatMatMatMult(pR,pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
1565 ierr = MatDestroy(&pR); PCHKERRQ(pRt,ierr);
1580 #if defined(PETSC_HAVE_HYPRE)
1595 ierr = MatMatMult(*A,*B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AB);
1605 ierr = MatDuplicate(A,MAT_COPY_VALUES,&Ae); PCHKERRQ(A,ierr);
1607 ierr = MatAXPY(Ae,-1.,A,SAME_NONZERO_PATTERN); PCHKERRQ(A,ierr);
1616 MFEM_ABORT(
"Missing PetscParMatrix::EliminateRowsCols() with HypreParVectors");
1625 ierr = MatGetSize(A,&M,&N); PCHKERRQ(A,ierr);
1626 MFEM_VERIFY(M == N,
"Rectangular case unsupported");
1629 ierr = MatSetOption(A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(A,ierr);
1633 ierr = MatGetOwnershipRange(A,&rst,NULL); PCHKERRQ(A,ierr);
1636 ierr = Convert_Array_IS(
GetComm(),
true,&rows_cols,rst,&dir); PCHKERRQ(A,ierr);
1639 ierr = MatZeroRowsColumnsIS(A,dir,diag,NULL,NULL); PCHKERRQ(A,ierr);
1643 ierr = MatZeroRowsColumnsIS(A,dir,diag,X,B); PCHKERRQ(A,ierr);
1645 ierr = ISDestroy(&dir); PCHKERRQ(A,ierr);
1650 ierr = MatSetOption(A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(A,ierr);
1654 ierr = MatGetOwnershipRange(A,&rst,NULL); PCHKERRQ(A,ierr);
1657 ierr = Convert_Array_IS(
GetComm(),
true,&rows,rst,&dir); PCHKERRQ(A,ierr);
1658 ierr = MatZeroRowsIS(A,dir,0.0,NULL,NULL); PCHKERRQ(A,ierr);
1659 ierr = ISDestroy(&dir); PCHKERRQ(A,ierr);
1669 ierr = PetscObjectDereference((
PetscObject)A); CCHKERRQ(comm,ierr);
1678 MFEM_VERIFY(A,
"no associated PETSc Mat object");
1681 ierr = PetscObjectTypeCompare(oA, MATAIJ, &ok); PCHKERRQ(A,ierr);
1683 ierr = PetscObjectTypeCompare(oA, MATSEQAIJ, &ok); PCHKERRQ(A,ierr);
1685 ierr = PetscObjectTypeCompare(oA, MATMPIAIJ, &ok); PCHKERRQ(A,ierr);
1687 ierr = PetscObjectTypeCompare(oA, MATIS, &ok); PCHKERRQ(A,ierr);
1689 ierr = PetscObjectTypeCompare(oA, MATSHELL, &ok); PCHKERRQ(A,ierr);
1691 ierr = PetscObjectTypeCompare(oA, MATNEST, &ok); PCHKERRQ(A,ierr);
1693 #if defined(PETSC_HAVE_HYPRE)
1694 ierr = PetscObjectTypeCompare(oA, MATHYPRE, &ok); PCHKERRQ(A,ierr);
1708 Ae.
Mult(-1.0, X, 1.0, B);
1711 ierr = MatGetDiagonal(pA,diag); PCHKERRQ(pA,ierr);
1712 ierr = VecGetArrayRead(diag,&array); PCHKERRQ(diag,ierr);
1713 for (
int i = 0; i < ess_dof_list.
Size(); i++)
1715 int r = ess_dof_list[i];
1716 B(r) = array[r] * X(r);
1718 ierr = VecRestoreArrayRead(diag,&array); PCHKERRQ(diag,ierr);
1747 if (
cid == KSP_CLASSID)
1750 ierr = KSPSetTolerances(ksp,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
1752 else if (
cid == SNES_CLASSID)
1755 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT,
1758 else if (
cid == TS_CLASSID)
1761 ierr = TSSetTolerances(ts,PETSC_DECIDE,NULL,tol,NULL);
1765 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
1772 if (
cid == KSP_CLASSID)
1775 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT);
1777 else if (
cid == SNES_CLASSID)
1780 ierr = SNESSetTolerances(snes,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
1783 else if (
cid == TS_CLASSID)
1786 ierr = TSSetTolerances(ts,tol,NULL,PETSC_DECIDE,NULL);
1790 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
1797 if (
cid == KSP_CLASSID)
1800 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
1803 else if (
cid == SNES_CLASSID)
1806 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
1807 max_iter,PETSC_DEFAULT);
1809 else if (
cid == TS_CLASSID)
1812 ierr = TSSetMaxSteps(ts,max_iter);
1816 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
1824 typedef PetscErrorCode (*myPetscFunc)(
void**);
1825 PetscViewerAndFormat *vf = NULL;
1826 PetscViewer viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm(
obj));
1830 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
1833 if (
cid == KSP_CLASSID)
1841 ierr = KSPMonitorCancel(ksp); PCHKERRQ(ksp,ierr);
1845 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorDefault,vf,
1846 (myPetscFunc)PetscViewerAndFormatDestroy);
1851 ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE); PCHKERRQ(ksp,ierr);
1852 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorSingularValue,vf,
1853 (myPetscFunc)PetscViewerAndFormatDestroy);
1857 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
1858 PCHKERRQ(viewer,ierr);
1859 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorTrueResidualNorm,vf,
1860 (myPetscFunc)PetscViewerAndFormatDestroy);
1865 else if (
cid == SNES_CLASSID)
1871 ierr = SNESMonitorCancel(snes); PCHKERRQ(snes,ierr);
1875 ierr = SNESMonitorSet(snes,(myMonitor)SNESMonitorDefault,vf,
1876 (myPetscFunc)PetscViewerAndFormatDestroy);
1877 PCHKERRQ(snes,ierr);
1880 else if (
cid == TS_CLASSID)
1885 ierr = TSMonitorCancel(ts); PCHKERRQ(ts,ierr);
1890 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
1896 return obj ? PetscObjectComm(
obj) : MPI_COMM_NULL;
1901 __mfem_monitor_ctx *monctx;
1902 ierr = PetscNew(&monctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
1903 monctx->solver =
this;
1904 monctx->monitor = ctx;
1905 if (
cid == KSP_CLASSID)
1907 ierr = KSPMonitorSet((
KSP)
obj,__mfem_ksp_monitor,monctx,
1908 __mfem_monitor_ctx_destroy);
1911 else if (
cid == SNES_CLASSID)
1913 ierr = SNESMonitorSet((
SNES)
obj,__mfem_snes_monitor,monctx,
1914 __mfem_monitor_ctx_destroy);
1917 else if (
cid == TS_CLASSID)
1919 ierr = TSMonitorSet((
TS)
obj,__mfem_ts_monitor,monctx,
1920 __mfem_monitor_ctx_destroy);
1925 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
1932 if (
cid == SNES_CLASSID)
1934 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
private_ctx;
1937 else if (
cid == TS_CLASSID)
1939 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
private_ctx;
1944 MFEM_ABORT(
"Handling of essential bc only implemented for nonlinear and time-dependent solvers");
1951 if (
cid == TS_CLASSID)
1956 ierr = TSGetSNES((
TS)
obj,&snes); PCHKERRQ(obj,ierr);
1957 ierr = SNESGetKSP(snes,&ksp); PCHKERRQ(obj,ierr);
1958 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(obj,ierr);
1960 else if (
cid == SNES_CLASSID)
1964 ierr = SNESGetKSP((
SNES)
obj,&ksp); PCHKERRQ(obj,ierr);
1965 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(obj,ierr);
1967 else if (
cid == KSP_CLASSID)
1969 ierr = KSPGetPC((
KSP)
obj,&pc); PCHKERRQ(obj,ierr);
1971 else if (
cid == PC_CLASSID)
1977 MFEM_ABORT(
"No support for PetscPreconditionerFactory for this object");
1981 ierr = MakeShellPCWithFactory(pc,factory); PCHKERRQ(pc,ierr);
1985 ierr = PCSetType(pc, PCNONE); PCHKERRQ(pc,ierr);
1991 if (!customize) {
clcustom =
true; }
1994 if (
cid == PC_CLASSID)
1997 ierr = PCSetFromOptions(pc); PCHKERRQ(pc, ierr);
1999 else if (
cid == KSP_CLASSID)
2002 ierr = KSPSetFromOptions(ksp); PCHKERRQ(ksp, ierr);
2004 else if (
cid == SNES_CLASSID)
2007 ierr = SNESSetFromOptions(snes); PCHKERRQ(snes, ierr);
2009 else if (
cid == TS_CLASSID)
2012 ierr = TSSetFromOptions(ts); PCHKERRQ(ts, ierr);
2016 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2024 if (
cid == KSP_CLASSID)
2027 KSPConvergedReason reason;
2028 ierr = KSPGetConvergedReason(ksp,&reason);
2030 return reason > 0 ? 1 : 0;
2032 else if (
cid == SNES_CLASSID)
2035 SNESConvergedReason reason;
2036 ierr = SNESGetConvergedReason(snes,&reason);
2037 PCHKERRQ(snes,ierr);
2038 return reason > 0 ? 1 : 0;
2040 else if (
cid == TS_CLASSID)
2043 TSConvergedReason reason;
2044 ierr = TSGetConvergedReason(ts,&reason);
2046 return reason > 0 ? 1 : 0;
2050 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2057 if (
cid == KSP_CLASSID)
2061 ierr = KSPGetIterationNumber(ksp,&its);
2065 else if (
cid == SNES_CLASSID)
2069 ierr = SNESGetIterationNumber(snes,&its);
2070 PCHKERRQ(snes,ierr);
2073 else if (
cid == TS_CLASSID)
2077 ierr = TSGetStepNumber(ts,&its);
2083 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2090 if (
cid == KSP_CLASSID)
2094 ierr = KSPGetResidualNorm(ksp,&norm);
2098 if (
cid == SNES_CLASSID)
2102 ierr = SNESGetFunctionNorm(snes,&norm);
2103 PCHKERRQ(snes,ierr);
2108 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2109 return PETSC_MAX_REAL;
2116 if (
cid == SNES_CLASSID)
2118 __mfem_snes_ctx *snes_ctx;
2119 ierr = PetscNew(&snes_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2120 snes_ctx->op = NULL;
2121 snes_ctx->bchandler = NULL;
2122 snes_ctx->work = NULL;
2126 else if (
cid == TS_CLASSID)
2128 __mfem_ts_ctx *ts_ctx;
2129 ierr = PetscNew(&ts_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2131 ts_ctx->bchandler = NULL;
2132 ts_ctx->work = NULL;
2133 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
2134 ts_ctx->cached_ijacstate = -1;
2135 ts_ctx->cached_rhsjacstate = -1;
2136 ts_ctx->cached_splits_xstate = -1;
2137 ts_ctx->cached_splits_xdotstate = -1;
2148 if (
cid == SNES_CLASSID)
2150 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx *)
private_ctx;
2151 delete snes_ctx->work;
2153 else if (
cid == TS_CLASSID)
2155 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx *)
private_ctx;
2156 delete ts_ctx->work;
2158 ierr = PetscFree(
private_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2165 : bctype(_type), setup(false), eval_t(0.0),
2166 eval_t_cached(std::numeric_limits<double>::min())
2174 ess_tdof_list.
Assign(list);
2180 if (setup) {
return; }
2184 this->
Eval(eval_t,eval_g);
2185 eval_t_cached = eval_t;
2196 (*this).SetUp(x.
Size());
2200 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2202 y[ess_tdof_list[i]] = 0.0;
2207 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2209 Eval(eval_t,eval_g);
2210 eval_t_cached = eval_t;
2212 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2214 y[ess_tdof_list[i]] = eval_g[ess_tdof_list[i]];
2221 (*this).SetUp(x.
Size());
2224 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2226 x[ess_tdof_list[i]] = 0.0;
2231 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2233 Eval(eval_t,eval_g);
2234 eval_t_cached = eval_t;
2236 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2238 x[ess_tdof_list[i]] = eval_g[ess_tdof_list[i]];
2245 (*this).SetUp(x.
Size());
2248 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2250 y[ess_tdof_list[i]] = x[ess_tdof_list[i]];
2255 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2257 y[ess_tdof_list[i]] = x[ess_tdof_list[i]] - eval_g[ess_tdof_list[i]];
2269 ierr = KSPCreate(comm,&ksp); CCHKERRQ(comm,ierr);
2271 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2272 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2276 const std::string &prefix)
2282 ierr = PetscObjectGetClassId(obj,&
cid); PCHKERRQ(obj,ierr);
2283 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2288 const std::string &prefix)
2294 ierr = PetscObjectGetClassId(obj, &
cid); PCHKERRQ(obj, ierr);
2295 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2310 ierr = KSPGetOperatorsSet(ksp,NULL,&pmat); PCHKERRQ(ksp,ierr);
2313 ierr = KSPGetOperators(ksp,NULL,&P); PCHKERRQ(ksp,ierr);
2314 ierr = PetscObjectReference((
PetscObject)P); PCHKERRQ(ksp,ierr);
2318 bool delete_pA =
false;
2336 MFEM_VERIFY(pA,
"Unsupported operation!");
2343 PetscInt nheight,nwidth,oheight,owidth;
2345 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
2346 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
2347 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
2348 if (nheight != oheight || nwidth != owidth)
2352 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
2361 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
2362 ierr = MatDestroy(&P); PCHKERRQ(ksp,ierr);
2366 ierr = KSPSetOperators(ksp,A,A); PCHKERRQ(ksp,ierr);
2376 if (delete_pA) {
delete pA; }
2391 bool delete_pA =
false;
2409 MFEM_VERIFY(pA,
"Unsupported operation!");
2412 bool delete_ppA =
false;
2415 if (oA == poA && !wrap)
2425 MFEM_VERIFY(ppA,
"Unsupported operation!");
2434 PetscInt nheight,nwidth,oheight,owidth;
2436 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
2437 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
2438 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
2439 if (nheight != oheight || nwidth != owidth)
2443 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
2450 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
2459 if (delete_pA) {
delete pA; }
2460 if (delete_ppA) {
delete ppA; }
2470 ierr = KSPGetOperatorsSet(ksp,&amat,NULL); PCHKERRQ(ksp,ierr);
2473 ierr = KSPGetOperators(ksp,&A,NULL); PCHKERRQ(ksp,ierr);
2474 ierr = PetscObjectReference((
PetscObject)A); PCHKERRQ(ksp,ierr);
2479 ierr = KSPSetPC(ksp,*ppc); PCHKERRQ(ksp,ierr);
2488 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(ksp,ierr);
2489 ierr = MakeShellPC(pc,precond,
false); PCHKERRQ(ksp,ierr);
2495 ierr = KSPGetOperators(ksp,NULL,&P); PCHKERRQ(ksp,ierr);
2496 ierr = PetscObjectReference((
PetscObject)P); PCHKERRQ(ksp,ierr);
2497 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
2498 ierr = MatDestroy(&A); PCHKERRQ(ksp,ierr);
2499 ierr = MatDestroy(&P); PCHKERRQ(ksp,ierr);
2510 ierr = KSPGetOperators(ksp, &pA, NULL); PCHKERRQ(
obj, ierr);
2527 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2528 PCHKERRQ(ksp, ierr);
2531 ierr = KSPSolve(ksp,
B->
x, X->x); PCHKERRQ(ksp,ierr);
2540 ierr = PetscObjectGetComm((
PetscObject)ksp,&comm); PCHKERRQ(ksp,ierr);
2541 ierr = KSPDestroy(&ksp); CCHKERRQ(comm,ierr);
2550 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
2552 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
2559 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
2561 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
2565 const std::string &prefix)
2569 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
2571 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
2577 const std::string &prefix)
2581 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
2583 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2584 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
2588 const string &prefix)
2594 ierr = PetscObjectGetClassId(obj,&
cid); PCHKERRQ(obj,ierr);
2595 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
2600 const string &prefix)
2604 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
2606 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2607 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
2613 bool delete_pA =
false;
2630 PetscInt nheight,nwidth,oheight,owidth;
2632 ierr = PCGetOperators(pc,&C,NULL); PCHKERRQ(pc,ierr);
2633 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
2634 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
2635 if (nheight != oheight || nwidth != owidth)
2639 ierr = PCReset(pc); PCHKERRQ(pc,ierr);
2645 ierr = PCSetOperators(pc,pA->
A,pA->
A); PCHKERRQ(
obj,ierr);
2654 if (delete_pA) {
delete pA; };
2664 ierr = PCGetOperators(pc, NULL, &pA); PCHKERRQ(
obj, ierr);
2682 ierr = PCApply(pc,
B->
x, X->x); PCHKERRQ(pc, ierr);
2691 ierr = PetscObjectGetComm((
PetscObject)pc,&comm); PCHKERRQ(pc,ierr);
2692 ierr = PCDestroy(&pc); CCHKERRQ(comm,ierr);
2700 for (
int i = 0; i < x.
Size(); i++) { y(i) = x(i); }
2703 void PetscBDDCSolver::BDDCSolverConstructor(
const PetscBDDCSolverParams &opts)
2705 MPI_Comm comm = PetscObjectComm(
obj);
2710 ierr = PCGetOperators(pc,NULL,&pA); PCHKERRQ(pc,ierr);
2714 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&ismatis);
2716 MFEM_VERIFY(ismatis,
"PetscBDDCSolver needs the matrix in unassembled format");
2719 ParFiniteElementSpace *fespace = opts.fespace;
2720 if (opts.netflux && !fespace)
2722 MFEM_WARNING(
"Don't know how to compute an auxiliary quadrature form without a ParFiniteElementSpace");
2729 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(comm,ierr);
2730 ierr = MatNullSpaceCreate(PetscObjectComm((
PetscObject)lA),PETSC_TRUE,0,NULL,
2731 &nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
2732 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
2733 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
2737 ierr = PCSetType(pc,PCBDDC); PCHKERRQ(
obj,ierr);
2740 ierr = MatGetOwnershipRange(pA,&rst,NULL); PCHKERRQ(pA,ierr);
2741 ierr = MatGetLocalSize(pA,&nl,NULL); PCHKERRQ(pA,ierr);
2750 int vdim = fespace->GetVDim();
2757 ierr = MatSetBlockSize(pA,vdim); PCHKERRQ(pA,ierr);
2758 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(PETSC_COMM_SELF,ierr);
2759 ierr = MatSetBlockSize(lA,vdim); PCHKERRQ(pA,ierr);
2768 ierr = PetscMalloc1(nf,&fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
2781 ierr = ISCreateStride(comm,nlf,st,bs,&fields[i]); CCHKERRQ(comm,ierr);
2787 const FiniteElementCollection *fec = fespace->FEColl();
2788 bool h1space =
dynamic_cast<const H1_FECollection*
>(fec);
2791 ParFiniteElementSpace *fespace_coords = fespace;
2793 sdim = fespace->GetParMesh()->SpaceDimension();
2796 fespace_coords =
new ParFiniteElementSpace(fespace->GetParMesh(),fec,sdim,
2799 VectorFunctionCoefficient coeff_coords(sdim, func_coords);
2800 ParGridFunction gf_coords(fespace_coords);
2801 gf_coords.ProjectCoefficient(coeff_coords);
2802 HypreParVector *hvec_coords = gf_coords.ParallelProject();
2809 Vec pvec_coords,lvec_coords;
2810 ISLocalToGlobalMapping l2g;
2816 ierr = VecCreateMPIWithArray(comm,sdim,hvec_coords->Size(),
2817 hvec_coords->GlobalSize(),hvec_coords->GetData(),&pvec_coords);
2818 CCHKERRQ(comm,ierr);
2819 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(PETSC_COMM_SELF,ierr);
2820 ierr = MatCreateVecs(lA,&lvec_coords,NULL); CCHKERRQ(PETSC_COMM_SELF,ierr);
2821 ierr = VecSetBlockSize(lvec_coords,sdim); CCHKERRQ(PETSC_COMM_SELF,ierr);
2822 ierr = MatGetLocalToGlobalMapping(pA,&l2g,NULL); CCHKERRQ(comm,ierr);
2823 ierr = MatGetLayouts(pA,&rmap,NULL); CCHKERRQ(comm,ierr);
2824 ierr = PetscSFCreate(comm,&sf); CCHKERRQ(comm,ierr);
2825 ierr = ISLocalToGlobalMappingGetIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
2826 ierr = ISLocalToGlobalMappingGetSize(l2g,&nleaves); CCHKERRQ(comm,ierr);
2827 ierr = PetscSFSetGraphLayout(sf,rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);
2828 CCHKERRQ(comm,ierr);
2829 ierr = ISLocalToGlobalMappingRestoreIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
2834 ierr = VecGetArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
2835 ierr = VecGetArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
2836 ierr = PetscSFBcastBegin(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
2837 ierr = PetscSFBcastEnd(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
2838 ierr = VecRestoreArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
2839 ierr = VecRestoreArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
2841 ierr = VecDestroy(&pvec_coords); CCHKERRQ(comm,ierr);
2842 ierr = MatNullSpaceCreateRigidBody(lvec_coords,&nnsp);
2843 CCHKERRQ(PETSC_COMM_SELF,ierr);
2844 ierr = VecDestroy(&lvec_coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
2845 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
2846 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
2847 ierr = PetscSFDestroy(&sf); CCHKERRQ(PETSC_COMM_SELF,ierr);
2851 ierr = PetscMalloc1(nl*sdim,&coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
2861 ierr = ISGetLocalSize(fields[i],&nn); CCHKERRQ(comm,ierr);
2862 ierr = ISGetIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
2866 for (
PetscInt d = 0; d < sdim; d++)
2868 coords[sdim*idx+d] = data[sdim*j+d];
2871 ierr = ISRestoreIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
2876 ierr = PetscMemcpy(coords,hvec_coords->GetData(),nl*sdim*
sizeof(
PetscReal));
2877 CCHKERRQ(comm,ierr);
2879 if (fespace_coords != fespace)
2881 delete fespace_coords;
2888 IS dir = NULL, neu = NULL;
2891 Array<Mat> *l2l = NULL;
2892 if (opts.ess_dof_local || opts.nat_dof_local)
2897 MFEM_VERIFY(c,
"Local-to-local PETSc container not present");
2898 ierr = PetscContainerGetPointer(c,(
void**)&l2l); PCHKERRQ(c,ierr);
2905 PetscBool lpr = PETSC_FALSE,pr;
2906 if (opts.ess_dof) { lpr = PETSC_TRUE; }
2907 ierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
2909 MFEM_VERIFY(lpr == pr,
"ess_dof should be collectively set");
2911 if (opts.nat_dof) { lpr = PETSC_TRUE; }
2912 ierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
2914 MFEM_VERIFY(lpr == pr,
"nat_dof should be collectively set");
2917 ms[0] = -nf; ms[1] = nf;
2918 ierr = MPI_Allreduce(&ms,&Ms,2,MPIU_INT,MPI_MAX,comm);
2920 MFEM_VERIFY(-Ms[0] == Ms[1],
2921 "number of fields should be the same across processes");
2928 PetscInt st = opts.ess_dof_local ? 0 : rst;
2929 if (!opts.ess_dof_local)
2932 ierr = Convert_Array_IS(comm,
true,opts.ess_dof,st,&dir);
2933 CCHKERRQ(comm,ierr);
2934 ierr = PCBDDCSetDirichletBoundaries(pc,dir); PCHKERRQ(pc,ierr);
2939 ierr = Convert_Vmarks_IS(comm,*l2l,opts.ess_dof,st,&dir);
2940 CCHKERRQ(comm,ierr);
2941 ierr = PCBDDCSetDirichletBoundariesLocal(pc,dir); PCHKERRQ(pc,ierr);
2946 PetscInt st = opts.nat_dof_local ? 0 : rst;
2947 if (!opts.nat_dof_local)
2950 ierr = Convert_Array_IS(comm,
true,opts.nat_dof,st,&neu);
2951 CCHKERRQ(comm,ierr);
2952 ierr = PCBDDCSetNeumannBoundaries(pc,neu); PCHKERRQ(pc,ierr);
2957 ierr = Convert_Vmarks_IS(comm,*l2l,opts.nat_dof,st,&neu);
2958 CCHKERRQ(comm,ierr);
2959 ierr = PCBDDCSetNeumannBoundariesLocal(pc,neu); PCHKERRQ(pc,ierr);
2966 ierr = PCBDDCSetDofsSplitting(pc,nf,fields); PCHKERRQ(pc,ierr);
2970 ierr = ISDestroy(&fields[i]); CCHKERRQ(comm,ierr);
2972 ierr = PetscFree(fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
2977 ierr = PCSetCoordinates(pc,sdim,nl,coords); PCHKERRQ(pc,ierr);
2979 ierr = PetscFree(coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
2988 const FiniteElementCollection *fec = fespace->FEColl();
2989 bool edgespace, rtspace, h1space;
2990 bool needint = opts.netflux;
2991 bool tracespace, rt_tracespace, edge_tracespace;
2993 PetscBool B_is_Trans = PETSC_FALSE;
2995 ParMesh *pmesh = (ParMesh *) fespace->GetMesh();
2996 dim = pmesh->Dimension();
2997 vdim = fespace->GetVDim();
2998 h1space =
dynamic_cast<const H1_FECollection*
>(fec);
2999 rtspace =
dynamic_cast<const RT_FECollection*
>(fec);
3000 edgespace =
dynamic_cast<const ND_FECollection*
>(fec);
3001 edge_tracespace =
dynamic_cast<const ND_Trace_FECollection*
>(fec);
3002 rt_tracespace =
dynamic_cast<const RT_Trace_FECollection*
>(fec);
3003 tracespace = edge_tracespace || rt_tracespace;
3006 if (fespace->GetNE() > 0)
3010 p = fespace->GetOrder(0);
3014 p = fespace->GetFaceOrder(0);
3015 if (dim == 2) { p++; }
3026 MFEM_WARNING(
"Tracespace case doesn't work for H(curl) and p=2,"
3027 " not using auxiliary quadrature");
3033 FiniteElementCollection *vfec;
3036 vfec =
new H1_Trace_FECollection(p,dim);
3040 vfec =
new H1_FECollection(p,dim);
3042 ParFiniteElementSpace *vfespace =
new ParFiniteElementSpace(pmesh,vfec);
3043 ParDiscreteLinearOperator *grad;
3044 grad =
new ParDiscreteLinearOperator(vfespace,fespace);
3047 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3051 grad->AddDomainInterpolator(
new GradientInterpolator);
3055 HypreParMatrix *hG = grad->ParallelAssemble();
3056 PetscParMatrix *G =
new PetscParMatrix(hG,
PETSC_MATAIJ);
3060 PetscBool conforming = PETSC_TRUE;
3061 if (pmesh->Nonconforming()) { conforming = PETSC_FALSE; }
3062 ierr = PCBDDCSetDiscreteGradient(pc,*G,p,0,PETSC_TRUE,conforming);
3074 MFEM_WARNING(
"Tracespace case doesn't work for H(div), not using"
3075 " auxiliary quadrature");
3081 if (vdim != dim) { needint =
false; }
3084 PetscParMatrix *
B = NULL;
3090 FiniteElementCollection *auxcoll;
3091 if (tracespace) { auxcoll =
new RT_Trace_FECollection(p,dim); }
3096 auxcoll =
new H1_FECollection(std::max(p-1,1),dim);
3100 auxcoll =
new L2_FECollection(p,dim);
3103 ParFiniteElementSpace *pspace =
new ParFiniteElementSpace(pmesh,auxcoll);
3104 ParMixedBilinearForm *b =
new ParMixedBilinearForm(fespace,pspace);
3110 b->AddTraceFaceIntegrator(
new VectorFECurlIntegrator);
3114 b->AddDomainIntegrator(
new VectorFECurlIntegrator);
3121 b->AddTraceFaceIntegrator(
new VectorFEDivergenceIntegrator);
3125 b->AddDomainIntegrator(
new VectorFEDivergenceIntegrator);
3130 b->AddDomainIntegrator(
new VectorDivergenceIntegrator);
3135 b->ParallelAssemble(Bh);
3137 Bh.SetOperatorOwner(
false);
3142 ierr = MatTranspose(pB,MAT_INPLACE_MATRIX,&pB); PCHKERRQ(pA,ierr);
3143 if (!opts.ess_dof_local)
3145 ierr = MatZeroRowsIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3149 ierr = MatZeroRowsLocalIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3151 B_is_Trans = PETSC_TRUE;
3160 ierr = PCBDDCSetDivergenceMat(pc,*B,B_is_Trans,NULL); PCHKERRQ(pc,ierr);
3164 ierr = ISDestroy(&dir); PCHKERRQ(pc,ierr);
3165 ierr = ISDestroy(&neu); PCHKERRQ(pc,ierr);
3170 const std::string &prefix)
3173 BDDCSolverConstructor(opts);
3179 const std::string &prefix)
3182 BDDCSolverConstructor(opts);
3187 const string &prefix)
3193 ierr = PCGetOperators(pc,&pA,NULL); PCHKERRQ(pc,ierr);
3198 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATNEST,&isnest);
3201 "PetscFieldSplitSolver needs the matrix in nested format.");
3205 ierr = PCSetType(pc,PCFIELDSPLIT); PCHKERRQ(pc,ierr);
3206 ierr = MatNestGetSize(pA,&nr,NULL); PCHKERRQ(pc,ierr);
3207 ierr = PetscCalloc1(nr,&isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3208 ierr = MatNestGetISs(pA,isrow,NULL); PCHKERRQ(pc,ierr);
3215 ierr = PCFieldSplitSetIS(pc,NULL,isrow[i]); PCHKERRQ(pc,ierr);
3217 ierr = PetscFree(isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3223 const std::string &prefix)
3228 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3230 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3231 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
3238 const std::string &prefix)
3243 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3245 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3246 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
3258 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj, ierr);
3259 ierr = SNESDestroy(&snes); CCHKERRQ(comm, ierr);
3271 ierr = SNESGetFunction(snes, NULL, NULL, &fctx);
3272 PCHKERRQ(snes, ierr);
3273 ierr = SNESGetJacobian(snes, NULL, NULL, NULL, &jctx);
3274 PCHKERRQ(snes, ierr);
3277 (
void*)&op == fctx &&
3278 (
void*)&op == jctx);
3279 ierr = MPI_Allreduce(&ls,&gs,1,MPIU_BOOL,MPI_LAND,
3281 PCHKERRQ(snes,ierr);
3284 ierr = SNESReset(snes); PCHKERRQ(snes,ierr);
3295 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
3296 ierr = SNESLineSearchSetType(ls, SNESLINESEARCHBT); PCHKERRQ(snes,ierr);
3299 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
3301 ierr = SNESSetFunction(snes, NULL, __mfem_snes_function, (
void *)snes_ctx);
3302 PCHKERRQ(snes, ierr);
3303 ierr = SNESSetJacobian(snes, NULL, NULL, __mfem_snes_jacobian,
3305 PCHKERRQ(snes, ierr);
3317 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
3318 snes_ctx->jacType = jacType;
3324 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
3325 snes_ctx->objective = objfn;
3328 ierr = SNESSetObjective(snes, __mfem_snes_objective, (
void *)snes_ctx);
3329 PCHKERRQ(snes, ierr);
3336 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
3337 snes_ctx->postcheck = post;
3341 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
3342 ierr = SNESLineSearchSetPostCheck(ls, __mfem_snes_postcheck, (
void *)snes_ctx);
3352 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
3353 snes_ctx->update = update;
3356 ierr = SNESSetUpdate(snes, __mfem_snes_update); PCHKERRQ(snes, ierr);
3363 bool b_nonempty = b.
Size();
3367 if (b_nonempty) { B->PlaceArray(b.
GetData()); }
3375 ierr = SNESSolve(snes, B->x, X->x); PCHKERRQ(snes, ierr);
3377 if (b_nonempty) { B->ResetArray(); }
3387 ierr = TSCreate(comm,&ts); CCHKERRQ(comm,ierr);
3389 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3390 ierr = TSSetOptionsPrefix(ts, prefix.c_str()); PCHKERRQ(ts, ierr);
3396 ierr = TSSetMaxSteps(ts,PETSC_MAX_INT-1);
3398 ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
3401 ierr = TSGetAdapt(ts,&tsad);
3403 ierr = TSAdaptSetType(tsad,TSADAPTNONE);
3411 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj,ierr);
3412 ierr = TSDestroy(&ts); CCHKERRQ(comm,ierr);
3420 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
3423 ierr = TSReset(ts); PCHKERRQ(ts,ierr);
3426 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
3427 ts_ctx->cached_ijacstate = -1;
3428 ts_ctx->cached_rhsjacstate = -1;
3429 ts_ctx->cached_splits_xstate = -1;
3430 ts_ctx->cached_splits_xdotstate = -1;
3438 ierr = TSSetIFunction(ts, NULL, __mfem_ts_ifunction, (
void *)ts_ctx);
3440 ierr = TSSetIJacobian(ts, NULL, NULL, __mfem_ts_ijacobian, (
void *)ts_ctx);
3442 ierr = TSSetEquationType(ts, TS_EQ_IMPLICIT);
3449 ierr = TSSetEquationType(ts, TS_EQ_EXPLICIT);
3452 ierr = TSSetRHSFunction(ts, NULL, __mfem_ts_rhsfunction, (
void *)ts_ctx);
3454 ierr = TSSetRHSJacobian(ts, NULL, NULL, __mfem_ts_rhsjacobian, (
void *)ts_ctx);
3463 ierr = TSSetSolution(ts,X); PCHKERRQ(ts,ierr);
3466 PetscBool use = PETSC_TRUE;
3467 ierr = PetscOptionsGetBool(NULL,NULL,
"-mfem_use_splitjac",&use,NULL);
3470 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
3471 __mfem_ts_computesplits);
3476 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
3484 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
3485 ts_ctx->jacType = jacType;
3490 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
3491 return ts_ctx->type;
3496 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
3499 ts_ctx->type = type;
3502 ierr = TSSetProblemType(ts, TS_LINEAR);
3507 ierr = TSSetProblemType(ts, TS_NONLINEAR);
3516 ierr = TSSetTime(ts, t); PCHKERRQ(ts, ierr);
3517 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
3525 ierr = TSSetSolution(ts, *X); PCHKERRQ(ts, ierr);
3526 ierr = TSStep(ts); PCHKERRQ(ts, ierr);
3532 ierr = TSGetTime(ts,&pt); PCHKERRQ(ts,ierr);
3541 ierr = TSSetTime(ts, t); PCHKERRQ(ts, ierr);
3542 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
3543 ierr = TSSetMaxTime(ts, t_final); PCHKERRQ(ts, ierr);
3544 ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
3556 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
3557 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
3558 ts_ctx->cached_ijacstate = -1;
3559 ts_ctx->cached_rhsjacstate = -1;
3560 ts_ctx->cached_splits_xstate = -1;
3561 ts_ctx->cached_splits_xdotstate = -1;
3564 ierr = TSSolve(ts, X->x); PCHKERRQ(ts, ierr);
3569 ierr = TSGetTime(ts, &pt); PCHKERRQ(ts,ierr);
3571 ierr = TSGetTimeStep(ts,&pt); PCHKERRQ(ts,ierr);
3577 #include "petsc/private/petscimpl.h"
3583 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)ctx;
3585 PetscFunctionBeginUser;
3588 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
3600 PetscFunctionReturn(0);
3603 static PetscErrorCode __mfem_ts_ifunction(
TS ts,
PetscReal t, Vec x, Vec xp,
3606 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)ctx;
3607 PetscErrorCode ierr;
3609 PetscFunctionBeginUser;
3617 if (ts_ctx->bchandler)
3620 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(xx.Size()); }
3636 ierr = PetscObjectStateIncrease((
PetscObject)f); CHKERRQ(ierr);
3637 PetscFunctionReturn(0);
3640 static PetscErrorCode __mfem_ts_rhsfunction(
TS ts,
PetscReal t, Vec x, Vec f,
3643 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)ctx;
3644 PetscErrorCode ierr;
3646 PetscFunctionBeginUser;
3647 if (ts_ctx->bchandler) { MFEM_ABORT(
"RHS evaluation with bc not implemented"); }
3657 ierr = PetscObjectStateIncrease((
PetscObject)f); CHKERRQ(ierr);
3658 PetscFunctionReturn(0);
3661 static PetscErrorCode __mfem_ts_ijacobian(
TS ts,
PetscReal t, Vec x,
3665 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)ctx;
3670 PetscObjectState state;
3671 PetscErrorCode ierr;
3673 PetscFunctionBeginUser;
3677 ierr = PetscObjectStateGet((
PetscObject)A,&state); CHKERRQ(ierr);
3679 std::abs(ts_ctx->cached_shift/shift - 1.0) < eps &&
3680 state == ts_ctx->cached_ijacstate) { PetscFunctionReturn(0); }
3687 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
3688 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
3690 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
3691 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3692 if (!ts_ctx->bchandler)
3699 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
3706 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3710 if (!ts_ctx->bchandler) {
delete xx; }
3711 ts_ctx->cached_shift = shift;
3714 bool delete_pA =
false;
3718 pA->
GetType() != ts_ctx->jacType))
3726 if (ts_ctx->bchandler)
3736 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
3737 if (delete_pA) {
delete pA; }
3740 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3741 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3745 ierr = PetscObjectStateGet((
PetscObject)P,&ts_ctx->cached_ijacstate);
3747 PetscFunctionReturn(0);
3750 static PetscErrorCode __mfem_ts_computesplits(
TS ts,
PetscReal t,Vec x,Vec xp,
3754 __mfem_ts_ctx* ts_ctx;
3758 PetscObjectState state;
3759 PetscBool rx = PETSC_TRUE, rxp = PETSC_TRUE;
3760 PetscBool assembled;
3761 PetscErrorCode ierr;
3763 PetscFunctionBeginUser;
3764 ierr = TSGetIJacobian(ts,NULL,NULL,NULL,(
void**)&ts_ctx); CHKERRQ(ierr);
3767 ierr = PetscObjectStateGet((
PetscObject)Jx,&state); CHKERRQ(ierr);
3769 state == ts_ctx->cached_splits_xstate) { rx = PETSC_FALSE; }
3770 ierr = PetscObjectStateGet((
PetscObject)Jxp,&state); CHKERRQ(ierr);
3772 state == ts_ctx->cached_splits_xdotstate) { rxp = PETSC_FALSE; }
3774 if (!rx && !rxp) { PetscFunctionReturn(0); }
3781 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
3782 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
3784 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
3785 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3786 if (!ts_ctx->bchandler)
3793 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
3800 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3809 bool delete_mat =
false;
3813 pJx->
GetType() != ts_ctx->jacType))
3818 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
3826 ierr = MatAssembled(Jx,&assembled); CHKERRQ(ierr);
3829 ierr = MatCopy(*pJx,Jx,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
3834 ierr = MatDuplicate(*pJx,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
3835 ierr = MatHeaderReplace(Jx,&B); CHKERRQ(ierr);
3838 if (delete_mat) {
delete pJx; }
3842 if (ts_ctx->bchandler)
3859 pJxp->
GetType() != ts_ctx->jacType))
3864 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
3867 &oJxp,ts_ctx->jacType);
3871 ierr = MatAssembled(Jxp,&assembled); CHKERRQ(ierr);
3874 ierr = MatCopy(*pJxp,Jxp,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
3879 ierr = MatDuplicate(*pJxp,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
3880 ierr = MatHeaderReplace(Jxp,&B); CHKERRQ(ierr);
3882 if (delete_mat) {
delete pJxp; }
3886 if (ts_ctx->bchandler)
3897 ierr = MatAXPY(*pJxp,-1.0,*pJx,SAME_NONZERO_PATTERN); PCHKERRQ(ts,ierr);
3902 ierr = MatAssemblyBegin(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3903 ierr = MatAssemblyEnd(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3905 if (Axp && Axp != Jxp)
3907 ierr = MatAssemblyBegin(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3908 ierr = MatAssemblyEnd(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3912 ierr = PetscObjectStateGet((
PetscObject)Jx,&ts_ctx->cached_splits_xstate);
3914 ierr = PetscObjectStateGet((
PetscObject)Jxp,&ts_ctx->cached_splits_xdotstate);
3919 if (!ts_ctx->bchandler) {
delete xx; }
3920 PetscFunctionReturn(0);
3923 static PetscErrorCode __mfem_ts_rhsjacobian(
TS ts,
PetscReal t, Vec x,
3926 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)ctx;
3930 PetscObjectState state;
3931 PetscErrorCode ierr;
3933 PetscFunctionBeginUser;
3935 ierr = PetscObjectStateGet((
PetscObject)A,&state); CHKERRQ(ierr);
3937 state == ts_ctx->cached_rhsjacstate) { PetscFunctionReturn(0); }
3944 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
3945 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3946 if (!ts_ctx->bchandler)
3953 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
3960 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
3964 if (!ts_ctx->bchandler) {
delete xx; }
3967 bool delete_pA =
false;
3971 pA->
GetType() != ts_ctx->jacType))
3979 if (ts_ctx->bchandler)
3989 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
3990 if (delete_pA) {
delete pA; }
3994 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
3995 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4001 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE); PCHKERRQ(ts,ierr);
4003 ierr = PetscObjectStateGet((
PetscObject)A,&ts_ctx->cached_rhsjacstate);
4005 PetscFunctionReturn(0);
4011 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)ctx;
4013 PetscFunctionBeginUser;
4016 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4025 PetscErrorCode ierr;
4027 ierr = SNESGetSolution(snes,&x); CHKERRQ(ierr);
4034 PetscErrorCode ierr;
4036 ierr = SNESGetFunction(snes,&x,NULL,NULL); CHKERRQ(ierr);
4041 PetscFunctionReturn(0);
4044 static PetscErrorCode __mfem_snes_jacobian(
SNES snes, Vec x,
Mat A,
Mat P,
4049 PetscErrorCode ierr;
4051 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)ctx;
4053 PetscFunctionBeginUser;
4054 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4055 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4056 if (!snes_ctx->bchandler)
4063 if (!snes_ctx->work) { snes_ctx->work =
new mfem::Vector(n); }
4066 xx = snes_ctx->work;
4072 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4073 if (!snes_ctx->bchandler) {
delete xx; }
4076 bool delete_pA =
false;
4080 pA->
GetType() != snes_ctx->jacType))
4088 if (snes_ctx->bchandler)
4097 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4098 if (delete_pA) {
delete pA; }
4101 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4102 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4104 PetscFunctionReturn(0);
4107 static PetscErrorCode __mfem_snes_function(
SNES snes, Vec x, Vec f,
void *ctx)
4109 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)ctx;
4111 PetscFunctionBeginUser;
4114 if (snes_ctx->bchandler)
4121 snes_ctx->op->Mult(*txx,ff);
4128 snes_ctx->op->Mult(xx,ff);
4131 ierr = PetscObjectStateIncrease((
PetscObject)f); CHKERRQ(ierr);
4132 PetscFunctionReturn(0);
4135 static PetscErrorCode __mfem_snes_objective(
SNES snes, Vec x,
PetscReal *f,
4138 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)ctx;
4140 PetscFunctionBeginUser;
4141 if (!snes_ctx->objective)
4143 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing objective function");
4147 (*snes_ctx->objective)(snes_ctx->op,xx,&lf);
4149 PetscFunctionReturn(0);
4152 static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch ls,Vec X,Vec Y,Vec W,
4153 PetscBool *cy,PetscBool *cw,
void* ctx)
4155 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)ctx;
4156 bool lcy =
false,lcw =
false;
4158 PetscFunctionBeginUser;
4162 (*snes_ctx->postcheck)(snes_ctx->op,x,y,w,lcy,lcw);
4163 if (lcy) { *cy = PETSC_TRUE; }
4164 if (lcw) { *cw = PETSC_TRUE; }
4165 PetscFunctionReturn(0);
4168 static PetscErrorCode __mfem_snes_update(
SNES snes,
PetscInt it)
4171 __mfem_snes_ctx* snes_ctx;
4173 PetscFunctionBeginUser;
4175 ierr = SNESGetFunction(snes,&F,NULL,(
void **)&snes_ctx); CHKERRQ(ierr);
4176 ierr = SNESGetSolution(snes,&X); CHKERRQ(ierr);
4179 ierr = VecDuplicate(X,&pX); CHKERRQ(ierr);
4182 ierr = VecDestroy(&pX); CHKERRQ(ierr);
4186 if (!pX) SETERRQ(PetscObjectComm((
PetscObject)snes),PETSC_ERR_USER,
4187 "Missing previous solution");
4188 ierr = SNESGetSolutionUpdate(snes,&dX); CHKERRQ(ierr);
4193 (*snes_ctx->update)(snes_ctx->op,it,f,x,dx,px);
4195 ierr = VecCopy(X,pX); CHKERRQ(ierr);
4196 PetscFunctionReturn(0);
4202 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)ctx;
4204 PetscFunctionBeginUser;
4207 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4216 PetscErrorCode ierr;
4218 ierr = KSPBuildSolution(ksp,NULL,&x); CHKERRQ(ierr);
4225 PetscErrorCode ierr;
4227 ierr = KSPBuildResidual(ksp,NULL,NULL,&x); CHKERRQ(ierr);
4232 PetscFunctionReturn(0);
4235 static PetscErrorCode __mfem_mat_shell_apply(
Mat A, Vec x, Vec y)
4237 __mfem_mat_shell_ctx *ctx;
4238 PetscErrorCode ierr;
4240 PetscFunctionBeginUser;
4241 ierr = MatShellGetContext(A,(
void **)&ctx); CHKERRQ(ierr);
4244 ctx->op->Mult(xx,yy);
4246 ierr = PetscObjectStateIncrease((
PetscObject)y); CHKERRQ(ierr);
4247 PetscFunctionReturn(0);
4250 static PetscErrorCode __mfem_mat_shell_apply_transpose(
Mat A, Vec x, Vec y)
4252 __mfem_mat_shell_ctx *ctx;
4253 PetscErrorCode ierr;
4255 PetscFunctionBeginUser;
4256 ierr = MatShellGetContext(A,(
void **)&ctx); CHKERRQ(ierr);
4259 ctx->op->MultTranspose(xx,yy);
4261 ierr = PetscObjectStateIncrease((
PetscObject)y); CHKERRQ(ierr);
4262 PetscFunctionReturn(0);
4265 static PetscErrorCode __mfem_mat_shell_destroy(
Mat A)
4267 __mfem_mat_shell_ctx *ctx;
4268 PetscErrorCode ierr;
4270 PetscFunctionBeginUser;
4271 ierr = MatShellGetContext(A,(
void **)&ctx); CHKERRQ(ierr);
4273 PetscFunctionReturn(0);
4276 static PetscErrorCode __mfem_pc_shell_view(
PC pc, PetscViewer viewer)
4278 __mfem_pc_shell_ctx *ctx;
4279 PetscErrorCode ierr;
4281 PetscFunctionBeginUser;
4282 ierr = PCShellGetContext(pc,(
void **)&ctx); CHKERRQ(ierr);
4286 ierr = PetscObjectTypeCompare((
PetscObject)viewer,PETSCVIEWERASCII,&isascii);
4293 ierr = PCView(*ppc,viewer); CHKERRQ(ierr);
4299 ierr = PetscViewerASCIIPrintf(viewer,
4300 "No information available on the mfem::Solver\n");
4304 if (isascii && ctx->factory)
4306 ierr = PetscViewerASCIIPrintf(viewer,
4307 "Number of preconditioners created by the factory %lu\n",ctx->numprec);
4311 PetscFunctionReturn(0);
4314 static PetscErrorCode __mfem_pc_shell_apply(
PC pc, Vec x, Vec y)
4316 __mfem_pc_shell_ctx *ctx;
4317 PetscErrorCode ierr;
4319 PetscFunctionBeginUser;
4322 ierr = PCShellGetContext(pc,(
void **)&ctx); CHKERRQ(ierr);
4325 ctx->op->Mult(xx,yy);
4327 ierr = PetscObjectStateIncrease((
PetscObject)y); CHKERRQ(ierr);
4333 PetscFunctionReturn(0);
4336 static PetscErrorCode __mfem_pc_shell_apply_transpose(
PC pc, Vec x, Vec y)
4338 __mfem_pc_shell_ctx *ctx;
4339 PetscErrorCode ierr;
4341 PetscFunctionBeginUser;
4344 ierr = PCShellGetContext(pc,(
void **)&ctx); CHKERRQ(ierr);
4347 ctx->op->MultTranspose(xx,yy);
4349 ierr = PetscObjectStateIncrease((
PetscObject)y); CHKERRQ(ierr);
4355 PetscFunctionReturn(0);
4358 static PetscErrorCode __mfem_pc_shell_setup(
PC pc)
4360 __mfem_pc_shell_ctx *ctx;
4362 PetscFunctionBeginUser;
4363 ierr = PCShellGetContext(pc,(
void **)&ctx); CHKERRQ(ierr);
4374 ierr = PCGetOperators(pc,NULL,&B); CHKERRQ(ierr);
4383 PetscFunctionReturn(0);
4386 static PetscErrorCode __mfem_pc_shell_destroy(
PC pc)
4388 __mfem_pc_shell_ctx *ctx;
4389 PetscErrorCode ierr;
4391 PetscFunctionBeginUser;
4392 ierr = PCShellGetContext(pc,(
void **)&ctx); CHKERRQ(ierr);
4398 PetscFunctionReturn(0);
4401 static PetscErrorCode __mfem_array_container_destroy(
void *ptr)
4403 PetscErrorCode ierr;
4405 PetscFunctionBeginUser;
4406 ierr = PetscFree(ptr); CHKERRQ(ierr);
4407 PetscFunctionReturn(0);
4410 static PetscErrorCode __mfem_matarray_container_destroy(
void *ptr)
4413 PetscErrorCode ierr;
4415 PetscFunctionBeginUser;
4416 for (
int i=0; i<a->
Size(); i++)
4420 ierr = MatDestroy(&M); CCHKERRQ(comm,ierr);
4423 PetscFunctionReturn(0);
4426 static PetscErrorCode __mfem_monitor_ctx_destroy(
void **ctx)
4428 PetscErrorCode ierr;
4430 PetscFunctionBeginUser;
4431 ierr = PetscFree(*ctx); CHKERRQ(ierr);
4432 PetscFunctionReturn(0);
4437 PetscErrorCode MakeShellPC(
PC pc,
mfem::Solver &precond,
bool ownsop)
4439 PetscFunctionBeginUser;
4440 __mfem_pc_shell_ctx *ctx =
new __mfem_pc_shell_ctx;
4442 ctx->ownsop = ownsop;
4443 ctx->factory = NULL;
4446 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
4447 ierr = PCShellSetName(pc,
"MFEM Solver (unknown Pmat)"); CHKERRQ(ierr);
4448 ierr = PCShellSetContext(pc,(
void *)ctx); CHKERRQ(ierr);
4449 ierr = PCShellSetApply(pc,__mfem_pc_shell_apply); CHKERRQ(ierr);
4450 ierr = PCShellSetApplyTranspose(pc,__mfem_pc_shell_apply_transpose);
4452 ierr = PCShellSetSetUp(pc,__mfem_pc_shell_setup); CHKERRQ(ierr);
4453 ierr = PCShellSetView(pc,__mfem_pc_shell_view); CHKERRQ(ierr);
4454 ierr = PCShellSetDestroy(pc,__mfem_pc_shell_destroy); CHKERRQ(ierr);
4455 PetscFunctionReturn(0);
4460 PetscErrorCode MakeShellPCWithFactory(
PC pc,
4463 PetscFunctionBeginUser;
4464 __mfem_pc_shell_ctx *ctx =
new __mfem_pc_shell_ctx;
4467 ctx->factory = factory;
4470 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
4471 ierr = PCShellSetName(pc,factory->
GetName()); CHKERRQ(ierr);
4472 ierr = PCShellSetContext(pc,(
void *)ctx); CHKERRQ(ierr);
4473 ierr = PCShellSetApply(pc,__mfem_pc_shell_apply); CHKERRQ(ierr);
4474 ierr = PCShellSetApplyTranspose(pc,__mfem_pc_shell_apply_transpose);
4476 ierr = PCShellSetSetUp(pc,__mfem_pc_shell_setup); CHKERRQ(ierr);
4477 ierr = PCShellSetView(pc,__mfem_pc_shell_view); CHKERRQ(ierr);
4478 ierr = PCShellSetDestroy(pc,__mfem_pc_shell_destroy); CHKERRQ(ierr);
4479 PetscFunctionReturn(0);
4484 static PetscErrorCode Convert_Array_IS(MPI_Comm comm,
bool islist,
4489 const int *data = list ? list->
GetData() : NULL;
4490 PetscErrorCode ierr;
4492 PetscFunctionBeginUser;
4493 ierr = PetscMalloc1(n,&idxs); CHKERRQ(ierr);
4496 for (
PetscInt i=0; i<n; i++) { idxs[i] = data[i] + st; }
4503 if (data[i]) { idxs[cum++] = i+st; }
4507 ierr = ISCreateGeneral(comm,n,idxs,PETSC_OWN_POINTER,is);
4509 PetscFunctionReturn(0);
4515 static PetscErrorCode Convert_Vmarks_IS(MPI_Comm comm,
4523 PetscErrorCode ierr;
4525 PetscFunctionBeginUser;
4526 for (
int i = 0; i < pl2l.
Size(); i++)
4530 ierr = MatGetRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,(
const PetscInt**)&ii,
4531 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
4532 MFEM_VERIFY(done,
"Unable to perform MatGetRowIJ on " << i <<
" l2l matrix");
4533 ierr = MatGetSize(pl2l[i],NULL,&n); CHKERRQ(ierr);
4534 #if defined(PETSC_USE_64BIT_INDICES)
4535 int nnz = (int)ii[m];
4536 int *mii =
new int[m+1];
4537 int *mjj =
new int[nnz];
4538 for (
int j = 0; j < m+1; j++) { mii[j] = (int)ii[j]; }
4539 for (
int j = 0; j < nnz; j++) { mjj[j] = (int)jj[j]; }
4544 ierr = MatRestoreRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,
4546 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
4547 MFEM_VERIFY(done,
"Unable to perform MatRestoreRowIJ on "
4548 << i <<
" l2l matrix");
4551 for (
int i = 0; i < l2l.Size(); i++) { nl += l2l[i]->Width(); }
4553 const int* vdata = mark->
GetData();
4554 int* sdata = sub_dof_marker.
GetData();
4555 int cumh = 0, cumw = 0;
4556 for (
int i = 0; i < l2l.Size(); i++)
4561 l2l[i]->BooleanMultTranspose(vf_marker,sf_marker);
4562 cumh += l2l[i]->Height();
4563 cumw += l2l[i]->Width();
4565 ierr = Convert_Array_IS(comm,
false,&sub_dof_marker,st,is); CCHKERRQ(comm,ierr);
4566 for (
int i = 0; i < pl2l.
Size(); i++)
4570 PetscFunctionReturn(0);
4573 #if !defined(PETSC_HAVE_HYPRE)
4575 #if defined(HYPRE_MIXEDINT)
4576 #error "HYPRE_MIXEDINT not supported"
4579 #include "_hypre_parcsr_mv.h"
4580 static PetscErrorCode MatConvert_hypreParCSR_AIJ(hypre_ParCSRMatrix* hA,
Mat* pA)
4582 MPI_Comm comm = hypre_ParCSRMatrixComm(hA);
4583 hypre_CSRMatrix *hdiag,*hoffd;
4585 PetscInt *dii,*djj,*oii,*ojj,*iptr;
4588 PetscErrorCode ierr;
4590 PetscFunctionBeginUser;
4591 hdiag = hypre_ParCSRMatrixDiag(hA);
4592 hoffd = hypre_ParCSRMatrixOffd(hA);
4593 m = hypre_CSRMatrixNumRows(hdiag);
4594 n = hypre_CSRMatrixNumCols(hdiag);
4595 dnnz = hypre_CSRMatrixNumNonzeros(hdiag);
4596 onnz = hypre_CSRMatrixNumNonzeros(hoffd);
4597 ierr = PetscMalloc1(m+1,&dii); CHKERRQ(ierr);
4598 ierr = PetscMalloc1(dnnz,&djj); CHKERRQ(ierr);
4599 ierr = PetscMalloc1(dnnz,&da); CHKERRQ(ierr);
4600 ierr = PetscMemcpy(dii,hypre_CSRMatrixI(hdiag),(m+1)*
sizeof(
PetscInt));
4602 ierr = PetscMemcpy(djj,hypre_CSRMatrixJ(hdiag),dnnz*
sizeof(
PetscInt));
4604 ierr = PetscMemcpy(da,hypre_CSRMatrixData(hdiag),dnnz*
sizeof(
PetscScalar));
4611 ierr = PetscSortIntWithScalarArray(nc,iptr,aptr); CHKERRQ(ierr);
4615 ierr = MPI_Comm_size(comm,&size); CHKERRQ(ierr);
4620 ierr = PetscMalloc1(m+1,&oii); CHKERRQ(ierr);
4621 ierr = PetscMalloc1(onnz,&ojj); CHKERRQ(ierr);
4622 ierr = PetscMalloc1(onnz,&oa); CHKERRQ(ierr);
4623 ierr = PetscMemcpy(oii,hypre_CSRMatrixI(hoffd),(m+1)*
sizeof(
PetscInt));
4625 offdj = hypre_CSRMatrixJ(hoffd);
4626 coffd = hypre_ParCSRMatrixColMapOffd(hA);
4627 for (i=0; i<onnz; i++) { ojj[i] = coffd[offdj[i]]; }
4628 ierr = PetscMemcpy(oa,hypre_CSRMatrixData(hoffd),onnz*
sizeof(
PetscScalar));
4635 ierr = PetscSortIntWithScalarArray(nc,iptr,aptr); CHKERRQ(ierr);
4639 ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,
4640 djj,da,oii,ojj,oa,pA); CHKERRQ(ierr);
4646 ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,pA); CHKERRQ(ierr);
4652 void *ptrs[6] = {dii,djj,da,oii,ojj,oa};
4653 const char *names[6] = {
"_mfem_csr_dii",
4664 ierr = PetscContainerCreate(comm,&c); CHKERRQ(ierr);
4665 ierr = PetscContainerSetPointer(c,ptrs[i]); CHKERRQ(ierr);
4666 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
4670 ierr = PetscContainerDestroy(&c); CHKERRQ(ierr);
4672 PetscFunctionReturn(0);
4675 static PetscErrorCode MatConvert_hypreParCSR_IS(hypre_ParCSRMatrix* hA,
Mat* pA)
4678 ISLocalToGlobalMapping rl2g,cl2g;
4680 hypre_CSRMatrix *hdiag,*hoffd;
4681 MPI_Comm comm = hypre_ParCSRMatrixComm(hA);
4683 const char *names[2] = {
"_mfem_csr_aux",
4687 PetscInt *col_map_offd,*hdi,*hdj,*hoi,*hoj;
4689 PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo;
4690 PetscErrorCode ierr;
4692 PetscFunctionBeginUser;
4694 str = hypre_ParCSRMatrixFirstRowIndex(hA);
4695 stc = hypre_ParCSRMatrixFirstColDiag(hA);
4696 hdiag = hypre_ParCSRMatrixDiag(hA);
4697 hoffd = hypre_ParCSRMatrixOffd(hA);
4698 dr = hypre_CSRMatrixNumRows(hdiag);
4699 dc = hypre_CSRMatrixNumCols(hdiag);
4700 nnz = hypre_CSRMatrixNumNonzeros(hdiag);
4701 hdi = hypre_CSRMatrixI(hdiag);
4702 hdj = hypre_CSRMatrixJ(hdiag);
4703 hdd = hypre_CSRMatrixData(hdiag);
4704 oc = hypre_CSRMatrixNumCols(hoffd);
4705 nnz += hypre_CSRMatrixNumNonzeros(hoffd);
4706 hoi = hypre_CSRMatrixI(hoffd);
4707 hoj = hypre_CSRMatrixJ(hoffd);
4708 hod = hypre_CSRMatrixData(hoffd);
4711 ierr = ISCreateStride(comm,dr,str,1,&is); CHKERRQ(ierr);
4712 ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g); CHKERRQ(ierr);
4713 ierr = ISDestroy(&is); CHKERRQ(ierr);
4714 col_map_offd = hypre_ParCSRMatrixColMapOffd(hA);
4715 ierr = PetscMalloc1(dc+oc,&aux); CHKERRQ(ierr);
4716 for (i=0; i<dc; i++) { aux[i] = i+stc; }
4717 for (i=0; i<oc; i++) { aux[i+dc] = col_map_offd[i]; }
4718 ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is); CHKERRQ(ierr);
4719 ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g); CHKERRQ(ierr);
4720 ierr = ISDestroy(&is); CHKERRQ(ierr);
4723 ierr = MatCreate(comm,pA); CHKERRQ(ierr);
4724 ierr = MatSetSizes(*pA,dr,dc,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr);
4725 ierr = MatSetType(*pA,MATIS); CHKERRQ(ierr);
4726 ierr = MatSetLocalToGlobalMapping(*pA,rl2g,cl2g); CHKERRQ(ierr);
4727 ierr = ISLocalToGlobalMappingDestroy(&rl2g); CHKERRQ(ierr);
4728 ierr = ISLocalToGlobalMappingDestroy(&cl2g); CHKERRQ(ierr);
4731 ierr = PetscMalloc1(nnz+dr+1,&aux); CHKERRQ(ierr);
4732 ierr = PetscMalloc1(nnz,&data); CHKERRQ(ierr);
4736 *ii = *(hdi++) + *(hoi++);
4737 for (jd=0,jo=0,cum=0; *ii<nnz; cum++)
4741 for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; }
4742 for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; }
4743 *(++ii) = *(hdi++) + *(hoi++);
4744 ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold); CHKERRQ(ierr);
4746 for (; cum<dr; cum++) { *(++ii) = nnz; }
4750 ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,ii,jj,aa,&lA);
4758 ierr = PetscContainerCreate(PETSC_COMM_SELF,&c); CHKERRQ(ierr);
4759 ierr = PetscContainerSetPointer(c,ptrs[i]); CHKERRQ(ierr);
4760 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
4764 ierr = PetscContainerDestroy(&c); CHKERRQ(ierr);
4766 ierr = MatISSetLocalMat(*pA,lA); CHKERRQ(ierr);
4767 ierr = MatDestroy(&lA); CHKERRQ(ierr);
4768 ierr = MatAssemblyBegin(*pA,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4769 ierr = MatAssemblyEnd(*pA,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4770 PetscFunctionReturn(0);
4774 #endif // MFEM_USE_PETSC
4775 #endif // MFEM_USE_MPI
int Size() const
Logical size of the array.
void SetPreconditioner(Solver &precond)
Sets the solver to perform preconditioning.
void SetPrintLevel(int plev)
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
PetscParVector * B
Right-hand side and solution vector.
void CreatePrivateContext()
void Print(const char *fname=NULL, bool binary=false) const
Prints the matrix (to stdout if fname is NULL)
Vector()
Default constructor for Vector. Sets size = 0 and data = NULL.
MPI_Comm GetComm() const
MPI communicator.
bool isImplicit() const
True if type is IMPLICIT or HOMOGENEOUS.
bool isHomogeneous() const
True if type is HOMOGENEOUS.
virtual void SetOperator(const Operator &op)
Specification of the nonlinear operator.
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
Abstract class for PETSc's preconditioners.
PetscParMatrix & operator+=(const PetscParMatrix &B)
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
bool clcustom
Boolean to handle SetFromOptions calls.
void SetObjective(void(*obj)(Operator *op, const Vector &x, double *f))
Specification of an objective function to be used for line search.
void ConvertOperator(MPI_Comm comm, const Operator &op, Mat *B, Operator::Type tid)
Wrapper for PETSc's matrix class.
PetscParVector & operator+=(const PetscParVector &y)
void ApplyBC(const Vector &x, Vector &y)
y = x on ess_tdof_list_c and y = g (internally evaluated) on ess_tdof_list
Abstract class for PETSc's linear solvers.
Vec x
The actual PETSc object.
void SetSize(int s)
Resize the vector to size s.
Abstract class for PETSc's solvers.
PetscODESolver::Type GetType() const
virtual void Run(Vector &x, double &t, double &dt, double t_final)
Perform time integration from time t [in] to time tf [in].
void SetPostCheck(void(*post)(Operator *op, const Vector &X, Vector &Y, Vector &W, bool &changed_y, bool &changed_w))
Base abstract class for time dependent operators.
PetscInt GetNumCols() const
Returns the local number of columns.
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void SetType(PetscODESolver::Type)
virtual void MonitorSolver(PetscSolver *solver)
Generic monitor to take access to the solver.
Pointer to an Operator of a specified type.
int * GetJ()
Return the array J.
void Mult(double a, const Vector &x, double b, Vector &y) const
Matvec: y = a A x + b y.
PetscBDDCSolver(MPI_Comm comm, Operator &op, const PetscBDDCSolverParams &opts=PetscBDDCSolverParams(), const std::string &prefix=std::string())
PetscParVector & AddValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Add values in a vector.
void SetMat(Mat newA)
Replace the inner Mat Object. The reference count of newA is increased.
virtual ~PetscSolver()
Destroy the PetscParVectors allocated (if any).
PetscNonlinearSolver(MPI_Comm comm, const std::string &prefix=std::string())
T * GetData()
Returns the data.
virtual void SetTime(const double _t)
Set the current time.
int Size() const
Returns the size of the vector.
virtual void Step(Vector &x, double &t, double &dt)
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in]...
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
int * GetI()
Return the array I.
void Init()
Initialize with defaults. Does not initialize inherited members.
PetscPreconditioner(MPI_Comm comm, const std::string &prefix=std::string())
PetscClassId cid
The class id of the actual PETSc object.
ID for class PetscParMatrix, MATHYPRE format.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
Abstract parallel finite element space.
void SetRelTol(double tol)
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
void Randomize(PetscInt seed=0)
Set random values.
PetscPCGSolver(MPI_Comm comm, const std::string &prefix=std::string())
void Destroy()
Delete all owned data. Does not perform re-initialization with defaults.
virtual Operator & GetExplicitGradient(const Vector &x) const
Return an Operator representing dG/dx at the given point x and the currently set time.
void SetMonitor(PetscSolverMonitor *ctx)
Sets user-defined monitoring routine.
void SetMaxIter(int max_iter)
double * GetData() const
Return a pointer to the beginning of the Vector data.
PetscParVector & operator*=(PetscScalar d)
void SortColumnIndices()
Sort the column indices corresponding to each row.
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B)
Returns the matrix A * B.
void EliminateRowsCols(const Array< int > &rows_cols, const PetscParVector &X, PetscParVector &B, double diag=1.)
Eliminate rows and columns from the matrix, and rows from the vector B. Modify B with the BC values i...
Wrapper for PETSc's vector class.
void Customize(bool customize=true) const
Customize object with options set.
PetscInt M() const
Returns the global number of rows.
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
virtual ~PetscLinearSolver()
double * GetData()
Return the element data, i.e. the array A.
PetscInt GetNumRows() const
Returns the local number of rows.
void Print(const char *fname=NULL, bool binary=false) const
Prints the vector (to stdout if fname is NULL)
void EliminateBC(HypreParMatrix &A, HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
void ResetArray()
Reset the PETSc Vec object to use its default data. Call this method after the use of PlaceArray()...
virtual Operator & GetImplicitGradient(const Vector &x, const Vector &k, double shift) const
Return an Operator representing (dF/dk shift + dF/dx) at the given x, k, and the currently set time...
PetscParVector & SetValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Set values in a vector.
virtual void Init(TimeDependentOperator &f_, enum PetscODESolver::Type type)
Initialize the ODE solver.
PetscParMatrix * Transpose(bool action=false)
Returns the transpose of the PetscParMatrix.
ID for the base class Operator, i.e. any type.
PetscObject obj
The actual PETSc object (KSP, PC, SNES or TS).
Abstract class for monitoring PETSc's solvers.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void SetJacobianType(Operator::Type type)
bool areColumnsSorted() const
int to_int(const std::string &str)
Auxiliary class for BDDC customization.
virtual ~PetscPreconditioner()
ID for class PetscParMatrix, unspecified format.
MPI_Comm GetComm() const
Get the associated MPI communicator.
void FixResidualBC(const Vector &x, Vector &y)
y = x-g on ess_tdof_list, the rest of y is unchanged
void LoseData()
NULL-ifies the data.
PetscParMatrix & operator=(const PetscParMatrix &B)
PetscInt GetColStart() const
Returns the global index of the first local column.
virtual ~PetscParVector()
Calls PETSc's destroy function.
PetscFieldSplitSolver(MPI_Comm comm, Operator &op, const std::string &prefix=std::string())
PetscBCHandler * bchandler
Handler for boundary conditions.
PetscParMatrix & operator-=(const PetscParMatrix &B)
virtual Solver * NewPreconditioner(const OperatorHandle &oh)=0
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
MPI_Comm GetComm() const
Get the associated MPI communicator.
void Shift(double s)
Shift diagonal by a constant.
ID for class PetscParMatrix, MATNEST format.
void SetTime(double t)
Sets the current time.
ID for class PetscParMatrix, MATSHELL format.
PetscParMatrix()
Create an empty matrix to be used as a reference to an existing matrix.
void SetBCHandler(PetscBCHandler *bch)
Sets the object to handle essential boundary conditions.
Wrapper for hypre's parallel vector class.
virtual void Eval(double t, Vector &g)
Boundary conditions evaluation.
Type
Enumeration defining IDs for some classes derived from Operator.
PetscBCHandler(Type _type=ZERO)
PetscInt NNZ() const
Returns the number of nonzeros.
PetscLinearSolver(MPI_Comm comm, const std::string &prefix=std::string(), bool wrap=true)
virtual void ExplicitMult(const Vector &x, Vector &y) const
Perform the action of the explicit part of the operator, G: y = G(x, t) where t is the current time...
virtual void Mult(const Vector &b, Vector &x) const
Application of the preconditioner.
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Mat A
The actual PETSc object.
PetscInt N() const
Returns the global number of columns.
PetscParVector * GetY() const
Returns the inner vector in the range of A (it creates it if needed)
void SetJacobianType(Operator::Type type)
void MakeWrapper(MPI_Comm comm, const Operator *op, Mat *B)
Creates a wrapper around a mfem::Operator op using PETSc's MATSHELL object and returns the Mat in B...
void SetUpdate(void(*update)(Operator *op, int it, const mfem::Vector &F, const mfem::Vector &X, const mfem::Vector &D, const mfem::Vector &P))
bool operatorset
Boolean to handle SetOperator calls.
PetscParVector * X
Auxiliary vectors for typecasting.
void MultTranspose(double a, const Vector &x, double b, Vector &y) const
Matvec transpose: y = a A^T x + b y.
int height
Dimension of the output / number of rows in the matrix.
PetscParVector & operator-=(const PetscParVector &y)
virtual ~PetscNonlinearSolver()
virtual ~PetscODESolver()
PetscSolver()
Construct an empty PetscSolver. Initialize protected objects to NULL.
void SetPreconditionerFactory(PetscPreconditionerFactory *factory)
Sets the object for the creation of the preconditioner.
void MFEMInitializePetsc()
Convenience functions to initialize/finalize PETSc.
Mat ReleaseMat(bool dereference)
Release the PETSc Mat object. If dereference is true, decrement the refcount of the Mat object...
PetscParVector(MPI_Comm comm, PetscInt glob_size, PetscInt *col=NULL)
Creates vector with given global size and partitioning of the columns.
virtual void MonitorSolution(PetscInt it, PetscReal norm, const Vector &x)
Monitor the solution vector x.
ID for class PetscParMatrix, MATAIJ format.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
MPI_Comm GetComm() const
Get the associated MPI communicator.
PetscInt GlobalSize() const
Returns the global number of rows.
PetscInt GetRowStart() const
Returns the global index of the first local row.
struct _p_PetscObject * PetscObject
void SetAbsTol(double tol)
Helper class for handling essential boundary conditions.
PetscParVector * GetX() const
Returns the inner vector in the domain of A (it creates it if needed)
Array< int > & GetTDofs()
Gets essential dofs (local, per-process numbering)
PetscParVector & operator=(PetscScalar d)
Set constant values.
HYPRE_Int * GetTrueDofOffsets() const
virtual void MonitorResidual(PetscInt it, PetscReal norm, const Vector &r)
Monitor the residual vector r.
int NumRowBlocks() const
Return the number of row blocks.
Identity Operator I: x -> x.
void PlaceArray(PetscScalar *temp_data)
Temporarily replace the data of the PETSc Vec object. To return to the original data array...
void FreePrivateContext()
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Vector * GlobalVector() const
Returns the global vector in each processor.
PetscODESolver(MPI_Comm comm, const std::string &prefix=std::string())
void EliminateRows(const Array< int > &rows)
Eliminate only the rows from the matrix.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Wrapper for hypre's ParCSR matrix class.
A class to handle Block systems in a matrix-free implementation.
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
void operator*=(double s)
Scale all entries by s: A_scaled = s*A.
int NumColBlocks() const
Return the number of column blocks.
void SetTDofs(Array< int > &list)
Sets essential dofs (local, per-process numbering)
ID for class PetscParMatrix, MATIS format.
int width
Dimension of the input / number of columns in the matrix.
void * private_ctx
Private context for solver.
void SetUp(PetscInt n)
SetUp the helper object, where n is the size of the solution vector.
void MakeRef(const PetscParMatrix &master)
Makes this object a reference to another PetscParMatrix.
virtual void ImplicitMult(const Vector &x, const Vector &k, Vector &y) const
Perform the action of the implicit part of the operator, F: y = F(x, k, t) where t is the current tim...
void ScaleCols(const Vector &s)
Scale the local col i by s(i).