23#include "petscmathypre.h"
26#if PETSC_VERSION_LT(3,11,0)
27#define VecLockReadPush VecLockPush
28#define VecLockReadPop VecLockPop
30#if PETSC_VERSION_LT(3,12,0)
31#define VecGetArrayWrite VecGetArray
32#define VecRestoreArrayWrite VecRestoreArray
33#define MatComputeOperator(A,B,C) MatComputeExplicitOperator(A,C)
34#define MatComputeOperatorTranspose(A,B,C) MatComputeExplicitOperatorTranspose(A,C)
36#if PETSC_VERSION_LT(3,19,0)
37#define PETSC_SUCCESS 0
39#if PETSC_VERSION_LT(3,23,0)
40#define PetscContainerSetCtxDestroy(A,B) PetscContainerSetUserDestroy(A,B)
43#if PETSC_VERSION_LT(3,24,0)
58static PetscErrorCode __mfem_ts_rhsfunction(TS,
PetscReal,Vec,Vec,
void*);
59static PetscErrorCode __mfem_ts_rhsjacobian(TS,
PetscReal,Vec,Mat,Mat,
61static PetscErrorCode __mfem_ts_ifunction(TS,
PetscReal,Vec,Vec,Vec,
void*);
62static PetscErrorCode __mfem_ts_ijacobian(TS,
PetscReal,Vec,Vec,
65static PetscErrorCode __mfem_ts_computesplits(TS,
PetscReal,Vec,Vec,
68static PetscErrorCode __mfem_snes_jacobian(SNES,Vec,Mat,Mat,
void*);
69static PetscErrorCode __mfem_snes_function(SNES,Vec,Vec,
void*);
70static PetscErrorCode __mfem_snes_objective(SNES,Vec,
PetscReal*,
void*);
71static PetscErrorCode __mfem_snes_update(SNES,
PetscInt);
72static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch,Vec,Vec,Vec,
73 PetscBool*,PetscBool*,
void*);
75static PetscErrorCode __mfem_pc_shell_apply(PC,Vec,Vec);
76static PetscErrorCode __mfem_pc_shell_apply_transpose(PC,Vec,Vec);
77static PetscErrorCode __mfem_pc_shell_setup(PC);
78static PetscErrorCode __mfem_pc_shell_destroy(PC);
79static PetscErrorCode __mfem_pc_shell_view(PC,PetscViewer);
80static PetscErrorCode __mfem_mat_shell_apply(Mat,Vec,Vec);
81static PetscErrorCode __mfem_mat_shell_apply_transpose(Mat,Vec,Vec);
82static PetscErrorCode __mfem_mat_shell_destroy(Mat);
83static PetscErrorCode __mfem_mat_shell_copy(Mat,Mat,MatStructure);
84#if PETSC_VERSION_LT(3,23,0)
86#elif PETSC_VERSION_LT(3,25,0)
89static PetscErrorCode __mfem_array_container_destroy(
PetscCtxRt);
90static PetscErrorCode __mfem_matarray_container_destroy(
PetscCtxRt);
91#if PETSC_VERSION_LT(3,23,0)
92static PetscErrorCode __mfem_monitor_ctx_destroy(
void**);
94static PetscErrorCode __mfem_monitor_ctx_destroy(
PetscCtxRt);
102static PetscErrorCode MakeShellPC(PC,
mfem::Solver&,
bool);
103static PetscErrorCode MakeShellPCWithFactory(PC,
106#if PETSC_VERSION_GE(3,15,0) && defined(PETSC_HAVE_DEVICE)
107#if defined(MFEM_USE_CUDA) && defined(PETSC_HAVE_CUDA)
109#define PETSC_VECDEVICE VECCUDA
110#define PETSC_MATAIJDEVICE MATAIJCUSPARSE
111#define VecDeviceGetArrayRead VecCUDAGetArrayRead
112#define VecDeviceGetArrayWrite VecCUDAGetArrayWrite
113#define VecDeviceGetArray VecCUDAGetArray
114#define VecDeviceRestoreArrayRead VecCUDARestoreArrayRead
115#define VecDeviceRestoreArrayWrite VecCUDARestoreArrayWrite
116#define VecDeviceRestoreArray VecCUDARestoreArray
117#define VecDevicePlaceArray VecCUDAPlaceArray
118#define VecDeviceResetArray VecCUDAResetArray
119#elif defined(MFEM_USE_HIP) && defined(PETSC_HAVE_HIP)
121#define PETSC_VECDEVICE VECHIP
122#define PETSC_MATAIJDEVICE MATAIJHIPSPARSE
123#define VecDeviceGetArrayRead VecHIPGetArrayRead
124#define VecDeviceGetArrayWrite VecHIPGetArrayWrite
125#define VecDeviceGetArray VecHIPGetArray
126#define VecDeviceRestoreArrayRead VecHIPRestoreArrayRead
127#define VecDeviceRestoreArrayWrite VecHIPRestoreArrayWrite
128#define VecDeviceRestoreArray VecHIPRestoreArray
129#define VecDevicePlaceArray VecHIPPlaceArray
130#define VecDeviceResetArray VecHIPResetArray
132#define VecDeviceGetArrayRead VecGetArrayRead
133#define VecDeviceGetArrayWrite VecGetArrayWrite
134#define VecDeviceGetArray VecGetArray
135#define VecDeviceRestoreArrayRead VecRestoreArrayRead
136#define VecDeviceRestoreArrayWrite VecRestoreArrayWrite
137#define VecDeviceRestoreArray VecRestoreArray
138#define VecDevicePlaceArray VecPlaceArray
139#define VecDeviceResetArray VecResetArray
143#if defined(PETSC_HAVE_DEVICE)
144static PetscErrorCode __mfem_VecSetOffloadMask(Vec,PetscOffloadMask);
146static PetscErrorCode __mfem_VecBoundToCPU(Vec,PetscBool*);
147static PetscErrorCode __mfem_PetscObjectStateIncrease(
PetscObject);
148static PetscErrorCode __mfem_MatCreateDummy(MPI_Comm,
PetscInt,
PetscInt,Mat*);
156 unsigned long int numprec;
157} __mfem_pc_shell_ctx;
186 PetscObjectState cached_ijacstate;
187 PetscObjectState cached_rhsjacstate;
188 PetscObjectState cached_splits_xstate;
189 PetscObjectState cached_splits_xdotstate;
199static PetscErrorCode ierr;
200static PetscMPIInt mpiierr;
223#if PETSC_VERSION_LT(3,17,0)
224 const char *opts =
"-cuda_device";
226 const char *opts =
"-device_select_cuda";
228 ierr = PetscOptionsSetValue(NULL,opts,
230 MFEM_VERIFY(!ierr,
"Unable to set initial option value to PETSc");
234#if PETSC_VERSION_LT(3,17,0)
235 const char *opts =
"-hip_device";
237 const char *opts =
"-device_select_hip";
239 ierr = PetscOptionsSetValue(NULL,opts,
241 MFEM_VERIFY(!ierr,
"Unable to set initial option value to PETSc");
243 ierr = PetscInitialize(argc,argv,rc_file,help);
244 MFEM_VERIFY(!ierr,
"Unable to initialize PETSc");
249 ierr = PetscFinalize();
250 MFEM_VERIFY(!ierr,
"Unable to finalize PETSc");
279 MFEM_VERIFY(
x,
"Missing Vec");
280 ierr = VecSetUp(
x); PCHKERRQ(
x,ierr);
281 ierr = PetscObjectTypeCompare((
PetscObject)
x,VECNEST,&isnest); PCHKERRQ(
x,ierr);
282 MFEM_VERIFY(!isnest,
"Not for type nest");
283 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
284 MFEM_VERIFY(n >= 0,
"Invalid local size");
286#if defined(PETSC_HAVE_DEVICE)
287 PetscOffloadMask omask;
290 ierr = VecGetOffloadMask(
x,&omask); PCHKERRQ(
x,ierr);
291 if (omask != PETSC_OFFLOAD_BOTH)
293 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
296 ierr = VecGetArrayRead(
x,(
const PetscScalar**)&array); PCHKERRQ(
x,ierr);
297#if defined(PETSC_HAVE_DEVICE)
298 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
299 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
300 ""); PCHKERRQ(
x,ierr);
303 if (omask != PETSC_OFFLOAD_BOTH)
305 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
308 ierr = VecDeviceGetArrayRead(
x,(
const PetscScalar**)&darray);
311 ierr = VecDeviceRestoreArrayRead(
x,(
const PetscScalar**)&darray);
319 ierr = VecRestoreArrayRead(
x,(
const PetscScalar**)&array); PCHKERRQ(
x,ierr);
321#if defined(PETSC_HAVE_DEVICE)
322 if (omask == PETSC_OFFLOAD_UNALLOCATED && isdevice) { omask = PETSC_OFFLOAD_CPU; }
323 ierr = __mfem_VecSetOffloadMask(
x,omask); PCHKERRQ(
x,ierr);
331 MFEM_VERIFY(
x,
"Missing Vec");
332#if defined(_USE_DEVICE)
333 PetscOffloadMask mask;
335 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
336 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
337 ""); PCHKERRQ(
x,ierr);
338 ierr = VecGetOffloadMask(
x,&mask); PCHKERRQ(
x,ierr);
343 case PETSC_OFFLOAD_CPU:
347 case PETSC_OFFLOAD_GPU:
351 case PETSC_OFFLOAD_BOTH:
356 MFEM_ABORT(
"Unhandled case " << mask);
365 MFEM_VERIFY(
x,
"Missing Vec");
366 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
367#if defined(_USE_DEVICE)
369 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
370 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
371 ""); PCHKERRQ(
x,ierr);
376 PetscOffloadMask mask;
377 if (dv && hv) { mask = PETSC_OFFLOAD_BOTH; }
378 else if (dv) { mask = PETSC_OFFLOAD_GPU; }
379 else { mask = PETSC_OFFLOAD_CPU; }
380 ierr = __mfem_VecSetOffloadMask(
x,mask); PCHKERRQ(
x,ierr);
387 ierr = VecGetArrayWrite(
x,&v); PCHKERRQ(
x,ierr);
389 ierr = VecRestoreArrayWrite(
x,&v); PCHKERRQ(
x,ierr);
396 MFEM_VERIFY(
x,
"Missing Vec");
397 ierr = VecGetType(
x,&vectype); PCHKERRQ(
x,ierr);
398#if defined(_USE_DEVICE)
403 ierr = VecSetType(
x,PETSC_VECDEVICE); PCHKERRQ(
x,ierr);
406 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
412 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
420 MFEM_VERIFY(
x,
"Missing Vec");
421#if defined(PETSC_HAVE_DEVICE)
423 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
424 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
425 ""); PCHKERRQ(
x,ierr);
426 if (on_dev && isdevice)
428 ierr = VecDeviceGetArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
429 ierr = VecDeviceRestoreArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
434 ierr = VecGetArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
435 ierr = VecRestoreArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
449 MFEM_VERIFY(
x,
"Missing Vec");
450#if defined(PETSC_HAVE_DEVICE)
452 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
453 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
454 ""); PCHKERRQ(
x,ierr);
455 if (on_dev && isdevice)
457 ierr = VecDeviceGetArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
458 ierr = VecDeviceRestoreArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
463 ierr = VecGetArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
464 ierr = VecRestoreArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
466 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
479 MFEM_VERIFY(
x,
"Missing Vec");
480#if defined(PETSC_HAVE_DEVICE)
482 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
483 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
484 ""); PCHKERRQ(
x,ierr);
485 if (on_dev && isdevice)
487 ierr = VecDeviceGetArray(
x,&dummy); PCHKERRQ(
x,ierr);
488 ierr = VecDeviceRestoreArray(
x,&dummy); PCHKERRQ(
x,ierr);
493 ierr = VecGetArray(
x,&dummy); PCHKERRQ(
x,ierr);
494 ierr = VecRestoreArray(
x,&dummy); PCHKERRQ(
x,ierr);
496 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
508 MFEM_VERIFY(
x,
"Missing Vec");
509#if defined(PETSC_HAVE_DEVICE)
510 ierr = VecBindToCPU(
x,!dev ? PETSC_TRUE : PETSC_FALSE); PCHKERRQ(
x,ierr);
518 MFEM_VERIFY(
x,
"Missing Vec");
519 ierr = __mfem_VecBoundToCPU(
x,&flg); PCHKERRQ(
x,ierr);
520 return flg ? false :
true;
526 ierr = VecGetSize(
x,&N); PCHKERRQ(
x,ierr);
532 ierr = VecSetBlockSize(
x,bs); PCHKERRQ(
x,ierr);
541 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
542 ierr = VecSetSizes(
x,n,PETSC_DECIDE); PCHKERRQ(
x,ierr);
545 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
546 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
547 ""); PCHKERRQ(
x,ierr);
553#if defined(PETSC_HAVE_DEVICE)
557 ierr = VecDeviceGetArrayWrite(
x,&array); PCHKERRQ(
x,ierr);
558 rest = VecDeviceRestoreArrayWrite;
564 ierr = VecGetArrayWrite(
x,&array); PCHKERRQ(
x,ierr);
565 rest = VecRestoreArrayWrite;
568 ierr = (*rest)(
x,&array); PCHKERRQ(
x,ierr);
587 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
591 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
592 ierr = VecSetSizes(
x,col[myid+1]-col[myid],PETSC_DECIDE); PCHKERRQ(
x,ierr);
596 ierr = VecSetSizes(
x,PETSC_DECIDE,glob_size); PCHKERRQ(
x,ierr);
605 ierr = VecDestroy(&
x); CCHKERRQ(comm,ierr);
612 MFEM_VERIFY(col,
"Missing distribution");
614 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
615 ierr = VecCreateMPIWithArray(comm,1,col[myid+1]-col[myid],glob_size,data_,
616 &
x); CCHKERRQ(comm,ierr)
623 ierr = VecDuplicate(y.
x,&
x); PCHKERRQ(
x,ierr);
628 bool transpose,
bool allocate) :
Vector()
632 ierr = VecCreate(comm,&
x);
634 ierr = VecSetSizes(
x,loc,PETSC_DECIDE);
649 bool transpose,
bool allocate) :
Vector()
654 ierr = MatCreateVecs(pA,&
x,NULL); PCHKERRQ(pA,ierr);
658 ierr = MatCreateVecs(pA,NULL,&
x); PCHKERRQ(pA,ierr);
664 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
677 ierr = PetscObjectReference((
PetscObject)y); PCHKERRQ(y,ierr);
686 MPI_Comm comm = pfes->
GetComm();
687 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
689 PetscMPIInt myid = 0;
690 if (!HYPRE_AssumedPartitionCheck())
692 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
694 ierr = VecSetSizes(
x,offsets[myid+1]-offsets[myid],PETSC_DECIDE);
712 ierr = VecScatterCreateToAll(
x,&scctx,&vout); PCHKERRQ(
x,ierr);
713 ierr = VecScatterBegin(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
715 ierr = VecScatterEnd(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
717 ierr = VecScatterDestroy(&scctx); PCHKERRQ(
x,ierr);
718 ierr = VecGetArrayRead(vout,&array); PCHKERRQ(
x,ierr);
719 ierr = VecGetLocalSize(vout,&
size); PCHKERRQ(
x,ierr);
722 ierr = VecRestoreArrayRead(vout,&array); PCHKERRQ(
x,ierr);
723 ierr = VecDestroy(&vout); PCHKERRQ(
x,ierr);
732 ierr = VecSet(
x,d); PCHKERRQ(
x,ierr);
740 MFEM_VERIFY(idx.
Size() == vals.
Size(),
741 "Size mismatch between indices and values");
745 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
746 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
754 MFEM_VERIFY(idx.
Size() == vals.
Size(),
755 "Size mismatch between indices and values");
759 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
760 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
767 ierr = VecCopy(y.
x,
x); PCHKERRQ(
x,ierr);
774 ierr = VecAXPY(
x,1.0,y.
x); PCHKERRQ(
x,ierr);
781 ierr = VecAXPY(
x,-1.0,y.
x); PCHKERRQ(
x,ierr);
788 ierr = VecScale(
x,s); PCHKERRQ(
x,ierr);
795 ierr = VecShift(
x,s); PCHKERRQ(
x,ierr);
802 ierr = VecPlaceArray(
x,temp_data); PCHKERRQ(
x,ierr);
807 ierr = VecResetArray(
x); PCHKERRQ(
x,ierr);
814 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
816 "Memory size " << mem.
Capacity() <<
" < " << n <<
" vector size!");
817 MFEM_VERIFY(
pdata.
Empty(),
"Vector data is not empty");
818 MFEM_VERIFY(
data.
Empty(),
"Vector data is not empty");
819#if defined(_USE_DEVICE)
821 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
822 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
823 ""); PCHKERRQ(
x,ierr);
830 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
835 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
845#if defined(PETSC_HAVE_DEVICE)
846 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
848 ierr = VecPlaceArray(
x,w); PCHKERRQ(
x,ierr);
850 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
858 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
860 "Memory size " << mem.
Capacity() <<
" < " << n <<
" vector size!");
861 MFEM_VERIFY(
pdata.
Empty(),
"Vector data is not empty");
862 MFEM_VERIFY(
data.
Empty(),
"Vector data is not empty");
863#if defined(_USE_DEVICE)
865 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
866 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
867 ""); PCHKERRQ(
x,ierr);
873 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
878 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
887#if defined(PETSC_HAVE_DEVICE)
888 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
890 ierr = VecPlaceArray(
x,w); PCHKERRQ(
x,ierr);
893 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
894 ierr = VecLockReadPush(
x); PCHKERRQ(
x,ierr);
900 MFEM_VERIFY(!
pdata.
Empty(),
"Vector data is empty");
912#if defined(PETSC_HAVE_DEVICE)
913 PetscOffloadMask mask;
914 ierr = VecGetOffloadMask(
x,&mask); PCHKERRQ(
x,ierr);
915 if ((usedev && (mask != PETSC_OFFLOAD_GPU && mask != PETSC_OFFLOAD_BOTH)) ||
916 (!usedev && (mask != PETSC_OFFLOAD_CPU && mask != PETSC_OFFLOAD_BOTH)))
919 ierr = VecGetArrayRead(
x,&v); PCHKERRQ(
x,ierr);
921 ierr = VecRestoreArrayRead(
x,&v); PCHKERRQ(
x,ierr);
926 if (
read && !
write) { ierr = VecLockReadPop(
x); PCHKERRQ(
x,ierr); }
929#if defined(PETSC_HAVE_DEVICE)
930 ierr = VecDeviceResetArray(
x); PCHKERRQ(
x,ierr);
932 MFEM_VERIFY(
false,
"This should not happen");
937 ierr = VecResetArray(
x); PCHKERRQ(
x,ierr);
943 PetscRandom rctx = NULL;
947 ierr = PetscRandomCreate(PetscObjectComm((
PetscObject)
x),&rctx);
949 ierr = PetscRandomSetSeed(rctx,(
unsigned long)seed); PCHKERRQ(
x,ierr);
950 ierr = PetscRandomSeed(rctx); PCHKERRQ(
x,ierr);
952 ierr = VecSetRandom(
x,rctx); PCHKERRQ(
x,ierr);
953 ierr = PetscRandomDestroy(&rctx); PCHKERRQ(
x,ierr);
964 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)
x),fname,
965 FILE_MODE_WRITE,&view);
969 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)
x),fname,&view);
972 ierr = VecView(
x,view); PCHKERRQ(
x,ierr);
973 ierr = PetscViewerDestroy(&view); PCHKERRQ(
x,ierr);
977 ierr = VecView(
x,NULL); PCHKERRQ(
x,ierr);
986 ierr = MatGetOwnershipRange(
A,&
N,NULL); PCHKERRQ(
A,ierr);
993 ierr = MatGetOwnershipRangeColumn(
A,&
N,NULL); PCHKERRQ(
A,ierr);
1000 ierr = MatGetLocalSize(
A,&
N,NULL); PCHKERRQ(
A,ierr);
1007 ierr = MatGetLocalSize(
A,NULL,&
N); PCHKERRQ(
A,ierr);
1014 ierr = MatGetSize(
A,&
N,NULL); PCHKERRQ(
A,ierr);
1021 ierr = MatGetSize(
A,NULL,&
N); PCHKERRQ(
A,ierr);
1028 ierr = MatGetInfo(
A,MAT_GLOBAL_SUM,&info); PCHKERRQ(
A,ierr);
1034 if (cbs < 0) { cbs = rbs; }
1035 ierr = MatSetBlockSizes(
A,rbs,cbs); PCHKERRQ(
A,ierr);
1059 rows.
GetData(),PETSC_USE_POINTER,&isr); PCHKERRQ(B,ierr);
1061 cols.
GetData(),PETSC_USE_POINTER,&isc); PCHKERRQ(B,ierr);
1062 ierr = MatCreateSubMatrix(B,isr,isc,MAT_INITIAL_MATRIX,&
A); PCHKERRQ(B,ierr);
1063 ierr = ISDestroy(&isr); PCHKERRQ(B,ierr);
1064 ierr = ISDestroy(&isc); PCHKERRQ(B,ierr);
1108 BlockDiagonalConstructor(comm,row_starts,row_starts,diag,
1122 BlockDiagonalConstructor(comm,row_starts,col_starts,diag,
1135 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1136 if (
X) {
delete X; }
1137 if (
Y) {
delete Y; }
1143 ierr = MatCreateFromParCSR(B,MATAIJ,PETSC_USE_POINTER,&
A);
1155 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1156 if (
X) {
delete X; }
1157 if (
Y) {
delete Y; }
1162 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1170 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1174 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
1175 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
1176 ierr = MatAXPY(
A,1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
1185 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1186 ierr = MatScale(
A,-1.0); PCHKERRQ(
A,ierr);
1190 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
1191 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
1192 ierr = MatAXPY(
A,-1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
1197void PetscParMatrix::
1198BlockDiagonalConstructor(MPI_Comm comm,
1203 PetscInt lrsize,lcsize,rstart,cstart;
1204 PetscMPIInt myid = 0,commsize;
1206 mpiierr = MPI_Comm_size(comm,&commsize); CCHKERRQ(comm,mpiierr);
1207 if (!HYPRE_AssumedPartitionCheck())
1209 mpiierr = MPI_Comm_rank(comm,&myid); CCHKERRQ(comm,mpiierr);
1211 lrsize = row_starts[myid+1]-row_starts[myid];
1212 rstart = row_starts[myid];
1213 lcsize = col_starts[myid+1]-col_starts[myid];
1214 cstart = col_starts[myid];
1219 ierr = ISCreateStride(comm,diag->
Height(),rstart,1,&is); CCHKERRQ(comm,ierr);
1220 ISLocalToGlobalMapping rl2g,cl2g;
1221 ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g); PCHKERRQ(is,ierr);
1222 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
1223 if (row_starts != col_starts)
1225 ierr = ISCreateStride(comm,diag->
Width(),cstart,1,&is);
1226 CCHKERRQ(comm,ierr);
1227 ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g); PCHKERRQ(is,ierr);
1228 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
1232 ierr = PetscObjectReference((
PetscObject)rl2g); PCHKERRQ(rl2g,ierr);
1237 ierr = MatCreate(comm,&
A); CCHKERRQ(comm,ierr);
1238 ierr = MatSetSizes(
A,lrsize,lcsize,PETSC_DECIDE,PETSC_DECIDE);
1240 ierr = MatSetType(
A,MATIS); PCHKERRQ(
A,ierr);
1241 ierr = MatSetLocalToGlobalMapping(
A,rl2g,cl2g); PCHKERRQ(
A,ierr);
1242 ierr = ISLocalToGlobalMappingDestroy(&rl2g); PCHKERRQ(
A,ierr)
1243 ierr = ISLocalToGlobalMappingDestroy(&cl2g); PCHKERRQ(
A,ierr)
1248 ierr = MatISGetLocalMat(
A,&lA); PCHKERRQ(
A,ierr);
1251#if defined(PETSC_USE_64BIT_INDICES)
1254 ierr = PetscMalloc2(m,&pII,nnz,&pJJ); PCHKERRQ(lA,ierr);
1255 for (
int i = 0; i < m; i++) { pII[i] = II[i]; }
1256 for (
int i = 0; i < nnz; i++) { pJJ[i] = JJ[i]; }
1257 ierr = MatSeqAIJSetPreallocationCSR(lA,pII,pJJ,
1259 ierr = PetscFree2(pII,pJJ); PCHKERRQ(lA,ierr);
1261 ierr = MatSeqAIJSetPreallocationCSR(lA,II,JJ,
1274 ierr = PetscMalloc1(m,&dii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1275 ierr = PetscMalloc1(nnz,&djj); CCHKERRQ(PETSC_COMM_SELF,ierr);
1276 ierr = PetscMalloc1(nnz,&da); CCHKERRQ(PETSC_COMM_SELF,ierr);
1277 if (
sizeof(
PetscInt) ==
sizeof(
int))
1280 CCHKERRQ(PETSC_COMM_SELF,ierr);
1282 CCHKERRQ(PETSC_COMM_SELF,ierr);
1288 for (
int i = 0; i < m; i++) { dii[i] = iii[i]; }
1289 for (
int i = 0; i < nnz; i++) { djj[i] = jjj[i]; }
1292 CCHKERRQ(PETSC_COMM_SELF,ierr);
1293 ierr = PetscCalloc1(m,&oii);
1294 CCHKERRQ(PETSC_COMM_SELF,ierr);
1297 ierr = MatCreateMPIAIJWithSplitArrays(comm,lrsize,lcsize,PETSC_DECIDE,
1299 dii,djj,da,oii,NULL,NULL,&
A);
1300 CCHKERRQ(comm,ierr);
1304 ierr = MatCreateSeqAIJWithArrays(comm,lrsize,lcsize,dii,djj,da,&
A);
1305 CCHKERRQ(comm,ierr);
1308 void *ptrs[4] = {dii,djj,da,oii};
1309 const char *names[4] = {
"_mfem_csr_dii",
1318 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
1319 ierr = PetscContainerSetPointer(c,ptrs[i]); CCHKERRQ(comm,ierr);
1320 ierr = PetscContainerSetCtxDestroy(c,__mfem_array_container_destroy);
1321 CCHKERRQ(comm,ierr);
1323 CCHKERRQ(comm,ierr);
1324 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
1329 ierr = MatAssemblyBegin(
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(
A,ierr);
1330 ierr = MatAssemblyEnd(
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(
A,ierr);
1350 ierr = MatCreate(comm,
A); CCHKERRQ(comm,ierr);
1352 PETSC_DECIDE,PETSC_DECIDE); PCHKERRQ(
A,ierr);
1353 ierr = MatSetType(*
A,MATSHELL); PCHKERRQ(
A,ierr);
1354 ierr = MatShellSetContext(*
A,(
void *)op); PCHKERRQ(
A,ierr);
1355#if PETSC_VERSION_LT(3,24,0)
1356 ierr = MatShellSetOperation(*
A,MATOP_MULT,
1357 (
void (*)())__mfem_mat_shell_apply);
1359 ierr = MatShellSetOperation(*
A,MATOP_MULT_TRANSPOSE,
1360 (
void (*)())__mfem_mat_shell_apply_transpose);
1362 ierr = MatShellSetOperation(*
A,MATOP_COPY,
1363 (
void (*)())__mfem_mat_shell_copy);
1365 ierr = MatShellSetOperation(*
A,MATOP_DESTROY,
1366 (
void (*)())__mfem_mat_shell_destroy);
1368 ierr = MatShellSetOperation(*
A,MATOP_MULT,
1369 (PetscErrorCodeFn*)__mfem_mat_shell_apply);
1371 ierr = MatShellSetOperation(*
A,MATOP_MULT_TRANSPOSE,
1372 (PetscErrorCodeFn*)__mfem_mat_shell_apply_transpose);
1374 ierr = MatShellSetOperation(*
A,MATOP_COPY,
1375 (PetscErrorCodeFn*)__mfem_mat_shell_copy);
1377 ierr = MatShellSetOperation(*
A,MATOP_DESTROY,
1378 (PetscErrorCodeFn*)__mfem_mat_shell_destroy);
1380#if defined(_USE_DEVICE)
1384 ierr = MatShellSetVecType(*
A,PETSC_VECDEVICE); PCHKERRQ(
A,ierr);
1385 ierr = MatBindToCPU(*
A,PETSC_FALSE); PCHKERRQ(
A,ierr);
1389 ierr = MatBindToCPU(*
A,PETSC_TRUE); PCHKERRQ(
A,ierr);
1393 ierr = MatSetUp(*
A); PCHKERRQ(*
A,ierr);
1418 PetscBool avoidmatconvert = PETSC_FALSE;
1421 ierr = PetscObjectTypeCompareAny((
PetscObject)(pA->
A),&avoidmatconvert,MATMFFD,
1423 CCHKERRQ(comm,ierr);
1425 if (pA && !avoidmatconvert)
1429#if PETSC_VERSION_LT(3,10,0)
1433#if PETSC_VERSION_LT(3,18,0)
1434 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATTRANSPOSEMAT,&istrans);
1436 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATTRANSPOSEVIRTUAL,
1449#if PETSC_VERSION_LT(3,10,0)
1450 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATIS,&ismatis);
1456 ierr = MatTransposeGetMat(pA->
A,&At); CCHKERRQ(pA->
GetComm(),ierr);
1457#if PETSC_VERSION_LT(3,10,0)
1458 ierr = PetscObjectTypeCompare((
PetscObject)(At),MATIS,&ismatis);
1466#if PETSC_VERSION_LT(3,10,0)
1473 ierr = MatISGetMPIXAIJ(At,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1474 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1475 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1479 ierr = MatISGetMPIXAIJ(pA->
A,MAT_INITIAL_MATRIX,
A);
1480 PCHKERRQ(pA->
A,ierr);
1487 mpiierr = MPI_Comm_size(comm,&size); CCHKERRQ(comm,mpiierr);
1493 ierr = MatConvert(At,size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);
1494 PCHKERRQ(pA->
A,ierr);
1495 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1496 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1500 ierr = MatConvert(pA->
A, size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,
A);
1501 PCHKERRQ(pA->
A,ierr);
1510 ierr = MatConvert(At,MATIS,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1511 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1512 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1516 ierr = MatConvert(pA->
A,MATIS,MAT_INITIAL_MATRIX,
A); PCHKERRQ(pA->
A,ierr);
1524 ierr = MatConvert(At,MATHYPRE,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1525 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1526 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1530 ierr = MatConvert(pA->
A,MATHYPRE,MAT_INITIAL_MATRIX,
A); PCHKERRQ(pA->
A,ierr);
1539 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1546 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATAIJ,
1547 PETSC_USE_POINTER,
A);
1552 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATIS,
1553 PETSC_USE_POINTER,
A);
1558 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATHYPRE,
1559 PETSC_USE_POINTER,
A);
1568 MFEM_ABORT(
"Conversion from HypreParCSR to operator type = " << tid <<
1569 " is not implemented");
1574 Mat *mats,*matsl2l = NULL;
1579 ierr = PetscCalloc1(nr*nc,&mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1582 ierr = PetscCalloc1(nr,&matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1584 for (i=0; i<nr; i++)
1586 PetscBool needl2l = PETSC_TRUE;
1588 for (j=0; j<nc; j++)
1596 ierr = PetscObjectQuery((
PetscObject)mats[i*nc+j],
"_MatIS_PtAP_l2l",
1598 PCHKERRQ(mats[i*nc+j],ierr);
1606 ierr = PetscContainerGetPointer(c,(
void**)&l2l);
1608 MFEM_VERIFY(l2l->
Size() == 1,
"Unexpected size "
1609 << l2l->
Size() <<
" for block row " << i );
1610 ierr = PetscObjectReference((
PetscObject)(*l2l)[0]);
1612 matsl2l[i] = (*l2l)[0];
1613 needl2l = PETSC_FALSE;
1619 ierr = MatCreateNest(comm,nr,NULL,nc,NULL,mats,
A); CCHKERRQ(comm,ierr);
1622 ierr = MatConvert(*
A,MATIS,MAT_INPLACE_MATRIX,
A); CCHKERRQ(comm,ierr);
1625 for (
int i=0; i<(int)nr; i++) { (*vmatsl2l)[i] = matsl2l[i]; }
1626 ierr = PetscFree(matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1629 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
1630 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
1631 ierr = PetscContainerSetCtxDestroy(c,__mfem_matarray_container_destroy);
1634 PCHKERRQ((*
A),ierr);
1635 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
1637 for (i=0; i<nr*nc; i++) { ierr = MatDestroy(&mats[i]); CCHKERRQ(comm,ierr); }
1638 ierr = PetscFree(mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1644 ierr = MatCreate(comm,
A); CCHKERRQ(comm,ierr);
1645 ierr = MatSetSizes(*
A,pI->
Height(),pI->
Width(),PETSC_DECIDE,PETSC_DECIDE);
1647 ierr = MatSetType(*
A,MATAIJ); PCHKERRQ(*
A,ierr);
1648 ierr = MatMPIAIJSetPreallocation(*
A,1,NULL,0,NULL); PCHKERRQ(*
A,ierr);
1649 ierr = MatSeqAIJSetPreallocation(*
A,1,NULL); PCHKERRQ(*
A,ierr);
1650 ierr = MatSetOption(*
A,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE); PCHKERRQ(*
A,ierr);
1651 ierr = MatGetOwnershipRange(*
A,&rst,NULL); PCHKERRQ(*
A,ierr);
1654 ierr = MatSetValue(*
A,i,i,1.,INSERT_VALUES); PCHKERRQ(*
A,ierr);
1656 ierr = MatAssemblyBegin(*
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*
A,ierr);
1657 ierr = MatAssemblyEnd(*
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*
A,ierr);
1674 int n = pS->
Width();
1679 ierr = PetscMalloc1(m+1,&pii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1680 ierr = PetscMalloc1(ii[m],&pjj); CCHKERRQ(PETSC_COMM_SELF,ierr);
1681 ierr = PetscMalloc1(ii[m],&pdata); CCHKERRQ(PETSC_COMM_SELF,ierr);
1683 for (
int i = 0; i < m; i++)
1685 bool issorted =
true;
1687 for (
int j = ii[i]; j < ii[i+1]; j++)
1690 if (issorted && j != ii[i]) { issorted = (pjj[j] > pjj[j-1]); }
1695 ierr = PetscSortIntWithScalarArray(pii[i+1]-pii[i],pjj + pii[i],pdata + pii[i]);
1696 CCHKERRQ(PETSC_COMM_SELF,ierr);
1700 mpiierr = MPI_Comm_size(comm,&size); CCHKERRQ(comm,mpiierr);
1703 ierr = MatCreateSeqAIJWithArrays(comm,m,n,pii,pjj,pdata,&B);
1704 CCHKERRQ(comm,ierr);
1709 ierr = PetscCalloc1(m+1,&oii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1710 ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,
1712 pii,pjj,pdata,oii,NULL,NULL,&B);
1713 CCHKERRQ(comm,ierr);
1715 void *ptrs[4] = {pii,pjj,pdata,oii};
1716 const char *names[4] = {
"_mfem_csr_pii",
1721 for (
int i=0; i<4; i++)
1725 ierr = PetscContainerCreate(PETSC_COMM_SELF,&c); PCHKERRQ(B,ierr);
1726 ierr = PetscContainerSetPointer(c,ptrs[i]); PCHKERRQ(B,ierr);
1727 ierr = PetscContainerSetCtxDestroy(c,__mfem_array_container_destroy);
1731 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
1739 ierr = MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,
A); PCHKERRQ(B,ierr);
1740 ierr = MatDestroy(&B); PCHKERRQ(*
A,ierr);
1744 ierr = MatConvert(B,MATIS,MAT_INITIAL_MATRIX,
A); PCHKERRQ(B,ierr);
1745 ierr = MatDestroy(&B); PCHKERRQ(*
A,ierr);
1749 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1756 "Supported types are ANY_TYPE, PETSC_MATSHELL or PETSC_MATAIJ");
1763 ierr = MatComputeOperator(*
A,MATMPIAIJ,&B); CCHKERRQ(comm,ierr);
1764 ierr = PetscObjectTypeCompare((
PetscObject)B,MATMPIAIJ,&isaij);
1765 CCHKERRQ(comm,ierr);
1766 ierr = MatDestroy(
A); CCHKERRQ(comm,ierr);
1769 ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,
A); CCHKERRQ(comm,ierr);
1770 ierr = MatDestroy(&B); CCHKERRQ(comm,ierr);
1785 MPI_Comm comm = MPI_COMM_NULL;
1786 ierr = PetscObjectGetComm((
PetscObject)
A,&comm); PCHKERRQ(
A,ierr);
1787 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1798 ierr = PetscObjectReference((
PetscObject)
a); PCHKERRQ(
a,ierr);
1808 if (A_ ==
A) {
return; }
1810 ierr = PetscObjectReference((
PetscObject)A_); PCHKERRQ(A_,ierr);
1816void PetscParMatrix::SetUpForDevice()
1818#if !defined(_USE_DEVICE)
1824 if (
A) { ierr = MatBindToCPU(
A, PETSC_TRUE); PCHKERRQ(
A,ierr); }
1827 PetscBool ismatis,isnest,isaij;
1828 ierr = PetscObjectTypeCompare((
PetscObject)
A,MATIS,&ismatis);
1830 ierr = PetscObjectTypeCompare((
PetscObject)
A,MATNEST,&isnest);
1835 ierr = MatISGetLocalMat(
A,&tA); PCHKERRQ(
A,ierr);
1836 ierr = PetscObjectTypeCompare((
PetscObject)tA,MATNEST,&isnest);
1843 ierr = MatNestGetSubMats(tA,&n,&m,&sub); PCHKERRQ(tA,ierr);
1853 ierr = PetscObjectTypeCompareAny((
PetscObject)sA,&isaij,MATSEQAIJ,MATMPIAIJ,
"");
1857 ierr = MatSetType(sA,PETSC_MATAIJDEVICE); PCHKERRQ(sA,ierr);
1863 ierr = MatSetOption(sA,MAT_FORM_EXPLICIT_TRANSPOSE,
1864 PETSC_TRUE); PCHKERRQ(sA,ierr);
1871 ierr = MatSetVecType(tA,PETSC_VECDEVICE); PCHKERRQ(tA,ierr);
1877 ierr = PetscObjectTypeCompareAny((
PetscObject)tA,&isaij,MATSEQAIJ,MATMPIAIJ,
"");
1881 ierr = MatSetType(tA,PETSC_MATAIJDEVICE); PCHKERRQ(tA,ierr);
1886 ierr = MatSetOption(tA,MAT_FORM_EXPLICIT_TRANSPOSE,
1887 PETSC_TRUE); PCHKERRQ(tA,ierr);
1902 f = MatMultTranspose;
1903 fadd = MatMultTransposeAdd;
1914 ierr = VecScale(Y,
b/
a); PCHKERRQ(A,ierr);
1915 ierr = (*fadd)(A,X,Y,Y); PCHKERRQ(A,ierr);
1916 ierr = VecScale(Y,
a); PCHKERRQ(A,ierr);
1920 ierr = (*f)(A,X,Y); PCHKERRQ(A,ierr);
1921 ierr = VecScale(Y,
a); PCHKERRQ(A,ierr);
1932 ierr = VecScale(Y,
b); PCHKERRQ(A,ierr);
1936 ierr = VecSet(Y,0.); PCHKERRQ(A,ierr);
1943 ierr = PetscObjectReference((
PetscObject)master.
A); PCHKERRQ(master.
A,ierr);
1955 MFEM_VERIFY(
A,
"Mat not present");
1965 MFEM_VERIFY(
A,
"Mat not present");
1976 ierr = MatCreateTranspose(
A,&B); PCHKERRQ(
A,ierr);
1980 ierr = MatTranspose(
A,MAT_INITIAL_MATRIX,&B); PCHKERRQ(
A,ierr);
1987 ierr = MatScale(
A,s); PCHKERRQ(
A,ierr);
1993 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1994 <<
", expected size = " <<
Width());
1995 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1996 <<
", expected size = " <<
Height());
2000 bool rw = (
b != 0.0);
2003 MatMultKernel(
A,
a,XX->
x,
b,YY->
x,
false);
2012 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
2013 <<
", expected size = " <<
Height());
2014 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
2015 <<
", expected size = " <<
Width());
2019 bool rw = (
b != 0.0);
2022 MatMultKernel(
A,
a,YY->
x,
b,XX->
x,
true);
2035 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)
A),fname,
2036 FILE_MODE_WRITE,&view);
2040 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)
A),fname,&view);
2043 ierr = MatView(
A,view); PCHKERRQ(
A,ierr);
2044 ierr = PetscViewerDestroy(&view); PCHKERRQ(
A,ierr);
2048 ierr = MatView(
A,NULL); PCHKERRQ(
A,ierr);
2054 MFEM_ASSERT(s.
Size() ==
Height(),
"invalid s.Size() = " << s.
Size()
2055 <<
", expected size = " <<
Height());
2059 ierr = MatDiagonalScale(
A,*YY,NULL); PCHKERRQ(
A,ierr);
2065 MFEM_ASSERT(s.
Size() ==
Width(),
"invalid s.Size() = " << s.
Size()
2066 <<
", expected size = " <<
Width());
2070 ierr = MatDiagonalScale(
A,NULL,*XX); PCHKERRQ(
A,ierr);
2082 MFEM_ASSERT(s.
Size() ==
Height(),
"invalid s.Size() = " << s.
Size()
2083 <<
", expected size = " <<
Height());
2084 MFEM_ASSERT(s.
Size() ==
Width(),
"invalid s.Size() = " << s.
Size()
2085 <<
", expected size = " <<
Width());
2089 ierr = MatDiagonalSet(
A,*XX,ADD_VALUES); PCHKERRQ(
A,ierr);
2097 "Petsc TripleMatrixProduct: Number of local cols of A " << A->
Width() <<
2098 " differs from number of local rows of P " << P->
Height());
2100 "Petsc TripleMatrixProduct: Number of local rows of A " << A->
Height() <<
2101 " differs from number of local cols of R " << R->
Width());
2103 ierr = MatMatMatMult(*R,*A,*P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2110 Mat pA = *A,pP = *P,pRt = *Rt;
2112 PetscBool Aismatis,Pismatis,Rtismatis;
2115 "Petsc RAP: Number of local cols of A " << A->
Width() <<
2116 " differs from number of local rows of P " << P->
Height());
2118 "Petsc RAP: Number of local rows of A " << A->
Height() <<
2119 " differs from number of local rows of Rt " << Rt->
Height());
2120 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&Aismatis);
2122 ierr = PetscObjectTypeCompare((
PetscObject)pP,MATIS,&Pismatis);
2124 ierr = PetscObjectTypeCompare((
PetscObject)pRt,MATIS,&Rtismatis);
2131 ISLocalToGlobalMapping cl2gP,cl2gRt;
2132 PetscInt rlsize,clsize,rsize,csize;
2134 ierr = MatGetLocalToGlobalMapping(pP,NULL,&cl2gP); PCHKERRQ(pA,ierr);
2135 ierr = MatGetLocalToGlobalMapping(pRt,NULL,&cl2gRt); PCHKERRQ(pA,ierr);
2136 ierr = MatGetLocalSize(pP,NULL,&clsize); PCHKERRQ(pP,ierr);
2137 ierr = MatGetLocalSize(pRt,NULL,&rlsize); PCHKERRQ(pRt,ierr);
2138 ierr = MatGetSize(pP,NULL,&csize); PCHKERRQ(pP,ierr);
2139 ierr = MatGetSize(pRt,NULL,&rsize); PCHKERRQ(pRt,ierr);
2140 ierr = MatCreate(A->
GetComm(),&B); PCHKERRQ(pA,ierr);
2141 ierr = MatSetSizes(B,rlsize,clsize,rsize,csize); PCHKERRQ(B,ierr);
2142 ierr = MatSetType(B,MATIS); PCHKERRQ(B,ierr);
2143 ierr = MatSetLocalToGlobalMapping(B,cl2gRt,cl2gP); PCHKERRQ(B,ierr);
2144 ierr = MatISGetLocalMat(pA,&lA); PCHKERRQ(pA,ierr);
2145 ierr = MatISGetLocalMat(pP,&lP); PCHKERRQ(pA,ierr);
2146 ierr = MatISGetLocalMat(pRt,&lRt); PCHKERRQ(pA,ierr);
2149 ierr = MatPtAP(lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
2155 ierr = MatTranspose(lRt,MAT_INITIAL_MATRIX,&lR); PCHKERRQ(lRt,ierr);
2156 ierr = MatMatMatMult(lR,lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
2158 ierr = MatDestroy(&lR); PCHKERRQ(lRt,ierr);
2166 ierr = PetscObjectReference((
PetscObject)lRt); PCHKERRQ(lRt,ierr);
2167 (*vmatsl2l)[0] = lRt;
2170 ierr = PetscContainerCreate(PetscObjectComm((
PetscObject)B),&c);
2172 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
2173 ierr = PetscContainerSetCtxDestroy(c,__mfem_matarray_container_destroy);
2177 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
2181 ierr = MatISSetLocalMat(B,lB); PCHKERRQ(lB,ierr);
2182 ierr = MatDestroy(&lB); PCHKERRQ(lA,ierr);
2183 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
2184 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
2190 ierr = MatPtAP(pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2196 ierr = MatTranspose(pRt,MAT_INITIAL_MATRIX,&pR); PCHKERRQ(Rt,ierr);
2197 ierr = MatMatMatMult(pR,pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2199 ierr = MatDestroy(&pR); PCHKERRQ(pRt,ierr);
2225 ierr = MatMatMult(*A,*B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AB);
2235 ierr = MatDuplicate(
A,MAT_COPY_VALUES,&Ae); PCHKERRQ(
A,ierr);
2237 ierr = MatAXPY(Ae,-1.,
A,SAME_NONZERO_PATTERN); PCHKERRQ(
A,ierr);
2246 MFEM_ABORT(
"Missing PetscParMatrix::EliminateRowsCols() with HypreParVectors");
2255 ierr = MatGetSize(
A,&
M,&
N); PCHKERRQ(
A,ierr);
2256 MFEM_VERIFY(
M ==
N,
"Rectangular case unsupported");
2259 ierr = MatSetOption(
A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(
A,ierr);
2263 ierr = MatGetOwnershipRange(
A,&rst,NULL); PCHKERRQ(
A,ierr);
2266 ierr = Convert_Array_IS(
GetComm(),
true,&rows_cols,rst,&dir); PCHKERRQ(
A,ierr);
2269 ierr = MatZeroRowsColumnsIS(
A,dir,diag,NULL,NULL); PCHKERRQ(
A,ierr);
2273 ierr = MatZeroRowsColumnsIS(
A,dir,diag,
X,B); PCHKERRQ(
A,ierr);
2275 ierr = ISDestroy(&dir); PCHKERRQ(
A,ierr);
2280 ierr = MatSetOption(
A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(
A,ierr);
2284 ierr = MatGetOwnershipRange(
A,&rst,NULL); PCHKERRQ(
A,ierr);
2287 ierr = Convert_Array_IS(
GetComm(),
true,&rows,rst,&dir); PCHKERRQ(
A,ierr);
2288 ierr = MatZeroRowsIS(
A,dir,0.0,NULL,NULL); PCHKERRQ(
A,ierr);
2289 ierr = ISDestroy(&dir); PCHKERRQ(
A,ierr);
2299 ierr = PetscObjectDereference((
PetscObject)
A); CCHKERRQ(comm,ierr);
2308 MFEM_VERIFY(
A,
"no associated PETSc Mat object");
2311 ierr = PetscObjectBaseTypeCompare(oA, MATSEQAIJ, &ok); PCHKERRQ(
A,ierr);
2313 ierr = PetscObjectBaseTypeCompare(oA, MATMPIAIJ, &ok); PCHKERRQ(
A,ierr);
2315 ierr = PetscObjectTypeCompare(oA, MATIS, &ok); PCHKERRQ(
A,ierr);
2317 ierr = PetscObjectTypeCompare(oA, MATSHELL, &ok); PCHKERRQ(
A,ierr);
2319 ierr = PetscObjectTypeCompare(oA, MATNEST, &ok); PCHKERRQ(
A,ierr);
2321 ierr = PetscObjectTypeCompare(oA, MATHYPRE, &ok); PCHKERRQ(
A,ierr);
2334 Ae.
Mult(-1.0, X, 1.0, B);
2337 ierr = MatGetDiagonal(pA,diag); PCHKERRQ(pA,ierr);
2338 ierr = VecGetArrayRead(diag,&array); PCHKERRQ(diag,ierr);
2339 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2341 int r = ess_dof_list[i];
2342 B(r) = array[r] * X(r);
2344 ierr = VecRestoreArrayRead(diag,&array); PCHKERRQ(diag,ierr);
2373 if (
cid == KSP_CLASSID)
2376 ierr = KSPSetTolerances(ksp,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2378 else if (
cid == SNES_CLASSID)
2380 SNES snes = (SNES)
obj;
2381 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT,
2384 else if (
cid == TS_CLASSID)
2387 ierr = TSSetTolerances(ts,PETSC_DECIDE,NULL,tol,NULL);
2391 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2398 if (
cid == KSP_CLASSID)
2401 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT);
2403 else if (
cid == SNES_CLASSID)
2405 SNES snes = (SNES)
obj;
2406 ierr = SNESSetTolerances(snes,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2409 else if (
cid == TS_CLASSID)
2412 ierr = TSSetTolerances(ts,tol,NULL,PETSC_DECIDE,NULL);
2416 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2423 if (
cid == KSP_CLASSID)
2426 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2429 else if (
cid == SNES_CLASSID)
2431 SNES snes = (SNES)
obj;
2432 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2433 max_iter,PETSC_DEFAULT);
2435 else if (
cid == TS_CLASSID)
2438 ierr = TSSetMaxSteps(ts,max_iter);
2442 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2450 PetscViewerAndFormat *vf = NULL;
2451 PetscViewer viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm(
obj));
2455 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
2458 if (
cid == KSP_CLASSID)
2465 ierr = KSPMonitorCancel(ksp); PCHKERRQ(ksp,ierr);
2469#if PETSC_VERSION_LT(3,15,0)
2470 ierr = KSPMonitorSet(ksp,(
KSPMonitorFn *)KSPMonitorDefault,vf,
2472 ierr = KSPMonitorSet(ksp,(
KSPMonitorFn *)KSPMonitorResidual,vf,
2479 ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE); PCHKERRQ(ksp,ierr);
2480 ierr = KSPMonitorSet(ksp,(
KSPMonitorFn *)KSPMonitorSingularValue,vf,
2485 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
2486 PCHKERRQ(viewer,ierr);
2487#if PETSC_VERSION_LT(3,15,0)
2488 ierr = KSPMonitorSet(ksp,(
KSPMonitorFn *)KSPMonitorTrueResidualNorm,vf,
2490 ierr = KSPMonitorSet(ksp,(
KSPMonitorFn *)KSPMonitorTrueResidual,vf,
2497 else if (
cid == SNES_CLASSID)
2500 SNES snes = (SNES)
obj;
2503 ierr = SNESMonitorCancel(snes); PCHKERRQ(snes,ierr);
2507 ierr = SNESMonitorSet(snes,(myMonitor)SNESMonitorDefault,vf,
2509 PCHKERRQ(snes,ierr);
2512 else if (
cid == TS_CLASSID)
2517 ierr = TSMonitorCancel(ts); PCHKERRQ(ts,ierr);
2522 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2528 return obj ? PetscObjectComm(
obj) : MPI_COMM_NULL;
2533 __mfem_monitor_ctx *monctx;
2534 ierr = PetscNew(&monctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2535 monctx->solver =
this;
2536 monctx->monitor =
ctx;
2537 if (
cid == KSP_CLASSID)
2539 ierr = KSPMonitorSet((KSP)
obj,__mfem_ksp_monitor,monctx,
2540 __mfem_monitor_ctx_destroy);
2543 else if (
cid == SNES_CLASSID)
2545 ierr = SNESMonitorSet((SNES)
obj,__mfem_snes_monitor,monctx,
2546 __mfem_monitor_ctx_destroy);
2549 else if (
cid == TS_CLASSID)
2551 ierr = TSMonitorSet((TS)
obj,__mfem_ts_monitor,monctx,
2552 __mfem_monitor_ctx_destroy);
2557 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2564 if (
cid == SNES_CLASSID)
2566 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
private_ctx;
2569 else if (
cid == TS_CLASSID)
2571 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
private_ctx;
2576 MFEM_ABORT(
"Handling of essential bc only implemented for nonlinear and time-dependent solvers");
2583 if (
cid == TS_CLASSID)
2588 ierr = TSGetSNES((TS)
obj,&snes); PCHKERRQ(
obj,ierr);
2589 ierr = SNESGetKSP(snes,&ksp); PCHKERRQ(
obj,ierr);
2590 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(
obj,ierr);
2592 else if (
cid == SNES_CLASSID)
2596 ierr = SNESGetKSP((SNES)
obj,&ksp); PCHKERRQ(
obj,ierr);
2597 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(
obj,ierr);
2599 else if (
cid == KSP_CLASSID)
2601 ierr = KSPGetPC((KSP)
obj,&pc); PCHKERRQ(
obj,ierr);
2603 else if (
cid == PC_CLASSID)
2609 MFEM_ABORT(
"No support for PetscPreconditionerFactory for this object");
2613 ierr = MakeShellPCWithFactory(pc,factory); PCHKERRQ(pc,ierr);
2617 ierr = PCSetType(pc, PCNONE); PCHKERRQ(pc,ierr);
2623 if (!customize) {
clcustom =
true; }
2626 if (
cid == PC_CLASSID)
2629 ierr = PCSetFromOptions(pc); PCHKERRQ(pc, ierr);
2631 else if (
cid == KSP_CLASSID)
2634 ierr = KSPSetFromOptions(ksp); PCHKERRQ(ksp, ierr);
2636 else if (
cid == SNES_CLASSID)
2638 SNES snes = (SNES)
obj;
2639 ierr = SNESSetFromOptions(snes); PCHKERRQ(snes, ierr);
2641 else if (
cid == TS_CLASSID)
2644 ierr = TSSetFromOptions(ts); PCHKERRQ(ts, ierr);
2648 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2656 if (
cid == KSP_CLASSID)
2659 KSPConvergedReason reason;
2660 ierr = KSPGetConvergedReason(ksp,&reason);
2662 return reason > 0 ? 1 : 0;
2664 else if (
cid == SNES_CLASSID)
2666 SNES snes = (SNES)
obj;
2667 SNESConvergedReason reason;
2668 ierr = SNESGetConvergedReason(snes,&reason);
2669 PCHKERRQ(snes,ierr);
2670 return reason > 0 ? 1 : 0;
2672 else if (
cid == TS_CLASSID)
2675 TSConvergedReason reason;
2676 ierr = TSGetConvergedReason(ts,&reason);
2678 return reason > 0 ? 1 : 0;
2682 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2689 if (
cid == KSP_CLASSID)
2693 ierr = KSPGetIterationNumber(ksp,&its);
2697 else if (
cid == SNES_CLASSID)
2699 SNES snes = (SNES)
obj;
2701 ierr = SNESGetIterationNumber(snes,&its);
2702 PCHKERRQ(snes,ierr);
2705 else if (
cid == TS_CLASSID)
2709 ierr = TSGetStepNumber(ts,&its);
2715 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2722 if (
cid == KSP_CLASSID)
2726 ierr = KSPGetResidualNorm(ksp,&
norm);
2730 if (
cid == SNES_CLASSID)
2732 SNES snes = (SNES)
obj;
2734 ierr = SNESGetFunctionNorm(snes,&
norm);
2735 PCHKERRQ(snes,ierr);
2740 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2741 return PETSC_MAX_REAL;
2748 if (
cid == SNES_CLASSID)
2750 __mfem_snes_ctx *snes_ctx;
2751 ierr = PetscNew(&snes_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2752 snes_ctx->op = NULL;
2753 snes_ctx->bchandler = NULL;
2754 snes_ctx->work = NULL;
2758 else if (
cid == TS_CLASSID)
2760 __mfem_ts_ctx *ts_ctx;
2761 ierr = PetscNew(&ts_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2763 ts_ctx->bchandler = NULL;
2764 ts_ctx->work = NULL;
2765 ts_ctx->work2 = NULL;
2766 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
2767 ts_ctx->cached_ijacstate = -1;
2768 ts_ctx->cached_rhsjacstate = -1;
2769 ts_ctx->cached_splits_xstate = -1;
2770 ts_ctx->cached_splits_xdotstate = -1;
2781 if (
cid == SNES_CLASSID)
2783 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx *)
private_ctx;
2784 delete snes_ctx->work;
2786 else if (
cid == TS_CLASSID)
2788 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx *)
private_ctx;
2789 delete ts_ctx->work;
2790 delete ts_ctx->work2;
2792 ierr = PetscFree(
private_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2799 : bctype(type_), setup(false), eval_t(0.0),
2807 ess_tdof_list.
SetSize(list.Size());
2808 ess_tdof_list.
Assign(list);
2814 if (setup) {
return; }
2818 this->
Eval(eval_t,eval_g);
2819 eval_t_cached = eval_t;
2830 (*this).SetUp(x.
Size());
2834 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2836 y[ess_tdof_list[i]] = 0.0;
2841 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2843 Eval(eval_t,eval_g);
2844 eval_t_cached = eval_t;
2846 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2855 (*this).SetUp(x.
Size());
2858 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2860 x[ess_tdof_list[i]] = 0.0;
2865 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2867 Eval(eval_t,eval_g);
2868 eval_t_cached = eval_t;
2870 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2879 (*this).SetUp(x.
Size());
2882 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2889 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2898 (*this).SetUp(x.
Size());
2899 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2901 x[ess_tdof_list[i]] = 0.0;
2907 (*this).SetUp(x.
Size());
2909 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2911 y[ess_tdof_list[i]] = 0.0;
2918 bool wrapin,
bool iter_mode)
2922 ierr = KSPCreate(comm,&ksp); CCHKERRQ(comm,ierr);
2924 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2925 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2926 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2927 PCHKERRQ(ksp, ierr);
2931 const std::string &prefix,
bool iter_mode)
2937 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2938 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2939 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2940 PCHKERRQ(ksp, ierr);
2945 const std::string &prefix,
bool iter_mode)
2951 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
2952 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2953 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2954 PCHKERRQ(ksp, ierr);
2966 bool delete_pA =
false;
2984 MFEM_VERIFY(pA,
"Unsupported operation!");
2992 PetscInt nheight,nwidth,oheight,owidth;
2994 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
2995 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
2996 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
2997 if (nheight != oheight || nwidth != owidth)
3001 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
3007 ierr = KSPSetOperators(ksp,A,A); PCHKERRQ(ksp,ierr);
3016 if (delete_pA) {
delete pA; }
3031 bool delete_pA =
false;
3049 MFEM_VERIFY(pA,
"Unsupported operation!");
3052 bool delete_ppA =
false;
3055 if (oA == poA && !wrap)
3065 MFEM_VERIFY(ppA,
"Unsupported operation!");
3074 PetscInt nheight,nwidth,oheight,owidth;
3076 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
3077 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
3078 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
3079 if (nheight != oheight || nwidth != owidth)
3083 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
3090 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
3099 if (delete_pA) {
delete pA; }
3100 if (delete_ppA) {
delete ppA; }
3110 ierr = KSPGetOperatorsSet(ksp,&amat,NULL); PCHKERRQ(ksp,ierr);
3113 ierr = KSPGetOperators(ksp,&A,NULL); PCHKERRQ(ksp,ierr);
3114 ierr = PetscObjectReference((
PetscObject)A); PCHKERRQ(ksp,ierr);
3119 ierr = KSPSetPC(ksp,*ppc); PCHKERRQ(ksp,ierr);
3128 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(ksp,ierr);
3129 ierr = MakeShellPC(pc,precond,
false); PCHKERRQ(ksp,ierr);
3135 ierr = KSPGetOperators(ksp,NULL,&P); PCHKERRQ(ksp,ierr);
3136 ierr = PetscObjectReference((
PetscObject)P); PCHKERRQ(ksp,ierr);
3137 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
3138 ierr = MatDestroy(&A); PCHKERRQ(ksp,ierr);
3139 ierr = MatDestroy(&P); PCHKERRQ(ksp,ierr);
3150 ierr = KSPGetOperators(ksp, &pA, NULL); PCHKERRQ(
obj, ierr);
3158 PetscParMatrix A = PetscParMatrix(pA,
true);
3159 X =
new PetscParVector(A,
false,
false);
3167 ierr = KSPGetInitialGuessNonzero(ksp, &flg);
3173 ierr = KSPSolveTranspose(ksp,
B->
x,
X->
x); PCHKERRQ(ksp,ierr);
3177 ierr = KSPSolve(ksp,
B->
x,
X->
x); PCHKERRQ(ksp,ierr);
3185 (*this).MultKernel(
b,x,
false);
3190 (*this).MultKernel(
b,x,
true);
3197 ierr = PetscObjectGetComm((
PetscObject)ksp,&comm); PCHKERRQ(ksp,ierr);
3198 ierr = KSPDestroy(&ksp); CCHKERRQ(comm,ierr);
3208 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3210 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3218 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3220 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3224 const std::string &prefix,
bool iter_mode)
3228 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3230 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3236 const std::string &prefix)
3240 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
3242 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3243 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3247 const string &prefix)
3253 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3254 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3259 const string &prefix)
3263 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
3265 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3266 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3272 bool delete_pA =
false;
3289 PetscInt nheight,nwidth,oheight,owidth;
3291 ierr = PCGetOperators(pc,&C,NULL); PCHKERRQ(pc,ierr);
3292 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
3293 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
3294 if (nheight != oheight || nwidth != owidth)
3298 ierr = PCReset(pc); PCHKERRQ(pc,ierr);
3304 ierr = PCSetOperators(pc,pA->
A,pA->
A); PCHKERRQ(
obj,ierr);
3313 if (delete_pA) {
delete pA; };
3316void PetscPreconditioner::MultKernel(
const Vector &
b,
Vector &x,
3320 "Iterative mode not supported for PetscPreconditioner");
3326 ierr = PCGetOperators(pc, NULL, &pA); PCHKERRQ(
obj, ierr);
3334 PetscParMatrix A(pA,
true);
3335 X =
new PetscParVector(A,
false,
false);
3346 ierr = PCApplyTranspose(pc,
B->
x,
X->
x); PCHKERRQ(pc, ierr);
3350 ierr = PCApply(pc,
B->
x,
X->
x); PCHKERRQ(pc, ierr);
3358 (*this).MultKernel(
b,x,
false);
3363 (*this).MultKernel(
b,x,
true);
3370 ierr = PetscObjectGetComm((
PetscObject)pc,&comm); PCHKERRQ(pc,ierr);
3371 ierr = PCDestroy(&pc); CCHKERRQ(comm,ierr);
3382void PetscBDDCSolver::BDDCSolverConstructor(
const PetscBDDCSolverParams &opts)
3384 MPI_Comm comm = PetscObjectComm(
obj);
3389 ierr = PCGetOperators(pc,NULL,&pA); PCHKERRQ(pc,ierr);
3393 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&ismatis);
3395 MFEM_VERIFY(ismatis,
"PetscBDDCSolver needs the matrix in unassembled format");
3398 ParFiniteElementSpace *fespace = opts.fespace;
3399 if (opts.netflux && !fespace)
3401 MFEM_WARNING(
"Don't know how to compute an auxiliary quadrature form without a ParFiniteElementSpace");
3408 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(comm,ierr);
3409 ierr = MatNullSpaceCreate(PetscObjectComm((
PetscObject)lA),PETSC_TRUE,0,NULL,
3410 &nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3411 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3412 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3416 ierr = PCSetType(pc,PCBDDC); PCHKERRQ(
obj,ierr);
3419 ierr = MatGetOwnershipRange(pA,&rst,NULL); PCHKERRQ(pA,ierr);
3420 ierr = MatGetLocalSize(pA,&nl,NULL); PCHKERRQ(pA,ierr);
3429 int vdim = fespace->GetVDim();
3436 ierr = MatSetBlockSize(pA,vdim); PCHKERRQ(pA,ierr);
3437 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(PETSC_COMM_SELF,ierr);
3438 ierr = MatSetBlockSize(lA,vdim); PCHKERRQ(pA,ierr);
3447 ierr = PetscMalloc1(nf,&fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
3460 ierr = ISCreateStride(comm,nlf,st,bs,&fields[i]); CCHKERRQ(comm,ierr);
3466 const FiniteElementCollection *fec = fespace->FEColl();
3467 bool h1space =
dynamic_cast<const H1_FECollection*
>(fec);
3470 ParFiniteElementSpace *fespace_coords = fespace;
3472 sdim = fespace->GetParMesh()->SpaceDimension();
3475 fespace_coords =
new ParFiniteElementSpace(fespace->GetParMesh(),fec,sdim,
3478 VectorFunctionCoefficient coeff_coords(sdim, func_coords);
3479 ParGridFunction gf_coords(fespace_coords);
3480 gf_coords.ProjectCoefficient(coeff_coords);
3481 HypreParVector *hvec_coords = gf_coords.ParallelProject();
3483 hvec_coords->Size(),
false);
3491 Vec pvec_coords,lvec_coords;
3492 ISLocalToGlobalMapping l2g;
3498 ierr = VecCreateMPIWithArray(comm,sdim,hvec_coords->Size(),
3499 hvec_coords->GlobalSize(),data_coords,&pvec_coords);
3500 CCHKERRQ(comm,ierr);
3501 ierr = MatGetNearNullSpace(pA,&nnsp); CCHKERRQ(comm,ierr);
3504 ierr = MatNullSpaceCreateRigidBody(pvec_coords,&nnsp);
3505 CCHKERRQ(comm,ierr);
3506 ierr = MatSetNearNullSpace(pA,nnsp); CCHKERRQ(comm,ierr);
3507 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(comm,ierr);
3509 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(comm,ierr);
3510 ierr = MatCreateVecs(lA,&lvec_coords,NULL); CCHKERRQ(PETSC_COMM_SELF,ierr);
3511 ierr = VecSetBlockSize(lvec_coords,sdim); CCHKERRQ(PETSC_COMM_SELF,ierr);
3512 ierr = MatGetLocalToGlobalMapping(pA,&l2g,NULL); CCHKERRQ(comm,ierr);
3513 ierr = MatGetLayouts(pA,&rmap,NULL); CCHKERRQ(comm,ierr);
3514 ierr = PetscSFCreate(comm,&sf); CCHKERRQ(comm,ierr);
3515 ierr = ISLocalToGlobalMappingGetIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
3516 ierr = ISLocalToGlobalMappingGetSize(l2g,&nleaves); CCHKERRQ(comm,ierr);
3517 ierr = PetscSFSetGraphLayout(sf,rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);
3518 CCHKERRQ(comm,ierr);
3519 ierr = ISLocalToGlobalMappingRestoreIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
3524 ierr = VecGetArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3525 ierr = VecGetArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3526#if PETSC_VERSION_LT(3,15,0)
3527 ierr = PetscSFBcastBegin(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
3528 ierr = PetscSFBcastEnd(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
3530 ierr = PetscSFBcastBegin(sf,MPIU_SCALAR,garray,larray,MPI_REPLACE);
3531 CCHKERRQ(comm,ierr);
3532 ierr = PetscSFBcastEnd(sf,MPIU_SCALAR,garray,larray,MPI_REPLACE);
3533 CCHKERRQ(comm,ierr);
3535 ierr = VecRestoreArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3536 ierr = VecRestoreArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3538 ierr = VecDestroy(&pvec_coords); CCHKERRQ(comm,ierr);
3539 ierr = MatNullSpaceCreateRigidBody(lvec_coords,&nnsp);
3540 CCHKERRQ(PETSC_COMM_SELF,ierr);
3541 ierr = VecDestroy(&lvec_coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3542 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3543 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3544 ierr = PetscSFDestroy(&sf); CCHKERRQ(PETSC_COMM_SELF,ierr);
3548 ierr = PetscMalloc1(nl*sdim,&coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3557 ierr = ISGetLocalSize(fields[i],&nn); CCHKERRQ(comm,ierr);
3558 ierr = ISGetIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
3562 for (
PetscInt d = 0; d < sdim; d++)
3564 coords[sdim*idx+d] = PetscRealPart(data_coords[sdim*j+d]);
3567 ierr = ISRestoreIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
3572 for (
PetscInt j = 0; j < nl*sdim; j++) { coords[j] = PetscRealPart(data_coords[j]); }
3574 if (fespace_coords != fespace)
3576 delete fespace_coords;
3583 IS dir = NULL, neu = NULL;
3586 Array<Mat> *l2l = NULL;
3587 if (opts.ess_dof_local || opts.nat_dof_local)
3592 MFEM_VERIFY(c,
"Local-to-local PETSc container not present");
3593 ierr = PetscContainerGetPointer(c,(
void**)&l2l); PCHKERRQ(c,ierr);
3600 PetscBool lpr = PETSC_FALSE,pr;
3601 if (opts.ess_dof) { lpr = PETSC_TRUE; }
3602#if PETSC_VERSION_LT(3,24,0)
3603 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
3605 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPI_C_BOOL,MPI_LOR,comm);
3607 CCHKERRQ(comm,mpiierr);
3608 MFEM_VERIFY(lpr == pr,
"ess_dof should be collectively set");
3610 if (opts.nat_dof) { lpr = PETSC_TRUE; }
3611#if PETSC_VERSION_LT(3,24,0)
3612 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
3614 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPI_C_BOOL,MPI_LOR,comm);
3616 CCHKERRQ(comm,mpiierr);
3617 MFEM_VERIFY(lpr == pr,
"nat_dof should be collectively set");
3620 ms[0] = -nf; ms[1] = nf;
3621 mpiierr = MPI_Allreduce(&ms,&Ms,2,MPIU_INT,MPI_MAX,comm);
3622 CCHKERRQ(comm,mpiierr);
3623 MFEM_VERIFY(-Ms[0] == Ms[1],
3624 "number of fields should be the same across processes");
3631 PetscInt st = opts.ess_dof_local ? 0 : rst;
3632 if (!opts.ess_dof_local)
3635 ierr = Convert_Array_IS(comm,
true,opts.ess_dof,st,&dir);
3636 CCHKERRQ(comm,ierr);
3637 ierr = PCBDDCSetDirichletBoundaries(pc,dir); PCHKERRQ(pc,ierr);
3642 ierr = Convert_Vmarks_IS(comm,*l2l,opts.ess_dof,st,&dir);
3643 CCHKERRQ(comm,ierr);
3644 ierr = PCBDDCSetDirichletBoundariesLocal(pc,dir); PCHKERRQ(pc,ierr);
3649 PetscInt st = opts.nat_dof_local ? 0 : rst;
3650 if (!opts.nat_dof_local)
3653 ierr = Convert_Array_IS(comm,
true,opts.nat_dof,st,&neu);
3654 CCHKERRQ(comm,ierr);
3655 ierr = PCBDDCSetNeumannBoundaries(pc,neu); PCHKERRQ(pc,ierr);
3660 ierr = Convert_Vmarks_IS(comm,*l2l,opts.nat_dof,st,&neu);
3661 CCHKERRQ(comm,ierr);
3662 ierr = PCBDDCSetNeumannBoundariesLocal(pc,neu); PCHKERRQ(pc,ierr);
3669 ierr = PCBDDCSetDofsSplitting(pc,nf,fields); PCHKERRQ(pc,ierr);
3673 ierr = ISDestroy(&fields[i]); CCHKERRQ(comm,ierr);
3675 ierr = PetscFree(fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
3680 ierr = PCSetCoordinates(pc,sdim,nl,coords); PCHKERRQ(pc,ierr);
3682 ierr = PetscFree(coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3691 const FiniteElementCollection *fec = fespace->FEColl();
3692 bool edgespace, rtspace, h1space;
3693 bool needint = opts.netflux;
3694 bool tracespace, rt_tracespace, edge_tracespace;
3696 PetscBool B_is_Trans = PETSC_FALSE;
3698 ParMesh *pmesh = (ParMesh *) fespace->GetMesh();
3699 dim = pmesh->Dimension();
3700 vdim = fespace->GetVDim();
3701 h1space =
dynamic_cast<const H1_FECollection*
>(fec);
3702 rtspace =
dynamic_cast<const RT_FECollection*
>(fec);
3703 edgespace =
dynamic_cast<const ND_FECollection*
>(fec);
3704 edge_tracespace =
dynamic_cast<const ND_Trace_FECollection*
>(fec);
3705 rt_tracespace =
dynamic_cast<const RT_Trace_FECollection*
>(fec);
3706 tracespace = edge_tracespace || rt_tracespace;
3709 if (fespace->GetNE() > 0)
3713 p = fespace->GetElementOrder(0);
3717 p = fespace->GetFaceOrder(0);
3718 if (
dim == 2) {
p++; }
3729 MFEM_WARNING(
"Tracespace case doesn't work for H(curl) and p=2,"
3730 " not using auxiliary quadrature");
3736 FiniteElementCollection *vfec;
3739 vfec =
new H1_Trace_FECollection(
p,
dim);
3743 vfec =
new H1_FECollection(
p,
dim);
3745 ParFiniteElementSpace *vfespace =
new ParFiniteElementSpace(pmesh,vfec);
3746 ParDiscreteLinearOperator *grad;
3747 grad =
new ParDiscreteLinearOperator(vfespace,fespace);
3750 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3754 grad->AddDomainInterpolator(
new GradientInterpolator);
3758 HypreParMatrix *hG = grad->ParallelAssemble();
3759 PetscParMatrix *G =
new PetscParMatrix(hG,
PETSC_MATAIJ);
3763 PetscBool conforming = PETSC_TRUE;
3764 if (pmesh->Nonconforming()) { conforming = PETSC_FALSE; }
3765 ierr = PCBDDCSetDiscreteGradient(pc,*G,
p,0,PETSC_TRUE,conforming);
3777 MFEM_WARNING(
"Tracespace case doesn't work for H(div), not using"
3778 " auxiliary quadrature");
3784 if (vdim !=
dim) { needint =
false; }
3787 PetscParMatrix *
B = NULL;
3793 FiniteElementCollection *auxcoll;
3794 if (tracespace) { auxcoll =
new RT_Trace_FECollection(
p,
dim); }
3799 auxcoll =
new H1_FECollection(std::max(
p-1,1),
dim);
3803 auxcoll =
new L2_FECollection(
p,
dim);
3806 ParFiniteElementSpace *pspace =
new ParFiniteElementSpace(pmesh,auxcoll);
3807 ParMixedBilinearForm *
b =
new ParMixedBilinearForm(fespace,pspace);
3813 b->AddTraceFaceIntegrator(
new VectorFECurlIntegrator);
3817 b->AddDomainIntegrator(
new VectorFECurlIntegrator);
3824 b->AddTraceFaceIntegrator(
new VectorFEDivergenceIntegrator);
3828 b->AddDomainIntegrator(
new VectorFEDivergenceIntegrator);
3833 b->AddDomainIntegrator(
new VectorDivergenceIntegrator);
3838 b->ParallelAssemble(Bh);
3840 Bh.SetOperatorOwner(
false);
3845 ierr = MatTranspose(pB,MAT_INPLACE_MATRIX,&pB); PCHKERRQ(pA,ierr);
3846 if (!opts.ess_dof_local)
3848 ierr = MatZeroRowsIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3852 ierr = MatZeroRowsLocalIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3854 B_is_Trans = PETSC_TRUE;
3863 ierr = PCBDDCSetDivergenceMat(pc,*
B,B_is_Trans,NULL); PCHKERRQ(pc,ierr);
3867 ierr = ISDestroy(&dir); PCHKERRQ(pc,ierr);
3868 ierr = ISDestroy(&neu); PCHKERRQ(pc,ierr);
3873 const std::string &prefix)
3876 BDDCSolverConstructor(opts);
3882 const std::string &prefix)
3885 BDDCSolverConstructor(opts);
3890 const string &prefix)
3894 ierr = PCSetType(pc,PCFIELDSPLIT); PCHKERRQ(pc,ierr);
3897 ierr = PCGetOperators(pc,&pA,NULL); PCHKERRQ(pc,ierr);
3901 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATNEST,&isnest);
3907 ierr = MatNestGetSize(pA,&nr,NULL); PCHKERRQ(pc,ierr);
3908 ierr = PetscCalloc1(nr,&isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3909 ierr = MatNestGetISs(pA,isrow,NULL); PCHKERRQ(pc,ierr);
3919 ierr = PCFieldSplitSetIS(pc,NULL,isrow[i]); PCHKERRQ(pc,ierr);
3921 ierr = PetscFree(isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3926 const std::string &prefix)
3930 ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE); PCHKERRQ(A,ierr);
3931 ierr = MatSetOption(A,MAT_SYMMETRY_ETERNAL,PETSC_TRUE); PCHKERRQ(A,ierr);
3933 H2SolverConstructor(fes);
3939#if defined(PETSC_HAVE_H2OPUS)
3951 VectorFunctionCoefficient ccoords(sdim, func_coords);
3953 ParGridFunction coords(fes);
3954 coords.ProjectCoefficient(ccoords);
3956 coords.ParallelProject(c);
3960 ierr = PCSetType(pc,PCH2OPUS); PCHKERRQ(
obj, ierr);
3961 ierr = PCSetCoordinates(pc,sdim,c.Size()/sdim,
3964 ierr = PCSetFromOptions(pc); PCHKERRQ(
obj, ierr);
3966 MFEM_ABORT(
"Need PETSc configured with --download-h2opus");
3973 const std::string &prefix)
3978 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3980 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3981 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
3988 const std::string &prefix)
3993 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3995 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3996 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
4008 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj, ierr);
4009 ierr = SNESDestroy(&snes); CCHKERRQ(comm, ierr);
4021 ierr = SNESGetFunction(snes, NULL, NULL, &fctx);
4022 PCHKERRQ(snes, ierr);
4023 ierr = SNESGetJacobian(snes, NULL, NULL, NULL, &jctx);
4024 PCHKERRQ(snes, ierr);
4027 (
void*)&op == fctx &&
4028 (
void*)&op == jctx);
4029#if PETSC_VERSION_LT(3,24,0)
4030 mpiierr = MPI_Allreduce(&ls,&gs,1,MPIU_BOOL,MPI_LAND,
4033 mpiierr = MPI_Allreduce(&ls,&gs,1,MPI_C_BOOL,MPI_LAND,
4036 CCHKERRQ(PetscObjectComm((
PetscObject)snes),mpiierr);
4039 ierr = SNESReset(snes); PCHKERRQ(snes,ierr);
4050 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
4051 ierr = SNESLineSearchSetType(ls, SNESLINESEARCHBT); PCHKERRQ(snes,ierr);
4060 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4062 ierr = SNESSetFunction(snes, NULL, __mfem_snes_function, (
void *)snes_ctx);
4063 PCHKERRQ(snes, ierr);
4064 ierr = SNESSetJacobian(snes, dummy, dummy, __mfem_snes_jacobian,
4066 PCHKERRQ(snes, ierr);
4068 ierr = MatDestroy(&dummy);
4069 PCHKERRQ(snes, ierr);
4081 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4082 snes_ctx->jacType = jacType;
4088 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4089 snes_ctx->objective = objfn;
4092 ierr = SNESSetObjective(snes, __mfem_snes_objective, (
void *)snes_ctx);
4093 PCHKERRQ(snes, ierr);
4100 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4101 snes_ctx->postcheck = post;
4105 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
4106 ierr = SNESLineSearchSetPostCheck(ls, __mfem_snes_postcheck, (
void *)snes_ctx);
4116 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4117 snes_ctx->update = update;
4120 ierr = SNESSetUpdate(snes, __mfem_snes_update); PCHKERRQ(snes, ierr);
4126 MPI_Comm comm = PetscObjectComm(
obj);
4130 PetscBool b_nonempty =
b.Size() ? PETSC_TRUE : PETSC_FALSE;
4131#if PETSC_VERSION_LT(3,24,0)
4132 mpiierr = MPI_Allreduce(MPI_IN_PLACE,&b_nonempty,1,MPIU_BOOL,MPI_LOR,comm);
4134 mpiierr = MPI_Allreduce(MPI_IN_PLACE,&b_nonempty,1,MPI_C_BOOL,MPI_LOR,comm);
4136 CCHKERRQ(comm,mpiierr);
4150 ierr = SNESSolve(snes, b_nonempty ?
B->
x :
nullptr,
X->
x); PCHKERRQ(snes, ierr);
4162 ierr = TSCreate(comm,&ts); CCHKERRQ(comm,ierr);
4164 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
4165 ierr = TSSetOptionsPrefix(ts, prefix.c_str()); PCHKERRQ(ts, ierr);
4171 ierr = TSSetMaxSteps(ts,PETSC_MAX_INT-1);
4173 ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
4176 ierr = TSGetAdapt(ts,&tsad);
4178 ierr = TSAdaptSetType(tsad,TSADAPTNONE);
4186 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj,ierr);
4187 ierr = TSDestroy(&ts); CCHKERRQ(comm,ierr);
4195 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4198 ierr = TSReset(ts); PCHKERRQ(ts,ierr);
4201 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
4202 ts_ctx->cached_ijacstate = -1;
4203 ts_ctx->cached_rhsjacstate = -1;
4204 ts_ctx->cached_splits_xstate = -1;
4205 ts_ctx->cached_splits_xdotstate = -1;
4217 ierr = TSSetIFunction(ts, NULL, __mfem_ts_ifunction, (
void *)ts_ctx);
4219 ierr = TSSetIJacobian(ts, dummy, dummy, __mfem_ts_ijacobian, (
void *)ts_ctx);
4221 ierr = TSSetEquationType(ts, TS_EQ_IMPLICIT);
4223 ierr = MatDestroy(&dummy);
4231 ierr = TSSetEquationType(ts, TS_EQ_EXPLICIT);
4240 ierr = TSSetRHSFunction(ts, NULL, __mfem_ts_rhsfunction, (
void *)ts_ctx);
4242 ierr = TSSetRHSJacobian(ts, dummy, dummy, __mfem_ts_rhsjacobian,
4245 ierr = MatDestroy(&dummy);
4254 ierr = TSSetSolution(ts,
X); PCHKERRQ(ts,ierr);
4257 PetscBool use = PETSC_TRUE;
4258 ierr = PetscOptionsGetBool(NULL,NULL,
"-mfem_use_splitjac",&use,NULL);
4261 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
4262 __mfem_ts_computesplits);
4267 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
4275 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4276 ts_ctx->jacType = jacType;
4281 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4282 return ts_ctx->type;
4287 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4290 ts_ctx->type = type;
4293 ierr = TSSetProblemType(ts, TS_LINEAR);
4298 ierr = TSSetProblemType(ts, TS_NONLINEAR);
4307 ierr = TSSetTime(ts, t); PCHKERRQ(ts, ierr);
4308 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
4311 ierr = TSGetStepNumber(ts, &i); PCHKERRQ(ts,ierr);
4321 ierr = TSMonitor(ts, i, t, *
X); PCHKERRQ(ts,ierr);
4325 ierr = TSSetSolution(ts, *
X); PCHKERRQ(ts, ierr);
4326 ierr = TSStep(ts); PCHKERRQ(ts, ierr);
4331 ierr = TSGetTime(ts, &pt); PCHKERRQ(ts,ierr);
4336 ierr = TSMonitor(ts, i+1, pt, *
X); PCHKERRQ(ts,ierr);
4346 ierr = TSSetTime(ts, t); PCHKERRQ(ts, ierr);
4347 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
4348 ierr = TSSetMaxTime(ts, t_final); PCHKERRQ(ts, ierr);
4349 ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
4361 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4362 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
4363 ts_ctx->cached_ijacstate = -1;
4364 ts_ctx->cached_rhsjacstate = -1;
4365 ts_ctx->cached_splits_xstate = -1;
4366 ts_ctx->cached_splits_xdotstate = -1;
4369 ierr = TSSolve(ts,
X->
x); PCHKERRQ(ts, ierr);
4374 ierr = TSGetTime(ts, &pt); PCHKERRQ(ts,ierr);
4376 ierr = TSGetTimeStep(ts,&pt); PCHKERRQ(ts,ierr);
4382#include "petsc/private/petscimpl.h"
4383#include "petsc/private/matimpl.h"
4389 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
4391 PetscFunctionBeginUser;
4394 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4406 PetscFunctionReturn(PETSC_SUCCESS);
4409static PetscErrorCode __mfem_ts_ifunction(TS ts,
PetscReal t, Vec x, Vec xp,
4412 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4414 PetscFunctionBeginUser;
4422 if (ts_ctx->bchandler)
4427 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(xx.Size()); }
4428 if (!ts_ctx->work2) { ts_ctx->work2 =
new mfem::Vector(xx.Size()); }
4434 bchandler->
ZeroBC(yy,*txp);
4444 ff.UpdateVecFromFlags();
4445 PetscFunctionReturn(PETSC_SUCCESS);
4448static PetscErrorCode __mfem_ts_rhsfunction(TS ts,
PetscReal t, Vec x, Vec
f,
4451 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4453 PetscFunctionBeginUser;
4454 if (ts_ctx->bchandler) { MFEM_ABORT(
"RHS evaluation with bc not implemented"); }
4463 ff.UpdateVecFromFlags();
4464 PetscFunctionReturn(PETSC_SUCCESS);
4467static PetscErrorCode __mfem_ts_ijacobian(TS ts,
PetscReal t, Vec x,
4471 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4476 PetscObjectState state;
4477 PetscErrorCode ierr;
4479 PetscFunctionBeginUser;
4483 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4484 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4490 ierr = PetscObjectStateGet((
PetscObject)P,&state); CHKERRQ(ierr);
4492 std::abs(ts_ctx->cached_shift/shift - 1.0) < eps &&
4493 state == ts_ctx->cached_ijacstate) { PetscFunctionReturn(PETSC_SUCCESS); }
4500 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4501 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4503 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4504 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4505 if (!ts_ctx->bchandler)
4512 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4519 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4523 if (!ts_ctx->bchandler) {
delete xx; }
4524 ts_ctx->cached_shift = shift;
4527 bool delete_pA =
false;
4531 pA->
GetType() != ts_ctx->jacType))
4539 if (ts_ctx->bchandler)
4547 PetscObjectState nonzerostate;
4548 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4553 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4554 if (delete_pA) {
delete pA; }
4566 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4568 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4571 ierr = PetscObjectStateGet((
PetscObject)P,&ts_ctx->cached_ijacstate);
4577 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4578 ierr = TSGetDM(ts,&dm); CHKERRQ(ierr);
4579 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4580 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4581 PetscFunctionReturn(PETSC_SUCCESS);
4584static PetscErrorCode __mfem_ts_computesplits(TS ts,
PetscReal t,Vec x,Vec xp,
4588 __mfem_ts_ctx* ts_ctx;
4592 PetscObjectState state;
4593 PetscBool rx = PETSC_TRUE, rxp = PETSC_TRUE;
4594 PetscBool assembled;
4595 PetscErrorCode ierr;
4597 PetscFunctionBeginUser;
4601 ierr = MatAssemblyBegin(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4602 ierr = MatAssemblyEnd(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4604 if (Axp && Axp != Jxp)
4606 ierr = MatAssemblyBegin(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4607 ierr = MatAssemblyEnd(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4610 ierr = TSGetIJacobian(ts,NULL,NULL,NULL,(
void**)&ts_ctx); CHKERRQ(ierr);
4613 ierr = PetscObjectStateGet((
PetscObject)Jx,&state); CHKERRQ(ierr);
4615 state == ts_ctx->cached_splits_xstate) { rx = PETSC_FALSE; }
4616 ierr = PetscObjectStateGet((
PetscObject)Jxp,&state); CHKERRQ(ierr);
4618 state == ts_ctx->cached_splits_xdotstate) { rxp = PETSC_FALSE; }
4619 if (!rx && !rxp) { PetscFunctionReturn(PETSC_SUCCESS); }
4626 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4627 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4629 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4630 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4631 if (!ts_ctx->bchandler)
4638 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4645 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4654 bool delete_mat =
false;
4658 pJx->
GetType() != ts_ctx->jacType))
4663 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
4671 ierr = MatAssembled(Jx,&assembled); CHKERRQ(ierr);
4674 ierr = MatCopy(*pJx,Jx,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
4679 ierr = MatDuplicate(*pJx,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
4680 ierr = MatHeaderReplace(Jx,&B); CHKERRQ(ierr);
4683 if (delete_mat) {
delete pJx; }
4687 if (ts_ctx->bchandler)
4704 pJxp->
GetType() != ts_ctx->jacType))
4709 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
4712 &oJxp,ts_ctx->jacType);
4716 ierr = MatAssembled(Jxp,&assembled); CHKERRQ(ierr);
4719 ierr = MatCopy(*pJxp,Jxp,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
4724 ierr = MatDuplicate(*pJxp,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
4725 ierr = MatHeaderReplace(Jxp,&B); CHKERRQ(ierr);
4727 if (delete_mat) {
delete pJxp; }
4731 if (ts_ctx->bchandler)
4742 ierr = MatAXPY(*pJxp,-1.0,*pJx,SAME_NONZERO_PATTERN); PCHKERRQ(ts,ierr);
4746 ierr = PetscObjectStateGet((
PetscObject)Jx,&ts_ctx->cached_splits_xstate);
4748 ierr = PetscObjectStateGet((
PetscObject)Jxp,&ts_ctx->cached_splits_xdotstate);
4753 if (!ts_ctx->bchandler) {
delete xx; }
4754 PetscFunctionReturn(PETSC_SUCCESS);
4757static PetscErrorCode __mfem_ts_rhsjacobian(TS ts,
PetscReal t, Vec x,
4758 Mat A, Mat P,
void *
ctx)
4760 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4764 PetscObjectState state;
4765 PetscErrorCode ierr;
4767 PetscFunctionBeginUser;
4771 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4772 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4776 ierr = PetscObjectStateGet((
PetscObject)P,&state); CHKERRQ(ierr);
4778 state == ts_ctx->cached_rhsjacstate) { PetscFunctionReturn(PETSC_SUCCESS); }
4785 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4786 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4787 if (!ts_ctx->bchandler)
4794 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4801 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4805 if (!ts_ctx->bchandler) {
delete xx; }
4808 bool delete_pA =
false;
4812 pA->
GetType() != ts_ctx->jacType))
4820 if (ts_ctx->bchandler)
4828 PetscObjectState nonzerostate;
4829 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4834 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4835 if (delete_pA) {
delete pA; }
4847 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4849 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4854 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE); PCHKERRQ(ts,ierr);
4856 ierr = PetscObjectStateGet((
PetscObject)P,&ts_ctx->cached_rhsjacstate);
4862 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4863 ierr = TSGetDM(ts,&dm); CHKERRQ(ierr);
4864 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4865 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4866 PetscFunctionReturn(PETSC_SUCCESS);
4872 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
4874 PetscFunctionBeginUser;
4877 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4886 PetscErrorCode ierr;
4888 ierr = SNESGetSolution(snes,&x); CHKERRQ(ierr);
4895 PetscErrorCode ierr;
4897 ierr = SNESGetFunction(snes,&x,NULL,NULL); CHKERRQ(ierr);
4902 PetscFunctionReturn(PETSC_SUCCESS);
4905static PetscErrorCode __mfem_snes_jacobian(SNES snes, Vec x, Mat A, Mat P,
4910 PetscErrorCode ierr;
4912 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
ctx;
4914 PetscFunctionBeginUser;
4915 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4916 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4917 if (!snes_ctx->bchandler)
4924 if (!snes_ctx->work) { snes_ctx->work =
new mfem::Vector(n); }
4927 xx = snes_ctx->work;
4933 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4934 if (!snes_ctx->bchandler) {
delete xx; }
4937 bool delete_pA =
false;
4941 pA->
GetType() != snes_ctx->jacType))
4949 if (snes_ctx->bchandler)
4957 PetscObjectState nonzerostate;
4958 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4962 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4963 if (delete_pA) {
delete pA; }
4975 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4977 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4982 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4983 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4989 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4990 ierr = SNESGetDM(snes,&dm); CHKERRQ(ierr);
4991 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4992 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4993 PetscFunctionReturn(PETSC_SUCCESS);
4996static PetscErrorCode __mfem_snes_function(SNES snes, Vec x, Vec
f,
void *
ctx)
4998 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
5000 PetscFunctionBeginUser;
5003 if (snes_ctx->bchandler)
5010 snes_ctx->op->
Mult(*txx,ff);
5017 snes_ctx->op->
Mult(xx,ff);
5019 ff.UpdateVecFromFlags();
5020 PetscFunctionReturn(PETSC_SUCCESS);
5023static PetscErrorCode __mfem_snes_objective(SNES snes, Vec x,
PetscReal *
f,
5026 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
5028 PetscFunctionBeginUser;
5029 if (!snes_ctx->objective)
5031 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing objective function");
5035 (*snes_ctx->objective)(snes_ctx->op,xx,&lf);
5037 PetscFunctionReturn(PETSC_SUCCESS);
5040static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch ls,Vec X,Vec Y,Vec W,
5041 PetscBool *cy,PetscBool *cw,
void*
ctx)
5043 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
5044 bool lcy =
false,lcw =
false;
5046 PetscFunctionBeginUser;
5050 (*snes_ctx->postcheck)(snes_ctx->op,x,y,w,lcy,lcw);
5051 if (lcy) { y.UpdateVecFromFlags(); *cy = PETSC_TRUE; }
5052 if (lcw) { w.UpdateVecFromFlags(); *cw = PETSC_TRUE; }
5053 PetscFunctionReturn(PETSC_SUCCESS);
5056static PetscErrorCode __mfem_snes_update(SNES snes,
PetscInt it)
5059 __mfem_snes_ctx* snes_ctx;
5061 PetscFunctionBeginUser;
5063 ierr = SNESGetFunction(snes,&F,NULL,(
void **)&snes_ctx); CHKERRQ(ierr);
5064 ierr = SNESGetSolution(snes,&X); CHKERRQ(ierr);
5067 ierr = VecDuplicate(X,&pX); CHKERRQ(ierr);
5070 ierr = VecDestroy(&pX); CHKERRQ(ierr);
5074 if (!pX) SETERRQ(PetscObjectComm((
PetscObject)snes),PETSC_ERR_USER,
5075 "Missing previous solution");
5076 ierr = SNESGetSolutionUpdate(snes,&dX); CHKERRQ(ierr);
5081 (*snes_ctx->update)(snes_ctx->op,it,
f,x,dx,px);
5083 ierr = VecCopy(X,pX); CHKERRQ(ierr);
5084 PetscFunctionReturn(PETSC_SUCCESS);
5090 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
5092 PetscFunctionBeginUser;
5095 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
5104 PetscErrorCode ierr;
5106 ierr = KSPBuildSolution(ksp,NULL,&x); CHKERRQ(ierr);
5113 PetscErrorCode ierr;
5115 ierr = KSPBuildResidual(ksp,NULL,NULL,&x); CHKERRQ(ierr);
5120 PetscFunctionReturn(PETSC_SUCCESS);
5123static PetscErrorCode __mfem_mat_shell_apply(Mat A, Vec x, Vec y)
5126 PetscErrorCode ierr;
5128 PetscFunctionBeginUser;
5129 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5130 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5134 yy.UpdateVecFromFlags();
5135 PetscFunctionReturn(PETSC_SUCCESS);
5138static PetscErrorCode __mfem_mat_shell_apply_transpose(Mat A, Vec x, Vec y)
5141 PetscErrorCode ierr;
5144 PetscFunctionBeginUser;
5145 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5146 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5149 ierr = MatIsSymmetricKnown(A,&flg,&symm); CHKERRQ(ierr);
5158 yy.UpdateVecFromFlags();
5159 PetscFunctionReturn(PETSC_SUCCESS);
5162static PetscErrorCode __mfem_mat_shell_copy(Mat A, Mat B, MatStructure str)
5165 PetscErrorCode ierr;
5167 PetscFunctionBeginUser;
5168 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5169 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5170 ierr = MatShellSetContext(B,(
void *)op); CHKERRQ(ierr);
5171 PetscFunctionReturn(PETSC_SUCCESS);
5174static PetscErrorCode __mfem_mat_shell_destroy(Mat A)
5176 PetscFunctionBeginUser;
5177 PetscFunctionReturn(PETSC_SUCCESS);
5180static PetscErrorCode __mfem_pc_shell_view(PC pc, PetscViewer viewer)
5182 __mfem_pc_shell_ctx *
ctx;
5183 PetscErrorCode ierr;
5185 PetscFunctionBeginUser;
5186 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5190 ierr = PetscObjectTypeCompare((
PetscObject)viewer,PETSCVIEWERASCII,&isascii);
5197 ierr = PCView(*ppc,viewer); CHKERRQ(ierr);
5203 ierr = PetscViewerASCIIPrintf(viewer,
5204 "No information available on the mfem::Solver\n");
5208 if (isascii &&
ctx->factory)
5210 ierr = PetscViewerASCIIPrintf(viewer,
5211 "Number of preconditioners created by the factory %lu\n",
ctx->numprec);
5215 PetscFunctionReturn(PETSC_SUCCESS);
5218static PetscErrorCode __mfem_pc_shell_apply(PC pc, Vec x, Vec y)
5220 __mfem_pc_shell_ctx *
ctx;
5221 PetscErrorCode ierr;
5223 PetscFunctionBeginUser;
5226 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5229 ctx->op->Mult(xx,yy);
5230 yy.UpdateVecFromFlags();
5236 PetscFunctionReturn(PETSC_SUCCESS);
5239static PetscErrorCode __mfem_pc_shell_apply_transpose(PC pc, Vec x, Vec y)
5241 __mfem_pc_shell_ctx *
ctx;
5242 PetscErrorCode ierr;
5244 PetscFunctionBeginUser;
5247 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5250 ctx->op->MultTranspose(xx,yy);
5251 yy.UpdateVecFromFlags();
5257 PetscFunctionReturn(PETSC_SUCCESS);
5260static PetscErrorCode __mfem_pc_shell_setup(PC pc)
5262 __mfem_pc_shell_ctx *
ctx;
5264 PetscFunctionBeginUser;
5265 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5276 ierr = PCGetOperators(pc,NULL,&B); CHKERRQ(ierr);
5285 PetscFunctionReturn(PETSC_SUCCESS);
5288static PetscErrorCode __mfem_pc_shell_destroy(PC pc)
5290 __mfem_pc_shell_ctx *
ctx;
5291 PetscErrorCode ierr;
5293 PetscFunctionBeginUser;
5294 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5300 PetscFunctionReturn(PETSC_SUCCESS);
5303static PetscErrorCode __mfem_array_container_destroy(
PetscCtxRt ptr)
5305 PetscErrorCode ierr;
5307 PetscFunctionBeginUser;
5308#if PETSC_VERSION_LT(3,23,0)
5309 ierr = PetscFree(ptr); CHKERRQ(ierr);
5311 ierr = PetscFree(*(
void**)ptr); CHKERRQ(ierr);
5313 PetscFunctionReturn(PETSC_SUCCESS);
5316static PetscErrorCode __mfem_matarray_container_destroy(
PetscCtxRt ptr)
5318#if PETSC_VERSION_LT(3,23,0)
5323 PetscErrorCode ierr;
5325 PetscFunctionBeginUser;
5326 for (
int i=0; i<
a->Size(); i++)
5330 ierr = MatDestroy(&M); CCHKERRQ(comm,ierr);
5333 PetscFunctionReturn(PETSC_SUCCESS);
5336#if PETSC_VERSION_LT(3,23,0)
5337static PetscErrorCode __mfem_monitor_ctx_destroy(
void **
ctx)
5339static PetscErrorCode __mfem_monitor_ctx_destroy(
PetscCtxRt ctx)
5342 PetscErrorCode ierr;
5344 PetscFunctionBeginUser;
5345 ierr = PetscFree(*(
void**)
ctx); CHKERRQ(ierr);
5346 PetscFunctionReturn(PETSC_SUCCESS);
5351PetscErrorCode MakeShellPC(PC pc,
mfem::Solver &precond,
bool ownsop)
5353 PetscFunctionBeginUser;
5354 __mfem_pc_shell_ctx *
ctx =
new __mfem_pc_shell_ctx;
5356 ctx->ownsop = ownsop;
5357 ctx->factory = NULL;
5363 ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr);
5365 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
5366 ierr = PCShellSetName(pc,
"MFEM Solver (unknown Pmat)"); CHKERRQ(ierr);
5367 ierr = PCShellSetContext(pc,(
void *)
ctx); CHKERRQ(ierr);
5368 ierr = PCShellSetApply(pc,__mfem_pc_shell_apply); CHKERRQ(ierr);
5369 ierr = PCShellSetApplyTranspose(pc,__mfem_pc_shell_apply_transpose);
5371 ierr = PCShellSetSetUp(pc,__mfem_pc_shell_setup); CHKERRQ(ierr);
5372 ierr = PCShellSetView(pc,__mfem_pc_shell_view); CHKERRQ(ierr);
5373 ierr = PCShellSetDestroy(pc,__mfem_pc_shell_destroy); CHKERRQ(ierr);
5374 PetscFunctionReturn(PETSC_SUCCESS);
5379PetscErrorCode MakeShellPCWithFactory(PC pc,
5382 PetscFunctionBeginUser;
5383 __mfem_pc_shell_ctx *
ctx =
new __mfem_pc_shell_ctx;
5386 ctx->factory = factory;
5392 ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr);
5394 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
5395 ierr = PCShellSetName(pc,factory->
GetName()); CHKERRQ(ierr);
5396 ierr = PCShellSetContext(pc,(
void *)
ctx); CHKERRQ(ierr);
5397 ierr = PCShellSetApply(pc,__mfem_pc_shell_apply); CHKERRQ(ierr);
5398 ierr = PCShellSetApplyTranspose(pc,__mfem_pc_shell_apply_transpose);
5400 ierr = PCShellSetSetUp(pc,__mfem_pc_shell_setup); CHKERRQ(ierr);
5401 ierr = PCShellSetView(pc,__mfem_pc_shell_view); CHKERRQ(ierr);
5402 ierr = PCShellSetDestroy(pc,__mfem_pc_shell_destroy); CHKERRQ(ierr);
5403 PetscFunctionReturn(PETSC_SUCCESS);
5408static PetscErrorCode Convert_Array_IS(MPI_Comm comm,
bool islist,
5412 PetscInt n = list ? list->Size() : 0,*idxs;
5413 const int *data = list ? list->GetData() : NULL;
5414 PetscErrorCode ierr;
5416 PetscFunctionBeginUser;
5417 ierr = PetscMalloc1(n,&idxs); CHKERRQ(ierr);
5420 for (
PetscInt i=0; i<n; i++) { idxs[i] = data[i] + st; }
5427 if (data[i]) { idxs[cum++] = i+st; }
5431 ierr = ISCreateGeneral(comm,n,idxs,PETSC_OWN_POINTER,is);
5433 PetscFunctionReturn(PETSC_SUCCESS);
5439static PetscErrorCode Convert_Vmarks_IS(MPI_Comm comm,
5447 PetscErrorCode ierr;
5449 PetscFunctionBeginUser;
5450 for (
int i = 0; i < pl2l.
Size(); i++)
5454 ierr = MatGetRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,(
const PetscInt**)&ii,
5455 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
5456 MFEM_VERIFY(done,
"Unable to perform MatGetRowIJ on " << i <<
" l2l matrix");
5457 ierr = MatGetSize(pl2l[i],NULL,&n); CHKERRQ(ierr);
5458#if defined(PETSC_USE_64BIT_INDICES)
5459 int nnz = (int)ii[m];
5460 int *mii =
new int[m+1];
5461 int *mjj =
new int[nnz];
5462 for (
int j = 0; j < m+1; j++) { mii[j] = (int)ii[j]; }
5463 for (
int j = 0; j < nnz; j++) { mjj[j] = (int)jj[j]; }
5468 ierr = MatRestoreRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,
5470 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
5471 MFEM_VERIFY(done,
"Unable to perform MatRestoreRowIJ on "
5472 << i <<
" l2l matrix");
5475 for (
int i = 0; i < l2l.Size(); i++) { nl += l2l[i]->Width(); }
5477 const int* vdata = mark->
GetData();
5478 int* sdata = sub_dof_marker.
GetData();
5479 int cumh = 0, cumw = 0;
5480 for (
int i = 0; i < l2l.Size(); i++)
5485 l2l[i]->BooleanMultTranspose(vf_marker,sf_marker);
5486 cumh += l2l[i]->Height();
5487 cumw += l2l[i]->Width();
5489 ierr = Convert_Array_IS(comm,
false,&sub_dof_marker,st,is); CCHKERRQ(comm,ierr);
5490 for (
int i = 0; i < pl2l.
Size(); i++)
5494 PetscFunctionReturn(PETSC_SUCCESS);
5497#include <petsc/private/matimpl.h>
5499static PetscErrorCode __mfem_MatCreateDummy(MPI_Comm comm,
PetscInt m,
5503 ierr = MatCreate(comm,A); CHKERRQ(ierr);
5504 ierr = MatSetSizes(*A,m,n,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr);
5505 ierr = PetscObjectChangeTypeName((
PetscObject)*A,
"mfemdummy"); CHKERRQ(ierr);
5506 (*A)->preallocated = PETSC_TRUE;
5507 ierr = MatSetUp(*A); CHKERRQ(ierr);
5508 PetscFunctionReturn(PETSC_SUCCESS);
5511#include <petsc/private/vecimpl.h>
5513#if defined(PETSC_HAVE_DEVICE)
5514static PetscErrorCode __mfem_VecSetOffloadMask(Vec v, PetscOffloadMask m)
5518 PetscFunctionReturn(PETSC_SUCCESS);
5522static PetscErrorCode __mfem_VecBoundToCPU(Vec v, PetscBool *flg)
5525#if defined(PETSC_HAVE_DEVICE)
5526 *flg = v->boundtocpu;
5530 PetscFunctionReturn(PETSC_SUCCESS);
5533static PetscErrorCode __mfem_PetscObjectStateIncrease(
PetscObject o)
5535 PetscErrorCode ierr;
5538 ierr = PetscObjectStateIncrease(o); CHKERRQ(ierr);
5539 PetscFunctionReturn(PETSC_SUCCESS);
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
T * GetData()
Returns the data.
A class to handle Block systems in a matrix-free implementation.
int IsZeroBlock(int i, int j) const
Check if block (i,j) is a zero block.
Operator & GetBlock(int i, int j)
Return a reference to block i,j.
int NumRowBlocks() const
Return the number of row blocks.
int NumColBlocks() const
Return the number of column blocks.
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
static int GetId()
Get the device ID of the configured device.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
Ordering::Type GetOrdering() const
Return the ordering method.
const FiniteElementCollection * FEColl() const
int GetVDim() const
Returns the vector dimension of the finite element space.
Wrapper for hypre's ParCSR matrix class.
MPI_Comm GetComm() const
MPI communicator.
Wrapper for hypre's parallel vector class.
Identity Operator I: x -> x.
Class used by MFEM to store pointers to host and/or device memory.
bool DeviceIsValid() const
Return true if device pointer is valid.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool HostIsValid() const
Return true if host pointer is valid.
bool UseDevice() const
Read the internal device flag.
void CopyToHost(T *dest, int size) const
Copy size entries from *this to the host pointer dest.
bool Empty() const
Return true if the Memory object is empty, see Reset().
void Sync(const Memory &other) const
Copy the host/device pointer validity flags from other to *this.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
void Delete()
Delete the owned pointers and reset the Memory object.
int SpaceDimension() const
Dimension of the physical space containing the mesh.
Abstract class for solving systems of ODEs: dx/dt = f(x,t)
TimeDependentOperator * f
Pointer to the associated TimeDependentOperator.
Pointer to an Operator of a specified type.
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
int width
Dimension of the input / number of columns in the matrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int height
Dimension of the output / number of rows in the matrix.
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Type
Enumeration defining IDs for some classes derived from Operator.
@ ANY_TYPE
ID for the base class Operator, i.e. any type.
@ PETSC_MATIS
ID for class PetscParMatrix, MATIS format.
@ PETSC_MATHYPRE
ID for class PetscParMatrix, MATHYPRE format.
@ PETSC_MATGENERIC
ID for class PetscParMatrix, unspecified format.
@ PETSC_MATAIJ
ID for class PetscParMatrix, MATAIJ format.
@ PETSC_MATNEST
ID for class PetscParMatrix, MATNEST format.
@ PETSC_MATSHELL
ID for class PetscParMatrix, MATSHELL format.
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
virtual Operator & GetGradient(const Vector &x) const
Evaluate the gradient operator at the point x. The default behavior in class Operator is to generate ...
Abstract parallel finite element space.
HYPRE_BigInt * GetTrueDofOffsets() const
int GetTrueVSize() const override
Return the number of local vector true dofs.
ParMesh * GetParMesh() const
Helper class for handling essential boundary conditions.
PetscBCHandler(Type type_=ZERO)
@ CONSTANT
Constant in time b.c.
void SetTDofs(Array< int > &list)
Sets essential dofs (local, per-process numbering)
virtual void Eval(real_t t, Vector &g)
Boundary conditions evaluation.
void SetTime(real_t t)
Sets the current time.
void SetUp(PetscInt n)
SetUp the helper object, where n is the size of the solution vector.
void ZeroBC(const Vector &x, Vector &y)
y = x on ess_tdof_list_c and y = 0 on ess_tdof_list
Array< int > & GetTDofs()
Gets essential dofs (local, per-process numbering)
void FixResidualBC(const Vector &x, Vector &y)
y = x-g on ess_tdof_list, the rest of y is unchanged
void ApplyBC(const Vector &x, Vector &y)
y = x on ess_tdof_list_c and y = g (internally evaluated) on ess_tdof_list
void Zero(Vector &x)
Replace boundary dofs with 0.
Auxiliary class for BDDC customization.
PetscBDDCSolver(MPI_Comm comm, Operator &op, const PetscBDDCSolverParams &opts=PetscBDDCSolverParams(), const std::string &prefix=std::string())
PetscFieldSplitSolver(MPI_Comm comm, Operator &op, const std::string &prefix=std::string())
PetscH2Solver(Operator &op, ParFiniteElementSpace *fes, const std::string &prefix=std::string())
Abstract class for PETSc's linear solvers.
void SetOperator(const Operator &op) override
operator petsc::KSP() const
Conversion function to PETSc's KSP type.
virtual ~PetscLinearSolver()
void MultTranspose(const Vector &b, Vector &x) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
PetscLinearSolver(MPI_Comm comm, const std::string &prefix=std::string(), bool wrap=true, bool iter_mode=false)
void SetPreconditioner(Solver &precond)
void Mult(const Vector &b, Vector &x) const override
Application of the solver.
bool DeviceRequested() const
void SetHostInvalid() const
void SetHostValid() const
bool WriteRequested() const
const real_t * GetDevicePointer() const
const real_t * GetHostPointer() const
bool IsAliasForSync() const
void MakeAliasForSync(const Memory< real_t > &base_, int offset_, int size_, bool usedev_)
void SetDeviceInvalid() const
bool ReadRequested() const
void SetDeviceValid() const
void Mult(const Vector &b, Vector &x) const override
Application of the solver.
void SetPostCheck(void(*post)(Operator *op, const Vector &X, Vector &Y, Vector &W, bool &changed_y, bool &changed_w))
void SetObjective(void(*obj)(Operator *op, const Vector &x, real_t *f))
Specification of an objective function to be used for line search.
operator petsc::SNES() const
Conversion function to PETSc's SNES type.
virtual ~PetscNonlinearSolver()
void SetJacobianType(Operator::Type type)
void SetUpdate(void(*update)(Operator *op, int it, const Vector &F, const Vector &X, const Vector &D, const Vector &P))
PetscNonlinearSolver(MPI_Comm comm, const std::string &prefix=std::string())
void SetOperator(const Operator &op) override
Specification of the nonlinear operator.
virtual void Init(TimeDependentOperator &f_, enum PetscODESolver::Type type)
Initialize the ODE solver.
virtual void Run(Vector &x, real_t &t, real_t &dt, real_t t_final)
Perform time integration from time t [in] to time tf [in].
virtual void Step(Vector &x, real_t &t, real_t &dt)
Perform a time step from time t [in] to time t [out] based on the requested step size dt [in].
operator petsc::TS() const
Conversion function to PETSc's TS type.
void SetType(PetscODESolver::Type)
PetscODESolver::Type GetType() const
PetscODESolver(MPI_Comm comm, const std::string &prefix=std::string())
void SetJacobianType(Operator::Type type)
virtual ~PetscODESolver()
PetscPCGSolver(MPI_Comm comm, const std::string &prefix=std::string(), bool iter_mode=false)
Wrapper for PETSc's matrix class.
void Print(const char *fname=NULL, bool binary=false) const
Prints the matrix (to stdout if fname is NULL)
PetscInt GetNumRows() const
Returns the local number of rows.
void ScaleCols(const Vector &s)
Scale the local col i by s(i).
void MakeRef(const PetscParMatrix &master)
Makes this object a reference to another PetscParMatrix.
void EliminateRows(const Array< int > &rows)
Eliminate only the rows from the matrix.
void ConvertOperator(MPI_Comm comm, const Operator &op, petsc::Mat *B, Operator::Type tid)
PetscParMatrix & operator-=(const PetscParMatrix &B)
void Mult(real_t a, const Vector &x, real_t b, Vector &y) const
Matvec: y = a A x + b y.
PetscInt GetColStart() const
Returns the global index of the first local column.
PetscInt M() const
Returns the global number of rows.
void EliminateRowsCols(const Array< int > &rows_cols, const PetscParVector &X, PetscParVector &B, real_t diag=1.)
Eliminate rows and columns from the matrix, and rows from the vector B. Modify B with the BC values i...
PetscParVector * GetY() const
Returns the inner vector in the range of A (it creates it if needed)
MPI_Comm GetComm() const
Get the associated MPI communicator.
PetscParMatrix & operator=(const PetscParMatrix &B)
petsc::Mat ReleaseMat(bool dereference)
Release the PETSc Mat object. If dereference is true, decrement the refcount of the Mat object.
void MakeWrapper(MPI_Comm comm, const Operator *op, petsc::Mat *B)
Creates a wrapper around a mfem::Operator op using PETSc's MATSHELL object and returns the Mat in B.
PetscInt GetNumCols() const
Returns the local number of columns.
PetscInt NNZ() const
Returns the number of nonzeros.
petsc::Mat A
The actual PETSc object.
PetscParVector * GetX() const
Returns the inner vector in the domain of A (it creates it if needed)
void Shift(real_t s)
Shift diagonal by a constant.
PetscParVector * X
Auxiliary vectors for typecasting.
PetscParMatrix()
Create an empty matrix to be used as a reference to an existing matrix.
operator petsc::Mat() const
Typecasting to PETSc's Mat type.
void SetMat(petsc::Mat newA)
Replace the inner Mat Object. The reference count of newA is increased.
void operator*=(real_t s)
Scale all entries by s: A_scaled = s*A.
void SetBlockSize(PetscInt rbs, PetscInt cbs=-1)
Set row and column block sizes of a matrix.
PetscInt N() const
Returns the global number of columns.
PetscParMatrix * Transpose(bool action=false)
Returns the transpose of the PetscParMatrix.
void Init()
Initialize with defaults. Does not initialize inherited members.
void Destroy()
Delete all owned data. Does not perform re-initialization with defaults.
PetscInt GetRowStart() const
Returns the global index of the first local row.
void MultTranspose(real_t a, const Vector &x, real_t b, Vector &y) const
Matvec transpose: y = a A^T x + b y.
PetscParMatrix & operator+=(const PetscParMatrix &B)
void ScaleRows(const Vector &s)
Scale the local row i by s(i).
void ResetMemory()
Completes the operation started with PlaceMemory.
void SetFlagsFromMask_() const
void PlaceMemory(Memory< real_t > &, bool=false)
This requests write access from where the memory is valid and temporarily replaces the corresponding ...
void Randomize(PetscInt seed=0)
Set random values.
void SetBlockSize(PetscInt bs)
Set block size of a vector.
bool UseDevice() const override
Return the device flag of the Memory object used by the Vector.
real_t * HostReadWrite() override
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
void PlaceArray(PetscScalar *temp_data)
Temporarily replace the data of the PETSc Vec object. To return to the original data array,...
PetscInt GlobalSize() const
Returns the global number of rows.
PetscParVector & operator-=(const PetscParVector &y)
real_t * Write(bool=true) override
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
void UpdateVecFromFlags()
Update PETSc's Vec after having accessed its data via GetMemory()
void Print(const char *fname=NULL, bool binary=false) const
Prints the vector (to stdout if fname is NULL)
real_t * ReadWrite(bool=true) override
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
const real_t * HostRead() const override
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
const real_t * Read(bool=true) const override
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
real_t * HostWrite() override
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
PetscParVector & operator+=(const PetscParVector &y)
petsc::Vec x
The actual PETSc object.
MPI_Comm GetComm() const
Get the associated MPI communicator.
virtual ~PetscParVector()
Calls PETSc's destroy function.
void ResetArray()
Reset the PETSc Vec object to use its default data. Call this method after the use of PlaceArray().
Vector * GlobalVector() const
Returns the global vector in each processor.
operator petsc::Vec() const
Typecasting to PETSc's Vec type.
PetscParVector & AddValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Add values in a vector.
PetscParVector(MPI_Comm comm, PetscInt glob_size, PetscInt *col=NULL)
Creates vector with given global size and partitioning of the columns.
PetscParVector & SetValues(const Array< PetscInt > &, const Array< PetscScalar > &)
Set values in a vector.
PetscParVector & operator*=(PetscScalar d)
PetscParVector & operator=(PetscScalar d)
Set constant values.
virtual Solver * NewPreconditioner(const OperatorHandle &oh)=0
Abstract class for PETSc's preconditioners.
void Mult(const Vector &b, Vector &x) const override
Application of the preconditioner.
virtual ~PetscPreconditioner()
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
PetscPreconditioner(MPI_Comm comm, const std::string &prefix=std::string())
operator petsc::PC() const
Conversion function to PETSc's PC type.
void MultTranspose(const Vector &b, Vector &x) const override
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Abstract class for monitoring PETSc's solvers.
virtual void MonitorResidual(PetscInt it, PetscReal norm, const Vector &r)
Monitor the residual vector r.
virtual void MonitorSolution(PetscInt it, PetscReal norm, const Vector &x)
Monitor the solution vector x.
virtual void MonitorSolver(PetscSolver *solver)
Generic monitor to take access to the solver.
Abstract class for PETSc's solvers.
PetscClassId cid
The class id of the actual PETSc object.
void SetAbsTol(real_t tol)
void * private_ctx
Private context for solver.
void SetPrintLevel(int plev)
void SetBCHandler(PetscBCHandler *bch)
Sets the object to handle essential boundary conditions.
void SetMaxIter(int max_iter)
void SetRelTol(real_t tol)
void CreatePrivateContext()
virtual ~PetscSolver()
Destroy the PetscParVectors allocated (if any).
MPI_Comm GetComm() const
Get the associated MPI communicator.
PetscSolver()
Construct an empty PetscSolver. Initialize protected objects to NULL.
PetscObject obj
The actual PETSc object (KSP, PC, SNES or TS).
bool clcustom
Boolean to handle SetFromOptions calls.
bool operatorset
Boolean to handle SetOperator calls.
void Customize(bool customize=true) const
Customize object with options set.
void SetMonitor(PetscSolverMonitor *ctx)
Sets user-defined monitoring routine.
void FreePrivateContext()
PetscBCHandler * bchandler
Handler for boundary conditions.
void SetPreconditionerFactory(PetscPreconditionerFactory *factory)
Sets the object for the creation of the preconditioner.
PetscParVector * B
Right-hand side and solution vector.
bool iterative_mode
If true, use the second argument of Mult() as an initial guess.
const int * HostReadJ() const
int NumNonZeroElems() const override
Returns the number of the nonzero elements in the matrix.
const real_t * HostReadData() const
void SortColumnIndices()
Sort the column indices corresponding to each row.
const int * HostReadI() const
Base abstract class for first order time dependent operators.
bool isHomogeneous() const
True if type is HOMOGENEOUS.
virtual Operator & GetExplicitGradient(const Vector &u) const
Return an Operator representing dG/du at the given point u and the currently set time.
bool isImplicit() const
True if type is IMPLICIT or HOMOGENEOUS.
virtual void ExplicitMult(const Vector &u, Vector &v) const
Perform the action of the explicit part of the operator, G: v = G(u, t) where t is the current time.
virtual Operator & GetImplicitGradient(const Vector &u, const Vector &k, real_t shift) const
Return an Operator representing (dF/dk shift + dF/du) at the given u, k, and the currently set time.
virtual void SetTime(const real_t t_)
Set the current time.
virtual void ImplicitMult(const Vector &u, const Vector &k, Vector &v) const
Perform the action of the implicit part of the operator, F: v = F(u, k, t) where t is the current tim...
void MakeDataOwner() const
Set the Vector data (host pointer) ownership flag.
Memory< real_t > & GetMemory()
Return a reference to the Memory object used by the Vector.
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
void SetSize(int s)
Resize the vector to size s.
const int * ess_tdof_list
void trans(const Vector &u, Vector &x)
struct LorentzContext ctx
real_t f(const Vector &p)
void write(std::ostream &os, T value)
Write 'value' to stream.
T read(std::istream &is)
Read a value from the stream and return it.
MFEM_HOST_DEVICE constexpr auto type(const tuple< T... > &t)
a function intended to be used for extracting the ith type from a tuple.
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
T * HostReadWrite(Memory< T > &mem, int size)
Shortcut to ReadWrite(Memory<T> &mem, int size, false)
const T * HostRead(const Memory< T > &mem, int size)
Shortcut to Read(const Memory<T> &mem, int size, false)
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
PetscParMatrix * TripleMatrixProduct(PetscParMatrix *R, PetscParMatrix *A, PetscParMatrix *P)
Returns the matrix R * A * P.
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void MFEMInitializePetsc()
Convenience functions to initialize/finalize PETSc.
MemoryType GetMemoryType(MemoryClass mc)
Return a suitable MemoryType for a given MemoryClass.
T * HostWrite(Memory< T > &mem, int size)
Shortcut to Write(const Memory<T> &mem, int size, false)
HypreParMatrix * ParMult(const HypreParMatrix *A, const HypreParMatrix *B, bool own_matrix)
MemoryType
Memory types supported by MFEM.
@ HOST
Host memory; using new[] and delete[].
@ DEVICE
Device memory; using CUDA or HIP *Malloc and *Free.
void EliminateBC(const HypreParMatrix &A, const HypreParMatrix &Ae, const Array< int > &ess_dof_list, const Vector &X, Vector &B)
Eliminate essential BC specified by ess_dof_list from the solution X to the r.h.s....
std::function< real_t(const Vector &)> f(real_t mass_coeff)
real_t p(const Vector &x, real_t t)
PetscErrorCode PetscCtxDestroyFn(void **)
PetscErrorCode KSPMonitorFn(KSP, PetscInt, PetscReal, void *)
struct _p_PetscObject * PetscObject
MFEM_HOST_DEVICE real_t norm(const Complex &z)
@ HIP_MASK
Biwise-OR of all HIP backends.
@ CUDA_MASK
Biwise-OR of all CUDA backends.