1 #include "zpetsc.h" 2 #include "petscsnes.h" 3 4 #ifdef PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE 5 #define snesconverged_tr_ snesconverged_tr__ 6 #define snesconverged_ls_ snesconverged_ls__ 7 #endif 8 9 #if defined(PETSC_HAVE_FORTRAN_CAPS) 10 #define snesdefaultcomputejacobian_ SNESDEFAULTCOMPUTEJACOBIAN 11 #define snesdefaultcomputejacobiancolor_ SNESDEFAULTCOMPUTEJACOBIANCOLOR 12 #define snesdacomputejacobian_ SNESDACOMPUTEJACOBIAN 13 #define snesdacomputejacobianwithadifor_ SNESDACOMPUTEJACOBIANWITHADIFOR 14 #define snessetjacobian_ SNESSETJACOBIAN 15 #define snesgetoptionsprefix_ SNESGETOPTIONSPREFIX 16 #define snesgettype_ SNESGETTYPE 17 #define snesdaformfunction_ SNESDAFORMFUNCTION 18 #define snessetfunction_ SNESSETFUNCTION 19 #define snesgetfunction_ SNESGETFUNCTION 20 #define snessetconvergencetest_ SNESSETCONVERGENCETEST 21 #define snesconverged_tr_ SNESCONVERGED_TR 22 #define snesconverged_ls_ SNESCONVERGED_LS 23 #define snesview_ SNESVIEW 24 #define snesgetconvergencehistory_ SNESGETCONVERGENCEHISTORY 25 #define snesgetjacobian_ SNESGETJACOBIAN 26 #define snessettype_ SNESSETTYPE 27 #define snesappendoptionsprefix_ SNESAPPENDOPTIONSPREFIX 28 #define snessetoptionsprefix_ SNESSETOPTIONSPREFIX 29 #define snesdefaultmonitor_ SNESDEFAULTMONITOR 30 #define snesvecviewmonitor_ SNESVECVIEWMONITOR 31 #define sneslgmonitor_ SNESLGMONITOR 32 #define snesvecviewupdatemonitor_ SNESVECVIEWUPDATEMONITOR 33 #define snessetmonitor_ SNESSETMONITOR 34 #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 35 #define snesdefaultcomputejacobian_ snesdefaultcomputejacobian 36 #define snesdefaultcomputejacobiancolor_ snesdefaultcomputejacobiancolor 37 #define snesdacomputejacobian_ snesdacomputejacobian 38 #define snesdacomputejacobianwithadifor_ snesdacomputejacobianwithadifor 39 #define snessetjacobian_ snessetjacobian 40 #define snesgetoptionsprefix_ snesgetoptionsprefix 41 #define snesgettype_ snesgettype 42 #define snesdaformfunction_ snesdaformfunction 43 #define snessetfunction_ snessetfunction 44 #define snesgetfunction_ snesgetfunction 45 #define snessetconvergencetest_ snessetconvergencetest 46 #define snesconverged_tr_ snesconverged_tr 47 #define snesconverged_ls_ snesconverged_ls 48 #define snesview_ snesview 49 #define snesgetjacobian_ snesgetjacobian 50 #define snesgetconvergencehistory_ snesgetconvergencehistory 51 #define snessettype_ snessettype 52 #define snesappendoptionsprefix_ snesappendoptionsprefix 53 #define snessetoptionsprefix_ snessetoptionsprefix 54 #define sneslgmonitor_ sneslgmonitor 55 #define snesdefaultmonitor_ snesdefaultmonitor 56 #define snesvecviewmonitor_ snesvecviewmonitor 57 #define snesvecviewupdatemonitor_ snesvecviewupdatemonitor 58 #define snessetmonitor_ snessetmonitor 59 #endif 60 61 EXTERN_C_BEGIN 62 static void (PETSC_STDCALL *f3)(SNES*,Vec*,Mat*,Mat*,MatStructure*,void*,PetscErrorCode*); 63 static void (PETSC_STDCALL *f2)(SNES*,Vec*,Vec*,void*,PetscErrorCode*); 64 static void (PETSC_STDCALL *f8)(SNES*,PetscReal*,PetscReal*,PetscReal*,SNESConvergedReason*,void*,PetscErrorCode*); 65 static void (PETSC_STDCALL *f7)(SNES*,PetscInt*,PetscReal*,void*,PetscErrorCode*); 66 static void (PETSC_STDCALL *f71)(void*,PetscErrorCode*); 67 EXTERN_C_END 68 69 static PetscErrorCode oursnesfunction(SNES snes,Vec x,Vec f,void *ctx) 70 { 71 PetscErrorCode ierr = 0; 72 (*f2)(&snes,&x,&f,ctx,&ierr);CHKERRQ(ierr); 73 return 0; 74 } 75 static PetscErrorCode oursnestest(SNES snes,PetscReal a,PetscReal d,PetscReal c,SNESConvergedReason*reason,void*ctx) 76 { 77 PetscErrorCode ierr = 0; 78 79 (*f8)(&snes,&a,&d,&c,reason,ctx,&ierr);CHKERRQ(ierr); 80 return 0; 81 } 82 83 static PetscErrorCode oursnesjacobian(SNES snes,Vec x,Mat* m,Mat* p,MatStructure* type,void*ctx) 84 { 85 PetscErrorCode ierr = 0; 86 (*f3)(&snes,&x,m,p,type,ctx,&ierr);CHKERRQ(ierr); 87 return 0; 88 } 89 static PetscErrorCode oursnesmonitor(SNES snes,PetscInt i,PetscReal d,void*ctx) 90 { 91 PetscErrorCode ierr = 0; 92 93 (*f7)(&snes,&i,&d,ctx,&ierr);CHKERRQ(ierr); 94 return 0; 95 } 96 static PetscErrorCode ourmondestroy(void* ctx) 97 { 98 PetscErrorCode ierr = 0; 99 100 (*f71)(ctx,&ierr);CHKERRQ(ierr); 101 return 0; 102 } 103 104 EXTERN_C_BEGIN 105 /* ---------------------------------------------------------*/ 106 /* 107 snesdefaultcomputejacobian() and snesdefaultcomputejacobiancolor() 108 These can be used directly from Fortran but are mostly so that 109 Fortran SNESSetJacobian() will properly handle the defaults being passed in. 110 111 functions, hence no STDCALL 112 */ 113 void snesdefaultcomputejacobian_(SNES *snes,Vec *x,Mat *m,Mat *p,MatStructure* type,void *ctx,PetscErrorCode *ierr) 114 { 115 *ierr = SNESDefaultComputeJacobian(*snes,*x,m,p,type,ctx); 116 } 117 void snesdefaultcomputejacobiancolor_(SNES *snes,Vec *x,Mat *m,Mat *p,MatStructure* type,void *ctx,PetscErrorCode *ierr) 118 { 119 *ierr = SNESDefaultComputeJacobianColor(*snes,*x,m,p,type,*(MatFDColoring*)ctx); 120 } 121 122 void snesdacomputejacobianwithadifor_(SNES *snes,Vec *X,Mat *m,Mat *p,MatStructure* type,void *ctx,PetscErrorCode *ierr) 123 { 124 (*PetscErrorPrintf)("Cannot call this function from Fortran"); 125 *ierr = 1; 126 } 127 128 void snesdacomputejacobian_(SNES *snes,Vec *X,Mat *m,Mat *p,MatStructure* type,void *ctx,PetscErrorCode *ierr) 129 { 130 (*PetscErrorPrintf)("Cannot call this function from Fortran"); 131 *ierr = 1; 132 } 133 134 void PETSC_STDCALL snessetjacobian_(SNES *snes,Mat *A,Mat *B,void (PETSC_STDCALL *func)(SNES*,Vec*,Mat*,Mat*, 135 MatStructure*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr) 136 { 137 CHKFORTRANNULLOBJECT(ctx); 138 if ((FCNVOID)func == (FCNVOID)snesdefaultcomputejacobian_) { 139 *ierr = SNESSetJacobian(*snes,*A,*B,SNESDefaultComputeJacobian,ctx); 140 } else if ((FCNVOID)func == (FCNVOID)snesdefaultcomputejacobiancolor_) { 141 *ierr = SNESSetJacobian(*snes,*A,*B,SNESDefaultComputeJacobianColor,*(MatFDColoring*)ctx); 142 } else if ((FCNVOID)func == (FCNVOID)snesdacomputejacobianwithadifor_) { 143 *ierr = SNESSetJacobian(*snes,*A,*B,SNESDAComputeJacobianWithAdifor,ctx); 144 } else if ((FCNVOID)func == (FCNVOID)snesdacomputejacobian_) { 145 *ierr = SNESSetJacobian(*snes,*A,*B,SNESDAComputeJacobian,ctx); 146 } else { 147 f3 = func; 148 *ierr = SNESSetJacobian(*snes,*A,*B,oursnesjacobian,ctx); 149 } 150 } 151 /* -------------------------------------------------------------*/ 152 153 void PETSC_STDCALL snesgetoptionsprefix_(SNES *snes,CHAR prefix PETSC_MIXED_LEN(len), 154 PetscErrorCode *ierr PETSC_END_LEN(len)) 155 { 156 const char *tname; 157 158 *ierr = SNESGetOptionsPrefix(*snes,&tname); 159 #if defined(PETSC_USES_CPTOFCD) 160 { 161 char *t = _fcdtocp(prefix); int len1 = _fcdlen(prefix); 162 *ierr = PetscStrncpy(t,tname,len1);if (*ierr) return; 163 } 164 #else 165 *ierr = PetscStrncpy(prefix,tname,len);if (*ierr) return; 166 #endif 167 } 168 169 void PETSC_STDCALL snesgettype_(SNES *snes,CHAR name PETSC_MIXED_LEN(len), 170 PetscErrorCode *ierr PETSC_END_LEN(len)) 171 { 172 const char *tname; 173 174 *ierr = SNESGetType(*snes,&tname); 175 #if defined(PETSC_USES_CPTOFCD) 176 { 177 char *t = _fcdtocp(name); int len1 = _fcdlen(name); 178 *ierr = PetscStrncpy(t,tname,len1);if (*ierr) return; 179 } 180 #else 181 *ierr = PetscStrncpy(name,tname,len);if (*ierr) return; 182 #endif 183 FIXRETURNCHAR(name,len); 184 } 185 /* ---------------------------------------------------------*/ 186 187 /* 188 These are not usually called from Fortran but allow Fortran users 189 to transparently set these monitors from .F code 190 191 functions, hence no STDCALL 192 */ 193 void snesdaformfunction_(SNES *snes,Vec *X, Vec *F,void *ptr,PetscErrorCode *ierr) 194 { 195 *ierr = SNESDAFormFunction(*snes,*X,*F,ptr); 196 } 197 198 void PETSC_STDCALL snessetfunction_(SNES *snes,Vec *r,void (PETSC_STDCALL *func)(SNES*,Vec*,Vec*,void*,PetscErrorCode*), 199 void *ctx,PetscErrorCode *ierr) 200 { 201 CHKFORTRANNULLOBJECT(ctx); 202 f2 = func; 203 if ((FCNVOID)func == (FCNVOID)snesdaformfunction_) { 204 *ierr = SNESSetFunction(*snes,*r,SNESDAFormFunction,ctx); 205 } else { 206 *ierr = SNESSetFunction(*snes,*r,oursnesfunction,ctx); 207 } 208 } 209 /* ---------------------------------------------------------*/ 210 211 /* the func argument is ignored */ 212 void PETSC_STDCALL snesgetfunction_(SNES *snes,Vec *r,void *func,void **ctx,PetscErrorCode *ierr) 213 { 214 CHKFORTRANNULLINTEGER(ctx); 215 CHKFORTRANNULLOBJECT(r); 216 *ierr = SNESGetFunction(*snes,r,PETSC_NULL,ctx); 217 } 218 /*----------------------------------------------------------------------*/ 219 220 void snesconverged_tr_(SNES *snes,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r, 221 void *ct,PetscErrorCode *ierr) 222 { 223 *ierr = SNESConverged_TR(*snes,*a,*b,*c,r,ct); 224 } 225 226 void snesconverged_ls_(SNES *snes,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r, 227 void *ct,PetscErrorCode *ierr) 228 { 229 *ierr = SNESConverged_LS(*snes,*a,*b,*c,r,ct); 230 } 231 232 233 void PETSC_STDCALL snessetconvergencetest_(SNES *snes, 234 void (PETSC_STDCALL *func)(SNES*,PetscReal*,PetscReal*,PetscReal*,SNESConvergedReason*,void*,PetscErrorCode*), 235 void *cctx,PetscErrorCode *ierr) 236 { 237 CHKFORTRANNULLOBJECT(cctx); 238 if ((FCNVOID)func == (FCNVOID)snesconverged_ls_){ 239 *ierr = SNESSetConvergenceTest(*snes,SNESConverged_LS,0); 240 } else if ((FCNVOID)func == (FCNVOID)snesconverged_tr_){ 241 *ierr = SNESSetConvergenceTest(*snes,SNESConverged_TR,0); 242 } else { 243 f8 = func; 244 *ierr = SNESSetConvergenceTest(*snes,oursnestest,cctx); 245 } 246 } 247 /*----------------------------------------------------------------------*/ 248 249 void PETSC_STDCALL snesview_(SNES *snes,PetscViewer *viewer, PetscErrorCode *ierr) 250 { 251 PetscViewer v; 252 PetscPatchDefaultViewers_Fortran(viewer,v); 253 *ierr = SNESView(*snes,v); 254 } 255 256 /* func is currently ignored from Fortran */ 257 void PETSC_STDCALL snesgetjacobian_(SNES *snes,Mat *A,Mat *B,int *func,void **ctx,PetscErrorCode *ierr) 258 { 259 CHKFORTRANNULLINTEGER(ctx); 260 CHKFORTRANNULLOBJECT(A); 261 CHKFORTRANNULLOBJECT(B); 262 *ierr = SNESGetJacobian(*snes,A,B,0,ctx); 263 } 264 265 void PETSC_STDCALL snesgetconvergencehistory_(SNES *snes,PetscInt *na,PetscErrorCode *ierr) 266 { 267 *ierr = SNESGetConvergenceHistory(*snes,PETSC_NULL,PETSC_NULL,na); 268 } 269 270 void PETSC_STDCALL snessettype_(SNES *snes,CHAR type PETSC_MIXED_LEN(len), 271 PetscErrorCode *ierr PETSC_END_LEN(len)) 272 { 273 char *t; 274 275 FIXCHAR(type,len,t); 276 *ierr = SNESSetType(*snes,t); 277 FREECHAR(type,t); 278 } 279 280 void PETSC_STDCALL snesappendoptionsprefix_(SNES *snes,CHAR prefix PETSC_MIXED_LEN(len), 281 PetscErrorCode *ierr PETSC_END_LEN(len)) 282 { 283 char *t; 284 285 FIXCHAR(prefix,len,t); 286 *ierr = SNESAppendOptionsPrefix(*snes,t); 287 FREECHAR(prefix,t); 288 } 289 290 void PETSC_STDCALL snessetoptionsprefix_(SNES *snes,CHAR prefix PETSC_MIXED_LEN(len), 291 PetscErrorCode *ierr PETSC_END_LEN(len)) 292 { 293 char *t; 294 295 FIXCHAR(prefix,len,t); 296 *ierr = SNESSetOptionsPrefix(*snes,t); 297 FREECHAR(prefix,t); 298 } 299 300 /*----------------------------------------------------------------------*/ 301 /* functions, hence no STDCALL */ 302 303 void sneslgmonitor_(SNES *snes,PetscInt *its,PetscReal *fgnorm,void *dummy,PetscErrorCode *ierr) 304 { 305 *ierr = SNESLGMonitor(*snes,*its,*fgnorm,dummy); 306 } 307 308 void snesdefaultmonitor_(SNES *snes,PetscInt *its,PetscReal *fgnorm,void *dummy,PetscErrorCode *ierr) 309 { 310 *ierr = SNESDefaultMonitor(*snes,*its,*fgnorm,dummy); 311 } 312 313 void snesvecviewmonitor_(SNES *snes,PetscInt *its,PetscReal *fgnorm,void *dummy,PetscErrorCode *ierr) 314 { 315 *ierr = SNESVecViewMonitor(*snes,*its,*fgnorm,dummy); 316 } 317 318 void snesvecviewupdatemonitor_(SNES *snes,PetscInt *its,PetscReal *fgnorm,void *dummy,PetscErrorCode *ierr) 319 { 320 *ierr = SNESVecViewUpdateMonitor(*snes,*its,*fgnorm,dummy); 321 } 322 323 324 void PETSC_STDCALL snessetmonitor_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,PetscInt*,PetscReal*,void*,PetscErrorCode*), 325 void *mctx,void (PETSC_STDCALL *mondestroy)(void*,PetscErrorCode*),PetscErrorCode *ierr) 326 { 327 CHKFORTRANNULLOBJECT(mctx); 328 if ((FCNVOID)func == (FCNVOID)snesdefaultmonitor_) { 329 *ierr = SNESSetMonitor(*snes,SNESDefaultMonitor,0,0); 330 } else if ((FCNVOID)func == (FCNVOID)snesvecviewmonitor_) { 331 *ierr = SNESSetMonitor(*snes,SNESVecViewMonitor,0,0); 332 } else if ((FCNVOID)func == (FCNVOID)snesvecviewupdatemonitor_) { 333 *ierr = SNESSetMonitor(*snes,SNESVecViewUpdateMonitor,0,0); 334 } else if ((FCNVOID)func == (FCNVOID)sneslgmonitor_) { 335 *ierr = SNESSetMonitor(*snes,SNESLGMonitor,0,0); 336 } else { 337 f7 = func; 338 if (FORTRANNULLFUNCTION(mondestroy)){ 339 *ierr = SNESSetMonitor(*snes,oursnesmonitor,mctx,0); 340 } else { 341 f71 = mondestroy; 342 *ierr = SNESSetMonitor(*snes,oursnesmonitor,mctx,ourmondestroy); 343 } 344 } 345 } 346 347 348 349 EXTERN_C_END 350