<div dir="ltr">With the code in attachement it's better.<div><br></div><div>And I set it up in Fortran as follow :: </div><div><br></div><div>            TS :: timeS<br></div><div>            TSAdapt        :: adapt<br></div><div>            call TSGetAdapt(timeS, adapt, ierr);                    CHKERRA(ierr)<br>            call MyTSAdaptRegister(timeS, adapt, gamma, cfl, ierr); CHKERRA(ierr)<br></div><div><br clear="all"><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 </div></div></div></div></div></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 28 déc. 2020 à 18:02, Thibault Bridel-Bertomeu <<a href="mailto:thibault.bridelbertomeu@gmail.com">thibault.bridelbertomeu@gmail.com</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"><div dir="auto">Hi Jed,</div><div dir="auto"><br></div><div dir="auto">Thanks for your message. </div><div dir="auto">I implemented everything in C as you suggested and it works fine except for one thing : the ts->vec_sol does not seem to get updated when seen from the C code (it is on the Fortran side though the solution is correct). </div><div dir="auto">As a result, the time step (that uses among other things the max velocity in the domain) is always at the value it gets from the initial solution. </div><div dir="auto">Any idea why ts->vec_sol does not seem to be updated ? (I checked the stepnum and time is updated though , when accessed with TSGetTime for instance). </div><div dir="auto"><br></div><div dir="auto">Cheers,</div><div dir="auto">Thibault</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 28 déc. 2020 à 15:30, Jed Brown <<a href="mailto:jed@jedbrown.org" target="_blank">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>
> Good morning everyone,<br>
><br>
> Thank you Barry for the answer, it works now !<br>
><br>
> I am facing (yet) another situation: the TSAdaptRegister function.<br>
> In the MR on gitlab, Jed mentioned that sometimes, when function pointers<br>
> are not stored in PETSc objects, one can use stack memory to pass that<br>
> pointer from fortran to C.<br>
<br>
The issue with stack memory is that when it returns, that memory is invalid. You can't use it in this instance.<br>
<br>
I think you're going to have problems implementing a TSAdaptCreate_XYZ in Fortran (because the body of that function will need to access private struct members; see below).<br>
<br>
I would implement what you need in C and you can call out to Fortran if you want from inside TSAdaptChoose_YourMethod().<br>
<br>
PETSC_EXTERN PetscErrorCode TSAdaptCreate_DSP(TSAdapt adapt)<br>
{<br>
  TSAdapt_DSP    *dsp;<br>
  PetscErrorCode ierr;<br>
<br>
  PetscFunctionBegin;<br>
  ierr = PetscNewLog(adapt,&dsp);CHKERRQ(ierr);<br>
  adapt->reject_safety = 1.0; /* unused */<br>
<br>
  adapt->data                = (void*)dsp;<br>
  adapt->ops->choose         = TSAdaptChoose_DSP;<br>
  adapt->ops->setfromoptions = TSAdaptSetFromOptions_DSP;<br>
  adapt->ops->destroy        = TSAdaptDestroy_DSP;<br>
  adapt->ops->view           = TSAdaptView_DSP;<br>
<br>
  ierr = PetscObjectComposeFunction((PetscObject)adapt,"TSAdaptDSPSetFilter_C",TSAdaptDSPSetFilter_DSP);CHKERRQ(ierr);<br>
  ierr = PetscObjectComposeFunction((PetscObject)adapt,"TSAdaptDSPSetPID_C",TSAdaptDSPSetPID_DSP);CHKERRQ(ierr);<br>
<br>
  ierr = TSAdaptDSPSetFilter_DSP(adapt,"PI42");CHKERRQ(ierr);<br>
  ierr = TSAdaptRestart_DSP(adapt);CHKERRQ(ierr);<br>
  PetscFunctionReturn(0);<br>
}<br>
<br>
> Can anyone develop that idea ? Because for TSAdaptRegister, i guess the<br>
> wrapper would start like :<br>
><br>
> PETSC_EXTERN void tsadaptregister_(char *sname,<br>
>                                    void (*func)(TSAdapt*,PetscErrorCode*),<br>
>                                    PetscErrorCode *ierr,<br>
>                                    PETSC_FORTRAN_CHARLEN_T snamelen)<br>
><br>
> but then the C TSAdaptRegister function takes a PetscErrorCode<br>
> (*func)(TSAdapt) function pointer as argument ... I cannot use any<br>
> FORTRAN_CALLBACK here since I do not have any object to hook it to, and I<br>
> could not find a similar situation among the pre-existing wrappers. Does<br>
> anyone have an idea on how to proceed ?<br>
><br>
> Thanks !!<br>
><br>
> Thibault<br>
><br>
> Le mar. 22 déc. 2020 à 21:20, Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank">bsmith@petsc.dev</a>> a écrit :<br>
><br>
>><br>
>> PetscObjectUseFortranCallback((PetscDS)ctx,<br>
>><br>
>><br>
>> *ierr = PetscObjectSetFortranCallback((PetscObject)*prob<br>
>><br>
>><br>
>>   It looks like the problem is that these user provided functions do not<br>
>> take a PetscDS directly as an argument so the Fortran callback information<br>
>> cannot be obtained from them.<br>
>><br>
>> The manual page for PetscDSAddBoundary() says<br>
>><br>
>>  - ctx         - An optional user context for bcFunc<br>
>><br>
>> but then when it lists the calling sequence for bcFunc it does not list<br>
>> the ctx as an argument, so either the manual page or code is wrong.<br>
>><br>
>> It looks  like you make the ctx be the PetscDS prob argument when you<br>
>> call PetscDSAddBoundary<br>
>><br>
>> In principle this sounds like it might work. I think you need to track<br>
>> through the debugger to see if the ctx passed to ourbocofunc() is<br>
>> actually the PetscDS prob variable and if not why it is not.<br>
>><br>
>>   Barry<br>
>><br>
>><br>
>> On Dec 22, 2020, at 5:49 AM, Thibault Bridel-Bertomeu <<br>
>> <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> wrote:<br>
>><br>
>> Dear all,<br>
>><br>
>> I have hit two snags while implementing the missing wrappers necessary to<br>
>> transcribe ex11 to Fortran.<br>
>><br>
>> First is about the PetscDSAddBoundary wrapper, that I have done so :<br>
>><br>
>> static PetscErrorCode ourbocofunc(PetscReal time, const PetscReal *c,<br>
>> const PetscReal *n, const PetscScalar *a_xI, const PetscScalar *a_xG, void<br>
>> *ctx)<br>
>> {<br>
>>     PetscObjectUseFortranCallback((PetscDS)ctx, bocofunc,<br>
>>                                   (PetscReal*,const PetscReal*,const<br>
>> PetscReal*,const PetscScalar*,const PetscScalar*,void*,PetscErrorCode*),<br>
>>                                   (&time,c,n,a_xI,a_xG,ctx,&ierr));<br>
>> }<br>
>> static PetscErrorCode ourbocofunc_time(PetscReal time, const PetscReal *c,<br>
>> const PetscReal *n, const PetscScalar *a_xI, const PetscScalar *a_xG, void<br>
>> *ctx)<br>
>> {<br>
>>     PetscObjectUseFortranCallback((PetscDS)ctx, bocofunc_time,<br>
>>                                   (PetscReal*,const PetscReal*,const<br>
>> PetscReal*,const PetscScalar*,const PetscScalar*,void*,PetscErrorCode*),<br>
>>                                   (&time,c,n,a_xI,a_xG,ctx,&ierr));<br>
>> }<br>
>> PETSC_EXTERN void petscdsaddboundary_(PetscDS *prob,<br>
>> DMBoundaryConditionType *type, char *name, char *labelname, PetscInt<br>
>> *field, PetscInt *numcomps, PetscInt *comps,<br>
>>                                       void (*bcFunc)(void),<br>
>>                                       void (*bcFunc_t)(void),<br>
>>                                       PetscInt *numids, const PetscInt<br>
>> *ids, void *ctx, PetscErrorCode *ierr,<br>
>>                                       PETSC_FORTRAN_CHARLEN_T namelen,<br>
>> PETSC_FORTRAN_CHARLEN_T labelnamelen)<br>
>> {<br>
>>     char *newname, *newlabelname;<br>
>>     FIXCHAR(name, namelen, newname);<br>
>>     FIXCHAR(labelname, labelnamelen, newlabelname);<br>
>>     *ierr = PetscObjectSetFortranCallback((PetscObject)*prob,<br>
>> PETSC_FORTRAN_CALLBACK_CLASS, &bocofunc,      (PetscVoidFunction)bcFunc,<br>
>> ctx);<br>
>>     *ierr = PetscObjectSetFortranCallback((PetscObject)*prob,<br>
>> PETSC_FORTRAN_CALLBACK_CLASS, &bocofunc_time, (PetscVoidFunction)bcFunc_t,<br>
>> ctx);<br>
>>     *ierr = PetscDSAddBoundary(*prob, *type, newname, newlabelname,<br>
>> *field, *numcomps, comps,<br>
>>                                (void (*)(void))ourbocofunc,<br>
>>                                (void (*)(void))ourbocofunc_time,<br>
>>                                *numids, ids, *prob);<br>
>>     FREECHAR(name, newname);<br>
>>     FREECHAR(labelname, newlabelname);<br>
>> }<br>
>><br>
>><br>
>><br>
>> but when I call it in the program, with adequate routines,  I obtain the<br>
>> following error :<br>
>><br>
>> [0]PETSC ERROR: --------------------- Error Message --------------------------------------------------------------[0]PETSC ERROR: Corrupt argument: <a href="https://www.mcs.anl.gov/petsc/documentation/faq.html#valgrind[0]PETSC" rel="noreferrer" target="_blank">https://www.mcs.anl.gov/petsc/documentation/faq.html#valgrind[0]PETSC</a> ERROR: Fortran callback not set on this object[0]PETSC ERROR: See <a href="https://www.mcs.anl.gov/petsc/documentation/faq.html" rel="noreferrer" target="_blank">https://www.mcs.anl.gov/petsc/documentation/faq.html</a> for trouble shooting.[0]PETSC ERROR: Petsc Development GIT revision: v3.14.2-297-gf36a7edeb8  GIT Date: 2020-12-18 04:42:53 +0000[0]PETSC ERROR: ../../../bin/eulerian3D on a  named macbook-pro-de-thibault.home by tbridel Sun Dec 20 15:05:15 2020[0]PETSC ERROR: Configure options --with-clean=0 --prefix=/Users/tbridel/Documents/1-CODES/04-PETSC/build --with-make-np=2 --with-windows-graphics=0 --with-debugging=0 --download-fblaslapack --download-mpich-shared=0 --with-x=0 --with-pthread=0 --with-valgrind=0 --PETSC_ARCH=macosx --with-fc=/usr/local/Cellar/open-mpi/4.0.1_2/bin/mpifort --with-cc=/usr/local/Cellar/open-mpi/4.0.1_2/bin/mpicc --with-cxx=/usr/local/Cellar/open-mpi/4.0.1_2/bin/mpic++ --with-openmp=0 --download-hypre=yes --download-sowing=yes --download-metis=yes --download-parmetis=yes --download-triangle=yes --download-tetgen=yes --download-ctetgen=yes --download-p4est=yes --download-zlib=yes --download-c2html=yes --download-eigen=yes --download-pragmatic=yes --with-hdf5-dir=/usr/local/Cellar/hdf5/1.10.5_1 --with-cmake-dir=/usr/local/Cellar/cmake/3.15.3[0]PETSC ERROR: #1 PetscObjectGetFortranCallback() line 258 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/sys/objects/inherit.c[0]PETSC ERROR: #2 ourbocofunc() line 141 in /Users/tbridel/Documents/1-CODES/59-EULERIAN3D/sources/petsc_wrapping/wrapper_petsc.c[0]PETSC ERROR: #3 DMPlexInsertBoundaryValuesRiemann() line 989 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/dm/impls/plex/plexfem.c[0]PETSC ERROR: #4 DMPlexInsertBoundaryValues_Plex() line 1052 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/dm/impls/plex/plexfem.c[0]PETSC ERROR: #5 DMPlexInsertBoundaryValues() line 1142 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/dm/impls/plex/plexfem.c[0]PETSC ERROR: #6 DMPlexComputeResidual_Internal() line 4524 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/dm/impls/plex/plexfem.c[0]PETSC ERROR: #7 DMPlexTSComputeRHSFunctionFVM() line 74 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/utils/dmplexts.c[0]PETSC ERROR: #8 ourdmtsrhsfunc() line 186 in /Users/tbridel/Documents/1-CODES/59-EULERIAN3D/sources/petsc_wrapping/wrapper_petsc.c[0]PETSC ERROR: #9 TSComputeRHSFunction_DMLocal() line 105 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/utils/dmlocalts.c[0]PETSC ERROR: #10 TSComputeRHSFunction() line 653 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/interface/ts.c[0]PETSC ERROR: #11 TSSSPStep_RK_3() line 120 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/impls/explicit/ssp/ssp.c[0]PETSC ERROR: #12 TSStep_SSP() line 208 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/impls/explicit/ssp/ssp.c[0]PETSC ERROR: #13 TSStep() line 3757 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/interface/ts.c[0]PETSC ERROR: #14 TSSolve() line 4154 in /Users/tbridel/Documents/1-CODES/04-PETSC/src/ts/interface/ts.c[0]PETSC ERROR: #15 User provided function() line 0 in User file<br>
>><br>
>><br>
>> Second is about the DMProjectFunction wrapper, that I have done so :<br>
>><br>
>> static PetscErrorCode ourdmprojfunc(PetscInt dim, PetscReal time,<br>
>> PetscReal x[], PetscInt Nf, PetscScalar u[], void *ctx)<br>
>> {<br>
>>     PetscObjectUseFortranCallback((DM)ctx, dmprojfunc,<br>
>><br>
>> (PetscInt*,PetscReal*,PetscReal*,PetscInt*,PetscScalar*,void*,PetscErrorCode*),<br>
>>                                   (&dim,&time,x,&Nf,u,_ctx,&ierr))<br>
>> }<br>
>> PETSC_EXTERN void dmprojectfunction_(DM *dm, PetscReal *time,<br>
>>                                      void<br>
>> (*func)(PetscInt*,PetscReal*,PetscReal*,PetscInt*,PetscScalar*,void*,PetscErrorCode*),<br>
>>                                      void *ctx, InsertMode *mode, Vec X,<br>
>> PetscErrorCode *ierr)<br>
>> {<br>
>>     PetscErrorCode (*funcarr[1]) (PetscInt dim, PetscReal time, PetscReal<br>
>> x[], PetscInt Nf, PetscScalar *u, void *ctx);<br>
>>     *ierr = PetscObjectSetFortranCallback((PetscObject)*dm,<br>
>> PETSC_FORTRAN_CALLBACK_CLASS, &dmprojfunc, (PetscVoidFunction)func, ctx);<br>
>>     funcarr[0] = ourdmprojfunc;<br>
>>     *ierr = DMProjectFunction(*dm, *time, funcarr, &ctx, *mode, X);<br>
>> }<br>
>><br>
>><br>
>> This time there is no error because I cannot reach this point in the<br>
>> program, but I am not sure anyways how to write this wrapper, especially<br>
>> because of the double pointers that DMProjectFunction takes as arguments.<br>
>><br>
>> Does anyone have any idea what could be going wrong with those two<br>
>> wrappers ?<br>
>><br>
>> Thank you very much in advance !!<br>
>><br>
>> Thibault<br>
>><br>
>> Le ven. 18 déc. 2020 à 11:02, Thibault Bridel-Bertomeu <<br>
>> <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> a écrit :<br>
>><br>
>>> Aah that is a nice trick, I was getting ready to fork, clone the fork and<br>
>>> redo the work, but that worked fine ! Thank you Barry !<br>
>>><br>
>>> The MR will appear in a little while !<br>
>>><br>
>>> Thibault<br>
>>><br>
>>><br>
>>> Le ven. 18 déc. 2020 à 10:16, Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank">bsmith@petsc.dev</a>> a écrit :<br>
>>><br>
>>>><br>
>>>>   Good question.  There is a trick to limit the amount of work you need<br>
>>>> to do with a  new fork after you have already made changes with a PETSc<br>
>>>> clone, but it looks like we do not document this clearly in the webpages.<br>
>>>> (I couldn't find it).<br>
>>>><br>
>>>>   Yes, you do need to make a fork, but after you have made the fork on<br>
>>>> the GitLab website (and have done nothing on your machine) edit the file<br>
>>>> $PETSC_DIR/.git/config  for your clone on your machine<br>
>>>><br>
>>>>   Locate the line that has url = git@gitlab.com:petsc/petsc.git  (this<br>
>>>> may have an https at the beginning of the line)<br>
>>>><br>
>>>>   Change this line to point to the fork url instead with git@ not<br>
>>>> https, which will be pretty much the same URL but with your user id instead<br>
>>>> of petsc in the address.  Then git push and it will push to your fork.<br>
>>>><br>
>>>>   Now you changes will be in your fork and you can make the MR from your<br>
>>>> fork URL on Gitlab. (In other words this editing trick converts your PETSc<br>
>>>> clone on your machine to a PETSc fork).<br>
>>>><br>
>>>>   I hope I have explained this clearly enough it goes smoothly.<br>
>>>><br>
>>>>   Barry<br>
>>>><br>
>>>><br>
>>>><br>
>>>> On Dec 18, 2020, at 3:00 AM, Thibault Bridel-Bertomeu <<br>
>>>> <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> wrote:<br>
>>>><br>
>>>> Hello Barry,<br>
>>>><br>
>>>> I'll start the MR as soon as possible then so that specialists can<br>
>>>> indeed have a look. Do I have to fork PETSc to start a MR or are PETSc repo<br>
>>>> settings such that can I push a branch from the PETSc clone I got ?<br>
>>>><br>
>>>> Thibault<br>
>>>><br>
>>>><br>
>>>> Le mer. 16 déc. 2020 à 07:47, Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank">bsmith@petsc.dev</a>> a écrit :<br>
>>>><br>
>>>>><br>
>>>>>   Thibault,<br>
>>>>><br>
>>>>>   A subdirectory for the example is fine; we have other examples that<br>
>>>>> use subdirectories and multiple files.<br>
>>>>><br>
>>>>>   Note: even if you don't have something completely working you can<br>
>>>>> still make MR and list it as DRAFT request for comments, some other PETSc<br>
>>>>> members who understand the packages you are using and Fortran better than I<br>
>>>>> may be able to help as you develop the code.<br>
>>>>><br>
>>>>>   Barry<br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>>> On Dec 16, 2020, at 12:35 AM, Thibault Bridel-Bertomeu <<br>
>>>>> <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> wrote:<br>
>>>>><br>
>>>>> Hello everyone,<br>
>>>>><br>
>>>>> Thank you Barry for the feedback.<br>
>>>>> OK, yes I'll work up an MR as soon as I have got something working. By<br>
>>>>> the way, does the fortran-version of the example have to be a single file ?<br>
>>>>> If my push contains a directory with several files (different modules and<br>
>>>>> the main), and the Makefile that goes with it, is that ok ?<br>
>>>>><br>
>>>>> Thibault Bridel-Bertomeu<br>
>>>>><br>
>>>>><br>
>>>>> Le mer. 16 déc. 2020 à 04:46, Barry Smith <<a href="mailto:bsmith@petsc.dev" target="_blank">bsmith@petsc.dev</a>> a écrit :<br>
>>>>><br>
>>>>>><br>
>>>>>>   This is great. If you make a branch off of the PETSc  git repository<br>
>>>>>> with these additions and work on ex11 you can make a merge request and we<br>
>>>>>> can run the code easily on all our test systems (for security reasons one<br>
>>>>>> of use needs to launch the tests from your MR).<br>
>>>>>> <a href="https://docs.petsc.org/en/latest/developers/integration/" rel="noreferrer" target="_blank">https://docs.petsc.org/en/latest/developers/integration/</a><br>
>>>>>><br>
>>>>>>    Barry<br>
>>>>>><br>
>>>>>><br>
>>>>>> On Dec 15, 2020, at 5:35 AM, Thibault Bridel-Bertomeu <<br>
>>>>>> <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a>> wrote:<br>
>>>>>><br>
>>>>>> Hello everyone,<br>
>>>>>><br>
>>>>>> So far, I have the wrappers in the files attached to this e-mail. I<br>
>>>>>> still do not know if they work properly - at least the code compiles and<br>
>>>>>> the calls to the wrapped-subroutine do not fail - but I wanted to put this<br>
>>>>>> here in case someone sees something really wrong with it already.<br>
>>>>>><br>
>>>>>> Thank you again for your help, I'll try to post updates of the F90<br>
>>>>>> version of ex11 regularly in this thread.<br>
>>>>>><br>
>>>>>> Stay safe,<br>
>>>>>><br>
>>>>>> Thibault Bridel-Bertomeu<br>
>>>>>><br>
>>>>>> Le dim. 13 déc. 2020 à 16:39, Jed Brown <<a href="mailto:jed@jedbrown.org" target="_blank">jed@jedbrown.org</a>> a écrit :<br>
>>>>>><br>
>>>>>>> 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<br>
>>>>>>> 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<br>
>>>>>>> pointers, so I<br>
>>>>>>> > guess it is possible ? Although I am not sure exactly how to play<br>
>>>>>>> with the<br>
>>>>>>> > PetscObjectSetFortranCallback & PetscObjectUseFortranCallback<br>
>>>>>>> macros -<br>
>>>>>>> > could anybody advise please ?<br>
>>>>>>><br>
>>>>>>> tsmonitorset_ is a good example to follow. In your file, create one<br>
>>>>>>> of these static structs with a member for each callback. These are IDs that<br>
>>>>>>> will be used as keys for Fortran callbacks and their contexts. The salient<br>
>>>>>>> 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<br>
>>>>>>> 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<br>
>>>>>>> v,void *ctx)<br>
>>>>>>> {<br>
>>>>>>><br>
>>>>>>> PetscObjectUseFortranCallback(ts,_cb.monitor,(TS*,PetscInt*,PetscReal*,Vec<br>
>>>>>>> *,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<br>
>>>>>>> (*func)(TS*,PetscInt*,PetscReal*,Vec*,void*,PetscErrorCode*),void<br>
>>>>>>> *mctx,void (*d)(void*,PetscErrorCode*),PetscErrorCode *ierr)<br>
>>>>>>> {<br>
>>>>>>>   CHKFORTRANNULLFUNCTION(d);<br>
>>>>>>>   if ((PetscVoidFunction)func == (PetscVoidFunction)<br>
>>>>>>> tsmonitordefault_) {<br>
>>>>>>>     *ierr = TSMonitorSet(*ts,(PetscErrorCode<br>
>>>>>>> (*)(TS,PetscInt,PetscReal,Vec,void*))TSMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode<br>
>>>>>>> (*)(void **))PetscViewerAndFormatDestroy);<br>
>>>>>>>   } else {<br>
>>>>>>>     *ierr =<br>
>>>>>>> PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);<br>
>>>>>>>     *ierr =<br>
>>>>>>> PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)d,mctx);<br>
>>>>>>>     *ierr = TSMonitorSet(*ts,ourmonitor,*ts,ourmonitordestroy);<br>
>>>>>>>   }<br>
>>>>>>> }<br>
>>>>>>><br>
>>>>>> <wrapper_petsc.h90><wrapper_petsc.c><br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>><br>
>>>><br>
>><br>
</blockquote></div></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div><div><div><div><div>Thibault Bridel-Bertomeu<br>—<br></div></div></div></div>Eng, MSc, PhD</div><div>Research Engineer</div><div>CEA/CESTA</div><div>33114 LE BARP</div><div>Tel.: (+33)557046924</div><div>Mob.: (+33)611025322<br></div><div>Mail: <a href="mailto:thibault.bridelbertomeu@gmail.com" target="_blank">thibault.bridelbertomeu@gmail.com</a><br></div></div></div></div></div></div>
</blockquote></div>