<div dir="ltr"><div>Hello everyone, <br></div><div><br></div><div>So far, I have the wrappers in the files attached to this e-mail. I still do not know if they work properly - at least the code compiles and the calls to the wrapped-subroutine do not fail - but I wanted to put this here in case someone sees something really wrong with it already.</div><div><br></div><div>Thank you again for your help, I'll try to post updates of the F90 version of ex11 regularly in this thread.</div><div><br></div><div>Stay safe, <br></div><div><br></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div><div><div><div><div>Thibault Bridel-Bertomeu<br></div></div></div></div></div></div></div></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le dim. 13 déc. 2020 à 16:39, Jed Brown <<a href="mailto:jed@jedbrown.org">jed@jedbrown.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Thibault Bridel-Bertomeu <<a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> writes:<br>
<br>
> Thank you Mark for your answer.<br>
><br>
> I am not sure what you think could be in the setBC1 routine ? How to make<br>
> the connection with the PetscDS ?<br>
><br>
> On the other hand, I actually found after a while TSMonitorSet has a<br>
> fortran wrapper, and it does take as arguments two function pointers, so I<br>
> guess it is possible ? Although I am not sure exactly how to play with the<br>
> PetscObjectSetFortranCallback & PetscObjectUseFortranCallback macros -<br>
> could anybody advise please ?<br>
<br>
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.<br>
<br>
static struct {<br>
  PetscFortranCallbackId prestep;<br>
  PetscFortranCallbackId poststep;<br>
  PetscFortranCallbackId rhsfunction;<br>
  PetscFortranCallbackId rhsjacobian;<br>
  PetscFortranCallbackId ifunction;<br>
  PetscFortranCallbackId ijacobian;<br>
  PetscFortranCallbackId monitor;<br>
  PetscFortranCallbackId mondestroy;<br>
  PetscFortranCallbackId transform;<br>
#if defined(PETSC_HAVE_F90_2PTR_ARG)<br>
  PetscFortranCallbackId function_pgiptr;<br>
#endif<br>
} _cb;<br>
<br>
/*<br>
   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<br>
*/<br>
static PetscErrorCode ourmonitor(TS ts,PetscInt i,PetscReal d,Vec v,void *ctx)<br>
{<br>
  PetscObjectUseFortranCallback(ts,_cb.monitor,(TS*,PetscInt*,PetscReal*,Vec *,void*,PetscErrorCode*),(&ts,&i,&d,&v,_ctx,&ierr));<br>
}<br>
<br>
Then follow as in tsmonitorset_, which sets two callbacks. <br>
<br>
PETSC_EXTERN void tsmonitorset_(TS *ts,void (*func)(TS*,PetscInt*,PetscReal*,Vec*,void*,PetscErrorCode*),void *mctx,void (*d)(void*,PetscErrorCode*),PetscErrorCode *ierr)<br>
{<br>
  CHKFORTRANNULLFUNCTION(d);<br>
  if ((PetscVoidFunction)func == (PetscVoidFunction) tsmonitordefault_) {<br>
    *ierr = TSMonitorSet(*ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))TSMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);<br>
  } else {<br>
    *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);<br>
    *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)d,mctx);<br>
    *ierr = TSMonitorSet(*ts,ourmonitor,*ts,ourmonitordestroy);<br>
  }<br>
}<br>
</blockquote></div>