[petsc-users] TS tutorial ex11 in Fortran
Jed Brown
jed at jedbrown.org
Sun Dec 13 09:39:03 CST 2020
Thibault Bridel-Bertomeu <thibault.bridelbertomeu at gmail.com> writes:
> Thank you Mark for your answer.
>
> I am not sure what you think could be in the setBC1 routine ? How to make
> the connection with the PetscDS ?
>
> On the other hand, I actually found after a while TSMonitorSet has a
> fortran wrapper, and it does take as arguments two function pointers, so I
> guess it is possible ? Although I am not sure exactly how to play with the
> PetscObjectSetFortranCallback & PetscObjectUseFortranCallback macros -
> could anybody advise please ?
tsmonitorset_ is a good example to follow. In your file, create one of these static structs with a member for each callback. These are IDs that will be used as keys for Fortran callbacks and their contexts. The salient parts of the file are below.
static struct {
PetscFortranCallbackId prestep;
PetscFortranCallbackId poststep;
PetscFortranCallbackId rhsfunction;
PetscFortranCallbackId rhsjacobian;
PetscFortranCallbackId ifunction;
PetscFortranCallbackId ijacobian;
PetscFortranCallbackId monitor;
PetscFortranCallbackId mondestroy;
PetscFortranCallbackId transform;
#if defined(PETSC_HAVE_F90_2PTR_ARG)
PetscFortranCallbackId function_pgiptr;
#endif
} _cb;
/*
Note ctx is the same as ts so we need to get the Fortran context out of the TS; this gets put in _ctx using the callback ID
*/
static PetscErrorCode ourmonitor(TS ts,PetscInt i,PetscReal d,Vec v,void *ctx)
{
PetscObjectUseFortranCallback(ts,_cb.monitor,(TS*,PetscInt*,PetscReal*,Vec *,void*,PetscErrorCode*),(&ts,&i,&d,&v,_ctx,&ierr));
}
Then follow as in tsmonitorset_, which sets two callbacks.
PETSC_EXTERN void tsmonitorset_(TS *ts,void (*func)(TS*,PetscInt*,PetscReal*,Vec*,void*,PetscErrorCode*),void *mctx,void (*d)(void*,PetscErrorCode*),PetscErrorCode *ierr)
{
CHKFORTRANNULLFUNCTION(d);
if ((PetscVoidFunction)func == (PetscVoidFunction) tsmonitordefault_) {
*ierr = TSMonitorSet(*ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))TSMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
} else {
*ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);
*ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)d,mctx);
*ierr = TSMonitorSet(*ts,ourmonitor,*ts,ourmonitordestroy);
}
}
More information about the petsc-users
mailing list