23#if defined(PETSC_HAVE_HYPRE)
24#include "petscmathypre.h"
28#if PETSC_VERSION_LT(3,11,0)
29#define VecLockReadPush VecLockPush
30#define VecLockReadPop VecLockPop
32#if PETSC_VERSION_LT(3,12,0)
33#define VecGetArrayWrite VecGetArray
34#define VecRestoreArrayWrite VecRestoreArray
35#define MatComputeOperator(A,B,C) MatComputeExplicitOperator(A,C)
36#define MatComputeOperatorTranspose(A,B,C) MatComputeExplicitOperatorTranspose(A,C)
38#if PETSC_VERSION_LT(3,19,0)
39#define PETSC_SUCCESS 0
53static PetscErrorCode __mfem_ts_rhsfunction(TS,
PetscReal,Vec,Vec,
void*);
54static PetscErrorCode __mfem_ts_rhsjacobian(TS,
PetscReal,Vec,Mat,Mat,
56static PetscErrorCode __mfem_ts_ifunction(TS,
PetscReal,Vec,Vec,Vec,
void*);
57static PetscErrorCode __mfem_ts_ijacobian(TS,
PetscReal,Vec,Vec,
60static PetscErrorCode __mfem_ts_computesplits(TS,
PetscReal,Vec,Vec,
63static PetscErrorCode __mfem_snes_jacobian(SNES,Vec,Mat,Mat,
void*);
64static PetscErrorCode __mfem_snes_function(SNES,Vec,Vec,
void*);
65static PetscErrorCode __mfem_snes_objective(SNES,Vec,
PetscReal*,
void*);
66static PetscErrorCode __mfem_snes_update(SNES,
PetscInt);
67static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch,Vec,Vec,Vec,
68 PetscBool*,PetscBool*,
void*);
70static PetscErrorCode __mfem_pc_shell_apply(PC,Vec,Vec);
71static PetscErrorCode __mfem_pc_shell_apply_transpose(PC,Vec,Vec);
72static PetscErrorCode __mfem_pc_shell_setup(PC);
73static PetscErrorCode __mfem_pc_shell_destroy(PC);
74static PetscErrorCode __mfem_pc_shell_view(PC,PetscViewer);
75static PetscErrorCode __mfem_mat_shell_apply(Mat,Vec,Vec);
76static PetscErrorCode __mfem_mat_shell_apply_transpose(Mat,Vec,Vec);
77static PetscErrorCode __mfem_mat_shell_destroy(Mat);
78static PetscErrorCode __mfem_mat_shell_copy(Mat,Mat,MatStructure);
79static PetscErrorCode __mfem_array_container_destroy(
void*);
80static PetscErrorCode __mfem_matarray_container_destroy(
void*);
81static PetscErrorCode __mfem_monitor_ctx_destroy(
void**);
89static PetscErrorCode MakeShellPCWithFactory(PC,
95#if !defined(PETSC_HAVE_HYPRE)
96static PetscErrorCode MatConvert_hypreParCSR_AIJ(hypre_ParCSRMatrix*,Mat*);
97static PetscErrorCode MatConvert_hypreParCSR_IS(hypre_ParCSRMatrix*,Mat*);
100#if PETSC_VERSION_GE(3,15,0) && defined(PETSC_HAVE_DEVICE)
101#if defined(MFEM_USE_CUDA) && defined(PETSC_HAVE_CUDA)
103#define PETSC_VECDEVICE VECCUDA
104#define PETSC_MATAIJDEVICE MATAIJCUSPARSE
105#define VecDeviceGetArrayRead VecCUDAGetArrayRead
106#define VecDeviceGetArrayWrite VecCUDAGetArrayWrite
107#define VecDeviceGetArray VecCUDAGetArray
108#define VecDeviceRestoreArrayRead VecCUDARestoreArrayRead
109#define VecDeviceRestoreArrayWrite VecCUDARestoreArrayWrite
110#define VecDeviceRestoreArray VecCUDARestoreArray
111#define VecDevicePlaceArray VecCUDAPlaceArray
112#define VecDeviceResetArray VecCUDAResetArray
113#elif defined(MFEM_USE_HIP) && defined(PETSC_HAVE_HIP)
115#define PETSC_VECDEVICE VECHIP
116#define PETSC_MATAIJDEVICE MATAIJHIPSPARSE
117#define VecDeviceGetArrayRead VecHIPGetArrayRead
118#define VecDeviceGetArrayWrite VecHIPGetArrayWrite
119#define VecDeviceGetArray VecHIPGetArray
120#define VecDeviceRestoreArrayRead VecHIPRestoreArrayRead
121#define VecDeviceRestoreArrayWrite VecHIPRestoreArrayWrite
122#define VecDeviceRestoreArray VecHIPRestoreArray
123#define VecDevicePlaceArray VecHIPPlaceArray
124#define VecDeviceResetArray VecHIPResetArray
126#define VecDeviceGetArrayRead VecGetArrayRead
127#define VecDeviceGetArrayWrite VecGetArrayWrite
128#define VecDeviceGetArray VecGetArray
129#define VecDeviceRestoreArrayRead VecRestoreArrayRead
130#define VecDeviceRestoreArrayWrite VecRestoreArrayWrite
131#define VecDeviceRestoreArray VecRestoreArray
132#define VecDevicePlaceArray VecPlaceArray
133#define VecDeviceResetArray VecResetArray
137#if defined(PETSC_HAVE_DEVICE)
138static PetscErrorCode __mfem_VecSetOffloadMask(Vec,PetscOffloadMask);
140static PetscErrorCode __mfem_VecBoundToCPU(Vec,PetscBool*);
141static PetscErrorCode __mfem_PetscObjectStateIncrease(
PetscObject);
142static PetscErrorCode __mfem_MatCreateDummy(MPI_Comm,
PetscInt,
PetscInt,Mat*);
150 unsigned long int numprec;
151} __mfem_pc_shell_ctx;
180 PetscObjectState cached_ijacstate;
181 PetscObjectState cached_rhsjacstate;
182 PetscObjectState cached_splits_xstate;
183 PetscObjectState cached_splits_xdotstate;
193static PetscErrorCode ierr;
194static PetscMPIInt mpiierr;
217#if PETSC_VERSION_LT(3,17,0)
218 const char *opts =
"-cuda_device";
220 const char *opts =
"-device_select_cuda";
222 ierr = PetscOptionsSetValue(NULL,opts,
224 MFEM_VERIFY(!ierr,
"Unable to set initial option value to PETSc");
228#if PETSC_VERSION_LT(3,17,0)
229 const char *opts =
"-hip_device";
231 const char *opts =
"-device_select_hip";
233 ierr = PetscOptionsSetValue(NULL,opts,
235 MFEM_VERIFY(!ierr,
"Unable to set initial option value to PETSc");
237 ierr = PetscInitialize(argc,argv,rc_file,help);
238 MFEM_VERIFY(!ierr,
"Unable to initialize PETSc");
243 ierr = PetscFinalize();
244 MFEM_VERIFY(!ierr,
"Unable to finalize PETSc");
273 MFEM_VERIFY(
x,
"Missing Vec");
274 ierr = VecSetUp(
x); PCHKERRQ(
x,ierr);
275 ierr = PetscObjectTypeCompare((
PetscObject)
x,VECNEST,&isnest); PCHKERRQ(
x,ierr);
276 MFEM_VERIFY(!isnest,
"Not for type nest");
277 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
278 MFEM_VERIFY(n >= 0,
"Invalid local size");
280#if defined(PETSC_HAVE_DEVICE)
281 PetscOffloadMask omask;
284 ierr = VecGetOffloadMask(
x,&omask); PCHKERRQ(
x,ierr);
285 if (omask != PETSC_OFFLOAD_BOTH)
287 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
290 ierr = VecGetArrayRead(
x,(
const PetscScalar**)&array); PCHKERRQ(
x,ierr);
291#if defined(PETSC_HAVE_DEVICE)
292 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
293 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
294 ""); PCHKERRQ(
x,ierr);
297 if (omask != PETSC_OFFLOAD_BOTH)
299 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
302 ierr = VecDeviceGetArrayRead(
x,(
const PetscScalar**)&darray);
305 ierr = VecDeviceRestoreArrayRead(
x,(
const PetscScalar**)&darray);
313 ierr = VecRestoreArrayRead(
x,(
const PetscScalar**)&array); PCHKERRQ(
x,ierr);
315#if defined(PETSC_HAVE_DEVICE)
316 if (omask == PETSC_OFFLOAD_UNALLOCATED && isdevice) { omask = PETSC_OFFLOAD_CPU; }
317 ierr = __mfem_VecSetOffloadMask(
x,omask); PCHKERRQ(
x,ierr);
325 MFEM_VERIFY(
x,
"Missing Vec");
326#if defined(_USE_DEVICE)
327 PetscOffloadMask mask;
329 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
330 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
331 ""); PCHKERRQ(
x,ierr);
332 ierr = VecGetOffloadMask(
x,&mask); PCHKERRQ(
x,ierr);
337 case PETSC_OFFLOAD_CPU:
341 case PETSC_OFFLOAD_GPU:
345 case PETSC_OFFLOAD_BOTH:
350 MFEM_ABORT(
"Unhandled case " << mask);
359 MFEM_VERIFY(
x,
"Missing Vec");
360 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
361#if defined(_USE_DEVICE)
363 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
364 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
365 ""); PCHKERRQ(
x,ierr);
370 PetscOffloadMask mask;
371 if (dv && hv) { mask = PETSC_OFFLOAD_BOTH; }
372 else if (dv) { mask = PETSC_OFFLOAD_GPU; }
373 else { mask = PETSC_OFFLOAD_CPU; }
374 ierr = __mfem_VecSetOffloadMask(
x,mask); PCHKERRQ(
x,ierr);
381 ierr = VecGetArrayWrite(
x,&v); PCHKERRQ(
x,ierr);
383 ierr = VecRestoreArrayWrite(
x,&v); PCHKERRQ(
x,ierr);
390 MFEM_VERIFY(
x,
"Missing Vec");
391 ierr = VecGetType(
x,&vectype); PCHKERRQ(
x,ierr);
392#if defined(_USE_DEVICE)
397 ierr = VecSetType(
x,PETSC_VECDEVICE); PCHKERRQ(
x,ierr);
400 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
406 ierr = VecSetType(
x,VECSTANDARD); PCHKERRQ(
x,ierr);
414 MFEM_VERIFY(
x,
"Missing Vec");
415#if defined(PETSC_HAVE_DEVICE)
417 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
418 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
419 ""); PCHKERRQ(
x,ierr);
420 if (on_dev && isdevice)
422 ierr = VecDeviceGetArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
423 ierr = VecDeviceRestoreArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
428 ierr = VecGetArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
429 ierr = VecRestoreArrayRead(
x,&dummy); PCHKERRQ(
x,ierr);
443 MFEM_VERIFY(
x,
"Missing Vec");
444#if defined(PETSC_HAVE_DEVICE)
446 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
447 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
448 ""); PCHKERRQ(
x,ierr);
449 if (on_dev && isdevice)
451 ierr = VecDeviceGetArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
452 ierr = VecDeviceRestoreArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
457 ierr = VecGetArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
458 ierr = VecRestoreArrayWrite(
x,&dummy); PCHKERRQ(
x,ierr);
460 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
473 MFEM_VERIFY(
x,
"Missing Vec");
474#if defined(PETSC_HAVE_DEVICE)
476 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
477 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
478 ""); PCHKERRQ(
x,ierr);
479 if (on_dev && isdevice)
481 ierr = VecDeviceGetArray(
x,&dummy); PCHKERRQ(
x,ierr);
482 ierr = VecDeviceRestoreArray(
x,&dummy); PCHKERRQ(
x,ierr);
487 ierr = VecGetArray(
x,&dummy); PCHKERRQ(
x,ierr);
488 ierr = VecRestoreArray(
x,&dummy); PCHKERRQ(
x,ierr);
490 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
502 MFEM_VERIFY(
x,
"Missing Vec");
503#if defined(PETSC_HAVE_DEVICE)
504 ierr = VecBindToCPU(
x,!dev ? PETSC_TRUE : PETSC_FALSE); PCHKERRQ(
x,ierr);
512 MFEM_VERIFY(
x,
"Missing Vec");
513 ierr = __mfem_VecBoundToCPU(
x,&flg); PCHKERRQ(
x,ierr);
514 return flg ? false :
true;
520 ierr = VecGetSize(
x,&N); PCHKERRQ(
x,ierr);
526 ierr = VecSetBlockSize(
x,bs); PCHKERRQ(
x,ierr);
535 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
536 ierr = VecSetSizes(
x,n,PETSC_DECIDE); PCHKERRQ(
x,ierr);
539 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
540 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
541 ""); PCHKERRQ(
x,ierr);
547#if defined(PETSC_HAVE_DEVICE)
551 ierr = VecDeviceGetArrayWrite(
x,&array); PCHKERRQ(
x,ierr);
552 rest = VecDeviceRestoreArrayWrite;
558 ierr = VecGetArrayWrite(
x,&array); PCHKERRQ(
x,ierr);
559 rest = VecRestoreArrayWrite;
562 ierr = (*rest)(
x,&array); PCHKERRQ(
x,ierr);
581 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
585 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
586 ierr = VecSetSizes(
x,col[myid+1]-col[myid],PETSC_DECIDE); PCHKERRQ(
x,ierr);
590 ierr = VecSetSizes(
x,PETSC_DECIDE,glob_size); PCHKERRQ(
x,ierr);
599 ierr = VecDestroy(&
x); CCHKERRQ(comm,ierr);
606 MFEM_VERIFY(col,
"Missing distribution");
608 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
609 ierr = VecCreateMPIWithArray(comm,1,col[myid+1]-col[myid],glob_size,data_,
610 &
x); CCHKERRQ(comm,ierr)
617 ierr = VecDuplicate(y.
x,&
x); PCHKERRQ(
x,ierr);
622 bool transpose,
bool allocate) :
Vector()
626 ierr = VecCreate(comm,&
x);
628 ierr = VecSetSizes(
x,loc,PETSC_DECIDE);
643 bool transpose,
bool allocate) :
Vector()
648 ierr = MatCreateVecs(pA,&
x,NULL); PCHKERRQ(pA,ierr);
652 ierr = MatCreateVecs(pA,NULL,&
x); PCHKERRQ(pA,ierr);
658 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
671 ierr = PetscObjectReference((
PetscObject)y); PCHKERRQ(y,ierr);
680 MPI_Comm comm = pfes->
GetComm();
681 ierr = VecCreate(comm,&
x); CCHKERRQ(comm,ierr);
683 PetscMPIInt myid = 0;
684 if (!HYPRE_AssumedPartitionCheck())
686 mpiierr = MPI_Comm_rank(comm, &myid); CCHKERRQ(comm, mpiierr);
688 ierr = VecSetSizes(
x,offsets[myid+1]-offsets[myid],PETSC_DECIDE);
706 ierr = VecScatterCreateToAll(
x,&scctx,&vout); PCHKERRQ(
x,ierr);
707 ierr = VecScatterBegin(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
709 ierr = VecScatterEnd(scctx,
x,vout,INSERT_VALUES,SCATTER_FORWARD);
711 ierr = VecScatterDestroy(&scctx); PCHKERRQ(
x,ierr);
712 ierr = VecGetArrayRead(vout,&array); PCHKERRQ(
x,ierr);
713 ierr = VecGetLocalSize(vout,&
size); PCHKERRQ(
x,ierr);
716 ierr = VecRestoreArrayRead(vout,&array); PCHKERRQ(
x,ierr);
717 ierr = VecDestroy(&vout); PCHKERRQ(
x,ierr);
726 ierr = VecSet(
x,d); PCHKERRQ(
x,ierr);
734 MFEM_VERIFY(idx.
Size() == vals.
Size(),
735 "Size mismatch between indices and values");
739 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
740 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
748 MFEM_VERIFY(idx.
Size() == vals.
Size(),
749 "Size mismatch between indices and values");
753 ierr = VecAssemblyBegin(
x); PCHKERRQ(
x,ierr);
754 ierr = VecAssemblyEnd(
x); PCHKERRQ(
x,ierr);
761 ierr = VecCopy(y.
x,
x); PCHKERRQ(
x,ierr);
768 ierr = VecAXPY(
x,1.0,y.
x); PCHKERRQ(
x,ierr);
775 ierr = VecAXPY(
x,-1.0,y.
x); PCHKERRQ(
x,ierr);
782 ierr = VecScale(
x,
s); PCHKERRQ(
x,ierr);
789 ierr = VecShift(
x,
s); PCHKERRQ(
x,ierr);
796 ierr = VecPlaceArray(
x,temp_data); PCHKERRQ(
x,ierr);
801 ierr = VecResetArray(
x); PCHKERRQ(
x,ierr);
808 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
810 "Memory size " << mem.
Capacity() <<
" < " << n <<
" vector size!");
811 MFEM_VERIFY(
pdata.
Empty(),
"Vector data is not empty");
812 MFEM_VERIFY(
data.
Empty(),
"Vector data is not empty");
813#if defined(_USE_DEVICE)
815 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
816 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
817 ""); PCHKERRQ(
x,ierr);
824 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
829 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
839#if defined(PETSC_HAVE_DEVICE)
840 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
842 ierr = VecPlaceArray(
x,w); PCHKERRQ(
x,ierr);
844 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
852 ierr = VecGetLocalSize(
x,&n); PCHKERRQ(
x,ierr);
854 "Memory size " << mem.
Capacity() <<
" < " << n <<
" vector size!");
855 MFEM_VERIFY(
pdata.
Empty(),
"Vector data is not empty");
856 MFEM_VERIFY(
data.
Empty(),
"Vector data is not empty");
857#if defined(_USE_DEVICE)
859 ierr = PetscObjectTypeCompareAny((
PetscObject)
x,&isdevice,
860 VECSEQCUDA,VECMPICUDA,VECSEQHIP,VECMPIHIP,
861 ""); PCHKERRQ(
x,ierr);
867 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_GPU); PCHKERRQ(
x,ierr);
872 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
881#if defined(PETSC_HAVE_DEVICE)
882 ierr = __mfem_VecSetOffloadMask(
x,PETSC_OFFLOAD_CPU); PCHKERRQ(
x,ierr);
884 ierr = VecPlaceArray(
x,w); PCHKERRQ(
x,ierr);
887 ierr = __mfem_PetscObjectStateIncrease((
PetscObject)
x); PCHKERRQ(
x,ierr);
888 ierr = VecLockReadPush(
x); PCHKERRQ(
x,ierr);
894 MFEM_VERIFY(!
pdata.
Empty(),
"Vector data is empty");
906#if defined(PETSC_HAVE_DEVICE)
907 PetscOffloadMask mask;
908 ierr = VecGetOffloadMask(
x,&mask); PCHKERRQ(
x,ierr);
909 if ((usedev && (mask != PETSC_OFFLOAD_GPU && mask != PETSC_OFFLOAD_BOTH)) ||
910 (!usedev && (mask != PETSC_OFFLOAD_CPU && mask != PETSC_OFFLOAD_BOTH)))
913 ierr = VecGetArrayRead(
x,&v); PCHKERRQ(
x,ierr);
915 ierr = VecRestoreArrayRead(
x,&v); PCHKERRQ(
x,ierr);
920 if (
read && !
write) { ierr = VecLockReadPop(
x); PCHKERRQ(
x,ierr); }
923#if defined(PETSC_HAVE_DEVICE)
924 ierr = VecDeviceResetArray(
x); PCHKERRQ(
x,ierr);
926 MFEM_VERIFY(
false,
"This should not happen");
931 ierr = VecResetArray(
x); PCHKERRQ(
x,ierr);
937 PetscRandom rctx = NULL;
941 ierr = PetscRandomCreate(PetscObjectComm((
PetscObject)
x),&rctx);
943 ierr = PetscRandomSetSeed(rctx,(
unsigned long)seed); PCHKERRQ(
x,ierr);
944 ierr = PetscRandomSeed(rctx); PCHKERRQ(
x,ierr);
946 ierr = VecSetRandom(
x,rctx); PCHKERRQ(
x,ierr);
947 ierr = PetscRandomDestroy(&rctx); PCHKERRQ(
x,ierr);
958 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)
x),fname,
959 FILE_MODE_WRITE,&view);
963 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)
x),fname,&view);
966 ierr = VecView(
x,view); PCHKERRQ(
x,ierr);
967 ierr = PetscViewerDestroy(&view); PCHKERRQ(
x,ierr);
971 ierr = VecView(
x,NULL); PCHKERRQ(
x,ierr);
980 ierr = MatGetOwnershipRange(
A,&
N,NULL); PCHKERRQ(
A,ierr);
987 ierr = MatGetOwnershipRangeColumn(
A,&
N,NULL); PCHKERRQ(
A,ierr);
994 ierr = MatGetLocalSize(
A,&
N,NULL); PCHKERRQ(
A,ierr);
1001 ierr = MatGetLocalSize(
A,NULL,&
N); PCHKERRQ(
A,ierr);
1008 ierr = MatGetSize(
A,&
N,NULL); PCHKERRQ(
A,ierr);
1015 ierr = MatGetSize(
A,NULL,&
N); PCHKERRQ(
A,ierr);
1022 ierr = MatGetInfo(
A,MAT_GLOBAL_SUM,&info); PCHKERRQ(
A,ierr);
1028 if (cbs < 0) { cbs = rbs; }
1029 ierr = MatSetBlockSizes(
A,rbs,cbs); PCHKERRQ(
A,ierr);
1053 rows.
GetData(),PETSC_USE_POINTER,&isr); PCHKERRQ(B,ierr);
1055 cols.
GetData(),PETSC_USE_POINTER,&isc); PCHKERRQ(B,ierr);
1056 ierr = MatCreateSubMatrix(B,isr,isc,MAT_INITIAL_MATRIX,&
A); PCHKERRQ(B,ierr);
1057 ierr = ISDestroy(&isr); PCHKERRQ(B,ierr);
1058 ierr = ISDestroy(&isc); PCHKERRQ(B,ierr);
1102 BlockDiagonalConstructor(comm,row_starts,row_starts,diag,
1116 BlockDiagonalConstructor(comm,row_starts,col_starts,diag,
1129 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1130 if (
X) {
delete X; }
1131 if (
Y) {
delete Y; }
1136#if defined(PETSC_HAVE_HYPRE)
1137 ierr = MatCreateFromParCSR(B,MATAIJ,PETSC_USE_POINTER,&
A);
1139 ierr = MatConvert_hypreParCSR_AIJ(B,&
A); CCHKERRQ(B.
GetComm(),ierr);
1150 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1151 if (
X) {
delete X; }
1152 if (
Y) {
delete Y; }
1157 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1165 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1169 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
1170 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
1171 ierr = MatAXPY(
A,1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
1180 ierr = MatDuplicate(B,MAT_COPY_VALUES,&
A); CCHKERRQ(B.
GetComm(),ierr);
1181 ierr = MatScale(
A,-1.0); PCHKERRQ(
A,ierr);
1185 MFEM_VERIFY(
height == B.
Height(),
"Invalid number of local rows");
1186 MFEM_VERIFY(
width == B.
Width(),
"Invalid number of local columns");
1187 ierr = MatAXPY(
A,-1.0,B,DIFFERENT_NONZERO_PATTERN); CCHKERRQ(B.
GetComm(),ierr);
1192void PetscParMatrix::
1193BlockDiagonalConstructor(MPI_Comm comm,
1198 PetscInt lrsize,lcsize,rstart,cstart;
1199 PetscMPIInt myid = 0,commsize;
1201 mpiierr = MPI_Comm_size(comm,&commsize); CCHKERRQ(comm,mpiierr);
1202 if (!HYPRE_AssumedPartitionCheck())
1204 mpiierr = MPI_Comm_rank(comm,&myid); CCHKERRQ(comm,mpiierr);
1206 lrsize = row_starts[myid+1]-row_starts[myid];
1207 rstart = row_starts[myid];
1208 lcsize = col_starts[myid+1]-col_starts[myid];
1209 cstart = col_starts[myid];
1214 ierr = ISCreateStride(comm,diag->
Height(),rstart,1,&is); CCHKERRQ(comm,ierr);
1215 ISLocalToGlobalMapping rl2g,cl2g;
1216 ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g); PCHKERRQ(is,ierr);
1217 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
1218 if (row_starts != col_starts)
1220 ierr = ISCreateStride(comm,diag->
Width(),cstart,1,&is);
1221 CCHKERRQ(comm,ierr);
1222 ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g); PCHKERRQ(is,ierr);
1223 ierr = ISDestroy(&is); CCHKERRQ(comm,ierr);
1227 ierr = PetscObjectReference((
PetscObject)rl2g); PCHKERRQ(rl2g,ierr);
1232 ierr = MatCreate(comm,&
A); CCHKERRQ(comm,ierr);
1233 ierr = MatSetSizes(
A,lrsize,lcsize,PETSC_DECIDE,PETSC_DECIDE);
1235 ierr = MatSetType(
A,MATIS); PCHKERRQ(
A,ierr);
1236 ierr = MatSetLocalToGlobalMapping(
A,rl2g,cl2g); PCHKERRQ(
A,ierr);
1237 ierr = ISLocalToGlobalMappingDestroy(&rl2g); PCHKERRQ(
A,ierr)
1238 ierr = ISLocalToGlobalMappingDestroy(&cl2g); PCHKERRQ(
A,ierr)
1243 ierr = MatISGetLocalMat(
A,&lA); PCHKERRQ(
A,ierr);
1246#if defined(PETSC_USE_64BIT_INDICES)
1249 ierr = PetscMalloc2(m,&pII,nnz,&pJJ); PCHKERRQ(lA,ierr);
1250 for (
int i = 0; i < m; i++) { pII[i] = II[i]; }
1251 for (
int i = 0; i < nnz; i++) { pJJ[i] = JJ[i]; }
1252 ierr = MatSeqAIJSetPreallocationCSR(lA,pII,pJJ,
1254 ierr = PetscFree2(pII,pJJ); PCHKERRQ(lA,ierr);
1256 ierr = MatSeqAIJSetPreallocationCSR(lA,II,JJ,
1269 ierr = PetscMalloc1(m,&dii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1270 ierr = PetscMalloc1(nnz,&djj); CCHKERRQ(PETSC_COMM_SELF,ierr);
1271 ierr = PetscMalloc1(nnz,&da); CCHKERRQ(PETSC_COMM_SELF,ierr);
1272 if (
sizeof(
PetscInt) ==
sizeof(
int))
1275 CCHKERRQ(PETSC_COMM_SELF,ierr);
1277 CCHKERRQ(PETSC_COMM_SELF,ierr);
1283 for (
int i = 0; i < m; i++) { dii[i] = iii[i]; }
1284 for (
int i = 0; i < nnz; i++) { djj[i] = jjj[i]; }
1287 CCHKERRQ(PETSC_COMM_SELF,ierr);
1288 ierr = PetscCalloc1(m,&oii);
1289 CCHKERRQ(PETSC_COMM_SELF,ierr);
1292 ierr = MatCreateMPIAIJWithSplitArrays(comm,lrsize,lcsize,PETSC_DECIDE,
1294 dii,djj,da,oii,NULL,NULL,&
A);
1295 CCHKERRQ(comm,ierr);
1299 ierr = MatCreateSeqAIJWithArrays(comm,lrsize,lcsize,dii,djj,da,&
A);
1300 CCHKERRQ(comm,ierr);
1303 void *ptrs[4] = {dii,djj,da,oii};
1304 const char *names[4] = {
"_mfem_csr_dii",
1313 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
1314 ierr = PetscContainerSetPointer(c,ptrs[i]); CCHKERRQ(comm,ierr);
1315 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
1316 CCHKERRQ(comm,ierr);
1318 CCHKERRQ(comm,ierr);
1319 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
1324 ierr = MatAssemblyBegin(
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(
A,ierr);
1325 ierr = MatAssemblyEnd(
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(
A,ierr);
1345 ierr = MatCreate(comm,
A); CCHKERRQ(comm,ierr);
1347 PETSC_DECIDE,PETSC_DECIDE); PCHKERRQ(
A,ierr);
1348 ierr = MatSetType(*
A,MATSHELL); PCHKERRQ(
A,ierr);
1349 ierr = MatShellSetContext(*
A,(
void *)op); PCHKERRQ(
A,ierr);
1350 ierr = MatShellSetOperation(*
A,MATOP_MULT,
1351 (
void (*)())__mfem_mat_shell_apply);
1353 ierr = MatShellSetOperation(*
A,MATOP_MULT_TRANSPOSE,
1354 (
void (*)())__mfem_mat_shell_apply_transpose);
1356 ierr = MatShellSetOperation(*
A,MATOP_COPY,
1357 (
void (*)())__mfem_mat_shell_copy);
1359 ierr = MatShellSetOperation(*
A,MATOP_DESTROY,
1360 (
void (*)())__mfem_mat_shell_destroy);
1361#if defined(_USE_DEVICE)
1365 ierr = MatShellSetVecType(*
A,PETSC_VECDEVICE); PCHKERRQ(
A,ierr);
1366 ierr = MatBindToCPU(*
A,PETSC_FALSE); PCHKERRQ(
A,ierr);
1370 ierr = MatBindToCPU(*
A,PETSC_TRUE); PCHKERRQ(
A,ierr);
1374 ierr = MatSetUp(*
A); PCHKERRQ(*
A,ierr);
1399 PetscBool avoidmatconvert = PETSC_FALSE;
1402 ierr = PetscObjectTypeCompareAny((
PetscObject)(pA->
A),&avoidmatconvert,MATMFFD,
1404 CCHKERRQ(comm,ierr);
1406 if (pA && !avoidmatconvert)
1410#if PETSC_VERSION_LT(3,10,0)
1414#if PETSC_VERSION_LT(3,18,0)
1415 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATTRANSPOSEMAT,&istrans);
1417 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATTRANSPOSEVIRTUAL,
1430#if PETSC_VERSION_LT(3,10,0)
1431 ierr = PetscObjectTypeCompare((
PetscObject)(pA->
A),MATIS,&ismatis);
1437 ierr = MatTransposeGetMat(pA->
A,&At); CCHKERRQ(pA->
GetComm(),ierr);
1438#if PETSC_VERSION_LT(3,10,0)
1439 ierr = PetscObjectTypeCompare((
PetscObject)(At),MATIS,&ismatis);
1447#if PETSC_VERSION_LT(3,10,0)
1454 ierr = MatISGetMPIXAIJ(At,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1455 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1456 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1460 ierr = MatISGetMPIXAIJ(pA->
A,MAT_INITIAL_MATRIX,
A);
1461 PCHKERRQ(pA->
A,ierr);
1468 mpiierr = MPI_Comm_size(comm,&size); CCHKERRQ(comm,mpiierr);
1474 ierr = MatConvert(At,size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,&B);
1475 PCHKERRQ(pA->
A,ierr);
1476 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1477 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1481 ierr = MatConvert(pA->
A, size > 1 ? MATMPIAIJ : MATSEQAIJ,MAT_INITIAL_MATRIX,
A);
1482 PCHKERRQ(pA->
A,ierr);
1491 ierr = MatConvert(At,MATIS,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1492 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1493 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1497 ierr = MatConvert(pA->
A,MATIS,MAT_INITIAL_MATRIX,
A); PCHKERRQ(pA->
A,ierr);
1502#if defined(PETSC_HAVE_HYPRE)
1506 ierr = MatConvert(At,MATHYPRE,MAT_INITIAL_MATRIX,&B); PCHKERRQ(pA->
A,ierr);
1507 ierr = MatCreateTranspose(B,
A); PCHKERRQ(pA->
A,ierr);
1508 ierr = MatDestroy(&B); PCHKERRQ(pA->
A,ierr);
1512 ierr = MatConvert(pA->
A,MATHYPRE,MAT_INITIAL_MATRIX,
A); PCHKERRQ(pA->
A,ierr);
1515 MFEM_ABORT(
"Reconfigure PETSc with --download-hypre or --with-hypre")
1524 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1531#if defined(PETSC_HAVE_HYPRE)
1532 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATAIJ,
1533 PETSC_USE_POINTER,
A);
1535 ierr = MatConvert_hypreParCSR_AIJ(
const_cast<HypreParMatrix&
>(*pH),
A);
1541#if defined(PETSC_HAVE_HYPRE)
1542 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATIS,
1543 PETSC_USE_POINTER,
A);
1551#if defined(PETSC_HAVE_HYPRE)
1552 ierr = MatCreateFromParCSR(
const_cast<HypreParMatrix&
>(*pH),MATHYPRE,
1553 PETSC_USE_POINTER,
A);
1556 MFEM_ABORT(
"Reconfigure PETSc with --download-hypre or --with-hypre")
1565 MFEM_ABORT(
"Conversion from HypreParCSR to operator type = " << tid <<
1566 " is not implemented");
1571 Mat *mats,*matsl2l = NULL;
1576 ierr = PetscCalloc1(nr*nc,&mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1579 ierr = PetscCalloc1(nr,&matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1581 for (i=0; i<nr; i++)
1583 PetscBool needl2l = PETSC_TRUE;
1585 for (j=0; j<nc; j++)
1593 ierr = PetscObjectQuery((
PetscObject)mats[i*nc+j],
"_MatIS_PtAP_l2l",
1595 PCHKERRQ(mats[i*nc+j],ierr);
1603 ierr = PetscContainerGetPointer(c,(
void**)&l2l);
1605 MFEM_VERIFY(l2l->
Size() == 1,
"Unexpected size "
1606 << l2l->
Size() <<
" for block row " << i );
1607 ierr = PetscObjectReference((
PetscObject)(*l2l)[0]);
1609 matsl2l[i] = (*l2l)[0];
1610 needl2l = PETSC_FALSE;
1616 ierr = MatCreateNest(comm,nr,NULL,nc,NULL,mats,
A); CCHKERRQ(comm,ierr);
1619 ierr = MatConvert(*
A,MATIS,MAT_INPLACE_MATRIX,
A); CCHKERRQ(comm,ierr);
1622 for (
int i=0; i<(int)nr; i++) { (*vmatsl2l)[i] = matsl2l[i]; }
1623 ierr = PetscFree(matsl2l); CCHKERRQ(PETSC_COMM_SELF,ierr);
1626 ierr = PetscContainerCreate(comm,&c); CCHKERRQ(comm,ierr);
1627 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
1628 ierr = PetscContainerSetUserDestroy(c,__mfem_matarray_container_destroy);
1631 PCHKERRQ((*
A),ierr);
1632 ierr = PetscContainerDestroy(&c); CCHKERRQ(comm,ierr);
1634 for (i=0; i<nr*nc; i++) { ierr = MatDestroy(&mats[i]); CCHKERRQ(comm,ierr); }
1635 ierr = PetscFree(mats); CCHKERRQ(PETSC_COMM_SELF,ierr);
1641 ierr = MatCreate(comm,
A); CCHKERRQ(comm,ierr);
1642 ierr = MatSetSizes(*
A,pI->
Height(),pI->
Width(),PETSC_DECIDE,PETSC_DECIDE);
1644 ierr = MatSetType(*
A,MATAIJ); PCHKERRQ(*
A,ierr);
1645 ierr = MatMPIAIJSetPreallocation(*
A,1,NULL,0,NULL); PCHKERRQ(*
A,ierr);
1646 ierr = MatSeqAIJSetPreallocation(*
A,1,NULL); PCHKERRQ(*
A,ierr);
1647 ierr = MatSetOption(*
A,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE); PCHKERRQ(*
A,ierr);
1648 ierr = MatGetOwnershipRange(*
A,&rst,NULL); PCHKERRQ(*
A,ierr);
1651 ierr = MatSetValue(*
A,i,i,1.,INSERT_VALUES); PCHKERRQ(*
A,ierr);
1653 ierr = MatAssemblyBegin(*
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*
A,ierr);
1654 ierr = MatAssemblyEnd(*
A,MAT_FINAL_ASSEMBLY); PCHKERRQ(*
A,ierr);
1671 int n = pS->
Width();
1676 ierr = PetscMalloc1(m+1,&pii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1677 ierr = PetscMalloc1(ii[m],&pjj); CCHKERRQ(PETSC_COMM_SELF,ierr);
1678 ierr = PetscMalloc1(ii[m],&pdata); CCHKERRQ(PETSC_COMM_SELF,ierr);
1680 for (
int i = 0; i < m; i++)
1682 bool issorted =
true;
1684 for (
int j = ii[i]; j < ii[i+1]; j++)
1687 if (issorted && j != ii[i]) { issorted = (pjj[j] > pjj[j-1]); }
1692 ierr = PetscSortIntWithScalarArray(pii[i+1]-pii[i],pjj + pii[i],pdata + pii[i]);
1693 CCHKERRQ(PETSC_COMM_SELF,ierr);
1697 mpiierr = MPI_Comm_size(comm,&size); CCHKERRQ(comm,mpiierr);
1700 ierr = MatCreateSeqAIJWithArrays(comm,m,n,pii,pjj,pdata,&B);
1701 CCHKERRQ(comm,ierr);
1706 ierr = PetscCalloc1(m+1,&oii); CCHKERRQ(PETSC_COMM_SELF,ierr);
1707 ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,
1709 pii,pjj,pdata,oii,NULL,NULL,&B);
1710 CCHKERRQ(comm,ierr);
1712 void *ptrs[4] = {pii,pjj,pdata,oii};
1713 const char *names[4] = {
"_mfem_csr_pii",
1718 for (
int i=0; i<4; i++)
1722 ierr = PetscContainerCreate(PETSC_COMM_SELF,&c); PCHKERRQ(B,ierr);
1723 ierr = PetscContainerSetPointer(c,ptrs[i]); PCHKERRQ(B,ierr);
1724 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
1728 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
1736 ierr = MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,
A); PCHKERRQ(B,ierr);
1737 ierr = MatDestroy(&B); PCHKERRQ(*
A,ierr);
1741 ierr = MatConvert(B,MATIS,MAT_INITIAL_MATRIX,
A); PCHKERRQ(B,ierr);
1742 ierr = MatDestroy(&B); PCHKERRQ(*
A,ierr);
1746 MFEM_ABORT(
"Unsupported operator type conversion " << tid)
1753 "Supported types are ANY_TYPE, PETSC_MATSHELL or PETSC_MATAIJ");
1760 ierr = MatComputeOperator(*
A,MATMPIAIJ,&B); CCHKERRQ(comm,ierr);
1761 ierr = PetscObjectTypeCompare((
PetscObject)B,MATMPIAIJ,&isaij);
1762 CCHKERRQ(comm,ierr);
1763 ierr = MatDestroy(
A); CCHKERRQ(comm,ierr);
1766 ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,
A); CCHKERRQ(comm,ierr);
1767 ierr = MatDestroy(&B); CCHKERRQ(comm,ierr);
1782 MPI_Comm comm = MPI_COMM_NULL;
1783 ierr = PetscObjectGetComm((
PetscObject)
A,&comm); PCHKERRQ(
A,ierr);
1784 ierr = MatDestroy(&
A); CCHKERRQ(comm,ierr);
1795 ierr = PetscObjectReference((
PetscObject)
a); PCHKERRQ(
a,ierr);
1805 if (A_ ==
A) {
return; }
1807 ierr = PetscObjectReference((
PetscObject)A_); PCHKERRQ(A_,ierr);
1813void PetscParMatrix::SetUpForDevice()
1815#if !defined(_USE_DEVICE)
1821 if (
A) { ierr = MatBindToCPU(
A, PETSC_TRUE); PCHKERRQ(
A,ierr); }
1824 PetscBool ismatis,isnest,isaij;
1825 ierr = PetscObjectTypeCompare((
PetscObject)
A,MATIS,&ismatis);
1827 ierr = PetscObjectTypeCompare((
PetscObject)
A,MATNEST,&isnest);
1832 ierr = MatISGetLocalMat(
A,&tA); PCHKERRQ(
A,ierr);
1833 ierr = PetscObjectTypeCompare((
PetscObject)tA,MATNEST,&isnest);
1840 ierr = MatNestGetSubMats(tA,&n,&m,&sub); PCHKERRQ(tA,ierr);
1850 ierr = PetscObjectTypeCompareAny((
PetscObject)sA,&isaij,MATSEQAIJ,MATMPIAIJ,
"");
1854 ierr = MatSetType(sA,PETSC_MATAIJDEVICE); PCHKERRQ(sA,ierr);
1860 ierr = MatSetOption(sA,MAT_FORM_EXPLICIT_TRANSPOSE,
1861 PETSC_TRUE); PCHKERRQ(sA,ierr);
1868 ierr = MatSetVecType(tA,PETSC_VECDEVICE); PCHKERRQ(tA,ierr);
1874 ierr = PetscObjectTypeCompareAny((
PetscObject)tA,&isaij,MATSEQAIJ,MATMPIAIJ,
"");
1878 ierr = MatSetType(tA,PETSC_MATAIJDEVICE); PCHKERRQ(tA,ierr);
1883 ierr = MatSetOption(tA,MAT_FORM_EXPLICIT_TRANSPOSE,
1884 PETSC_TRUE); PCHKERRQ(tA,ierr);
1899 f = MatMultTranspose;
1900 fadd = MatMultTransposeAdd;
1911 ierr = VecScale(Y,
b/
a); PCHKERRQ(A,ierr);
1912 ierr = (*fadd)(A,X,Y,Y); PCHKERRQ(A,ierr);
1913 ierr = VecScale(Y,
a); PCHKERRQ(A,ierr);
1917 ierr = (*f)(A,X,Y); PCHKERRQ(A,ierr);
1918 ierr = VecScale(Y,
a); PCHKERRQ(A,ierr);
1929 ierr = VecScale(Y,
b); PCHKERRQ(A,ierr);
1933 ierr = VecSet(Y,0.); PCHKERRQ(A,ierr);
1940 ierr = PetscObjectReference((
PetscObject)master.
A); PCHKERRQ(master.
A,ierr);
1952 MFEM_VERIFY(
A,
"Mat not present");
1962 MFEM_VERIFY(
A,
"Mat not present");
1973 ierr = MatCreateTranspose(
A,&B); PCHKERRQ(
A,ierr);
1977 ierr = MatTranspose(
A,MAT_INITIAL_MATRIX,&B); PCHKERRQ(
A,ierr);
1984 ierr = MatScale(
A,
s); PCHKERRQ(
A,ierr);
1990 MFEM_ASSERT(x.
Size() ==
Width(),
"invalid x.Size() = " << x.
Size()
1991 <<
", expected size = " <<
Width());
1992 MFEM_ASSERT(y.
Size() ==
Height(),
"invalid y.Size() = " << y.
Size()
1993 <<
", expected size = " <<
Height());
1997 bool rw = (
b != 0.0);
2000 MatMultKernel(
A,
a,XX->
x,
b,YY->
x,
false);
2009 MFEM_ASSERT(x.
Size() ==
Height(),
"invalid x.Size() = " << x.
Size()
2010 <<
", expected size = " <<
Height());
2011 MFEM_ASSERT(y.
Size() ==
Width(),
"invalid y.Size() = " << y.
Size()
2012 <<
", expected size = " <<
Width());
2016 bool rw = (
b != 0.0);
2019 MatMultKernel(
A,
a,YY->
x,
b,XX->
x,
true);
2032 ierr = PetscViewerBinaryOpen(PetscObjectComm((
PetscObject)
A),fname,
2033 FILE_MODE_WRITE,&view);
2037 ierr = PetscViewerASCIIOpen(PetscObjectComm((
PetscObject)
A),fname,&view);
2040 ierr = MatView(
A,view); PCHKERRQ(
A,ierr);
2041 ierr = PetscViewerDestroy(&view); PCHKERRQ(
A,ierr);
2045 ierr = MatView(
A,NULL); PCHKERRQ(
A,ierr);
2051 MFEM_ASSERT(
s.Size() ==
Height(),
"invalid s.Size() = " <<
s.Size()
2052 <<
", expected size = " <<
Height());
2056 ierr = MatDiagonalScale(
A,*YY,NULL); PCHKERRQ(
A,ierr);
2062 MFEM_ASSERT(
s.Size() ==
Width(),
"invalid s.Size() = " <<
s.Size()
2063 <<
", expected size = " <<
Width());
2067 ierr = MatDiagonalScale(
A,NULL,*XX); PCHKERRQ(
A,ierr);
2079 MFEM_ASSERT(
s.Size() ==
Height(),
"invalid s.Size() = " <<
s.Size()
2080 <<
", expected size = " <<
Height());
2081 MFEM_ASSERT(
s.Size() ==
Width(),
"invalid s.Size() = " <<
s.Size()
2082 <<
", expected size = " <<
Width());
2086 ierr = MatDiagonalSet(
A,*XX,ADD_VALUES); PCHKERRQ(
A,ierr);
2094 "Petsc TripleMatrixProduct: Number of local cols of A " << A->
Width() <<
2095 " differs from number of local rows of P " << P->
Height());
2097 "Petsc TripleMatrixProduct: Number of local rows of A " << A->
Height() <<
2098 " differs from number of local cols of R " << R->
Width());
2100 ierr = MatMatMatMult(*R,*A,*P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2107 Mat pA = *A,pP = *P,pRt = *Rt;
2109 PetscBool Aismatis,Pismatis,Rtismatis;
2112 "Petsc RAP: Number of local cols of A " << A->
Width() <<
2113 " differs from number of local rows of P " << P->
Height());
2115 "Petsc RAP: Number of local rows of A " << A->
Height() <<
2116 " differs from number of local rows of Rt " << Rt->
Height());
2117 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&Aismatis);
2119 ierr = PetscObjectTypeCompare((
PetscObject)pP,MATIS,&Pismatis);
2121 ierr = PetscObjectTypeCompare((
PetscObject)pRt,MATIS,&Rtismatis);
2128 ISLocalToGlobalMapping cl2gP,cl2gRt;
2129 PetscInt rlsize,clsize,rsize,csize;
2131 ierr = MatGetLocalToGlobalMapping(pP,NULL,&cl2gP); PCHKERRQ(pA,ierr);
2132 ierr = MatGetLocalToGlobalMapping(pRt,NULL,&cl2gRt); PCHKERRQ(pA,ierr);
2133 ierr = MatGetLocalSize(pP,NULL,&clsize); PCHKERRQ(pP,ierr);
2134 ierr = MatGetLocalSize(pRt,NULL,&rlsize); PCHKERRQ(pRt,ierr);
2135 ierr = MatGetSize(pP,NULL,&csize); PCHKERRQ(pP,ierr);
2136 ierr = MatGetSize(pRt,NULL,&rsize); PCHKERRQ(pRt,ierr);
2137 ierr = MatCreate(A->
GetComm(),&B); PCHKERRQ(pA,ierr);
2138 ierr = MatSetSizes(B,rlsize,clsize,rsize,csize); PCHKERRQ(B,ierr);
2139 ierr = MatSetType(B,MATIS); PCHKERRQ(B,ierr);
2140 ierr = MatSetLocalToGlobalMapping(B,cl2gRt,cl2gP); PCHKERRQ(B,ierr);
2141 ierr = MatISGetLocalMat(pA,&lA); PCHKERRQ(pA,ierr);
2142 ierr = MatISGetLocalMat(pP,&lP); PCHKERRQ(pA,ierr);
2143 ierr = MatISGetLocalMat(pRt,&lRt); PCHKERRQ(pA,ierr);
2146 ierr = MatPtAP(lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
2152 ierr = MatTranspose(lRt,MAT_INITIAL_MATRIX,&lR); PCHKERRQ(lRt,ierr);
2153 ierr = MatMatMatMult(lR,lA,lP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&lB);
2155 ierr = MatDestroy(&lR); PCHKERRQ(lRt,ierr);
2163 ierr = PetscObjectReference((
PetscObject)lRt); PCHKERRQ(lRt,ierr);
2164 (*vmatsl2l)[0] = lRt;
2167 ierr = PetscContainerCreate(PetscObjectComm((
PetscObject)B),&c);
2169 ierr = PetscContainerSetPointer(c,vmatsl2l); PCHKERRQ(c,ierr);
2170 ierr = PetscContainerSetUserDestroy(c,__mfem_matarray_container_destroy);
2174 ierr = PetscContainerDestroy(&c); PCHKERRQ(B,ierr);
2178 ierr = MatISSetLocalMat(B,lB); PCHKERRQ(lB,ierr);
2179 ierr = MatDestroy(&lB); PCHKERRQ(lA,ierr);
2180 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
2181 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); PCHKERRQ(B,ierr);
2187 ierr = MatPtAP(pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2193 ierr = MatTranspose(pRt,MAT_INITIAL_MATRIX,&pR); PCHKERRQ(Rt,ierr);
2194 ierr = MatMatMatMult(pR,pA,pP,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);
2196 ierr = MatDestroy(&pR); PCHKERRQ(pRt,ierr);
2211#if defined(PETSC_HAVE_HYPRE)
2226 ierr = MatMatMult(*A,*B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AB);
2236 ierr = MatDuplicate(
A,MAT_COPY_VALUES,&Ae); PCHKERRQ(
A,ierr);
2238 ierr = MatAXPY(Ae,-1.,
A,SAME_NONZERO_PATTERN); PCHKERRQ(
A,ierr);
2247 MFEM_ABORT(
"Missing PetscParMatrix::EliminateRowsCols() with HypreParVectors");
2256 ierr = MatGetSize(
A,&
M,&
N); PCHKERRQ(
A,ierr);
2257 MFEM_VERIFY(
M ==
N,
"Rectangular case unsupported");
2260 ierr = MatSetOption(
A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(
A,ierr);
2264 ierr = MatGetOwnershipRange(
A,&rst,NULL); PCHKERRQ(
A,ierr);
2267 ierr = Convert_Array_IS(
GetComm(),
true,&rows_cols,rst,&dir); PCHKERRQ(
A,ierr);
2270 ierr = MatZeroRowsColumnsIS(
A,dir,diag,NULL,NULL); PCHKERRQ(
A,ierr);
2274 ierr = MatZeroRowsColumnsIS(
A,dir,diag,
X,B); PCHKERRQ(
A,ierr);
2276 ierr = ISDestroy(&dir); PCHKERRQ(
A,ierr);
2281 ierr = MatSetOption(
A,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE); PCHKERRQ(
A,ierr);
2285 ierr = MatGetOwnershipRange(
A,&rst,NULL); PCHKERRQ(
A,ierr);
2288 ierr = Convert_Array_IS(
GetComm(),
true,&rows,rst,&dir); PCHKERRQ(
A,ierr);
2289 ierr = MatZeroRowsIS(
A,dir,0.0,NULL,NULL); PCHKERRQ(
A,ierr);
2290 ierr = ISDestroy(&dir); PCHKERRQ(
A,ierr);
2300 ierr = PetscObjectDereference((
PetscObject)
A); CCHKERRQ(comm,ierr);
2309 MFEM_VERIFY(
A,
"no associated PETSc Mat object");
2312 ierr = PetscObjectTypeCompare(oA, MATAIJ, &ok); PCHKERRQ(
A,ierr);
2314 ierr = PetscObjectTypeCompare(oA, MATSEQAIJ, &ok); PCHKERRQ(
A,ierr);
2316 ierr = PetscObjectTypeCompare(oA, MATMPIAIJ, &ok); PCHKERRQ(
A,ierr);
2318 ierr = PetscObjectTypeCompare(oA, MATIS, &ok); PCHKERRQ(
A,ierr);
2320 ierr = PetscObjectTypeCompare(oA, MATSHELL, &ok); PCHKERRQ(
A,ierr);
2322 ierr = PetscObjectTypeCompare(oA, MATNEST, &ok); PCHKERRQ(
A,ierr);
2324#if defined(PETSC_HAVE_HYPRE)
2325 ierr = PetscObjectTypeCompare(oA, MATHYPRE, &ok); PCHKERRQ(
A,ierr);
2339 Ae.
Mult(-1.0, X, 1.0, B);
2342 ierr = MatGetDiagonal(pA,diag); PCHKERRQ(pA,ierr);
2343 ierr = VecGetArrayRead(diag,&array); PCHKERRQ(diag,ierr);
2344 for (
int i = 0; i < ess_dof_list.
Size(); i++)
2346 int r = ess_dof_list[i];
2347 B(r) = array[r] * X(r);
2349 ierr = VecRestoreArrayRead(diag,&array); PCHKERRQ(diag,ierr);
2378 if (
cid == KSP_CLASSID)
2381 ierr = KSPSetTolerances(ksp,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2383 else if (
cid == SNES_CLASSID)
2385 SNES snes = (SNES)
obj;
2386 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT,
2389 else if (
cid == TS_CLASSID)
2392 ierr = TSSetTolerances(ts,PETSC_DECIDE,NULL,tol,NULL);
2396 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2403 if (
cid == KSP_CLASSID)
2406 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,tol,PETSC_DEFAULT,PETSC_DEFAULT);
2408 else if (
cid == SNES_CLASSID)
2410 SNES snes = (SNES)
obj;
2411 ierr = SNESSetTolerances(snes,tol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2414 else if (
cid == TS_CLASSID)
2417 ierr = TSSetTolerances(ts,tol,NULL,PETSC_DECIDE,NULL);
2421 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2428 if (
cid == KSP_CLASSID)
2431 ierr = KSPSetTolerances(ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2434 else if (
cid == SNES_CLASSID)
2436 SNES snes = (SNES)
obj;
2437 ierr = SNESSetTolerances(snes,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,
2438 max_iter,PETSC_DEFAULT);
2440 else if (
cid == TS_CLASSID)
2443 ierr = TSSetMaxSteps(ts,max_iter);
2447 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2455 typedef PetscErrorCode (*myPetscFunc)(
void**);
2456 PetscViewerAndFormat *vf = NULL;
2457 PetscViewer viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm(
obj));
2461 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
2464 if (
cid == KSP_CLASSID)
2472 ierr = KSPMonitorCancel(ksp); PCHKERRQ(ksp,ierr);
2476#if PETSC_VERSION_LT(3,15,0)
2477 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorDefault,vf,
2479 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorResidual,vf,
2481 (myPetscFunc)PetscViewerAndFormatDestroy);
2486 ierr = KSPSetComputeSingularValues(ksp,PETSC_TRUE); PCHKERRQ(ksp,ierr);
2487 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorSingularValue,vf,
2488 (myPetscFunc)PetscViewerAndFormatDestroy);
2492 ierr = PetscViewerAndFormatCreate(viewer,PETSC_VIEWER_DEFAULT,&vf);
2493 PCHKERRQ(viewer,ierr);
2494#if PETSC_VERSION_LT(3,15,0)
2495 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorTrueResidualNorm,vf,
2497 ierr = KSPMonitorSet(ksp,(myMonitor)KSPMonitorTrueResidual,vf,
2499 (myPetscFunc)PetscViewerAndFormatDestroy);
2504 else if (
cid == SNES_CLASSID)
2507 SNES snes = (SNES)
obj;
2510 ierr = SNESMonitorCancel(snes); PCHKERRQ(snes,ierr);
2514 ierr = SNESMonitorSet(snes,(myMonitor)SNESMonitorDefault,vf,
2515 (myPetscFunc)PetscViewerAndFormatDestroy);
2516 PCHKERRQ(snes,ierr);
2519 else if (
cid == TS_CLASSID)
2524 ierr = TSMonitorCancel(ts); PCHKERRQ(ts,ierr);
2529 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2535 return obj ? PetscObjectComm(
obj) : MPI_COMM_NULL;
2540 __mfem_monitor_ctx *monctx;
2541 ierr = PetscNew(&monctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2542 monctx->solver =
this;
2543 monctx->monitor =
ctx;
2544 if (
cid == KSP_CLASSID)
2546 ierr = KSPMonitorSet((KSP)
obj,__mfem_ksp_monitor,monctx,
2547 __mfem_monitor_ctx_destroy);
2550 else if (
cid == SNES_CLASSID)
2552 ierr = SNESMonitorSet((SNES)
obj,__mfem_snes_monitor,monctx,
2553 __mfem_monitor_ctx_destroy);
2556 else if (
cid == TS_CLASSID)
2558 ierr = TSMonitorSet((TS)
obj,__mfem_ts_monitor,monctx,
2559 __mfem_monitor_ctx_destroy);
2564 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2571 if (
cid == SNES_CLASSID)
2573 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
private_ctx;
2576 else if (
cid == TS_CLASSID)
2578 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
private_ctx;
2583 MFEM_ABORT(
"Handling of essential bc only implemented for nonlinear and time-dependent solvers");
2590 if (
cid == TS_CLASSID)
2595 ierr = TSGetSNES((TS)
obj,&snes); PCHKERRQ(
obj,ierr);
2596 ierr = SNESGetKSP(snes,&ksp); PCHKERRQ(
obj,ierr);
2597 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(
obj,ierr);
2599 else if (
cid == SNES_CLASSID)
2603 ierr = SNESGetKSP((SNES)
obj,&ksp); PCHKERRQ(
obj,ierr);
2604 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(
obj,ierr);
2606 else if (
cid == KSP_CLASSID)
2608 ierr = KSPGetPC((KSP)
obj,&pc); PCHKERRQ(
obj,ierr);
2610 else if (
cid == PC_CLASSID)
2616 MFEM_ABORT(
"No support for PetscPreconditionerFactory for this object");
2620 ierr = MakeShellPCWithFactory(pc,factory); PCHKERRQ(pc,ierr);
2624 ierr = PCSetType(pc, PCNONE); PCHKERRQ(pc,ierr);
2630 if (!customize) {
clcustom =
true; }
2633 if (
cid == PC_CLASSID)
2636 ierr = PCSetFromOptions(pc); PCHKERRQ(pc, ierr);
2638 else if (
cid == KSP_CLASSID)
2641 ierr = KSPSetFromOptions(ksp); PCHKERRQ(ksp, ierr);
2643 else if (
cid == SNES_CLASSID)
2645 SNES snes = (SNES)
obj;
2646 ierr = SNESSetFromOptions(snes); PCHKERRQ(snes, ierr);
2648 else if (
cid == TS_CLASSID)
2651 ierr = TSSetFromOptions(ts); PCHKERRQ(ts, ierr);
2655 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2663 if (
cid == KSP_CLASSID)
2666 KSPConvergedReason reason;
2667 ierr = KSPGetConvergedReason(ksp,&reason);
2669 return reason > 0 ? 1 : 0;
2671 else if (
cid == SNES_CLASSID)
2673 SNES snes = (SNES)
obj;
2674 SNESConvergedReason reason;
2675 ierr = SNESGetConvergedReason(snes,&reason);
2676 PCHKERRQ(snes,ierr);
2677 return reason > 0 ? 1 : 0;
2679 else if (
cid == TS_CLASSID)
2682 TSConvergedReason reason;
2683 ierr = TSGetConvergedReason(ts,&reason);
2685 return reason > 0 ? 1 : 0;
2689 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2696 if (
cid == KSP_CLASSID)
2700 ierr = KSPGetIterationNumber(ksp,&its);
2704 else if (
cid == SNES_CLASSID)
2706 SNES snes = (SNES)
obj;
2708 ierr = SNESGetIterationNumber(snes,&its);
2709 PCHKERRQ(snes,ierr);
2712 else if (
cid == TS_CLASSID)
2716 ierr = TSGetStepNumber(ts,&its);
2722 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2729 if (
cid == KSP_CLASSID)
2733 ierr = KSPGetResidualNorm(ksp,&norm);
2737 if (
cid == SNES_CLASSID)
2739 SNES snes = (SNES)
obj;
2741 ierr = SNESGetFunctionNorm(snes,&norm);
2742 PCHKERRQ(snes,ierr);
2747 MFEM_ABORT(
"CLASSID = " <<
cid <<
" is not implemented!");
2748 return PETSC_MAX_REAL;
2755 if (
cid == SNES_CLASSID)
2757 __mfem_snes_ctx *snes_ctx;
2758 ierr = PetscNew(&snes_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2759 snes_ctx->op = NULL;
2760 snes_ctx->bchandler = NULL;
2761 snes_ctx->work = NULL;
2765 else if (
cid == TS_CLASSID)
2767 __mfem_ts_ctx *ts_ctx;
2768 ierr = PetscNew(&ts_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2770 ts_ctx->bchandler = NULL;
2771 ts_ctx->work = NULL;
2772 ts_ctx->work2 = NULL;
2773 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
2774 ts_ctx->cached_ijacstate = -1;
2775 ts_ctx->cached_rhsjacstate = -1;
2776 ts_ctx->cached_splits_xstate = -1;
2777 ts_ctx->cached_splits_xdotstate = -1;
2788 if (
cid == SNES_CLASSID)
2790 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx *)
private_ctx;
2791 delete snes_ctx->work;
2793 else if (
cid == TS_CLASSID)
2795 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx *)
private_ctx;
2796 delete ts_ctx->work;
2797 delete ts_ctx->work2;
2799 ierr = PetscFree(
private_ctx); CCHKERRQ(PETSC_COMM_SELF,ierr);
2806 : bctype(type_), setup(false), eval_t(0.0),
2807 eval_t_cached(std::numeric_limits<
mfem::
real_t>::min())
2814 ess_tdof_list.
SetSize(list.Size());
2815 ess_tdof_list.
Assign(list);
2821 if (setup) {
return; }
2825 this->
Eval(eval_t,eval_g);
2826 eval_t_cached = eval_t;
2837 (*this).SetUp(x.
Size());
2841 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2843 y[ess_tdof_list[i]] = 0.0;
2848 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2850 Eval(eval_t,eval_g);
2851 eval_t_cached = eval_t;
2853 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2855 y[ess_tdof_list[i]] = eval_g[ess_tdof_list[i]];
2862 (*this).SetUp(x.
Size());
2865 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2867 x[ess_tdof_list[i]] = 0.0;
2872 if (bctype !=
CONSTANT && eval_t != eval_t_cached)
2874 Eval(eval_t,eval_g);
2875 eval_t_cached = eval_t;
2877 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2879 x[ess_tdof_list[i]] = eval_g[ess_tdof_list[i]];
2886 (*this).SetUp(x.
Size());
2889 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2891 y[ess_tdof_list[i]] = x[ess_tdof_list[i]];
2896 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2898 y[ess_tdof_list[i]] = x[ess_tdof_list[i]] - eval_g[ess_tdof_list[i]];
2905 (*this).SetUp(x.
Size());
2906 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2908 x[ess_tdof_list[i]] = 0.0;
2914 (*this).SetUp(x.
Size());
2916 for (
int i = 0; i < ess_tdof_list.
Size(); ++i)
2918 y[ess_tdof_list[i]] = 0.0;
2925 bool wrapin,
bool iter_mode)
2929 ierr = KSPCreate(comm,&ksp); CCHKERRQ(comm,ierr);
2931 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2932 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2933 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2934 PCHKERRQ(ksp, ierr);
2938 const std::string &prefix,
bool iter_mode)
2944 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
2945 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2946 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2947 PCHKERRQ(ksp, ierr);
2952 const std::string &prefix,
bool iter_mode)
2958 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
2959 ierr = KSPSetOptionsPrefix(ksp, prefix.c_str()); PCHKERRQ(ksp, ierr);
2960 ierr = KSPSetInitialGuessNonzero(ksp, (PetscBool)
iterative_mode);
2961 PCHKERRQ(ksp, ierr);
2973 bool delete_pA =
false;
2991 MFEM_VERIFY(pA,
"Unsupported operation!");
2999 PetscInt nheight,nwidth,oheight,owidth;
3001 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
3002 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
3003 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
3004 if (nheight != oheight || nwidth != owidth)
3008 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
3014 ierr = KSPSetOperators(ksp,A,A); PCHKERRQ(ksp,ierr);
3023 if (delete_pA) {
delete pA; }
3038 bool delete_pA =
false;
3056 MFEM_VERIFY(pA,
"Unsupported operation!");
3059 bool delete_ppA =
false;
3062 if (oA == poA && !wrap)
3072 MFEM_VERIFY(ppA,
"Unsupported operation!");
3081 PetscInt nheight,nwidth,oheight,owidth;
3083 ierr = KSPGetOperators(ksp,&C,NULL); PCHKERRQ(ksp,ierr);
3084 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
3085 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
3086 if (nheight != oheight || nwidth != owidth)
3090 ierr = KSPReset(ksp); PCHKERRQ(ksp,ierr);
3097 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
3106 if (delete_pA) {
delete pA; }
3107 if (delete_ppA) {
delete ppA; }
3117 ierr = KSPGetOperatorsSet(ksp,&amat,NULL); PCHKERRQ(ksp,ierr);
3120 ierr = KSPGetOperators(ksp,&A,NULL); PCHKERRQ(ksp,ierr);
3121 ierr = PetscObjectReference((
PetscObject)A); PCHKERRQ(ksp,ierr);
3126 ierr = KSPSetPC(ksp,*ppc); PCHKERRQ(ksp,ierr);
3135 ierr = KSPGetPC(ksp,&pc); PCHKERRQ(ksp,ierr);
3136 ierr = MakeShellPC(pc,precond,
false); PCHKERRQ(ksp,ierr);
3142 ierr = KSPGetOperators(ksp,NULL,&P); PCHKERRQ(ksp,ierr);
3143 ierr = PetscObjectReference((
PetscObject)P); PCHKERRQ(ksp,ierr);
3144 ierr = KSPSetOperators(ksp,A,P); PCHKERRQ(ksp,ierr);
3145 ierr = MatDestroy(&A); PCHKERRQ(ksp,ierr);
3146 ierr = MatDestroy(&P); PCHKERRQ(ksp,ierr);
3157 ierr = KSPGetOperators(ksp, &pA, NULL); PCHKERRQ(
obj, ierr);
3165 PetscParMatrix A = PetscParMatrix(pA,
true);
3166 X =
new PetscParVector(A,
false,
false);
3174 ierr = KSPGetInitialGuessNonzero(ksp, &flg);
3180 ierr = KSPSolveTranspose(ksp,
B->
x,
X->
x); PCHKERRQ(ksp,ierr);
3184 ierr = KSPSolve(ksp,
B->
x,
X->
x); PCHKERRQ(ksp,ierr);
3192 (*this).MultKernel(
b,x,
false);
3197 (*this).MultKernel(
b,x,
true);
3204 ierr = PetscObjectGetComm((
PetscObject)ksp,&comm); PCHKERRQ(ksp,ierr);
3205 ierr = KSPDestroy(&ksp); CCHKERRQ(comm,ierr);
3215 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3217 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3225 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3227 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3231 const std::string &prefix,
bool iter_mode)
3235 ierr = KSPSetType(ksp,KSPCG); PCHKERRQ(ksp,ierr);
3237 ierr = KSPSetNormType(ksp,KSP_NORM_NATURAL); PCHKERRQ(ksp,ierr);
3243 const std::string &prefix)
3247 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
3249 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3250 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3254 const string &prefix)
3260 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3261 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3266 const string &prefix)
3270 ierr = PCCreate(comm,&pc); CCHKERRQ(comm,ierr);
3272 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
3273 ierr = PCSetOptionsPrefix(pc, prefix.c_str()); PCHKERRQ(pc, ierr);
3279 bool delete_pA =
false;
3296 PetscInt nheight,nwidth,oheight,owidth;
3298 ierr = PCGetOperators(pc,&C,NULL); PCHKERRQ(pc,ierr);
3299 ierr = MatGetSize(A,&nheight,&nwidth); PCHKERRQ(A,ierr);
3300 ierr = MatGetSize(C,&oheight,&owidth); PCHKERRQ(A,ierr);
3301 if (nheight != oheight || nwidth != owidth)
3305 ierr = PCReset(pc); PCHKERRQ(pc,ierr);
3311 ierr = PCSetOperators(pc,pA->
A,pA->
A); PCHKERRQ(
obj,ierr);
3320 if (delete_pA) {
delete pA; };
3323void PetscPreconditioner::MultKernel(
const Vector &
b,
Vector &x,
3327 "Iterative mode not supported for PetscPreconditioner");
3333 ierr = PCGetOperators(pc, NULL, &pA); PCHKERRQ(
obj, ierr);
3341 PetscParMatrix A(pA,
true);
3342 X =
new PetscParVector(A,
false,
false);
3353 ierr = PCApplyTranspose(pc,
B->
x,
X->
x); PCHKERRQ(pc, ierr);
3357 ierr = PCApply(pc,
B->
x,
X->
x); PCHKERRQ(pc, ierr);
3365 (*this).MultKernel(
b,x,
false);
3370 (*this).MultKernel(
b,x,
true);
3377 ierr = PetscObjectGetComm((
PetscObject)pc,&comm); PCHKERRQ(pc,ierr);
3378 ierr = PCDestroy(&pc); CCHKERRQ(comm,ierr);
3389void PetscBDDCSolver::BDDCSolverConstructor(
const PetscBDDCSolverParams &opts)
3391 MPI_Comm comm = PetscObjectComm(
obj);
3396 ierr = PCGetOperators(pc,NULL,&pA); PCHKERRQ(pc,ierr);
3400 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATIS,&ismatis);
3402 MFEM_VERIFY(ismatis,
"PetscBDDCSolver needs the matrix in unassembled format");
3405 ParFiniteElementSpace *fespace = opts.fespace;
3406 if (opts.netflux && !fespace)
3408 MFEM_WARNING(
"Don't know how to compute an auxiliary quadrature form without a ParFiniteElementSpace");
3415 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(comm,ierr);
3416 ierr = MatNullSpaceCreate(PetscObjectComm((
PetscObject)lA),PETSC_TRUE,0,NULL,
3417 &nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3418 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3419 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3423 ierr = PCSetType(pc,PCBDDC); PCHKERRQ(
obj,ierr);
3426 ierr = MatGetOwnershipRange(pA,&rst,NULL); PCHKERRQ(pA,ierr);
3427 ierr = MatGetLocalSize(pA,&nl,NULL); PCHKERRQ(pA,ierr);
3436 int vdim = fespace->GetVDim();
3443 ierr = MatSetBlockSize(pA,vdim); PCHKERRQ(pA,ierr);
3444 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(PETSC_COMM_SELF,ierr);
3445 ierr = MatSetBlockSize(lA,vdim); PCHKERRQ(pA,ierr);
3454 ierr = PetscMalloc1(nf,&fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
3467 ierr = ISCreateStride(comm,nlf,st,bs,&fields[i]); CCHKERRQ(comm,ierr);
3473 const FiniteElementCollection *fec = fespace->FEColl();
3474 bool h1space =
dynamic_cast<const H1_FECollection*
>(fec);
3477 ParFiniteElementSpace *fespace_coords = fespace;
3479 sdim = fespace->GetParMesh()->SpaceDimension();
3482 fespace_coords =
new ParFiniteElementSpace(fespace->GetParMesh(),fec,sdim,
3485 VectorFunctionCoefficient coeff_coords(sdim, func_coords);
3486 ParGridFunction gf_coords(fespace_coords);
3487 gf_coords.ProjectCoefficient(coeff_coords);
3488 HypreParVector *hvec_coords = gf_coords.ParallelProject();
3490 hvec_coords->Size(),
false);
3498 Vec pvec_coords,lvec_coords;
3499 ISLocalToGlobalMapping l2g;
3505 ierr = VecCreateMPIWithArray(comm,sdim,hvec_coords->Size(),
3506 hvec_coords->GlobalSize(),data_coords,&pvec_coords);
3507 CCHKERRQ(comm,ierr);
3508 ierr = MatGetNearNullSpace(pA,&nnsp); CCHKERRQ(comm,ierr);
3511 ierr = MatNullSpaceCreateRigidBody(pvec_coords,&nnsp);
3512 CCHKERRQ(comm,ierr);
3513 ierr = MatSetNearNullSpace(pA,nnsp); CCHKERRQ(comm,ierr);
3514 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(comm,ierr);
3516 ierr = MatISGetLocalMat(pA,&lA); CCHKERRQ(comm,ierr);
3517 ierr = MatCreateVecs(lA,&lvec_coords,NULL); CCHKERRQ(PETSC_COMM_SELF,ierr);
3518 ierr = VecSetBlockSize(lvec_coords,sdim); CCHKERRQ(PETSC_COMM_SELF,ierr);
3519 ierr = MatGetLocalToGlobalMapping(pA,&l2g,NULL); CCHKERRQ(comm,ierr);
3520 ierr = MatGetLayouts(pA,&rmap,NULL); CCHKERRQ(comm,ierr);
3521 ierr = PetscSFCreate(comm,&sf); CCHKERRQ(comm,ierr);
3522 ierr = ISLocalToGlobalMappingGetIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
3523 ierr = ISLocalToGlobalMappingGetSize(l2g,&nleaves); CCHKERRQ(comm,ierr);
3524 ierr = PetscSFSetGraphLayout(sf,rmap,nleaves,NULL,PETSC_OWN_POINTER,gidxs);
3525 CCHKERRQ(comm,ierr);
3526 ierr = ISLocalToGlobalMappingRestoreIndices(l2g,&gidxs); CCHKERRQ(comm,ierr);
3531 ierr = VecGetArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3532 ierr = VecGetArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3533#if PETSC_VERSION_LT(3,15,0)
3534 ierr = PetscSFBcastBegin(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
3535 ierr = PetscSFBcastEnd(sf,MPIU_SCALAR,garray,larray); CCHKERRQ(comm,ierr);
3537 ierr = PetscSFBcastBegin(sf,MPIU_SCALAR,garray,larray,MPI_REPLACE);
3538 CCHKERRQ(comm,ierr);
3539 ierr = PetscSFBcastEnd(sf,MPIU_SCALAR,garray,larray,MPI_REPLACE);
3540 CCHKERRQ(comm,ierr);
3542 ierr = VecRestoreArrayRead(pvec_coords,&garray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3543 ierr = VecRestoreArray(lvec_coords,&larray); CCHKERRQ(PETSC_COMM_SELF,ierr);
3545 ierr = VecDestroy(&pvec_coords); CCHKERRQ(comm,ierr);
3546 ierr = MatNullSpaceCreateRigidBody(lvec_coords,&nnsp);
3547 CCHKERRQ(PETSC_COMM_SELF,ierr);
3548 ierr = VecDestroy(&lvec_coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3549 ierr = MatSetNearNullSpace(lA,nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3550 ierr = MatNullSpaceDestroy(&nnsp); CCHKERRQ(PETSC_COMM_SELF,ierr);
3551 ierr = PetscSFDestroy(&sf); CCHKERRQ(PETSC_COMM_SELF,ierr);
3555 ierr = PetscMalloc1(nl*sdim,&coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3564 ierr = ISGetLocalSize(fields[i],&nn); CCHKERRQ(comm,ierr);
3565 ierr = ISGetIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
3569 for (
PetscInt d = 0; d < sdim; d++)
3571 coords[sdim*idx+d] = PetscRealPart(data_coords[sdim*j+d]);
3574 ierr = ISRestoreIndices(fields[i],&idxs); CCHKERRQ(comm,ierr);
3579 for (
PetscInt j = 0; j < nl*sdim; j++) { coords[j] = PetscRealPart(data_coords[j]); }
3581 if (fespace_coords != fespace)
3583 delete fespace_coords;
3590 IS dir = NULL, neu = NULL;
3593 Array<Mat> *l2l = NULL;
3594 if (opts.ess_dof_local || opts.nat_dof_local)
3599 MFEM_VERIFY(c,
"Local-to-local PETSc container not present");
3600 ierr = PetscContainerGetPointer(c,(
void**)&l2l); PCHKERRQ(c,ierr);
3607 PetscBool lpr = PETSC_FALSE,pr;
3608 if (opts.ess_dof) { lpr = PETSC_TRUE; }
3609 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
3610 CCHKERRQ(comm,mpiierr);
3611 MFEM_VERIFY(lpr == pr,
"ess_dof should be collectively set");
3613 if (opts.nat_dof) { lpr = PETSC_TRUE; }
3614 mpiierr = MPI_Allreduce(&lpr,&pr,1,MPIU_BOOL,MPI_LOR,comm);
3615 CCHKERRQ(comm,mpiierr);
3616 MFEM_VERIFY(lpr == pr,
"nat_dof should be collectively set");
3619 ms[0] = -nf; ms[1] = nf;
3620 mpiierr = MPI_Allreduce(&ms,&Ms,2,MPIU_INT,MPI_MAX,comm);
3621 CCHKERRQ(comm,mpiierr);
3622 MFEM_VERIFY(-Ms[0] == Ms[1],
3623 "number of fields should be the same across processes");
3630 PetscInt st = opts.ess_dof_local ? 0 : rst;
3631 if (!opts.ess_dof_local)
3634 ierr = Convert_Array_IS(comm,
true,opts.ess_dof,st,&dir);
3635 CCHKERRQ(comm,ierr);
3636 ierr = PCBDDCSetDirichletBoundaries(pc,dir); PCHKERRQ(pc,ierr);
3641 ierr = Convert_Vmarks_IS(comm,*l2l,opts.ess_dof,st,&dir);
3642 CCHKERRQ(comm,ierr);
3643 ierr = PCBDDCSetDirichletBoundariesLocal(pc,dir); PCHKERRQ(pc,ierr);
3648 PetscInt st = opts.nat_dof_local ? 0 : rst;
3649 if (!opts.nat_dof_local)
3652 ierr = Convert_Array_IS(comm,
true,opts.nat_dof,st,&neu);
3653 CCHKERRQ(comm,ierr);
3654 ierr = PCBDDCSetNeumannBoundaries(pc,neu); PCHKERRQ(pc,ierr);
3659 ierr = Convert_Vmarks_IS(comm,*l2l,opts.nat_dof,st,&neu);
3660 CCHKERRQ(comm,ierr);
3661 ierr = PCBDDCSetNeumannBoundariesLocal(pc,neu); PCHKERRQ(pc,ierr);
3668 ierr = PCBDDCSetDofsSplitting(pc,nf,fields); PCHKERRQ(pc,ierr);
3672 ierr = ISDestroy(&fields[i]); CCHKERRQ(comm,ierr);
3674 ierr = PetscFree(fields); CCHKERRQ(PETSC_COMM_SELF,ierr);
3679 ierr = PCSetCoordinates(pc,sdim,nl,coords); PCHKERRQ(pc,ierr);
3681 ierr = PetscFree(coords); CCHKERRQ(PETSC_COMM_SELF,ierr);
3690 const FiniteElementCollection *fec = fespace->FEColl();
3691 bool edgespace, rtspace, h1space;
3692 bool needint = opts.netflux;
3693 bool tracespace, rt_tracespace, edge_tracespace;
3695 PetscBool B_is_Trans = PETSC_FALSE;
3697 ParMesh *pmesh = (ParMesh *) fespace->GetMesh();
3698 dim = pmesh->Dimension();
3699 vdim = fespace->GetVDim();
3700 h1space =
dynamic_cast<const H1_FECollection*
>(fec);
3701 rtspace =
dynamic_cast<const RT_FECollection*
>(fec);
3702 edgespace =
dynamic_cast<const ND_FECollection*
>(fec);
3703 edge_tracespace =
dynamic_cast<const ND_Trace_FECollection*
>(fec);
3704 rt_tracespace =
dynamic_cast<const RT_Trace_FECollection*
>(fec);
3705 tracespace = edge_tracespace || rt_tracespace;
3708 if (fespace->GetNE() > 0)
3712 p = fespace->GetElementOrder(0);
3716 p = fespace->GetFaceOrder(0);
3717 if (
dim == 2) {
p++; }
3728 MFEM_WARNING(
"Tracespace case doesn't work for H(curl) and p=2,"
3729 " not using auxiliary quadrature");
3735 FiniteElementCollection *vfec;
3738 vfec =
new H1_Trace_FECollection(
p,
dim);
3742 vfec =
new H1_FECollection(
p,
dim);
3744 ParFiniteElementSpace *vfespace =
new ParFiniteElementSpace(pmesh,vfec);
3745 ParDiscreteLinearOperator *grad;
3746 grad =
new ParDiscreteLinearOperator(vfespace,fespace);
3749 grad->AddTraceFaceInterpolator(
new GradientInterpolator);
3753 grad->AddDomainInterpolator(
new GradientInterpolator);
3757 HypreParMatrix *hG = grad->ParallelAssemble();
3758 PetscParMatrix *G =
new PetscParMatrix(hG,
PETSC_MATAIJ);
3762 PetscBool conforming = PETSC_TRUE;
3763 if (pmesh->Nonconforming()) { conforming = PETSC_FALSE; }
3764 ierr = PCBDDCSetDiscreteGradient(pc,*G,
p,0,PETSC_TRUE,conforming);
3776 MFEM_WARNING(
"Tracespace case doesn't work for H(div), not using"
3777 " auxiliary quadrature");
3783 if (vdim !=
dim) { needint =
false; }
3786 PetscParMatrix *
B = NULL;
3792 FiniteElementCollection *auxcoll;
3793 if (tracespace) { auxcoll =
new RT_Trace_FECollection(
p,
dim); }
3798 auxcoll =
new H1_FECollection(std::max(
p-1,1),
dim);
3802 auxcoll =
new L2_FECollection(
p,
dim);
3805 ParFiniteElementSpace *pspace =
new ParFiniteElementSpace(pmesh,auxcoll);
3806 ParMixedBilinearForm *
b =
new ParMixedBilinearForm(fespace,pspace);
3812 b->AddTraceFaceIntegrator(
new VectorFECurlIntegrator);
3816 b->AddDomainIntegrator(
new VectorFECurlIntegrator);
3823 b->AddTraceFaceIntegrator(
new VectorFEDivergenceIntegrator);
3827 b->AddDomainIntegrator(
new VectorFEDivergenceIntegrator);
3832 b->AddDomainIntegrator(
new VectorDivergenceIntegrator);
3837 b->ParallelAssemble(Bh);
3839 Bh.SetOperatorOwner(
false);
3844 ierr = MatTranspose(pB,MAT_INPLACE_MATRIX,&pB); PCHKERRQ(pA,ierr);
3845 if (!opts.ess_dof_local)
3847 ierr = MatZeroRowsIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3851 ierr = MatZeroRowsLocalIS(pB,dir,0.,NULL,NULL); PCHKERRQ(pA,ierr);
3853 B_is_Trans = PETSC_TRUE;
3862 ierr = PCBDDCSetDivergenceMat(pc,*
B,B_is_Trans,NULL); PCHKERRQ(pc,ierr);
3866 ierr = ISDestroy(&dir); PCHKERRQ(pc,ierr);
3867 ierr = ISDestroy(&neu); PCHKERRQ(pc,ierr);
3872 const std::string &prefix)
3875 BDDCSolverConstructor(opts);
3881 const std::string &prefix)
3884 BDDCSolverConstructor(opts);
3889 const string &prefix)
3893 ierr = PCSetType(pc,PCFIELDSPLIT); PCHKERRQ(pc,ierr);
3896 ierr = PCGetOperators(pc,&pA,NULL); PCHKERRQ(pc,ierr);
3900 ierr = PetscObjectTypeCompare((
PetscObject)pA,MATNEST,&isnest);
3906 ierr = MatNestGetSize(pA,&nr,NULL); PCHKERRQ(pc,ierr);
3907 ierr = PetscCalloc1(nr,&isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3908 ierr = MatNestGetISs(pA,isrow,NULL); PCHKERRQ(pc,ierr);
3918 ierr = PCFieldSplitSetIS(pc,NULL,isrow[i]); PCHKERRQ(pc,ierr);
3920 ierr = PetscFree(isrow); CCHKERRQ(PETSC_COMM_SELF,ierr);
3925 const std::string &prefix)
3929 ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE); PCHKERRQ(A,ierr);
3930 ierr = MatSetOption(A,MAT_SYMMETRY_ETERNAL,PETSC_TRUE); PCHKERRQ(A,ierr);
3932 H2SolverConstructor(fes);
3938#if defined(PETSC_HAVE_H2OPUS)
3950 VectorFunctionCoefficient ccoords(sdim, func_coords);
3952 ParGridFunction coords(fes);
3953 coords.ProjectCoefficient(ccoords);
3955 coords.ParallelProject(c);
3959 ierr = PCSetType(pc,PCH2OPUS); PCHKERRQ(
obj, ierr);
3960 ierr = PCSetCoordinates(pc,sdim,c.Size()/sdim,
3963 ierr = PCSetFromOptions(pc); PCHKERRQ(
obj, ierr);
3965 MFEM_ABORT(
"Need PETSc configured with --download-h2opus");
3972 const std::string &prefix)
3977 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3979 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3980 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
3987 const std::string &prefix)
3992 ierr = SNESCreate(comm, &snes); CCHKERRQ(comm, ierr);
3994 ierr = PetscObjectGetClassId(
obj, &
cid); PCHKERRQ(
obj, ierr);
3995 ierr = SNESSetOptionsPrefix(snes, prefix.c_str()); PCHKERRQ(snes, ierr);
4007 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj, ierr);
4008 ierr = SNESDestroy(&snes); CCHKERRQ(comm, ierr);
4020 ierr = SNESGetFunction(snes, NULL, NULL, &fctx);
4021 PCHKERRQ(snes, ierr);
4022 ierr = SNESGetJacobian(snes, NULL, NULL, NULL, &jctx);
4023 PCHKERRQ(snes, ierr);
4026 (
void*)&op == fctx &&
4027 (
void*)&op == jctx);
4028 mpiierr = MPI_Allreduce(&ls,&gs,1,MPIU_BOOL,MPI_LAND,
4030 CCHKERRQ(PetscObjectComm((
PetscObject)snes),mpiierr);
4033 ierr = SNESReset(snes); PCHKERRQ(snes,ierr);
4044 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
4045 ierr = SNESLineSearchSetType(ls, SNESLINESEARCHBT); PCHKERRQ(snes,ierr);
4054 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4056 ierr = SNESSetFunction(snes, NULL, __mfem_snes_function, (
void *)snes_ctx);
4057 PCHKERRQ(snes, ierr);
4058 ierr = SNESSetJacobian(snes, dummy, dummy, __mfem_snes_jacobian,
4060 PCHKERRQ(snes, ierr);
4062 ierr = MatDestroy(&dummy);
4063 PCHKERRQ(snes, ierr);
4075 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4076 snes_ctx->jacType = jacType;
4082 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4083 snes_ctx->objective = objfn;
4086 ierr = SNESSetObjective(snes, __mfem_snes_objective, (
void *)snes_ctx);
4087 PCHKERRQ(snes, ierr);
4094 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4095 snes_ctx->postcheck = post;
4099 ierr = SNESGetLineSearch(snes, &ls); PCHKERRQ(snes,ierr);
4100 ierr = SNESLineSearchSetPostCheck(ls, __mfem_snes_postcheck, (
void *)snes_ctx);
4110 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
private_ctx;
4111 snes_ctx->update = update;
4114 ierr = SNESSetUpdate(snes, __mfem_snes_update); PCHKERRQ(snes, ierr);
4121 bool b_nonempty =
b.Size();
4133 ierr = SNESSolve(snes,
B->
x,
X->
x); PCHKERRQ(snes, ierr);
4145 ierr = TSCreate(comm,&ts); CCHKERRQ(comm,ierr);
4147 ierr = PetscObjectGetClassId(
obj,&
cid); PCHKERRQ(
obj,ierr);
4148 ierr = TSSetOptionsPrefix(ts, prefix.c_str()); PCHKERRQ(ts, ierr);
4154 ierr = TSSetMaxSteps(ts,PETSC_MAX_INT-1);
4156 ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
4159 ierr = TSGetAdapt(ts,&tsad);
4161 ierr = TSAdaptSetType(tsad,TSADAPTNONE);
4169 ierr = PetscObjectGetComm(
obj,&comm); PCHKERRQ(
obj,ierr);
4170 ierr = TSDestroy(&ts); CCHKERRQ(comm,ierr);
4178 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4181 ierr = TSReset(ts); PCHKERRQ(ts,ierr);
4184 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
4185 ts_ctx->cached_ijacstate = -1;
4186 ts_ctx->cached_rhsjacstate = -1;
4187 ts_ctx->cached_splits_xstate = -1;
4188 ts_ctx->cached_splits_xdotstate = -1;
4200 ierr = TSSetIFunction(ts, NULL, __mfem_ts_ifunction, (
void *)ts_ctx);
4202 ierr = TSSetIJacobian(ts, dummy, dummy, __mfem_ts_ijacobian, (
void *)ts_ctx);
4204 ierr = TSSetEquationType(ts, TS_EQ_IMPLICIT);
4206 ierr = MatDestroy(&dummy);
4214 ierr = TSSetEquationType(ts, TS_EQ_EXPLICIT);
4223 ierr = TSSetRHSFunction(ts, NULL, __mfem_ts_rhsfunction, (
void *)ts_ctx);
4225 ierr = TSSetRHSJacobian(ts, dummy, dummy, __mfem_ts_rhsjacobian,
4228 ierr = MatDestroy(&dummy);
4237 ierr = TSSetSolution(ts,
X); PCHKERRQ(ts,ierr);
4240 PetscBool use = PETSC_TRUE;
4241 ierr = PetscOptionsGetBool(NULL,NULL,
"-mfem_use_splitjac",&use,NULL);
4244 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
4245 __mfem_ts_computesplits);
4250 ierr = PetscObjectComposeFunction((
PetscObject)ts,
"TSComputeSplitJacobians_C",
4258 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4259 ts_ctx->jacType = jacType;
4264 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4265 return ts_ctx->type;
4270 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4273 ts_ctx->type = type;
4276 ierr = TSSetProblemType(ts, TS_LINEAR);
4281 ierr = TSSetProblemType(ts, TS_NONLINEAR);
4290 ierr = TSSetTime(ts,
t); PCHKERRQ(ts, ierr);
4291 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
4294 ierr = TSGetStepNumber(ts, &i); PCHKERRQ(ts,ierr);
4304 ierr = TSMonitor(ts, i,
t, *
X); PCHKERRQ(ts,ierr);
4308 ierr = TSSetSolution(ts, *
X); PCHKERRQ(ts, ierr);
4309 ierr = TSStep(ts); PCHKERRQ(ts, ierr);
4314 ierr = TSGetTime(ts, &pt); PCHKERRQ(ts,ierr);
4319 ierr = TSMonitor(ts, i+1, pt, *
X); PCHKERRQ(ts,ierr);
4329 ierr = TSSetTime(ts,
t); PCHKERRQ(ts, ierr);
4330 ierr = TSSetTimeStep(ts, dt); PCHKERRQ(ts, ierr);
4331 ierr = TSSetMaxTime(ts, t_final); PCHKERRQ(ts, ierr);
4332 ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP);
4344 __mfem_ts_ctx *ts_ctx = (__mfem_ts_ctx*)
private_ctx;
4345 ts_ctx->cached_shift = std::numeric_limits<PetscReal>::min();
4346 ts_ctx->cached_ijacstate = -1;
4347 ts_ctx->cached_rhsjacstate = -1;
4348 ts_ctx->cached_splits_xstate = -1;
4349 ts_ctx->cached_splits_xdotstate = -1;
4352 ierr = TSSolve(ts,
X->
x); PCHKERRQ(ts, ierr);
4357 ierr = TSGetTime(ts, &pt); PCHKERRQ(ts,ierr);
4359 ierr = TSGetTimeStep(ts,&pt); PCHKERRQ(ts,ierr);
4365#include "petsc/private/petscimpl.h"
4366#include "petsc/private/matimpl.h"
4372 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
4374 PetscFunctionBeginUser;
4377 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4389 PetscFunctionReturn(PETSC_SUCCESS);
4392static PetscErrorCode __mfem_ts_ifunction(TS ts,
PetscReal t, Vec x, Vec xp,
4395 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4397 PetscFunctionBeginUser;
4405 if (ts_ctx->bchandler)
4410 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(xx.Size()); }
4411 if (!ts_ctx->work2) { ts_ctx->work2 =
new mfem::Vector(xx.Size()); }
4417 bchandler->
ZeroBC(yy,*txp);
4427 ff.UpdateVecFromFlags();
4428 PetscFunctionReturn(PETSC_SUCCESS);
4431static PetscErrorCode __mfem_ts_rhsfunction(TS ts,
PetscReal t, Vec x, Vec
f,
4434 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4436 PetscFunctionBeginUser;
4437 if (ts_ctx->bchandler) { MFEM_ABORT(
"RHS evaluation with bc not implemented"); }
4446 ff.UpdateVecFromFlags();
4447 PetscFunctionReturn(PETSC_SUCCESS);
4450static PetscErrorCode __mfem_ts_ijacobian(TS ts,
PetscReal t, Vec x,
4454 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4459 PetscObjectState state;
4460 PetscErrorCode ierr;
4462 PetscFunctionBeginUser;
4466 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4467 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4473 ierr = PetscObjectStateGet((
PetscObject)P,&state); CHKERRQ(ierr);
4475 std::abs(ts_ctx->cached_shift/shift - 1.0) < eps &&
4476 state == ts_ctx->cached_ijacstate) { PetscFunctionReturn(PETSC_SUCCESS); }
4483 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4484 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4486 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4487 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4488 if (!ts_ctx->bchandler)
4495 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4502 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4506 if (!ts_ctx->bchandler) {
delete xx; }
4507 ts_ctx->cached_shift = shift;
4510 bool delete_pA =
false;
4514 pA->
GetType() != ts_ctx->jacType))
4522 if (ts_ctx->bchandler)
4530 PetscObjectState nonzerostate;
4531 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4536 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4537 if (delete_pA) {
delete pA; }
4549 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4551 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4554 ierr = PetscObjectStateGet((
PetscObject)P,&ts_ctx->cached_ijacstate);
4560 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4561 ierr = TSGetDM(ts,&dm); CHKERRQ(ierr);
4562 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4563 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4564 PetscFunctionReturn(PETSC_SUCCESS);
4567static PetscErrorCode __mfem_ts_computesplits(TS ts,
PetscReal t,Vec x,Vec xp,
4571 __mfem_ts_ctx* ts_ctx;
4575 PetscObjectState state;
4576 PetscBool rx = PETSC_TRUE, rxp = PETSC_TRUE;
4577 PetscBool assembled;
4578 PetscErrorCode ierr;
4580 PetscFunctionBeginUser;
4584 ierr = MatAssemblyBegin(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4585 ierr = MatAssemblyEnd(Ax,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4587 if (Axp && Axp != Jxp)
4589 ierr = MatAssemblyBegin(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4590 ierr = MatAssemblyEnd(Axp,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4593 ierr = TSGetIJacobian(ts,NULL,NULL,NULL,(
void**)&ts_ctx); CHKERRQ(ierr);
4596 ierr = PetscObjectStateGet((
PetscObject)Jx,&state); CHKERRQ(ierr);
4598 state == ts_ctx->cached_splits_xstate) { rx = PETSC_FALSE; }
4599 ierr = PetscObjectStateGet((
PetscObject)Jxp,&state); CHKERRQ(ierr);
4601 state == ts_ctx->cached_splits_xdotstate) { rxp = PETSC_FALSE; }
4602 if (!rx && !rxp) { PetscFunctionReturn(PETSC_SUCCESS); }
4609 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4610 ierr = VecGetArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4612 ierr = VecRestoreArrayRead(xp,(
const PetscScalar**)&array); CHKERRQ(ierr);
4613 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4614 if (!ts_ctx->bchandler)
4621 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4628 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4637 bool delete_mat =
false;
4641 pJx->
GetType() != ts_ctx->jacType))
4646 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
4654 ierr = MatAssembled(Jx,&assembled); CHKERRQ(ierr);
4657 ierr = MatCopy(*pJx,Jx,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
4662 ierr = MatDuplicate(*pJx,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
4663 ierr = MatHeaderReplace(Jx,&B); CHKERRQ(ierr);
4666 if (delete_mat) {
delete pJx; }
4670 if (ts_ctx->bchandler)
4687 pJxp->
GetType() != ts_ctx->jacType))
4692 ierr = PetscObjectReference((
PetscObject)B); CHKERRQ(ierr);
4695 &oJxp,ts_ctx->jacType);
4699 ierr = MatAssembled(Jxp,&assembled); CHKERRQ(ierr);
4702 ierr = MatCopy(*pJxp,Jxp,SAME_NONZERO_PATTERN); CHKERRQ(ierr);
4707 ierr = MatDuplicate(*pJxp,MAT_COPY_VALUES,&B); CHKERRQ(ierr);
4708 ierr = MatHeaderReplace(Jxp,&B); CHKERRQ(ierr);
4710 if (delete_mat) {
delete pJxp; }
4714 if (ts_ctx->bchandler)
4725 ierr = MatAXPY(*pJxp,-1.0,*pJx,SAME_NONZERO_PATTERN); PCHKERRQ(ts,ierr);
4729 ierr = PetscObjectStateGet((
PetscObject)Jx,&ts_ctx->cached_splits_xstate);
4731 ierr = PetscObjectStateGet((
PetscObject)Jxp,&ts_ctx->cached_splits_xdotstate);
4736 if (!ts_ctx->bchandler) {
delete xx; }
4737 PetscFunctionReturn(PETSC_SUCCESS);
4740static PetscErrorCode __mfem_ts_rhsjacobian(TS ts,
PetscReal t, Vec x,
4741 Mat A, Mat P,
void *
ctx)
4743 __mfem_ts_ctx* ts_ctx = (__mfem_ts_ctx*)
ctx;
4747 PetscObjectState state;
4748 PetscErrorCode ierr;
4750 PetscFunctionBeginUser;
4754 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4755 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4759 ierr = PetscObjectStateGet((
PetscObject)P,&state); CHKERRQ(ierr);
4761 state == ts_ctx->cached_rhsjacstate) { PetscFunctionReturn(PETSC_SUCCESS); }
4768 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4769 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4770 if (!ts_ctx->bchandler)
4777 if (!ts_ctx->work) { ts_ctx->work =
new mfem::Vector(n); }
4784 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4788 if (!ts_ctx->bchandler) {
delete xx; }
4791 bool delete_pA =
false;
4795 pA->
GetType() != ts_ctx->jacType))
4803 if (ts_ctx->bchandler)
4811 PetscObjectState nonzerostate;
4812 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4817 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4818 if (delete_pA) {
delete pA; }
4830 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4832 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4837 ierr = TSRHSJacobianSetReuse(ts,PETSC_TRUE); PCHKERRQ(ts,ierr);
4839 ierr = PetscObjectStateGet((
PetscObject)P,&ts_ctx->cached_rhsjacstate);
4845 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4846 ierr = TSGetDM(ts,&dm); CHKERRQ(ierr);
4847 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4848 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4849 PetscFunctionReturn(PETSC_SUCCESS);
4855 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
4857 PetscFunctionBeginUser;
4860 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
4869 PetscErrorCode ierr;
4871 ierr = SNESGetSolution(snes,&x); CHKERRQ(ierr);
4878 PetscErrorCode ierr;
4880 ierr = SNESGetFunction(snes,&x,NULL,NULL); CHKERRQ(ierr);
4885 PetscFunctionReturn(PETSC_SUCCESS);
4888static PetscErrorCode __mfem_snes_jacobian(SNES snes, Vec x, Mat A, Mat P,
4893 PetscErrorCode ierr;
4895 __mfem_snes_ctx *snes_ctx = (__mfem_snes_ctx*)
ctx;
4897 PetscFunctionBeginUser;
4898 ierr = VecGetArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4899 ierr = VecGetLocalSize(x,&n); CHKERRQ(ierr);
4900 if (!snes_ctx->bchandler)
4907 if (!snes_ctx->work) { snes_ctx->work =
new mfem::Vector(n); }
4910 xx = snes_ctx->work;
4916 ierr = VecRestoreArrayRead(x,(
const PetscScalar**)&array); CHKERRQ(ierr);
4917 if (!snes_ctx->bchandler) {
delete xx; }
4920 bool delete_pA =
false;
4924 pA->
GetType() != snes_ctx->jacType))
4932 if (snes_ctx->bchandler)
4940 PetscObjectState nonzerostate;
4941 ierr = MatGetNonzeroState(P,&nonzerostate); CHKERRQ(ierr);
4945 ierr = MatHeaderReplace(P,&B); CHKERRQ(ierr);
4946 if (delete_pA) {
delete pA; }
4958 ierr = PetscObjectTypeCompare((
PetscObject)P,MATNEST,&isnest);
4960 if (isnest) { P->nonzerostate = nonzerostate + 1; }
4965 ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4966 ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
4972 ierr = MatGetType(P,&mtype); CHKERRQ(ierr);
4973 ierr = SNESGetDM(snes,&dm); CHKERRQ(ierr);
4974 ierr = DMSetMatType(dm,mtype); CHKERRQ(ierr);
4975 ierr = DMShellSetMatrix(dm,P); CHKERRQ(ierr);
4976 PetscFunctionReturn(PETSC_SUCCESS);
4979static PetscErrorCode __mfem_snes_function(SNES snes, Vec x, Vec
f,
void *
ctx)
4981 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
4983 PetscFunctionBeginUser;
4986 if (snes_ctx->bchandler)
4993 snes_ctx->op->
Mult(*txx,ff);
5000 snes_ctx->op->
Mult(xx,ff);
5002 ff.UpdateVecFromFlags();
5003 PetscFunctionReturn(PETSC_SUCCESS);
5006static PetscErrorCode __mfem_snes_objective(SNES snes, Vec x,
PetscReal *
f,
5009 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
5011 PetscFunctionBeginUser;
5012 if (!snes_ctx->objective)
5014 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing objective function");
5018 (*snes_ctx->objective)(snes_ctx->op,xx,&lf);
5020 PetscFunctionReturn(PETSC_SUCCESS);
5023static PetscErrorCode __mfem_snes_postcheck(SNESLineSearch ls,Vec X,Vec Y,Vec W,
5024 PetscBool *cy,PetscBool *cw,
void*
ctx)
5026 __mfem_snes_ctx* snes_ctx = (__mfem_snes_ctx*)
ctx;
5027 bool lcy =
false,lcw =
false;
5029 PetscFunctionBeginUser;
5033 (*snes_ctx->postcheck)(snes_ctx->op,x,y,w,lcy,lcw);
5034 if (lcy) { y.UpdateVecFromFlags(); *cy = PETSC_TRUE; }
5035 if (lcw) { w.UpdateVecFromFlags(); *cw = PETSC_TRUE; }
5036 PetscFunctionReturn(PETSC_SUCCESS);
5039static PetscErrorCode __mfem_snes_update(SNES snes,
PetscInt it)
5042 __mfem_snes_ctx* snes_ctx;
5044 PetscFunctionBeginUser;
5046 ierr = SNESGetFunction(snes,&F,NULL,(
void **)&snes_ctx); CHKERRQ(ierr);
5047 ierr = SNESGetSolution(snes,&X); CHKERRQ(ierr);
5050 ierr = VecDuplicate(X,&pX); CHKERRQ(ierr);
5053 ierr = VecDestroy(&pX); CHKERRQ(ierr);
5057 if (!pX) SETERRQ(PetscObjectComm((
PetscObject)snes),PETSC_ERR_USER,
5058 "Missing previous solution");
5059 ierr = SNESGetSolutionUpdate(snes,&dX); CHKERRQ(ierr);
5064 (*snes_ctx->update)(snes_ctx->op,it,
f,x,dx,px);
5066 ierr = VecCopy(X,pX); CHKERRQ(ierr);
5067 PetscFunctionReturn(PETSC_SUCCESS);
5073 __mfem_monitor_ctx *monctx = (__mfem_monitor_ctx*)
ctx;
5075 PetscFunctionBeginUser;
5078 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,
"Missing monitor context");
5087 PetscErrorCode ierr;
5089 ierr = KSPBuildSolution(ksp,NULL,&x); CHKERRQ(ierr);
5096 PetscErrorCode ierr;
5098 ierr = KSPBuildResidual(ksp,NULL,NULL,&x); CHKERRQ(ierr);
5103 PetscFunctionReturn(PETSC_SUCCESS);
5106static PetscErrorCode __mfem_mat_shell_apply(Mat A, Vec x, Vec y)
5109 PetscErrorCode ierr;
5111 PetscFunctionBeginUser;
5112 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5113 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5117 yy.UpdateVecFromFlags();
5118 PetscFunctionReturn(PETSC_SUCCESS);
5121static PetscErrorCode __mfem_mat_shell_apply_transpose(Mat A, Vec x, Vec y)
5124 PetscErrorCode ierr;
5127 PetscFunctionBeginUser;
5128 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5129 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5132 ierr = MatIsSymmetricKnown(A,&flg,&symm); CHKERRQ(ierr);
5141 yy.UpdateVecFromFlags();
5142 PetscFunctionReturn(PETSC_SUCCESS);
5145static PetscErrorCode __mfem_mat_shell_copy(Mat A, Mat B, MatStructure str)
5148 PetscErrorCode ierr;
5150 PetscFunctionBeginUser;
5151 ierr = MatShellGetContext(A,(
void **)&op); CHKERRQ(ierr);
5152 if (!op) { SETERRQ(PetscObjectComm((
PetscObject)A),PETSC_ERR_LIB,
"Missing operator"); }
5153 ierr = MatShellSetContext(B,(
void *)op); CHKERRQ(ierr);
5154 PetscFunctionReturn(PETSC_SUCCESS);
5157static PetscErrorCode __mfem_mat_shell_destroy(Mat A)
5159 PetscFunctionBeginUser;
5160 PetscFunctionReturn(PETSC_SUCCESS);
5163static PetscErrorCode __mfem_pc_shell_view(PC pc, PetscViewer viewer)
5165 __mfem_pc_shell_ctx *
ctx;
5166 PetscErrorCode ierr;
5168 PetscFunctionBeginUser;
5169 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5173 ierr = PetscObjectTypeCompare((
PetscObject)viewer,PETSCVIEWERASCII,&isascii);
5180 ierr = PCView(*ppc,viewer); CHKERRQ(ierr);
5186 ierr = PetscViewerASCIIPrintf(viewer,
5187 "No information available on the mfem::Solver\n");
5191 if (isascii &&
ctx->factory)
5193 ierr = PetscViewerASCIIPrintf(viewer,
5194 "Number of preconditioners created by the factory %lu\n",
ctx->numprec);
5198 PetscFunctionReturn(PETSC_SUCCESS);
5201static PetscErrorCode __mfem_pc_shell_apply(PC pc, Vec x, Vec y)
5203 __mfem_pc_shell_ctx *
ctx;
5204 PetscErrorCode ierr;
5206 PetscFunctionBeginUser;
5209 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5212 ctx->op->Mult(xx,yy);
5213 yy.UpdateVecFromFlags();
5219 PetscFunctionReturn(PETSC_SUCCESS);
5222static PetscErrorCode __mfem_pc_shell_apply_transpose(PC pc, Vec x, Vec y)
5224 __mfem_pc_shell_ctx *
ctx;
5225 PetscErrorCode ierr;
5227 PetscFunctionBeginUser;
5230 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5233 ctx->op->MultTranspose(xx,yy);
5234 yy.UpdateVecFromFlags();
5240 PetscFunctionReturn(PETSC_SUCCESS);
5243static PetscErrorCode __mfem_pc_shell_setup(PC pc)
5245 __mfem_pc_shell_ctx *
ctx;
5247 PetscFunctionBeginUser;
5248 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5259 ierr = PCGetOperators(pc,NULL,&B); CHKERRQ(ierr);
5268 PetscFunctionReturn(PETSC_SUCCESS);
5271static PetscErrorCode __mfem_pc_shell_destroy(PC pc)
5273 __mfem_pc_shell_ctx *
ctx;
5274 PetscErrorCode ierr;
5276 PetscFunctionBeginUser;
5277 ierr = PCShellGetContext(pc,(
void **)&
ctx); CHKERRQ(ierr);
5283 PetscFunctionReturn(PETSC_SUCCESS);
5286static PetscErrorCode __mfem_array_container_destroy(
void *ptr)
5288 PetscErrorCode ierr;
5290 PetscFunctionBeginUser;
5291 ierr = PetscFree(ptr); CHKERRQ(ierr);
5292 PetscFunctionReturn(PETSC_SUCCESS);
5295static PetscErrorCode __mfem_matarray_container_destroy(
void *ptr)
5298 PetscErrorCode ierr;
5300 PetscFunctionBeginUser;
5301 for (
int i=0; i<
a->Size(); i++)
5305 ierr = MatDestroy(&M); CCHKERRQ(comm,ierr);
5308 PetscFunctionReturn(PETSC_SUCCESS);
5311static PetscErrorCode __mfem_monitor_ctx_destroy(
void **
ctx)
5313 PetscErrorCode ierr;
5315 PetscFunctionBeginUser;
5316 ierr = PetscFree(*
ctx); CHKERRQ(ierr);
5317 PetscFunctionReturn(PETSC_SUCCESS);
5322PetscErrorCode MakeShellPC(PC pc,
mfem::Solver &precond,
bool ownsop)
5324 PetscFunctionBeginUser;
5325 __mfem_pc_shell_ctx *
ctx =
new __mfem_pc_shell_ctx;
5327 ctx->ownsop = ownsop;
5328 ctx->factory = NULL;
5334 ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr);
5336 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
5337 ierr = PCShellSetName(pc,
"MFEM Solver (unknown Pmat)"); CHKERRQ(ierr);
5338 ierr = PCShellSetContext(pc,(
void *)
ctx); CHKERRQ(ierr);
5339 ierr = PCShellSetApply(pc,__mfem_pc_shell_apply); CHKERRQ(ierr);
5340 ierr = PCShellSetApplyTranspose(pc,__mfem_pc_shell_apply_transpose);
5342 ierr = PCShellSetSetUp(pc,__mfem_pc_shell_setup); CHKERRQ(ierr);
5343 ierr = PCShellSetView(pc,__mfem_pc_shell_view); CHKERRQ(ierr);
5344 ierr = PCShellSetDestroy(pc,__mfem_pc_shell_destroy); CHKERRQ(ierr);
5345 PetscFunctionReturn(PETSC_SUCCESS);
5350PetscErrorCode MakeShellPCWithFactory(PC pc,
5353 PetscFunctionBeginUser;
5354 __mfem_pc_shell_ctx *
ctx =
new __mfem_pc_shell_ctx;
5357 ctx->factory = factory;
5363 ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr);
5365 ierr = PCSetType(pc,PCSHELL); CHKERRQ(ierr);
5366 ierr = PCShellSetName(pc,factory->
GetName()); 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);
5379static PetscErrorCode Convert_Array_IS(MPI_Comm comm,
bool islist,
5383 PetscInt n = list ? list->Size() : 0,*idxs;
5384 const int *data = list ? list->GetData() : NULL;
5385 PetscErrorCode ierr;
5387 PetscFunctionBeginUser;
5388 ierr = PetscMalloc1(n,&idxs); CHKERRQ(ierr);
5391 for (
PetscInt i=0; i<n; i++) { idxs[i] = data[i] + st; }
5398 if (data[i]) { idxs[cum++] = i+st; }
5402 ierr = ISCreateGeneral(comm,n,idxs,PETSC_OWN_POINTER,is);
5404 PetscFunctionReturn(PETSC_SUCCESS);
5410static PetscErrorCode Convert_Vmarks_IS(MPI_Comm comm,
5418 PetscErrorCode ierr;
5420 PetscFunctionBeginUser;
5421 for (
int i = 0; i < pl2l.
Size(); i++)
5425 ierr = MatGetRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,(
const PetscInt**)&ii,
5426 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
5427 MFEM_VERIFY(done,
"Unable to perform MatGetRowIJ on " << i <<
" l2l matrix");
5428 ierr = MatGetSize(pl2l[i],NULL,&n); CHKERRQ(ierr);
5429#if defined(PETSC_USE_64BIT_INDICES)
5430 int nnz = (int)ii[m];
5431 int *mii =
new int[m+1];
5432 int *mjj =
new int[nnz];
5433 for (
int j = 0; j < m+1; j++) { mii[j] = (int)ii[j]; }
5434 for (
int j = 0; j < nnz; j++) { mjj[j] = (int)jj[j]; }
5439 ierr = MatRestoreRowIJ(pl2l[i],0,PETSC_FALSE,PETSC_FALSE,&m,
5441 (
const PetscInt**)&jj,&done); CHKERRQ(ierr);
5442 MFEM_VERIFY(done,
"Unable to perform MatRestoreRowIJ on "
5443 << i <<
" l2l matrix");
5446 for (
int i = 0; i < l2l.Size(); i++) { nl += l2l[i]->Width(); }
5448 const int* vdata = mark->
GetData();
5449 int* sdata = sub_dof_marker.
GetData();
5450 int cumh = 0, cumw = 0;
5451 for (
int i = 0; i < l2l.Size(); i++)
5456 l2l[i]->BooleanMultTranspose(vf_marker,sf_marker);
5457 cumh += l2l[i]->Height();
5458 cumw += l2l[i]->Width();
5460 ierr = Convert_Array_IS(comm,
false,&sub_dof_marker,st,is); CCHKERRQ(comm,ierr);
5461 for (
int i = 0; i < pl2l.
Size(); i++)
5465 PetscFunctionReturn(PETSC_SUCCESS);
5468#if !defined(PETSC_HAVE_HYPRE)
5470#if defined(HYPRE_MIXEDINT)
5471#error "HYPRE_MIXEDINT not supported"
5474#include "_hypre_parcsr_mv.h"
5475static PetscErrorCode MatConvert_hypreParCSR_AIJ(hypre_ParCSRMatrix* hA,Mat* pA)
5477 MPI_Comm comm = hypre_ParCSRMatrixComm(hA);
5478 hypre_CSRMatrix *hdiag,*hoffd;
5480 PetscInt *dii,*djj,*oii,*ojj,*iptr;
5483 PetscErrorCode ierr;
5485 PetscFunctionBeginUser;
5486 hdiag = hypre_ParCSRMatrixDiag(hA);
5487 hoffd = hypre_ParCSRMatrixOffd(hA);
5488 m = hypre_CSRMatrixNumRows(hdiag);
5489 n = hypre_CSRMatrixNumCols(hdiag);
5490 dnnz = hypre_CSRMatrixNumNonzeros(hdiag);
5491 onnz = hypre_CSRMatrixNumNonzeros(hoffd);
5492 ierr = PetscMalloc1(m+1,&dii); CHKERRQ(ierr);
5493 ierr = PetscMalloc1(dnnz,&djj); CHKERRQ(ierr);
5494 ierr = PetscMalloc1(dnnz,&da); CHKERRQ(ierr);
5495 ierr = PetscMemcpy(dii,hypre_CSRMatrixI(hdiag),(m+1)*
sizeof(
PetscInt));
5497 ierr = PetscMemcpy(djj,hypre_CSRMatrixJ(hdiag),dnnz*
sizeof(
PetscInt));
5499 ierr = PetscMemcpy(da,hypre_CSRMatrixData(hdiag),dnnz*
sizeof(
PetscScalar));
5506 ierr = PetscSortIntWithScalarArray(nc,iptr,aptr); CHKERRQ(ierr);
5510 ierr = MPI_Comm_size(comm,&size); CHKERRQ(ierr);
5515 ierr = PetscMalloc1(m+1,&oii); CHKERRQ(ierr);
5516 ierr = PetscMalloc1(onnz,&ojj); CHKERRQ(ierr);
5517 ierr = PetscMalloc1(onnz,&oa); CHKERRQ(ierr);
5518 ierr = PetscMemcpy(oii,hypre_CSRMatrixI(hoffd),(m+1)*
sizeof(
PetscInt));
5520 offdj = hypre_CSRMatrixJ(hoffd);
5521 coffd = hypre_ParCSRMatrixColMapOffd(hA);
5522 for (i=0; i<onnz; i++) { ojj[i] = coffd[offdj[i]]; }
5523 ierr = PetscMemcpy(oa,hypre_CSRMatrixData(hoffd),onnz*
sizeof(
PetscScalar));
5530 ierr = PetscSortIntWithScalarArray(nc,iptr,aptr); CHKERRQ(ierr);
5534 ierr = MatCreateMPIAIJWithSplitArrays(comm,m,n,PETSC_DECIDE,PETSC_DECIDE,dii,
5535 djj,da,oii,ojj,oa,pA); CHKERRQ(ierr);
5541 ierr = MatCreateSeqAIJWithArrays(comm,m,n,dii,djj,da,pA); CHKERRQ(ierr);
5547 void *ptrs[6] = {dii,djj,da,oii,ojj,oa};
5548 const char *names[6] = {
"_mfem_csr_dii",
5559 ierr = PetscContainerCreate(comm,&c); CHKERRQ(ierr);
5560 ierr = PetscContainerSetPointer(c,ptrs[i]); CHKERRQ(ierr);
5561 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
5565 ierr = PetscContainerDestroy(&c); CHKERRQ(ierr);
5567 PetscFunctionReturn(PETSC_SUCCESS);
5570static PetscErrorCode MatConvert_hypreParCSR_IS(hypre_ParCSRMatrix* hA,Mat* pA)
5573 ISLocalToGlobalMapping rl2g,cl2g;
5575 hypre_CSRMatrix *hdiag,*hoffd;
5576 MPI_Comm comm = hypre_ParCSRMatrixComm(hA);
5578 const char *names[2] = {
"_mfem_csr_aux",
5582 PetscInt *col_map_offd,*hdi,*hdj,*hoi,*hoj;
5584 PetscInt cum,dr,dc,oc,str,stc,nnz,i,jd,jo;
5585 PetscErrorCode ierr;
5587 PetscFunctionBeginUser;
5589 str = hypre_ParCSRMatrixFirstRowIndex(hA);
5590 stc = hypre_ParCSRMatrixFirstColDiag(hA);
5591 hdiag = hypre_ParCSRMatrixDiag(hA);
5592 hoffd = hypre_ParCSRMatrixOffd(hA);
5593 dr = hypre_CSRMatrixNumRows(hdiag);
5594 dc = hypre_CSRMatrixNumCols(hdiag);
5595 nnz = hypre_CSRMatrixNumNonzeros(hdiag);
5596 hdi = hypre_CSRMatrixI(hdiag);
5597 hdj = hypre_CSRMatrixJ(hdiag);
5598 hdd = hypre_CSRMatrixData(hdiag);
5599 oc = hypre_CSRMatrixNumCols(hoffd);
5600 nnz += hypre_CSRMatrixNumNonzeros(hoffd);
5601 hoi = hypre_CSRMatrixI(hoffd);
5602 hoj = hypre_CSRMatrixJ(hoffd);
5603 hod = hypre_CSRMatrixData(hoffd);
5606 ierr = ISCreateStride(comm,dr,str,1,&is); CHKERRQ(ierr);
5607 ierr = ISLocalToGlobalMappingCreateIS(is,&rl2g); CHKERRQ(ierr);
5608 ierr = ISDestroy(&is); CHKERRQ(ierr);
5609 col_map_offd = hypre_ParCSRMatrixColMapOffd(hA);
5610 ierr = PetscMalloc1(dc+oc,&aux); CHKERRQ(ierr);
5611 for (i=0; i<dc; i++) { aux[i] = i+stc; }
5612 for (i=0; i<oc; i++) { aux[i+dc] = col_map_offd[i]; }
5613 ierr = ISCreateGeneral(comm,dc+oc,aux,PETSC_OWN_POINTER,&is); CHKERRQ(ierr);
5614 ierr = ISLocalToGlobalMappingCreateIS(is,&cl2g); CHKERRQ(ierr);
5615 ierr = ISDestroy(&is); CHKERRQ(ierr);
5618 ierr = MatCreate(comm,pA); CHKERRQ(ierr);
5619 ierr = MatSetSizes(*pA,dr,dc,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr);
5620 ierr = MatSetType(*pA,MATIS); CHKERRQ(ierr);
5621 ierr = MatSetLocalToGlobalMapping(*pA,rl2g,cl2g); CHKERRQ(ierr);
5622 ierr = ISLocalToGlobalMappingDestroy(&rl2g); CHKERRQ(ierr);
5623 ierr = ISLocalToGlobalMappingDestroy(&cl2g); CHKERRQ(ierr);
5626 ierr = PetscMalloc1(nnz+dr+1,&aux); CHKERRQ(ierr);
5627 ierr = PetscMalloc1(nnz,&data); CHKERRQ(ierr);
5631 *ii = *(hdi++) + *(hoi++);
5632 for (jd=0,jo=0,cum=0; *ii<nnz; cum++)
5636 for (; jd<*hdi; jd++) { *jj++ = *hdj++; *aa++ = *hdd++; }
5637 for (; jo<*hoi; jo++) { *jj++ = *hoj++ + dc; *aa++ = *hod++; }
5638 *(++ii) = *(hdi++) + *(hoi++);
5639 ierr = PetscSortIntWithScalarArray(jd+jo-nc,jold,aold); CHKERRQ(ierr);
5641 for (; cum<dr; cum++) { *(++ii) = nnz; }
5645 ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,dr,dc+oc,ii,jj,aa,&lA);
5653 ierr = PetscContainerCreate(PETSC_COMM_SELF,&c); CHKERRQ(ierr);
5654 ierr = PetscContainerSetPointer(c,ptrs[i]); CHKERRQ(ierr);
5655 ierr = PetscContainerSetUserDestroy(c,__mfem_array_container_destroy);
5659 ierr = PetscContainerDestroy(&c); CHKERRQ(ierr);
5661 ierr = MatISSetLocalMat(*pA,lA); CHKERRQ(ierr);
5662 ierr = MatDestroy(&lA); CHKERRQ(ierr);
5663 ierr = MatAssemblyBegin(*pA,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
5664 ierr = MatAssemblyEnd(*pA,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
5665 PetscFunctionReturn(PETSC_SUCCESS);
5669#include <petsc/private/matimpl.h>
5671static PetscErrorCode __mfem_MatCreateDummy(MPI_Comm comm,
PetscInt m,
5675 ierr = MatCreate(comm,A); CHKERRQ(ierr);
5676 ierr = MatSetSizes(*A,m,n,PETSC_DECIDE,PETSC_DECIDE); CHKERRQ(ierr);
5677 ierr = PetscObjectChangeTypeName((
PetscObject)*A,
"mfemdummy"); CHKERRQ(ierr);
5678 (*A)->preallocated = PETSC_TRUE;
5679 ierr = MatSetUp(*A); CHKERRQ(ierr);
5680 PetscFunctionReturn(PETSC_SUCCESS);
5683#include <petsc/private/vecimpl.h>
5685#if defined(PETSC_HAVE_DEVICE)
5686static PetscErrorCode __mfem_VecSetOffloadMask(Vec v, PetscOffloadMask m)
5690 PetscFunctionReturn(PETSC_SUCCESS);
5694static PetscErrorCode __mfem_VecBoundToCPU(Vec v, PetscBool *flg)
5697#if defined(PETSC_HAVE_DEVICE)
5698 *flg = v->boundtocpu;
5702 PetscFunctionReturn(PETSC_SUCCESS);
5705static PetscErrorCode __mfem_PetscObjectStateIncrease(
PetscObject o)
5707 PetscErrorCode ierr;
5710 ierr = PetscObjectStateIncrease(o); CHKERRQ(ierr);
5711 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 vector dimension.
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.
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
operator petsc::KSP() const
Conversion function to PETSc's KSP type.
virtual ~PetscLinearSolver()
virtual void SetOperator(const Operator &op)
PetscLinearSolver(MPI_Comm comm, const std::string &prefix=std::string(), bool wrap=true, bool iter_mode=false)
void SetPreconditioner(Solver &precond)
virtual void Mult(const Vector &b, Vector &x) const
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 SetPostCheck(void(*post)(Operator *op, const Vector &X, Vector &Y, Vector &W, bool &changed_y, bool &changed_w))
virtual void Mult(const Vector &b, Vector &x) const
Application of the solver.
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))
virtual void SetOperator(const Operator &op)
Specification of the nonlinear operator.
PetscNonlinearSolver(MPI_Comm comm, const std::string &prefix=std::string())
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.
virtual void MultTranspose(const Vector &b, Vector &x) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
virtual void Mult(const Vector &b, Vector &x) const
Application of the preconditioner.
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
virtual ~PetscPreconditioner()
PetscPreconditioner(MPI_Comm comm, const std::string &prefix=std::string())
operator petsc::PC() const
Conversion function to PETSc's PC type.
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
const real_t * HostReadData() const
void SortColumnIndices()
Sort the column indices corresponding to each row.
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
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 &x) const
Return an Operator representing dG/dx at the given point x and the currently set time.
virtual void ImplicitMult(const Vector &x, const Vector &k, Vector &y) const
Perform the action of the implicit part of the operator, F: y = F(x, k, t) where t is the current tim...
bool isImplicit() const
True if type is IMPLICIT or HOMOGENEOUS.
virtual void ExplicitMult(const Vector &x, Vector &y) const
Perform the action of the explicit part of the operator, G: y = G(x, t) where t is the current time.
virtual void SetTime(const real_t t_)
Set the current time.
virtual Operator & GetImplicitGradient(const Vector &x, const Vector &k, real_t shift) const
Return an Operator representing (dF/dk shift + dF/dx) at the given x, k, and the currently set time.
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.
void trans(const Vector &u, Vector &x)
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.
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)
struct s_NavierContext ctx
real_t p(const Vector &x, real_t t)
struct _p_PetscObject * PetscObject
@ HIP_MASK
Biwise-OR of all HIP backends.
@ CUDA_MASK
Biwise-OR of all CUDA backends.