1 #include <petsc-private/fortranimpl.h> 2 #include <petscmat.h> 3 4 #if defined(PETSC_HAVE_FORTRAN_CAPS) 5 #define matdestroymatrices_ MATDESTROYMATRICES 6 #define matgetfactor_ MATGETFACTOR 7 #define matfactorgetsolverpackage_ MATFACTORGETSOLVERPACKAGE 8 #define matgetrowij_ MATGETROWIJ 9 #define matrestorerowij_ MATRESTOREROWIJ 10 #define matgetrow_ MATGETROW 11 #define matrestorerow_ MATRESTOREROW 12 #define matload_ MATLOAD 13 #define matview_ MATVIEW 14 #define matgetarray_ MATGETARRAY 15 #define matrestorearray_ MATRESTOREARRAY 16 #define matconvert_ MATCONVERT 17 #define matgetsubmatrices_ MATGETSUBMATRICES 18 #define matzerorowscolumns_ MATZEROROWSCOLUMNS 19 #define matzerorowscolumnsis_ MATZEROROWSCOLUMNSIS 20 #define matzerorowsstencil_ MATZEROROWSSTENCIL 21 #define matzerorowscolumnsstencil_ MATZEROROWSCOLUMNSSTENCIL 22 #define matzerorows_ MATZEROROWS 23 #define matzerorowsis_ MATZEROROWSIS 24 #define matzerorowslocal_ MATZEROROWSLOCAL 25 #define matzerorowslocalis_ MATZEROROWSLOCALIS 26 #define matzerorowscolumnslocal_ MATZEROROWSCOLUMNSLOCAL 27 #define matzerorowscolumnslocalis_ MATZEROROWSCOLUMNSLOCALIS 28 #define matsetoptionsprefix_ MATSETOPTIONSPREFIX 29 #define matgetvecs_ MATGETVECS 30 #define matnullspaceremove_ MATNULLSPACEREMOVE 31 #define matgetinfo_ MATGETINFO 32 #define matlufactor_ MATLUFACTOR 33 #define matilufactor_ MATILUFACTOR 34 #define matlufactorsymbolic_ MATLUFACTORSYMBOLIC 35 #define matlufactornumeric_ MATLUFACTORNUMERIC 36 #define matcholeskyfactor_ MATCHOLESKYFACTOR 37 #define matcholeskyfactorsymbolic_ MATCHOLESKYFACTORSYMBOLIC 38 #define matcholeskyfactornumeric_ MATCHOLESKYFACTORNUMERIC 39 #define matilufactorsymbolic_ MATILUFACTORSYMBOLIC 40 #define maticcfactorsymbolic_ MATICCFACTORSYMBOLIC 41 #define maticcfactor_ MATICCFACTOR 42 #define matfactorinfoinitialize_ MATFACTORINFOINITIALIZE 43 #define matnullspacesetfunction_ MATNULLSPACESETFUNCTION 44 #define matfindnonzerorows_ MATFINDNONZEROROWS 45 #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 46 #define matdestroymatrices_ matdestroymatrices_ 47 #define matgetfactor_ matgetfactor 48 #define matfactorgetsolverpackage_ matfactorgetsolverpackage 49 #define matgetvecs_ matgetvecs 50 #define matgetrowij_ matgetrowij 51 #define matrestorerowij_ matrestorerowij 52 #define matgetrow_ matgetrow 53 #define matrestorerow_ matrestorerow 54 #define matview_ matview 55 #define matload_ matload 56 #define matgetarray_ matgetarray 57 #define matrestorearray_ matrestorearray 58 #define matconvert_ matconvert 59 #define matgetsubmatrices_ matgetsubmatrices 60 #define matzerorowscolumns_ matzerorowscolumns 61 #define matzerorowscolumnsis_ matzerorowscolumnsis 62 #define matzerorowsstencil_ matzerorowsstencil 63 #define matzerorowscolumnsstencil_ matzerorowscolumnsstencil 64 #define matzerorows_ matzerorows 65 #define matzerorowsis_ matzerorowsis 66 #define matzerorowslocal_ matzerorowslocal 67 #define matzerorowslocalis_ matzerorowslocalis 68 #define matzerorowscolumnslocal_ matzerorowscolumnslocal 69 #define matzerorowscolumnslocalis_ matzerorowscolumnslocalis 70 #define matsetoptionsprefix_ matsetoptionsprefix 71 #define matnullspaceremove_ matnullspaceremove 72 #define matgetinfo_ matgetinfo 73 #define matlufactor_ matlufactor 74 #define matilufactor_ matilufactor 75 #define matlufactorsymbolic_ matlufactorsymbolic 76 #define matlufactornumeric_ matlufactornumeric 77 #define matcholeskyfactor_ matcholeskyfactor 78 #define matcholeskyfactorsymbolic_ matcholeskyfactorsymbolic 79 #define matcholeskyfactornumeric_ matcholeskyfactornumeric 80 #define matilufactorsymbolic_ matilufactorsymbolic 81 #define maticcfactorsymbolic_ maticcfactorsymbolic 82 #define maticcfactor_ maticcfactor 83 #define matfactorinfoinitialize_ matfactorinfoinitialize 84 #define matnullspacesetfunction_ matnullspacesetfunction 85 #define matfindnonzerorows_ matfindnonzerorows 86 #endif 87 88 EXTERN_C_BEGIN 89 90 static PetscErrorCode ournullfunction(MatNullSpace sp,Vec x,void *ctx) 91 { 92 PetscErrorCode ierr = 0; 93 (*(void (PETSC_STDCALL *)(MatNullSpace*,Vec*,void*,PetscErrorCode*))(((PetscObject)sp)->fortran_func_pointers[0]))(&sp,&x,ctx,&ierr);CHKERRQ(ierr); 94 return 0; 95 } 96 97 void PETSC_STDCALL matnullspacesetfunction_(MatNullSpace *sp, PetscErrorCode (*rem)(MatNullSpace,Vec,void*),void *ctx,PetscErrorCode *ierr) 98 { 99 PetscObjectAllocateFortranPointers(*sp,1); 100 ((PetscObject)*sp)->fortran_func_pointers[0] = (PetscVoidFunction)rem; 101 *ierr = MatNullSpaceSetFunction(*sp,ournullfunction,ctx); 102 } 103 104 void PETSC_STDCALL matgetvecs_(Mat *mat,Vec *right,Vec *left, int *ierr ) 105 { 106 CHKFORTRANNULLOBJECT(right); 107 CHKFORTRANNULLOBJECT(left); 108 *ierr = MatGetVecs(*mat,right,left); 109 } 110 111 void PETSC_STDCALL matgetrowij_(Mat *B,PetscInt *shift,PetscBool *sym,PetscBool *blockcompressed,PetscInt *n,PetscInt *ia,size_t *iia, 112 PetscInt *ja,size_t *jja,PetscBool *done,PetscErrorCode *ierr) 113 { 114 PetscInt *IA,*JA; 115 *ierr = MatGetRowIJ(*B,*shift,*sym,*blockcompressed,n,&IA,&JA,done);if (*ierr) return; 116 *iia = PetscIntAddressToFortran(ia,IA); 117 *jja = PetscIntAddressToFortran(ja,JA); 118 } 119 120 void PETSC_STDCALL matrestorerowij_(Mat *B,PetscInt *shift,PetscBool *sym,PetscBool *blockcompressed, PetscInt *n,PetscInt *ia,size_t *iia, 121 PetscInt *ja,size_t *jja,PetscBool *done,PetscErrorCode *ierr) 122 { 123 PetscInt *IA = PetscIntAddressFromFortran(ia,*iia),*JA = PetscIntAddressFromFortran(ja,*jja); 124 *ierr = MatRestoreRowIJ(*B,*shift,*sym,*blockcompressed,n,&IA,&JA,done); 125 } 126 127 /* 128 This is a poor way of storing the column and value pointers 129 generated by MatGetRow() to be returned with MatRestoreRow() 130 but there is not natural,good place else to store them. Hence 131 Fortran programmers can only have one outstanding MatGetRows() 132 at a time. 133 */ 134 static PetscErrorCode matgetrowactive = 0; 135 static const PetscInt *my_ocols = 0; 136 static const PetscScalar *my_ovals = 0; 137 138 void PETSC_STDCALL matgetrow_(Mat *mat,PetscInt *row,PetscInt *ncols,PetscInt *cols,PetscScalar *vals,PetscErrorCode *ierr) 139 { 140 const PetscInt **oocols = &my_ocols; 141 const PetscScalar **oovals = &my_ovals; 142 143 if (matgetrowactive) { 144 PetscError(PETSC_COMM_SELF,__LINE__,"MatGetRow_Fortran",__FILE__,__SDIR__,PETSC_ERR_ARG_WRONGSTATE,PETSC_ERROR_INITIAL, 145 "Cannot have two MatGetRow() active simultaneously\n\ 146 call MatRestoreRow() before calling MatGetRow() a second time"); 147 *ierr = 1; 148 return; 149 } 150 151 CHKFORTRANNULLINTEGER(cols); if (!cols) oocols = PETSC_NULL; 152 CHKFORTRANNULLSCALAR(vals); if (!vals) oovals = PETSC_NULL; 153 154 *ierr = MatGetRow(*mat,*row,ncols,oocols,oovals); 155 if (*ierr) return; 156 157 if (oocols) { *ierr = PetscMemcpy(cols,my_ocols,(*ncols)*sizeof(PetscInt)); if (*ierr) return;} 158 if (oovals) { *ierr = PetscMemcpy(vals,my_ovals,(*ncols)*sizeof(PetscScalar)); if (*ierr) return; } 159 matgetrowactive = 1; 160 } 161 162 void PETSC_STDCALL matrestorerow_(Mat *mat,PetscInt *row,PetscInt *ncols,PetscInt *cols,PetscScalar *vals,PetscErrorCode *ierr) 163 { 164 const PetscInt **oocols = &my_ocols; 165 const PetscScalar **oovals = &my_ovals; 166 if (!matgetrowactive) { 167 PetscError(PETSC_COMM_SELF,__LINE__,"MatRestoreRow_Fortran",__FILE__,__SDIR__,PETSC_ERR_ARG_WRONGSTATE,PETSC_ERROR_INITIAL, 168 "Must call MatGetRow() first"); 169 *ierr = 1; 170 return; 171 } 172 CHKFORTRANNULLINTEGER(cols); if (!cols) oocols = PETSC_NULL; 173 CHKFORTRANNULLSCALAR(vals); if (!vals) oovals = PETSC_NULL; 174 175 *ierr = MatRestoreRow(*mat,*row,ncols,oocols,oovals); 176 matgetrowactive = 0; 177 } 178 179 void PETSC_STDCALL matview_(Mat *mat,PetscViewer *vin,PetscErrorCode *ierr) 180 { 181 PetscViewer v; 182 PetscPatchDefaultViewers_Fortran(vin,v); 183 *ierr = MatView(*mat,v); 184 } 185 186 void PETSC_STDCALL matload_(Mat *mat,PetscViewer *vin,PetscErrorCode *ierr) 187 { 188 PetscViewer v; 189 PetscPatchDefaultViewers_Fortran(vin,v); 190 *ierr = MatLoad(*mat,v); 191 } 192 193 void PETSC_STDCALL matgetarray_(Mat *mat,PetscScalar *fa,size_t *ia,PetscErrorCode *ierr) 194 { 195 PetscScalar *mm; 196 PetscInt m,n; 197 198 *ierr = MatGetArray(*mat,&mm); if (*ierr) return; 199 *ierr = MatGetSize(*mat,&m,&n); if (*ierr) return; 200 *ierr = PetscScalarAddressToFortran((PetscObject)*mat,1,fa,mm,m*n,ia); if (*ierr) return; 201 } 202 203 void PETSC_STDCALL matrestorearray_(Mat *mat,PetscScalar *fa,size_t *ia,PetscErrorCode *ierr) 204 { 205 PetscScalar *lx; 206 PetscInt m,n; 207 208 *ierr = MatGetSize(*mat,&m,&n); if (*ierr) return; 209 *ierr = PetscScalarAddressFromFortran((PetscObject)*mat,fa,*ia,m*n,&lx);if (*ierr) return; 210 *ierr = MatRestoreArray(*mat,&lx);if (*ierr) return; 211 } 212 213 void PETSC_STDCALL matfactorgetsolverpackage_(Mat *mat,CHAR name PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) 214 { 215 const char *tname; 216 217 *ierr = MatFactorGetSolverPackage(*mat,&tname);if (*ierr) return; 218 if (name != PETSC_NULL_CHARACTER_Fortran) { 219 *ierr = PetscStrncpy(name,tname,len);if (*ierr) return; 220 } 221 FIXRETURNCHAR(PETSC_TRUE,name,len); 222 } 223 224 void PETSC_STDCALL matgetfactor_(Mat *mat,CHAR outtype PETSC_MIXED_LEN(len),MatFactorType *ftype,Mat *M,PetscErrorCode *ierr PETSC_END_LEN(len)) 225 { 226 char *t; 227 FIXCHAR(outtype,len,t); 228 *ierr = MatGetFactor(*mat,t,*ftype,M); 229 FREECHAR(outtype,t); 230 } 231 232 void PETSC_STDCALL matconvert_(Mat *mat,CHAR outtype PETSC_MIXED_LEN(len),MatReuse *reuse,Mat *M,PetscErrorCode *ierr PETSC_END_LEN(len)) 233 { 234 char *t; 235 FIXCHAR(outtype,len,t); 236 *ierr = MatConvert(*mat,t,*reuse,M); 237 FREECHAR(outtype,t); 238 } 239 240 /* 241 MatGetSubmatrices() is slightly different from C since the 242 Fortran provides the array to hold the submatrix objects,while in C that 243 array is allocated by the MatGetSubmatrices() 244 */ 245 void PETSC_STDCALL matgetsubmatrices_(Mat *mat,PetscInt *n,IS *isrow,IS *iscol,MatReuse *scall,Mat *smat,PetscErrorCode *ierr) 246 { 247 Mat *lsmat; 248 PetscInt i; 249 250 if (*scall == MAT_INITIAL_MATRIX) { 251 *ierr = MatGetSubMatrices(*mat,*n,isrow,iscol,*scall,&lsmat); 252 for (i=0; i<*n; i++) { 253 smat[i] = lsmat[i]; 254 } 255 *ierr = PetscFree(lsmat); 256 } else { 257 *ierr = MatGetSubMatrices(*mat,*n,isrow,iscol,*scall,&smat); 258 } 259 } 260 261 /* 262 MatDestroyMatrices() is slightly different from C since the 263 Fortran provides the array to hold the submatrix objects,while in C that 264 array is allocated by the MatGetSubmatrices() 265 */ 266 void PETSC_STDCALL matdestroymatrices_(Mat *mat,PetscInt *n,Mat *smat,PetscErrorCode *ierr) 267 { 268 PetscInt i; 269 270 for (i=0; i<*n; i++) { 271 *ierr = MatDestroy(&smat[i]);if (*ierr) return; 272 } 273 } 274 275 void PETSC_STDCALL matzerorowscolumns_(Mat *mat,PetscInt *numRows,PetscInt *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 276 { 277 CHKFORTRANNULLOBJECTDEREFERENCE(x); 278 CHKFORTRANNULLOBJECTDEREFERENCE(b); 279 *ierr = MatZeroRowsColumns(*mat,*numRows,rows,*diag,*x,*b); 280 } 281 282 void PETSC_STDCALL matzerorowscolumnsis_(Mat *mat,IS *is,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 283 { 284 CHKFORTRANNULLOBJECTDEREFERENCE(x); 285 CHKFORTRANNULLOBJECTDEREFERENCE(b); 286 *ierr = MatZeroRowsColumnsIS(*mat,*is,*diag,*x,*b); 287 } 288 289 void PETSC_STDCALL matzerorowsstencil_(Mat *mat,PetscInt *numRows,MatStencil *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 290 { 291 CHKFORTRANNULLOBJECTDEREFERENCE(x); 292 CHKFORTRANNULLOBJECTDEREFERENCE(b); 293 *ierr = MatZeroRowsStencil(*mat,*numRows,rows,*diag,*x,*b); 294 } 295 296 void PETSC_STDCALL matzerorowscolumnsstencil_(Mat *mat,PetscInt *numRows,MatStencil *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 297 { 298 CHKFORTRANNULLOBJECTDEREFERENCE(x); 299 CHKFORTRANNULLOBJECTDEREFERENCE(b); 300 *ierr = MatZeroRowsColumnsStencil(*mat,*numRows,rows,*diag,*x,*b); 301 } 302 303 void PETSC_STDCALL matzerorows_(Mat *mat,PetscInt *numRows,PetscInt *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 304 { 305 CHKFORTRANNULLOBJECTDEREFERENCE(x); 306 CHKFORTRANNULLOBJECTDEREFERENCE(b); 307 *ierr = MatZeroRows(*mat,*numRows,rows,*diag,*x,*b); 308 } 309 310 void PETSC_STDCALL matzerorowsis_(Mat *mat,IS *is,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 311 { 312 CHKFORTRANNULLOBJECTDEREFERENCE(x); 313 CHKFORTRANNULLOBJECTDEREFERENCE(b); 314 *ierr = MatZeroRowsIS(*mat,*is,*diag,*x,*b); 315 } 316 317 void PETSC_STDCALL matzerorowslocal_(Mat *mat,PetscInt *numRows,PetscInt *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 318 { 319 CHKFORTRANNULLOBJECTDEREFERENCE(x); 320 CHKFORTRANNULLOBJECTDEREFERENCE(b); 321 *ierr = MatZeroRowsLocal(*mat,*numRows,rows,*diag,*x,*b); 322 } 323 324 void PETSC_STDCALL matzerorowslocalis_(Mat *mat,IS *is,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 325 { 326 CHKFORTRANNULLOBJECTDEREFERENCE(x); 327 CHKFORTRANNULLOBJECTDEREFERENCE(b); 328 *ierr = MatZeroRowsLocalIS(*mat,*is,*diag,*x,*b); 329 } 330 331 void PETSC_STDCALL matzerorowscolumnslocal_(Mat *mat,PetscInt *numRows,PetscInt *rows,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 332 { 333 CHKFORTRANNULLOBJECTDEREFERENCE(x); 334 CHKFORTRANNULLOBJECTDEREFERENCE(b); 335 *ierr = MatZeroRowsColumnsLocal(*mat,*numRows,rows,*diag,*x,*b); 336 } 337 338 void PETSC_STDCALL matzerorowscolumnslocalis_(Mat *mat,IS *is,PetscScalar *diag,Vec *x,Vec *b,PetscErrorCode *ierr) 339 { 340 CHKFORTRANNULLOBJECTDEREFERENCE(x); 341 CHKFORTRANNULLOBJECTDEREFERENCE(b); 342 *ierr = MatZeroRowsColumnsLocalIS(*mat,*is,*diag,*x,*b); 343 } 344 345 void PETSC_STDCALL matsetoptionsprefix_(Mat *mat,CHAR prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) 346 { 347 char *t; 348 349 FIXCHAR(prefix,len,t); 350 *ierr = MatSetOptionsPrefix(*mat,t); 351 FREECHAR(prefix,t); 352 } 353 354 void PETSC_STDCALL matnullspaceremove_(MatNullSpace *sp,Vec *vec,Vec *out,PetscErrorCode *ierr) 355 { 356 CHKFORTRANNULLOBJECT(out); 357 *ierr = MatNullSpaceRemove(*sp,*vec,out); 358 } 359 360 void PETSC_STDCALL matgetinfo_(Mat *mat,MatInfoType *flag,MatInfo *info, int *__ierr ) 361 { 362 *__ierr = MatGetInfo(*mat,*flag,info); 363 } 364 365 void PETSC_STDCALL matlufactor_(Mat *mat,IS *row,IS *col, MatFactorInfo *info, int *__ierr ) 366 { 367 *__ierr = MatLUFactor(*mat,*row,*col,info); 368 } 369 370 void PETSC_STDCALL matilufactor_(Mat *mat,IS *row,IS *col, MatFactorInfo *info, int *__ierr ) 371 { 372 *__ierr = MatILUFactor(*mat,*row,*col,info); 373 } 374 375 void PETSC_STDCALL matlufactorsymbolic_(Mat *fact,Mat *mat,IS *row,IS *col, MatFactorInfo *info, int *__ierr ) 376 { 377 *__ierr = MatLUFactorSymbolic(*fact,*mat,*row,*col,info); 378 } 379 380 void PETSC_STDCALL matlufactornumeric_(Mat *fact,Mat *mat, MatFactorInfo *info, int *__ierr ) 381 { 382 *__ierr = MatLUFactorNumeric(*fact,*mat,info); 383 } 384 385 void PETSC_STDCALL matcholeskyfactor_(Mat *mat,IS *perm, MatFactorInfo *info, int *__ierr ) 386 { 387 *__ierr = MatCholeskyFactor(*mat,*perm,info); 388 } 389 390 void PETSC_STDCALL matcholeskyfactorsymbolic_(Mat *fact,Mat *mat,IS *perm, MatFactorInfo *info, int *__ierr ) 391 { 392 *__ierr = MatCholeskyFactorSymbolic(*fact,*mat,*perm,info); 393 } 394 395 void PETSC_STDCALL matcholeskyfactornumeric_(Mat *fact,Mat *mat, MatFactorInfo *info, int *__ierr ) 396 { 397 *__ierr = MatCholeskyFactorNumeric(*fact,*mat,info); 398 } 399 400 void PETSC_STDCALL matilufactorsymbolic_(Mat *fact,Mat *mat,IS *row,IS *col, MatFactorInfo *info, int *__ierr ) 401 { 402 *__ierr = MatILUFactorSymbolic(*fact,*mat,*row,*col,info); 403 } 404 405 void PETSC_STDCALL maticcfactorsymbolic_(Mat *fact,Mat *mat,IS *perm, MatFactorInfo *info, int *__ierr ) 406 { 407 *__ierr = MatICCFactorSymbolic(*fact,*mat,*perm,info); 408 } 409 410 void PETSC_STDCALL maticcfactor_(Mat *mat,IS *row, MatFactorInfo* info, int *__ierr ) 411 { 412 *__ierr = MatICCFactor(*mat,*row,info); 413 } 414 415 void PETSC_STDCALL matfactorinfoinitialize_(MatFactorInfo *info, int *__ierr ) 416 { 417 *__ierr = MatFactorInfoInitialize(info); 418 } 419 420 EXTERN_C_END 421