Actual source code: petscmath.h

  1: /*
  2:     PETSc mathematics include file. Defines certain basic mathematical
  3:     constants and functions for working with single, double, and quad precision
  4:     floating point numbers as well as complex single and double.

  6:     This file is included by petscsys.h and should not be used directly.
  7: */
  8: #pragma once

 10: #include <math.h>
 11: #include <petscmacros.h>
 12: #include <petscsystypes.h>

 14: /* SUBMANSEC = Sys */

 16: /*
 17:    Defines operations that are different for complex and real numbers.
 18:    All PETSc objects in one program are built around the object
 19:    PetscScalar which is either always a real or a complex.
 20: */

 22: /*
 23:     Real number definitions
 24:  */
 25: #if defined(PETSC_USE_REAL_SINGLE)
 26:   /*MC
 27:     PetscSqrtReal - Returns the square root of a `PetscReal` value

 29:     Synopsis:
 30: #include <petscmath.h>
 31:     PetscReal PetscSqrtReal(PetscReal a)

 33:     Not Collective; No Fortran Support

 35:     Input Parameter:
 36:   . a - the value

 38:     Level: beginner

 40: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtComplex()`, `PetscSqrtScalar()`
 41:   M*/
 42:   #define PetscSqrtReal(a) sqrtf(a)
 43:   /*MC
 44:     PetscCbrtReal - Returns the cube root of a `PetscReal` value

 46:     Synopsis:
 47: #include <petscmath.h>
 48:     PetscReal PetscCbrtReal(PetscReal a)

 50:     Not Collective; No Fortran Support

 52:     Input Parameter:
 53:   . a - the value

 55:     Level: beginner

 57: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 58:   M*/
 59:   #define PetscCbrtReal(a) cbrtf(a)
 60:   /*MC
 61:     PetscHypotReal - Returns the Euclidean distance `sqrt(a*a + b*b)` of two `PetscReal` values, without intermediate overflow

 63:     Synopsis:
 64: #include <petscmath.h>
 65:     PetscReal PetscHypotReal(PetscReal a, PetscReal b)

 67:     Not Collective; No Fortran Support

 69:     Input Parameters:
 70:   + a - the value
 71:   - b - the value

 73:     Level: beginner

 75: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 76:   M*/
 77:   #define PetscHypotReal(a, b) hypotf(a, b)
 78:   /*MC
 79:     PetscAtan2Real - Returns the arc tangent of `a/b`, in the range $[-\pi, \pi]$, using the signs of `a` and `b` to select the quadrant

 81:     Synopsis:
 82: #include <petscmath.h>
 83:     PetscReal PetscAtan2Real(PetscReal a, PetscReal b)

 85:     Not Collective; No Fortran Support

 87:     Input Parameters:
 88:   + a - the value
 89:   - b - the value

 91:     Level: beginner

 93: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
 94:   M*/
 95:   #define PetscAtan2Real(a, b) atan2f(a, b)
 96:   /*MC
 97:     PetscPowReal - Returns the value of `a` raised to the power `b`, both `PetscReal`

 99:     Synopsis:
100: #include <petscmath.h>
101:     PetscReal PetscPowReal(PetscReal a, PetscReal b)

103:     Not Collective; No Fortran Support

105:     Input Parameters:
106:   + a - the value
107:   - b - the value

109:     Level: beginner

111: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowComplex()`, `PetscPowScalar()`
112:   M*/
113:   #define PetscPowReal(a, b) powf(a, b)
114:   /*MC
115:     PetscExpReal - Returns the natural exponential $e^a$ of a `PetscReal` value

117:     Synopsis:
118: #include <petscmath.h>
119:     PetscReal PetscExpReal(PetscReal a)

121:     Not Collective; No Fortran Support

123:     Input Parameter:
124:   . a - the value

126:     Level: beginner

128: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpComplex()`, `PetscExpScalar()`
129:   M*/
130:   #define PetscExpReal(a) expf(a)
131:   /*MC
132:     PetscLogReal - Returns the natural logarithm of a `PetscReal` value

134:     Synopsis:
135: #include <petscmath.h>
136:     PetscReal PetscLogReal(PetscReal a)

138:     Not Collective; No Fortran Support

140:     Input Parameter:
141:   . a - the value

143:     Level: beginner

145: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogComplex()`, `PetscLogScalar()`
146:   M*/
147:   #define PetscLogReal(a) logf(a)
148:   /*MC
149:     PetscLog10Real - Returns the base-10 logarithm of a `PetscReal` value

151:     Synopsis:
152: #include <petscmath.h>
153:     PetscReal PetscLog10Real(PetscReal a)

155:     Not Collective; No Fortran Support

157:     Input Parameter:
158:   . a - the value

160:     Level: beginner

162: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
163:   M*/
164:   #define PetscLog10Real(a) log10f(a)
165:   /*MC
166:     PetscLog2Real - Returns the base-2 logarithm of a `PetscReal` value

168:     Synopsis:
169: #include <petscmath.h>
170:     PetscReal PetscLog2Real(PetscReal a)

172:     Not Collective; No Fortran Support

174:     Input Parameter:
175:   . a - the value

177:     Level: beginner

179: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
180:   M*/
181:   #define PetscLog2Real(a) log2f(a)
182:   /*MC
183:     PetscSinReal - Returns the sine of a `PetscReal` value, with argument in radians

185:     Synopsis:
186: #include <petscmath.h>
187:     PetscReal PetscSinReal(PetscReal a)

189:     Not Collective; No Fortran Support

191:     Input Parameter:
192:   . a - the value

194:     Level: beginner

196: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinComplex()`, `PetscSinScalar()`
197:   M*/
198:   #define PetscSinReal(a) sinf(a)
199:   /*MC
200:     PetscCosReal - Returns the cosine of a `PetscReal` value, with argument in radians

202:     Synopsis:
203: #include <petscmath.h>
204:     PetscReal PetscCosReal(PetscReal a)

206:     Not Collective; No Fortran Support

208:     Input Parameter:
209:   . a - the value

211:     Level: beginner

213: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosComplex()`, `PetscCosScalar()`
214:   M*/
215:   #define PetscCosReal(a) cosf(a)
216:   /*MC
217:     PetscTanReal - Returns the tangent of a `PetscReal` value, with argument in radians

219:     Synopsis:
220: #include <petscmath.h>
221:     PetscReal PetscTanReal(PetscReal a)

223:     Not Collective; No Fortran Support

225:     Input Parameter:
226:   . a - the value

228:     Level: beginner

230: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanComplex()`, `PetscTanScalar()`
231:   M*/
232:   #define PetscTanReal(a) tanf(a)
233:   /*MC
234:     PetscAsinReal - Returns the arc sine of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

236:     Synopsis:
237: #include <petscmath.h>
238:     PetscReal PetscAsinReal(PetscReal a)

240:     Not Collective; No Fortran Support

242:     Input Parameter:
243:   . a - the value

245:     Level: beginner

247: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinComplex()`, `PetscAsinScalar()`
248:   M*/
249:   #define PetscAsinReal(a) asinf(a)
250:   /*MC
251:     PetscAcosReal - Returns the arc cosine of a `PetscReal` value, returned in radians in the range $[0, \pi]$

253:     Synopsis:
254: #include <petscmath.h>
255:     PetscReal PetscAcosReal(PetscReal a)

257:     Not Collective; No Fortran Support

259:     Input Parameter:
260:   . a - the value

262:     Level: beginner

264: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosComplex()`, `PetscAcosScalar()`
265:   M*/
266:   #define PetscAcosReal(a) acosf(a)
267:   /*MC
268:     PetscAtanReal - Returns the arc tangent of a `PetscReal` value, returned in radians in the range $[-\pi/2, \pi/2]$

270:     Synopsis:
271: #include <petscmath.h>
272:     PetscReal PetscAtanReal(PetscReal a)

274:     Not Collective; No Fortran Support

276:     Input Parameter:
277:   . a - the value

279:     Level: beginner

281: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanComplex()`, `PetscAtanScalar()`
282:   M*/
283:   #define PetscAtanReal(a) atanf(a)
284:   /*MC
285:     PetscSinhReal - Returns the hyperbolic sine of a `PetscReal` value

287:     Synopsis:
288: #include <petscmath.h>
289:     PetscReal PetscSinhReal(PetscReal a)

291:     Not Collective; No Fortran Support

293:     Input Parameter:
294:   . a - the value

296:     Level: beginner

298: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhComplex()`, `PetscSinhScalar()`
299:   M*/
300:   #define PetscSinhReal(a) sinhf(a)
301:   /*MC
302:     PetscCoshReal - Returns the hyperbolic cosine of a `PetscReal` value

304:     Synopsis:
305: #include <petscmath.h>
306:     PetscReal PetscCoshReal(PetscReal a)

308:     Not Collective; No Fortran Support

310:     Input Parameter:
311:   . a - the value

313:     Level: beginner

315: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshComplex()`, `PetscCoshScalar()`
316:   M*/
317:   #define PetscCoshReal(a) coshf(a)
318:   /*MC
319:     PetscTanhReal - Returns the hyperbolic tangent of a `PetscReal` value

321:     Synopsis:
322: #include <petscmath.h>
323:     PetscReal PetscTanhReal(PetscReal a)

325:     Not Collective; No Fortran Support

327:     Input Parameter:
328:   . a - the value

330:     Level: beginner

332: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhComplex()`, `PetscTanhScalar()`
333:   M*/
334:   #define PetscTanhReal(a) tanhf(a)
335:   /*MC
336:     PetscAsinhReal - Returns the inverse hyperbolic sine of a `PetscReal` value

338:     Synopsis:
339: #include <petscmath.h>
340:     PetscReal PetscAsinhReal(PetscReal a)

342:     Not Collective; No Fortran Support

344:     Input Parameter:
345:   . a - the value

347:     Level: beginner

349: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhComplex()`, `PetscAsinhScalar()`
350:   M*/
351:   #define PetscAsinhReal(a) asinhf(a)
352:   /*MC
353:     PetscAcoshReal - Returns the inverse hyperbolic cosine of a `PetscReal` value

355:     Synopsis:
356: #include <petscmath.h>
357:     PetscReal PetscAcoshReal(PetscReal a)

359:     Not Collective; No Fortran Support

361:     Input Parameter:
362:   . a - the value

364:     Level: beginner

366: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshComplex()`, `PetscAcoshScalar()`
367:   M*/
368:   #define PetscAcoshReal(a) acoshf(a)
369:   /*MC
370:     PetscAtanhReal - Returns the inverse hyperbolic tangent of a `PetscReal` value

372:     Synopsis:
373: #include <petscmath.h>
374:     PetscReal PetscAtanhReal(PetscReal a)

376:     Not Collective; No Fortran Support

378:     Input Parameter:
379:   . a - the value

381:     Level: beginner

383: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhComplex()`, `PetscAtanhScalar()`
384:   M*/
385:   #define PetscAtanhReal(a) atanhf(a)
386:   /*MC
387:     PetscErfReal - Returns the error function of a `PetscReal` value

389:     Synopsis:
390: #include <petscmath.h>
391:     PetscReal PetscErfReal(PetscReal a)

393:     Not Collective; No Fortran Support

395:     Input Parameter:
396:   . a - the value

398:     Level: beginner

400: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
401:   M*/
402:   #define PetscErfReal(a) erff(a)
403:   /*MC
404:     PetscCeilReal - Returns the smallest integer value, returned as a `PetscReal`, that is not less than `a`

406:     Synopsis:
407: #include <petscmath.h>
408:     PetscReal PetscCeilReal(PetscReal a)

410:     Not Collective; No Fortran Support

412:     Input Parameter:
413:   . a - the value

415:     Level: beginner

417: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
418:   M*/
419:   #define PetscCeilReal(a) ceilf(a)
420:   /*MC
421:     PetscFloorReal - Returns the largest integer value, returned as a `PetscReal`, that is not greater than `a`

423:     Synopsis:
424: #include <petscmath.h>
425:     PetscReal PetscFloorReal(PetscReal a)

427:     Not Collective; No Fortran Support

429:     Input Parameter:
430:   . a - the value

432:     Level: beginner

434: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
435:   M*/
436:   #define PetscFloorReal(a) floorf(a)
437:   /*MC
438:     PetscRintReal - Returns the value of `a` rounded to the nearest integer, returned as a `PetscReal` in the configured precision

440:     Synopsis:
441: #include <petscmath.h>
442:     PetscReal PetscRintReal(PetscReal a)

444:     Not Collective; No Fortran Support

446:     Input Parameter:
447:   . a - the value

449:     Level: beginner

451: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
452:   M*/
453:   #define PetscRintReal(a) rintf(a)
454:   /*MC
455:     PetscFmodReal - Returns the floating-point remainder of `a/b`, with the same sign as `a`, returned as a `PetscReal`

457:     Synopsis:
458: #include <petscmath.h>
459:     PetscReal PetscFmodReal(PetscReal a, PetscReal b)

461:     Not Collective; No Fortran Support

463:     Input Parameters:
464:   + a - the value
465:   - b - the value

467:     Level: beginner

469: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
470:   M*/
471:   #define PetscFmodReal(a, b) fmodf(a, b)
472:   /*MC
473:     PetscCopysignReal - Returns the value with the magnitude of `a` and the sign of `b`, as a `PetscReal`

475:     Synopsis:
476: #include <petscmath.h>
477:     PetscReal PetscCopysignReal(PetscReal a, PetscReal b)

479:     Not Collective; No Fortran Support

481:     Input Parameters:
482:   + a - the value
483:   - b - the value

485:     Level: beginner

487: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
488:   M*/
489:   #define PetscCopysignReal(a, b) copysignf(a, b)
490:   /*MC
491:     PetscTGamma - Returns the value of the gamma function $\Gamma(a)$ in the configured `PetscReal` precision

493:     Synopsis:
494: #include <petscmath.h>
495:     PetscReal PetscTGamma(PetscReal a)

497:     Not Collective; No Fortran Support

499:     Input Parameter:
500:   . a - the value

502:     Level: beginner

504: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
505:   M*/
506:   #define PetscTGamma(a) tgammaf(a)
507:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
508:     /*MC
509:       PetscLGamma - Returns the natural logarithm of the absolute value of the gamma function in the configured `PetscReal` precision

511:       Synopsis:
512: #include <petscmath.h>
513:       PetscReal PetscLGamma(PetscReal a)

515:       Not Collective; No Fortran Support

517:       Input Parameter:
518:     . a - the value

520:       Level: beginner

522: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
523:     M*/
524:     #define PetscLGamma(a) gammaf(a)
525:   #else
526:     #define PetscLGamma(a) lgammaf(a)
527:   #endif

529: #elif defined(PETSC_USE_REAL_DOUBLE)
530:   #define PetscSqrtReal(a)        sqrt(a)
531:   #define PetscCbrtReal(a)        cbrt(a)
532:   #define PetscHypotReal(a, b)    hypot(a, b)
533:   #define PetscAtan2Real(a, b)    atan2(a, b)
534:   #define PetscPowReal(a, b)      pow(a, b)
535:   #define PetscExpReal(a)         exp(a)
536:   #define PetscLogReal(a)         log(a)
537:   #define PetscLog10Real(a)       log10(a)
538:   #define PetscLog2Real(a)        log2(a)
539:   #define PetscSinReal(a)         sin(a)
540:   #define PetscCosReal(a)         cos(a)
541:   #define PetscTanReal(a)         tan(a)
542:   #define PetscAsinReal(a)        asin(a)
543:   #define PetscAcosReal(a)        acos(a)
544:   #define PetscAtanReal(a)        atan(a)
545:   #define PetscSinhReal(a)        sinh(a)
546:   #define PetscCoshReal(a)        cosh(a)
547:   #define PetscTanhReal(a)        tanh(a)
548:   #define PetscAsinhReal(a)       asinh(a)
549:   #define PetscAcoshReal(a)       acosh(a)
550:   #define PetscAtanhReal(a)       atanh(a)
551:   #define PetscErfReal(a)         erf(a)
552:   #define PetscCeilReal(a)        ceil(a)
553:   #define PetscFloorReal(a)       floor(a)
554:   #define PetscRintReal(a)        rint(a)
555:   #define PetscFmodReal(a, b)     fmod(a, b)
556:   #define PetscCopysignReal(a, b) copysign(a, b)
557:   #define PetscTGamma(a)          tgamma(a)
558:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
559:     #define PetscLGamma(a) gamma(a)
560:   #else
561:     #define PetscLGamma(a) lgamma(a)
562:   #endif

564: #elif defined(PETSC_USE_REAL___FLOAT128)
565:   #define PetscSqrtReal(a)        sqrtq(a)
566:   #define PetscCbrtReal(a)        cbrtq(a)
567:   #define PetscHypotReal(a, b)    hypotq(a, b)
568:   #define PetscAtan2Real(a, b)    atan2q(a, b)
569:   #define PetscPowReal(a, b)      powq(a, b)
570:   #define PetscExpReal(a)         expq(a)
571:   #define PetscLogReal(a)         logq(a)
572:   #define PetscLog10Real(a)       log10q(a)
573:   #define PetscLog2Real(a)        log2q(a)
574:   #define PetscSinReal(a)         sinq(a)
575:   #define PetscCosReal(a)         cosq(a)
576:   #define PetscTanReal(a)         tanq(a)
577:   #define PetscAsinReal(a)        asinq(a)
578:   #define PetscAcosReal(a)        acosq(a)
579:   #define PetscAtanReal(a)        atanq(a)
580:   #define PetscSinhReal(a)        sinhq(a)
581:   #define PetscCoshReal(a)        coshq(a)
582:   #define PetscTanhReal(a)        tanhq(a)
583:   #define PetscAsinhReal(a)       asinhq(a)
584:   #define PetscAcoshReal(a)       acoshq(a)
585:   #define PetscAtanhReal(a)       atanhq(a)
586:   #define PetscErfReal(a)         erfq(a)
587:   #define PetscCeilReal(a)        ceilq(a)
588:   #define PetscFloorReal(a)       floorq(a)
589:   #define PetscRintReal(a)        rintq(a)
590:   #define PetscFmodReal(a, b)     fmodq(a, b)
591:   #define PetscCopysignReal(a, b) copysignq(a, b)
592:   #define PetscTGamma(a)          tgammaq(a)
593:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
594:     #define PetscLGamma(a) gammaq(a)
595:   #else
596:     #define PetscLGamma(a) lgammaq(a)
597:   #endif

599: #elif defined(PETSC_USE_REAL___FP16)
600:   #define PetscSqrtReal(a)        sqrtf(a)
601:   #define PetscCbrtReal(a)        cbrtf(a)
602:   #define PetscHypotReal(a, b)    hypotf(a, b)
603:   #define PetscAtan2Real(a, b)    atan2f(a, b)
604:   #define PetscPowReal(a, b)      powf(a, b)
605:   #define PetscExpReal(a)         expf(a)
606:   #define PetscLogReal(a)         logf(a)
607:   #define PetscLog10Real(a)       log10f(a)
608:   #define PetscLog2Real(a)        log2f(a)
609:   #define PetscSinReal(a)         sinf(a)
610:   #define PetscCosReal(a)         cosf(a)
611:   #define PetscTanReal(a)         tanf(a)
612:   #define PetscAsinReal(a)        asinf(a)
613:   #define PetscAcosReal(a)        acosf(a)
614:   #define PetscAtanReal(a)        atanf(a)
615:   #define PetscSinhReal(a)        sinhf(a)
616:   #define PetscCoshReal(a)        coshf(a)
617:   #define PetscTanhReal(a)        tanhf(a)
618:   #define PetscAsinhReal(a)       asinhf(a)
619:   #define PetscAcoshReal(a)       acoshf(a)
620:   #define PetscAtanhReal(a)       atanhf(a)
621:   #define PetscErfReal(a)         erff(a)
622:   #define PetscCeilReal(a)        ceilf(a)
623:   #define PetscFloorReal(a)       floorf(a)
624:   #define PetscRintReal(a)        rintf(a)
625:   #define PetscFmodReal(a, b)     fmodf(a, b)
626:   #define PetscCopysignReal(a, b) copysignf(a, b)
627:   #define PetscTGamma(a)          tgammaf(a)
628:   #if defined(PETSC_HAVE_LGAMMA_IS_GAMMA)
629:     #define PetscLGamma(a) gammaf(a)
630:   #else
631:     #define PetscLGamma(a) lgammaf(a)
632:   #endif

634: #endif /* PETSC_USE_REAL_* */

636: static inline PetscReal PetscSignReal(PetscReal a)
637: {
638:   return (PetscReal)((a < (PetscReal)0) ? -1 : ((a > (PetscReal)0) ? 1 : 0));
639: }

641: #if !defined(PETSC_HAVE_LOG2)
642:   #undef PetscLog2Real
643: static inline PetscReal PetscLog2Real(PetscReal a)
644: {
645:   return PetscLogReal(a) / PetscLogReal((PetscReal)2);
646: }
647: #endif

649: #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
650: PETSC_EXTERN MPI_Datatype MPIU___FLOAT128 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__float128);
651: #endif
652: #if defined(PETSC_HAVE_REAL___FP16) && !defined(PETSC_SKIP_REAL___FP16)
653: PETSC_EXTERN MPI_Datatype MPIU___FP16 PETSC_ATTRIBUTE_MPI_TYPE_TAG(__fp16);
654: #endif

656: /*MC
657:    MPIU_REAL - Portable MPI datatype corresponding to `PetscReal` independent of what precision `PetscReal` is in

659:    Level: beginner

661:    Note:
662:    In MPI calls that require an MPI datatype that matches a `PetscReal` or array of `PetscReal` values, pass this value.

664: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
665: M*/
666: #if defined(PETSC_USE_REAL_SINGLE)
667:   #define MPIU_REAL MPI_FLOAT
668: #elif defined(PETSC_USE_REAL_DOUBLE)
669:   #define MPIU_REAL MPI_DOUBLE
670: #elif defined(PETSC_USE_REAL___FLOAT128)
671:   #define MPIU_REAL MPIU___FLOAT128
672: #elif defined(PETSC_USE_REAL___FP16)
673:   #define MPIU_REAL MPIU___FP16
674: #endif /* PETSC_USE_REAL_* */

676: /*
677:     Complex number definitions
678:  */
679: #if defined(PETSC_HAVE_COMPLEX)
680:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
681:   /* C++ support of complex number */

683:     /*MC
684:       PetscRealPartComplex - Returns the real part of a `PetscComplex` value, as a `PetscReal`

686:       Synopsis:
687: #include <petscmath.h>
688:       PetscReal PetscRealPartComplex(PetscComplex a)

690:       Not Collective; No Fortran Support

692:       Input Parameter:
693:     . a - the value

695:       Level: beginner

697: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
698:     M*/
699:     #define PetscRealPartComplex(a) (static_cast<PetscComplex>(a)).real()
700:     /*MC
701:       PetscImaginaryPartComplex - Returns the imaginary part of a `PetscComplex` value, as a `PetscReal`

703:       Synopsis:
704: #include <petscmath.h>
705:       PetscReal PetscImaginaryPartComplex(PetscComplex a)

707:       Not Collective; No Fortran Support

709:       Input Parameter:
710:     . a - the value

712:       Level: beginner

714: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
715:     M*/
716:     #define PetscImaginaryPartComplex(a) (static_cast<PetscComplex>(a)).imag()
717:     /*MC
718:       PetscAbsComplex - Returns the absolute value (magnitude) of a `PetscComplex` value, as a `PetscReal`

720:       Synopsis:
721: #include <petscmath.h>
722:       PetscReal PetscAbsComplex(PetscComplex a)

724:       Not Collective; No Fortran Support

726:       Input Parameter:
727:     . a - the value

729:       Level: beginner

731: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
732:     M*/
733:     #define PetscAbsComplex(a) petsccomplexlib::abs(static_cast<PetscComplex>(a))
734:     /*MC
735:       PetscArgComplex - Returns the argument (phase angle) of a `PetscComplex` value, as a `PetscReal`

737:       Synopsis:
738: #include <petscmath.h>
739:       PetscReal PetscArgComplex(PetscComplex a)

741:       Not Collective; No Fortran Support

743:       Input Parameter:
744:     . a - the value

746:       Level: beginner

748: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
749:     M*/
750:     #define PetscArgComplex(a) petsccomplexlib::arg(static_cast<PetscComplex>(a))
751:     /*MC
752:       PetscConjComplex - Returns the complex conjugate of a `PetscComplex` value

754:       Synopsis:
755: #include <petscmath.h>
756:       PetscComplex PetscConjComplex(PetscComplex a)

758:       Not Collective; No Fortran Support

760:       Input Parameter:
761:     . a - the value

763:       Level: beginner

765: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConj()`
766:     M*/
767:     #define PetscConjComplex(a) petsccomplexlib::conj(static_cast<PetscComplex>(a))
768:     /*MC
769:       PetscSqrtComplex - Returns the principal value of the square root of a `PetscComplex` value

771:       Synopsis:
772: #include <petscmath.h>
773:       PetscComplex PetscSqrtComplex(PetscComplex a)

775:       Not Collective; No Fortran Support

777:       Input Parameter:
778:     . a - the value

780:       Level: beginner

782: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtScalar()`
783:     M*/
784:     #define PetscSqrtComplex(a) petsccomplexlib::sqrt(static_cast<PetscComplex>(a))
785:     /*MC
786:       PetscPowComplex - Returns the complex value `a` raised to the complex power `b`

788:       Synopsis:
789: #include <petscmath.h>
790:       PetscComplex PetscPowComplex(PetscComplex a, PetscComplex b)

792:       Not Collective; No Fortran Support

794:       Input Parameters:
795:     + a - the value
796:     - b - the value

798:       Level: beginner

800: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowScalar()`
801:     M*/
802:     #define PetscPowComplex(a, b) petsccomplexlib::pow(static_cast<PetscComplex>(a), static_cast<PetscComplex>(b))
803:     /*MC
804:       PetscExpComplex - Returns the complex exponential $e^a$ of a `PetscComplex` value

806:       Synopsis:
807: #include <petscmath.h>
808:       PetscComplex PetscExpComplex(PetscComplex a)

810:       Not Collective; No Fortran Support

812:       Input Parameter:
813:     . a - the value

815:       Level: beginner

817: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpScalar()`
818:     M*/
819:     #define PetscExpComplex(a) petsccomplexlib::exp(static_cast<PetscComplex>(a))
820:     /*MC
821:       PetscLogComplex - Returns the principal value of the complex natural logarithm of a `PetscComplex` value

823:       Synopsis:
824: #include <petscmath.h>
825:       PetscComplex PetscLogComplex(PetscComplex a)

827:       Not Collective; No Fortran Support

829:       Input Parameter:
830:     . a - the value

832:       Level: beginner

834: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogScalar()`
835:     M*/
836:     #define PetscLogComplex(a) petsccomplexlib::log(static_cast<PetscComplex>(a))
837:     /*MC
838:       PetscSinComplex - Returns the complex sine of a `PetscComplex` value

840:       Synopsis:
841: #include <petscmath.h>
842:       PetscComplex PetscSinComplex(PetscComplex a)

844:       Not Collective; No Fortran Support

846:       Input Parameter:
847:     . a - the value

849:       Level: beginner

851: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinScalar()`
852:     M*/
853:     #define PetscSinComplex(a) petsccomplexlib::sin(static_cast<PetscComplex>(a))
854:     /*MC
855:       PetscCosComplex - Returns the complex cosine of a `PetscComplex` value

857:       Synopsis:
858: #include <petscmath.h>
859:       PetscComplex PetscCosComplex(PetscComplex a)

861:       Not Collective; No Fortran Support

863:       Input Parameter:
864:     . a - the value

866:       Level: beginner

868: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosScalar()`
869:     M*/
870:     #define PetscCosComplex(a) petsccomplexlib::cos(static_cast<PetscComplex>(a))
871:     /*MC
872:       PetscTanComplex - Returns the complex tangent of a `PetscComplex` value

874:       Synopsis:
875: #include <petscmath.h>
876:       PetscComplex PetscTanComplex(PetscComplex a)

878:       Not Collective; No Fortran Support

880:       Input Parameter:
881:     . a - the value

883:       Level: beginner

885: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanScalar()`
886:     M*/
887:     #define PetscTanComplex(a) petsccomplexlib::tan(static_cast<PetscComplex>(a))
888:     /*MC
889:       PetscAsinComplex - Returns the complex arc sine of a `PetscComplex` value

891:       Synopsis:
892: #include <petscmath.h>
893:       PetscComplex PetscAsinComplex(PetscComplex a)

895:       Not Collective; No Fortran Support

897:       Input Parameter:
898:     . a - the value

900:       Level: beginner

902: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinScalar()`
903:     M*/
904:     #define PetscAsinComplex(a) petsccomplexlib::asin(static_cast<PetscComplex>(a))
905:     /*MC
906:       PetscAcosComplex - Returns the complex arc cosine of a `PetscComplex` value

908:       Synopsis:
909: #include <petscmath.h>
910:       PetscComplex PetscAcosComplex(PetscComplex a)

912:       Not Collective; No Fortran Support

914:       Input Parameter:
915:     . a - the value

917:       Level: beginner

919: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosScalar()`
920:     M*/
921:     #define PetscAcosComplex(a) petsccomplexlib::acos(static_cast<PetscComplex>(a))
922:     /*MC
923:       PetscAtanComplex - Returns the complex arc tangent of a `PetscComplex` value

925:       Synopsis:
926: #include <petscmath.h>
927:       PetscComplex PetscAtanComplex(PetscComplex a)

929:       Not Collective; No Fortran Support

931:       Input Parameter:
932:     . a - the value

934:       Level: beginner

936: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanScalar()`
937:     M*/
938:     #define PetscAtanComplex(a) petsccomplexlib::atan(static_cast<PetscComplex>(a))
939:     /*MC
940:       PetscSinhComplex - Returns the complex hyperbolic sine of a `PetscComplex` value

942:       Synopsis:
943: #include <petscmath.h>
944:       PetscComplex PetscSinhComplex(PetscComplex a)

946:       Not Collective; No Fortran Support

948:       Input Parameter:
949:     . a - the value

951:       Level: beginner

953: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhScalar()`
954:     M*/
955:     #define PetscSinhComplex(a) petsccomplexlib::sinh(static_cast<PetscComplex>(a))
956:     /*MC
957:       PetscCoshComplex - Returns the complex hyperbolic cosine of a `PetscComplex` value

959:       Synopsis:
960: #include <petscmath.h>
961:       PetscComplex PetscCoshComplex(PetscComplex a)

963:       Not Collective; No Fortran Support

965:       Input Parameter:
966:     . a - the value

968:       Level: beginner

970: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshScalar()`
971:     M*/
972:     #define PetscCoshComplex(a) petsccomplexlib::cosh(static_cast<PetscComplex>(a))
973:     /*MC
974:       PetscTanhComplex - Returns the complex hyperbolic tangent of a `PetscComplex` value

976:       Synopsis:
977: #include <petscmath.h>
978:       PetscComplex PetscTanhComplex(PetscComplex a)

980:       Not Collective; No Fortran Support

982:       Input Parameter:
983:     . a - the value

985:       Level: beginner

987: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhScalar()`
988:     M*/
989:     #define PetscTanhComplex(a) petsccomplexlib::tanh(static_cast<PetscComplex>(a))
990:     /*MC
991:       PetscAsinhComplex - Returns the complex inverse hyperbolic sine of a `PetscComplex` value

993:       Synopsis:
994: #include <petscmath.h>
995:       PetscComplex PetscAsinhComplex(PetscComplex a)

997:       Not Collective; No Fortran Support

999:       Input Parameter:
1000:     . a - the value

1002:       Level: beginner

1004: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhScalar()`
1005:     M*/
1006:     #define PetscAsinhComplex(a) petsccomplexlib::asinh(static_cast<PetscComplex>(a))
1007:     /*MC
1008:       PetscAcoshComplex - Returns the complex inverse hyperbolic cosine of a `PetscComplex` value

1010:       Synopsis:
1011: #include <petscmath.h>
1012:       PetscComplex PetscAcoshComplex(PetscComplex a)

1014:       Not Collective; No Fortran Support

1016:       Input Parameter:
1017:     . a - the value

1019:       Level: beginner

1021: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshScalar()`
1022:     M*/
1023:     #define PetscAcoshComplex(a) petsccomplexlib::acosh(static_cast<PetscComplex>(a))
1024:     /*MC
1025:       PetscAtanhComplex - Returns the complex inverse hyperbolic tangent of a `PetscComplex` value

1027:       Synopsis:
1028: #include <petscmath.h>
1029:       PetscComplex PetscAtanhComplex(PetscComplex a)

1031:       Not Collective; No Fortran Support

1033:       Input Parameter:
1034:     . a - the value

1036:       Level: beginner

1038: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhScalar()`
1039:     M*/
1040:     #define PetscAtanhComplex(a) petsccomplexlib::atanh(static_cast<PetscComplex>(a))

1042:   /* TODO: Add configure tests

1044: #if !defined(PETSC_HAVE_CXX_TAN_COMPLEX)
1045: #undef PetscTanComplex
1046: static inline PetscComplex PetscTanComplex(PetscComplex z)
1047: {
1048:   return PetscSinComplex(z)/PetscCosComplex(z);
1049: }
1050: #endif

1052: #if !defined(PETSC_HAVE_CXX_TANH_COMPLEX)
1053: #undef PetscTanhComplex
1054: static inline PetscComplex PetscTanhComplex(PetscComplex z)
1055: {
1056:   return PetscSinhComplex(z)/PetscCoshComplex(z);
1057: }
1058: #endif

1060: #if !defined(PETSC_HAVE_CXX_ASIN_COMPLEX)
1061: #undef PetscAsinComplex
1062: static inline PetscComplex PetscAsinComplex(PetscComplex z)
1063: {
1064:   const PetscComplex j(0,1);
1065:   return -j*PetscLogComplex(j*z+PetscSqrtComplex(1.0f-z*z));
1066: }
1067: #endif

1069: #if !defined(PETSC_HAVE_CXX_ACOS_COMPLEX)
1070: #undef PetscAcosComplex
1071: static inline PetscComplex PetscAcosComplex(PetscComplex z)
1072: {
1073:   const PetscComplex j(0,1);
1074:   return j*PetscLogComplex(z-j*PetscSqrtComplex(1.0f-z*z));
1075: }
1076: #endif

1078: #if !defined(PETSC_HAVE_CXX_ATAN_COMPLEX)
1079: #undef PetscAtanComplex
1080: static inline PetscComplex PetscAtanComplex(PetscComplex z)
1081: {
1082:   const PetscComplex j(0,1);
1083:   return 0.5f*j*PetscLogComplex((1.0f-j*z)/(1.0f+j*z));
1084: }
1085: #endif

1087: #if !defined(PETSC_HAVE_CXX_ASINH_COMPLEX)
1088: #undef PetscAsinhComplex
1089: static inline PetscComplex PetscAsinhComplex(PetscComplex z)
1090: {
1091:   return PetscLogComplex(z+PetscSqrtComplex(z*z+1.0f));
1092: }
1093: #endif

1095: #if !defined(PETSC_HAVE_CXX_ACOSH_COMPLEX)
1096: #undef PetscAcoshComplex
1097: static inline PetscComplex PetscAcoshComplex(PetscComplex z)
1098: {
1099:   return PetscLogComplex(z+PetscSqrtComplex(z*z-1.0f));
1100: }
1101: #endif

1103: #if !defined(PETSC_HAVE_CXX_ATANH_COMPLEX)
1104: #undef PetscAtanhComplex
1105: static inline PetscComplex PetscAtanhComplex(PetscComplex z)
1106: {
1107:   return 0.5f*PetscLogComplex((1.0f+z)/(1.0f-z));
1108: }
1109: #endif

1111: */

1113:   #else /* C99 support of complex number */

1115:     #if defined(PETSC_USE_REAL_SINGLE)
1116:       #define PetscRealPartComplex(a)      crealf(a)
1117:       #define PetscImaginaryPartComplex(a) cimagf(a)
1118:       #define PetscAbsComplex(a)           cabsf(a)
1119:       #define PetscArgComplex(a)           cargf(a)
1120:       #define PetscConjComplex(a)          conjf(a)
1121:       #define PetscSqrtComplex(a)          csqrtf(a)
1122:       #define PetscPowComplex(a, b)        cpowf(a, b)
1123:       #define PetscExpComplex(a)           cexpf(a)
1124:       #define PetscLogComplex(a)           clogf(a)
1125:       #define PetscSinComplex(a)           csinf(a)
1126:       #define PetscCosComplex(a)           ccosf(a)
1127:       #define PetscTanComplex(a)           ctanf(a)
1128:       #define PetscAsinComplex(a)          casinf(a)
1129:       #define PetscAcosComplex(a)          cacosf(a)
1130:       #define PetscAtanComplex(a)          catanf(a)
1131:       #define PetscSinhComplex(a)          csinhf(a)
1132:       #define PetscCoshComplex(a)          ccoshf(a)
1133:       #define PetscTanhComplex(a)          ctanhf(a)
1134:       #define PetscAsinhComplex(a)         casinhf(a)
1135:       #define PetscAcoshComplex(a)         cacoshf(a)
1136:       #define PetscAtanhComplex(a)         catanhf(a)

1138:     #elif defined(PETSC_USE_REAL_DOUBLE)
1139:       #define PetscRealPartComplex(a)      creal(a)
1140:       #define PetscImaginaryPartComplex(a) cimag(a)
1141:       #define PetscAbsComplex(a)           cabs(a)
1142:       #define PetscArgComplex(a)           carg(a)
1143:       #define PetscConjComplex(a)          conj(a)
1144:       #define PetscSqrtComplex(a)          csqrt(a)
1145:       #define PetscPowComplex(a, b)        cpow(a, b)
1146:       #define PetscExpComplex(a)           cexp(a)
1147:       #define PetscLogComplex(a)           clog(a)
1148:       #define PetscSinComplex(a)           csin(a)
1149:       #define PetscCosComplex(a)           ccos(a)
1150:       #define PetscTanComplex(a)           ctan(a)
1151:       #define PetscAsinComplex(a)          casin(a)
1152:       #define PetscAcosComplex(a)          cacos(a)
1153:       #define PetscAtanComplex(a)          catan(a)
1154:       #define PetscSinhComplex(a)          csinh(a)
1155:       #define PetscCoshComplex(a)          ccosh(a)
1156:       #define PetscTanhComplex(a)          ctanh(a)
1157:       #define PetscAsinhComplex(a)         casinh(a)
1158:       #define PetscAcoshComplex(a)         cacosh(a)
1159:       #define PetscAtanhComplex(a)         catanh(a)

1161:     #elif defined(PETSC_USE_REAL___FLOAT128)
1162:       #define PetscRealPartComplex(a)      crealq(a)
1163:       #define PetscImaginaryPartComplex(a) cimagq(a)
1164:       #define PetscAbsComplex(a)           cabsq(a)
1165:       #define PetscArgComplex(a)           cargq(a)
1166:       #define PetscConjComplex(a)          conjq(a)
1167:       #define PetscSqrtComplex(a)          csqrtq(a)
1168:       #define PetscPowComplex(a, b)        cpowq(a, b)
1169:       #define PetscExpComplex(a)           cexpq(a)
1170:       #define PetscLogComplex(a)           clogq(a)
1171:       #define PetscSinComplex(a)           csinq(a)
1172:       #define PetscCosComplex(a)           ccosq(a)
1173:       #define PetscTanComplex(a)           ctanq(a)
1174:       #define PetscAsinComplex(a)          casinq(a)
1175:       #define PetscAcosComplex(a)          cacosq(a)
1176:       #define PetscAtanComplex(a)          catanq(a)
1177:       #define PetscSinhComplex(a)          csinhq(a)
1178:       #define PetscCoshComplex(a)          ccoshq(a)
1179:       #define PetscTanhComplex(a)          ctanhq(a)
1180:       #define PetscAsinhComplex(a)         casinhq(a)
1181:       #define PetscAcoshComplex(a)         cacoshq(a)
1182:       #define PetscAtanhComplex(a)         catanhq(a)

1184:     #endif /* PETSC_USE_REAL_* */
1185:   #endif   /* (__cplusplus) */

1187: /*MC
1188:    PETSC_i - the pure imaginary complex number i

1190:    Level: intermediate

1192: .seealso: `PetscComplex`, `PetscScalar`
1193: M*/
1194: PETSC_EXTERN PetscComplex PETSC_i;

1196: /*
1197:    Try to do the right thing for complex number construction: see
1198:    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1464.htm
1199:    for details
1200: */
1201: static inline PetscComplex PetscCMPLX(PetscReal x, PetscReal y)
1202: {
1203:   #if defined(__cplusplus) && !defined(PETSC_USE_REAL___FLOAT128)
1204:   return PetscComplex(x, y);
1205:   #elif defined(_Imaginary_I)
1206:   return x + y * _Imaginary_I;
1207:   #else
1208:   { /* In both C99 and C11 (ISO/IEC 9899, Section 6.2.5),

1210:        "For each floating type there is a corresponding real type, which is always a real floating
1211:        type. For real floating types, it is the same type. For complex types, it is the type given
1212:        by deleting the keyword _Complex from the type name."

1214:        So type punning should be portable. */
1215:     union
1216:     {
1217:       PetscComplex z;
1218:       PetscReal    f[2];
1219:     } uz;

1221:     uz.f[0] = x;
1222:     uz.f[1] = y;
1223:     return uz.z;
1224:   }
1225:   #endif
1226: }

1228:   #define MPIU_C_COMPLEX        MPI_C_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_COMPLEX", )
1229:   #define MPIU_C_DOUBLE_COMPLEX MPI_C_DOUBLE_COMPLEX PETSC_DEPRECATED_MACRO(3, 15, 0, "MPI_C_DOUBLE_COMPLEX", )

1231:   #if defined(PETSC_HAVE_REAL___FLOAT128) && !defined(PETSC_SKIP_REAL___FLOAT128)
1232:     // if complex is not used, then quadmath.h won't be included by petscsystypes.h
1233:     #if defined(PETSC_USE_COMPLEX)
1234:       #define MPIU___COMPLEX128_ATTR_TAG PETSC_ATTRIBUTE_MPI_TYPE_TAG(__complex128)
1235:     #else
1236:       #define MPIU___COMPLEX128_ATTR_TAG
1237:     #endif

1239: PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128 MPIU___COMPLEX128_ATTR_TAG;

1241:     #undef MPIU___COMPLEX128_ATTR_TAG
1242:   #endif /* PETSC_HAVE_REAL___FLOAT128 */

1244:   /*MC
1245:    MPIU_COMPLEX - Portable MPI datatype corresponding to `PetscComplex` independent of the precision of `PetscComplex`

1247:    Level: beginner

1249:    Note:
1250:    In MPI calls that require an MPI datatype that matches a `PetscComplex` or array of `PetscComplex` values, pass this value.

1252: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
1253: M*/
1254:   #if defined(PETSC_USE_REAL_SINGLE)
1255:     #define MPIU_COMPLEX MPI_C_COMPLEX
1256:   #elif defined(PETSC_USE_REAL_DOUBLE)
1257:     #define MPIU_COMPLEX MPI_C_DOUBLE_COMPLEX
1258:   #elif defined(PETSC_USE_REAL___FLOAT128)
1259:     #define MPIU_COMPLEX MPIU___COMPLEX128
1260:   #elif defined(PETSC_USE_REAL___FP16)
1261:     #define MPIU_COMPLEX MPI_C_COMPLEX
1262:   #endif /* PETSC_USE_REAL_* */

1264: #endif /* PETSC_HAVE_COMPLEX */

1266: /*
1267:     Scalar number definitions
1268:  */
1269: #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
1270:   /*MC
1271:    MPIU_SCALAR - Portable MPI datatype corresponding to `PetscScalar` independent of the precision of `PetscScalar`

1273:    Level: beginner

1275:    Note:
1276:    In MPI calls that require an MPI datatype that matches a `PetscScalar` or array of `PetscScalar` values, pass this value.

1278: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_COMPLEX`, `MPIU_INT`
1279: M*/
1280:   #define MPIU_SCALAR MPIU_COMPLEX

1282:   /*MC
1283:    PetscRealPart - Returns the real part of a `PetscScalar`

1285:    Synopsis:
1286: #include <petscmath.h>
1287:    PetscReal PetscRealPart(PetscScalar v)

1289:    Not Collective

1291:    Input Parameter:
1292: .  v - value to find the real part of

1294:    Level: beginner

1296: .seealso: `PetscScalar`, `PetscImaginaryPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1297: M*/
1298:   #define PetscRealPart(a) PetscRealPartComplex(a)

1300:   /*MC
1301:    PetscImaginaryPart - Returns the imaginary part of a `PetscScalar`

1303:    Synopsis:
1304: #include <petscmath.h>
1305:    PetscReal PetscImaginaryPart(PetscScalar v)

1307:    Not Collective

1309:    Input Parameter:
1310: .  v - value to find the imaginary part of

1312:    Level: beginner

1314:    Note:
1315:    If PETSc was configured for real numbers then this always returns the value 0

1317: .seealso: `PetscScalar`, `PetscRealPart()`, `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1318: M*/
1319:   #define PetscImaginaryPart(a) PetscImaginaryPartComplex(a)

1321:   /*MC
1322:     PetscAbsScalar - Returns the absolute value (magnitude) of a `PetscScalar` value, as a `PetscReal`

1324:     Synopsis:
1325: #include <petscmath.h>
1326:     PetscReal PetscAbsScalar(PetscScalar a)

1328:     Not Collective; No Fortran Support

1330:     Input Parameter:
1331:   . a - the value

1333:     Level: beginner

1335: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1336:   M*/
1337:   #define PetscAbsScalar(a) PetscAbsComplex(a)
1338:   /*MC
1339:     PetscArgScalar - Returns the argument (phase angle) of a `PetscScalar` value, as a `PetscReal`; for real `PetscScalar` this is `0` for nonnegative values and `PETSC_PI` otherwise

1341:     Synopsis:
1342: #include <petscmath.h>
1343:     PetscReal PetscArgScalar(PetscScalar a)

1345:     Not Collective; No Fortran Support

1347:     Input Parameter:
1348:   . a - the value

1350:     Level: beginner

1352: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`
1353:   M*/
1354:   #define PetscArgScalar(a) PetscArgComplex(a)
1355:   /*MC
1356:     PetscConj - Returns the complex conjugate of a `PetscScalar` value; the identity when `PetscScalar` is real

1358:     Synopsis:
1359: #include <petscmath.h>
1360:     PetscScalar PetscConj(PetscScalar a)

1362:     Not Collective; No Fortran Support

1364:     Input Parameter:
1365:   . a - the value

1367:     Level: beginner

1369: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscConjComplex()`
1370:   M*/
1371:   #define PetscConj(a) PetscConjComplex(a)
1372:   /*MC
1373:     PetscSqrtScalar - Returns the square root of a `PetscScalar` value

1375:     Synopsis:
1376: #include <petscmath.h>
1377:     PetscScalar PetscSqrtScalar(PetscScalar a)

1379:     Not Collective; No Fortran Support

1381:     Input Parameter:
1382:   . a - the value

1384:     Level: beginner

1386: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSqrtReal()`, `PetscSqrtComplex()`
1387:   M*/
1388:   #define PetscSqrtScalar(a) PetscSqrtComplex(a)
1389:   /*MC
1390:     PetscPowScalar - Returns the value of `a` raised to the power `b`, both `PetscScalar`

1392:     Synopsis:
1393: #include <petscmath.h>
1394:     PetscScalar PetscPowScalar(PetscScalar a, PetscScalar b)

1396:     Not Collective; No Fortran Support

1398:     Input Parameters:
1399:   + a - the value
1400:   - b - the value

1402:     Level: beginner

1404: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscPowReal()`, `PetscPowComplex()`
1405:   M*/
1406:   #define PetscPowScalar(a, b) PetscPowComplex(a, b)
1407:   /*MC
1408:     PetscExpScalar - Returns the exponential $e^a$ of a `PetscScalar` value

1410:     Synopsis:
1411: #include <petscmath.h>
1412:     PetscScalar PetscExpScalar(PetscScalar a)

1414:     Not Collective; No Fortran Support

1416:     Input Parameter:
1417:   . a - the value

1419:     Level: beginner

1421: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscExpReal()`, `PetscExpComplex()`
1422:   M*/
1423:   #define PetscExpScalar(a) PetscExpComplex(a)
1424:   /*MC
1425:     PetscLogScalar - Returns the natural logarithm of a `PetscScalar` value

1427:     Synopsis:
1428: #include <petscmath.h>
1429:     PetscScalar PetscLogScalar(PetscScalar a)

1431:     Not Collective; No Fortran Support

1433:     Input Parameter:
1434:   . a - the value

1436:     Level: beginner

1438: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscLogReal()`, `PetscLogComplex()`
1439:   M*/
1440:   #define PetscLogScalar(a) PetscLogComplex(a)
1441:   /*MC
1442:     PetscSinScalar - Returns the sine of a `PetscScalar` value

1444:     Synopsis:
1445: #include <petscmath.h>
1446:     PetscScalar PetscSinScalar(PetscScalar a)

1448:     Not Collective; No Fortran Support

1450:     Input Parameter:
1451:   . a - the value

1453:     Level: beginner

1455: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinReal()`, `PetscSinComplex()`
1456:   M*/
1457:   #define PetscSinScalar(a) PetscSinComplex(a)
1458:   /*MC
1459:     PetscCosScalar - Returns the cosine of a `PetscScalar` value

1461:     Synopsis:
1462: #include <petscmath.h>
1463:     PetscScalar PetscCosScalar(PetscScalar a)

1465:     Not Collective; No Fortran Support

1467:     Input Parameter:
1468:   . a - the value

1470:     Level: beginner

1472: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCosReal()`, `PetscCosComplex()`
1473:   M*/
1474:   #define PetscCosScalar(a) PetscCosComplex(a)
1475:   /*MC
1476:     PetscTanScalar - Returns the tangent of a `PetscScalar` value

1478:     Synopsis:
1479: #include <petscmath.h>
1480:     PetscScalar PetscTanScalar(PetscScalar a)

1482:     Not Collective; No Fortran Support

1484:     Input Parameter:
1485:   . a - the value

1487:     Level: beginner

1489: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanReal()`, `PetscTanComplex()`
1490:   M*/
1491:   #define PetscTanScalar(a) PetscTanComplex(a)
1492:   /*MC
1493:     PetscAsinScalar - Returns the arc sine of a `PetscScalar` value

1495:     Synopsis:
1496: #include <petscmath.h>
1497:     PetscScalar PetscAsinScalar(PetscScalar a)

1499:     Not Collective; No Fortran Support

1501:     Input Parameter:
1502:   . a - the value

1504:     Level: beginner

1506: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinReal()`, `PetscAsinComplex()`
1507:   M*/
1508:   #define PetscAsinScalar(a) PetscAsinComplex(a)
1509:   /*MC
1510:     PetscAcosScalar - Returns the arc cosine of a `PetscScalar` value

1512:     Synopsis:
1513: #include <petscmath.h>
1514:     PetscScalar PetscAcosScalar(PetscScalar a)

1516:     Not Collective; No Fortran Support

1518:     Input Parameter:
1519:   . a - the value

1521:     Level: beginner

1523: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcosReal()`, `PetscAcosComplex()`
1524:   M*/
1525:   #define PetscAcosScalar(a) PetscAcosComplex(a)
1526:   /*MC
1527:     PetscAtanScalar - Returns the arc tangent of a `PetscScalar` value

1529:     Synopsis:
1530: #include <petscmath.h>
1531:     PetscScalar PetscAtanScalar(PetscScalar a)

1533:     Not Collective; No Fortran Support

1535:     Input Parameter:
1536:   . a - the value

1538:     Level: beginner

1540: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanReal()`, `PetscAtanComplex()`
1541:   M*/
1542:   #define PetscAtanScalar(a) PetscAtanComplex(a)
1543:   /*MC
1544:     PetscSinhScalar - Returns the hyperbolic sine of a `PetscScalar` value

1546:     Synopsis:
1547: #include <petscmath.h>
1548:     PetscScalar PetscSinhScalar(PetscScalar a)

1550:     Not Collective; No Fortran Support

1552:     Input Parameter:
1553:   . a - the value

1555:     Level: beginner

1557: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscSinhReal()`, `PetscSinhComplex()`
1558:   M*/
1559:   #define PetscSinhScalar(a) PetscSinhComplex(a)
1560:   /*MC
1561:     PetscCoshScalar - Returns the hyperbolic cosine of a `PetscScalar` value

1563:     Synopsis:
1564: #include <petscmath.h>
1565:     PetscScalar PetscCoshScalar(PetscScalar a)

1567:     Not Collective; No Fortran Support

1569:     Input Parameter:
1570:   . a - the value

1572:     Level: beginner

1574: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscCoshReal()`, `PetscCoshComplex()`
1575:   M*/
1576:   #define PetscCoshScalar(a) PetscCoshComplex(a)
1577:   /*MC
1578:     PetscTanhScalar - Returns the hyperbolic tangent of a `PetscScalar` value

1580:     Synopsis:
1581: #include <petscmath.h>
1582:     PetscScalar PetscTanhScalar(PetscScalar a)

1584:     Not Collective; No Fortran Support

1586:     Input Parameter:
1587:   . a - the value

1589:     Level: beginner

1591: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscTanhReal()`, `PetscTanhComplex()`
1592:   M*/
1593:   #define PetscTanhScalar(a) PetscTanhComplex(a)
1594:   /*MC
1595:     PetscAsinhScalar - Returns the inverse hyperbolic sine of a `PetscScalar` value

1597:     Synopsis:
1598: #include <petscmath.h>
1599:     PetscScalar PetscAsinhScalar(PetscScalar a)

1601:     Not Collective; No Fortran Support

1603:     Input Parameter:
1604:   . a - the value

1606:     Level: beginner

1608: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAsinhReal()`, `PetscAsinhComplex()`
1609:   M*/
1610:   #define PetscAsinhScalar(a) PetscAsinhComplex(a)
1611:   /*MC
1612:     PetscAcoshScalar - Returns the inverse hyperbolic cosine of a `PetscScalar` value

1614:     Synopsis:
1615: #include <petscmath.h>
1616:     PetscScalar PetscAcoshScalar(PetscScalar a)

1618:     Not Collective; No Fortran Support

1620:     Input Parameter:
1621:   . a - the value

1623:     Level: beginner

1625: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAcoshReal()`, `PetscAcoshComplex()`
1626:   M*/
1627:   #define PetscAcoshScalar(a) PetscAcoshComplex(a)
1628:   /*MC
1629:     PetscAtanhScalar - Returns the inverse hyperbolic tangent of a `PetscScalar` value

1631:     Synopsis:
1632: #include <petscmath.h>
1633:     PetscScalar PetscAtanhScalar(PetscScalar a)

1635:     Not Collective; No Fortran Support

1637:     Input Parameter:
1638:   . a - the value

1640:     Level: beginner

1642: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscAtanhReal()`, `PetscAtanhComplex()`
1643:   M*/
1644:   #define PetscAtanhScalar(a) PetscAtanhComplex(a)

1646: #else /* PETSC_USE_COMPLEX */
1647:   #define MPIU_SCALAR           MPIU_REAL
1648:   #define PetscRealPart(a)      (a)
1649:   #define PetscImaginaryPart(a) ((PetscReal)0)
1650:   #define PetscAbsScalar(a)     PetscAbsReal(a)
1651:   #define PetscArgScalar(a)     (((a) < (PetscReal)0) ? PETSC_PI : (PetscReal)0)
1652:   #define PetscConj(a)          (a)
1653:   #define PetscSqrtScalar(a)    PetscSqrtReal(a)
1654:   #define PetscPowScalar(a, b)  PetscPowReal(a, b)
1655:   #define PetscExpScalar(a)     PetscExpReal(a)
1656:   #define PetscLogScalar(a)     PetscLogReal(a)
1657:   #define PetscSinScalar(a)     PetscSinReal(a)
1658:   #define PetscCosScalar(a)     PetscCosReal(a)
1659:   #define PetscTanScalar(a)     PetscTanReal(a)
1660:   #define PetscAsinScalar(a)    PetscAsinReal(a)
1661:   #define PetscAcosScalar(a)    PetscAcosReal(a)
1662:   #define PetscAtanScalar(a)    PetscAtanReal(a)
1663:   #define PetscSinhScalar(a)    PetscSinhReal(a)
1664:   #define PetscCoshScalar(a)    PetscCoshReal(a)
1665:   #define PetscTanhScalar(a)    PetscTanhReal(a)
1666:   #define PetscAsinhScalar(a)   PetscAsinhReal(a)
1667:   #define PetscAcoshScalar(a)   PetscAcoshReal(a)
1668:   #define PetscAtanhScalar(a)   PetscAtanhReal(a)

1670: #endif /* PETSC_USE_COMPLEX */

1672: /*E
1673:    PetscScalarPrecision - Names of the floating-point precisions that a `PetscScalar` could in principle be built with

1675:    Values:
1676: +   `PETSC_SCALAR_DOUBLE`      - IEEE double precision
1677: .   `PETSC_SCALAR_SINGLE`      - IEEE single precision
1678: .   `PETSC_SCALAR_LONG_DOUBLE` - C `long double` precision
1679: -   `PETSC_SCALAR_HALF`        - IEEE half precision

1681:    Level: developer

1683:    Note:
1684:    This enum is reserved for situations where an object might be created in a precision different from `PetscScalar`; the current PETSc code does not use it.

1686: .seealso: `PetscScalar`, `PetscReal`, `PetscComplex`
1687: E*/
1688: typedef enum {
1689:   PETSC_SCALAR_DOUBLE,
1690:   PETSC_SCALAR_SINGLE,
1691:   PETSC_SCALAR_LONG_DOUBLE,
1692:   PETSC_SCALAR_HALF
1693: } PetscScalarPrecision;

1695: /*MC
1696:    PetscAbs - Returns the absolute value of a number

1698:    Synopsis:
1699: #include <petscmath.h>
1700:    type PetscAbs(type v)

1702:    Not Collective

1704:    Input Parameter:
1705: .  v - the number

1707:    Level: beginner

1709:    Note:
1710:    The type can be integer or real floating point value, but cannot be complex

1712: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`, `PetscSign()`
1713: M*/
1714: #define PetscAbs(a) (((a) >= 0) ? (a) : (-(a)))

1716: /*MC
1717:    PetscSign - Returns the sign of a number as an integer of value -1, 0, or 1

1719:    Synopsis:
1720: #include <petscmath.h>
1721:    int PetscSign(type v)

1723:    Not Collective

1725:    Input Parameter:
1726: .  v - the number

1728:    Level: beginner

1730:    Note:
1731:    The type can be integer or real floating point value

1733: .seealso: `PetscAbsInt()`, `PetscAbsReal()`, `PetscAbsScalar()`
1734: M*/
1735: #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1)

1737: /*MC
1738:    PetscMin - Returns minimum of two numbers

1740:    Synopsis:
1741: #include <petscmath.h>
1742:    type PetscMin(type v1,type v2)

1744:    Not Collective

1746:    Input Parameters:
1747: +  v1 - first value to find minimum of
1748: -  v2 - second value to find minimum of

1750:    Level: beginner

1752:    Note:
1753:    The type can be integer or floating point value, but cannot be complex

1755: .seealso: `PetscMax()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1756: M*/
1757: #define PetscMin(a, b) (((a) < (b)) ? (a) : (b))

1759: /*MC
1760:    PetscMax - Returns maximum of two numbers

1762:    Synopsis:
1763: #include <petscmath.h>
1764:    type max PetscMax(type v1,type v2)

1766:    Not Collective

1768:    Input Parameters:
1769: +  v1 - first value to find maximum of
1770: -  v2 - second value to find maximum of

1772:    Level: beginner

1774:    Note:
1775:    The type can be integer or floating point value

1777: .seealso: `PetscMin()`, `PetscClipInterval()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1778: M*/
1779: #define PetscMax(a, b) (((a) < (b)) ? (b) : (a))

1781: /*MC
1782:    PetscClipInterval - Returns a number clipped to be within an interval

1784:    Synopsis:
1785: #include <petscmath.h>
1786:    type clip PetscClipInterval(type x,type a,type b)

1788:    Not Collective

1790:    Input Parameters:
1791: +  x - value to use if within interval [a,b]
1792: .  a - lower end of interval
1793: -  b - upper end of interval

1795:    Level: beginner

1797:    Note:
1798:    The type can be integer or floating point value

1800:    Example\:
1801: .vb
1802:   PetscInt c = PetscClipInterval(5, 2, 3); // the value of c is 3
1803:   PetscInt c = PetscClipInterval(5, 2, 6); // the value of c is 5
1804: .ve

1806: .seealso: `PetscMin()`, `PetscMax()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscSqr()`
1807: M*/
1808: #define PetscClipInterval(x, a, b) (PetscMax((a), PetscMin((x), (b))))

1810: /*MC
1811:    PetscAbsInt - Returns the absolute value of an integer

1813:    Synopsis:
1814: #include <petscmath.h>
1815:    int abs PetscAbsInt(int v1)

1817:    Input Parameter:
1818: .   v1 - the integer

1820:    Level: beginner

1822: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsReal()`, `PetscSqr()`
1823: M*/
1824: #define PetscAbsInt(a) (((a) < 0) ? (-(a)) : (a))

1826: /*MC
1827:    PetscAbsReal - Returns the absolute value of a real number

1829:    Synopsis:
1830: #include <petscmath.h>
1831:    Real abs PetscAbsReal(PetscReal v1)

1833:    Input Parameter:
1834: .   v1 - the `PetscReal` value

1836:    Level: beginner

1838: .seealso: `PetscReal`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscSqr()`
1839: M*/
1840: #if defined(PETSC_USE_REAL_SINGLE)
1841:   #define PetscAbsReal(a) fabsf(a)
1842: #elif defined(PETSC_USE_REAL_DOUBLE)
1843:   #define PetscAbsReal(a) fabs(a)
1844: #elif defined(PETSC_USE_REAL___FLOAT128)
1845:   #define PetscAbsReal(a) fabsq(a)
1846: #elif defined(PETSC_USE_REAL___FP16)
1847:   #define PetscAbsReal(a) fabsf(a)
1848: #endif

1850: /*MC
1851:    PetscSqr - Returns the square of a number

1853:    Synopsis:
1854: #include <petscmath.h>
1855:    type sqr PetscSqr(type v1)

1857:    Not Collective

1859:    Input Parameter:
1860: .   v1 - the value

1862:    Level: beginner

1864:    Note:
1865:    The type can be integer, floating point, or complex floating point

1867: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`
1868: M*/
1869: #define PetscSqr(a) ((a) * (a))

1871: /*MC
1872:    PetscRealConstant - a compile time macro that ensures a given constant real number is properly represented in the configured
1873:    precision of `PetscReal` be it half, single, double or 128-bit representation

1875:    Synopsis:
1876: #include <petscmath.h>
1877:    PetscReal PetscRealConstant(real_number)

1879:    Not Collective

1881:    Input Parameter:
1882: .   v1 - the real number, for example 1.5

1884:    Level: beginner

1886:    Note:
1887:    For example, if PETSc is configured with `--with-precision=__float128` and one writes
1888: .vb
1889:    PetscReal d = 1.5;
1890: .ve
1891:    the result is 1.5 in double precision extended to 128 bit representation, meaning it is very far from the correct value. Hence, one should write
1892: .vb
1893:    PetscReal d = PetscRealConstant(1.5);
1894: .ve

1896: .seealso: `PetscReal`
1897: M*/
1898: #if defined(PETSC_USE_REAL_SINGLE)
1899:   #define PetscRealConstant(constant) constant##F
1900: #elif defined(PETSC_USE_REAL_DOUBLE)
1901:   #define PetscRealConstant(constant) constant
1902: #elif defined(PETSC_USE_REAL___FLOAT128)
1903:   #define PetscRealConstant(constant) constant##Q
1904: #elif defined(PETSC_USE_REAL___FP16)
1905:   #define PetscRealConstant(constant) constant##F
1906: #endif

1908: /*
1909:      Basic constants
1910: */
1911: /*MC
1912:   PETSC_PI - the value of $ \pi$ to the correct precision of `PetscReal`.

1914:   Level: beginner

1916: .seealso: `PetscReal`, `PETSC_PHI`, `PETSC_SQRT2`
1917: M*/

1919: /*MC
1920:   PETSC_PHI - the value of $ \phi$, the Golden Ratio, to the correct precision of `PetscReal`.

1922:   Level: beginner

1924: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_SQRT2`
1925: M*/

1927: /*MC
1928:   PETSC_SQRT2 - the value of $ \sqrt{2} $ to the correct precision of `PetscReal`.

1930:   Level: beginner

1932: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1933: M*/

1935: /*MC
1936:   PETSC_E - the value of Euler's constant $ e $ to the correct precision of `PetscReal`.

1938:   Level: beginner

1940: .seealso: `PetscReal`, `PETSC_PI`, `PETSC_PHI`
1941: M*/

1943: #define PETSC_PI    PetscRealConstant(3.1415926535897932384626433832795029)
1944: #define PETSC_PHI   PetscRealConstant(1.6180339887498948482045868343656381)
1945: #define PETSC_SQRT2 PetscRealConstant(1.4142135623730950488016887242096981)
1946: #define PETSC_E     PetscRealConstant(2.7182818284590452353602874713526625)

1948: /*MC
1949:   PETSC_MAX_REAL - the largest real value that can be stored in a `PetscReal`

1951:   Level: beginner

1953: .seealso: `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1954: M*/

1956: /*MC
1957:   PETSC_MIN_REAL - the smallest real value that can be stored in a `PetscReal`, generally this is - `PETSC_MAX_REAL`

1959:   Level: beginner

1961: .seealso `PETSC_MAX_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1962: M*/

1964: /*MC
1965:   PETSC_REAL_MIN - the smallest positive normalized real value that can be stored in a `PetscReal`.

1967:   Level: beginner

1969:   Note:
1970:   See <https://en.wikipedia.org/wiki/Subnormal_number> for a discussion of normalized and subnormal floating point numbers

1972:   Developer Note:
1973:   The naming is confusing as there is both a `PETSC_REAL_MIN` and `PETSC_MIN_REAL` with different meanings.

1975: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_MACHINE_EPSILON`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1976: M*/

1978: /*MC
1979:   PETSC_MACHINE_EPSILON - the machine epsilon for the precision of `PetscReal`

1981:   Level: beginner

1983:   Note:
1984:   See <https://en.wikipedia.org/wiki/Machine_epsilon>

1986: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_SQRT_MACHINE_EPSILON`, `PETSC_SMALL`
1987: M*/

1989: /*MC
1990:   PETSC_SQRT_MACHINE_EPSILON - the square root of the machine epsilon for the precision of `PetscReal`

1992:   Level: beginner

1994:   Note:
1995:   See `PETSC_MACHINE_EPSILON`

1997: .seealso `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`, `PETSC_SMALL`
1998: M*/

2000: /*MC
2001:   PETSC_SMALL - an arbitrary "small" number which depends on the precision of `PetscReal` used in some PETSc examples
2002:   and in `PetscApproximateLTE()` and `PetscApproximateGTE()` to determine if a computation was successful.

2004:   Level: beginner

2006:   Note:
2007:   See `PETSC_MACHINE_EPSILON`

2009: .seealso `PetscApproximateLTE()`, `PetscApproximateGTE()`, `PETSC_MAX_REAL`, `PETSC_MIN_REAL`, `PETSC_REAL_MIN`, `PETSC_MACHINE_EPSILON`,
2010:          `PETSC_SQRT_MACHINE_EPSILON`
2011: M*/

2013: #if defined(PETSC_USE_REAL_SINGLE)
2014:   #define PETSC_MAX_REAL             3.40282346638528860e+38F
2015:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2016:   #define PETSC_REAL_MIN             1.1754944e-38F
2017:   #define PETSC_MACHINE_EPSILON      1.19209290e-07F
2018:   #define PETSC_SQRT_MACHINE_EPSILON 3.45266983e-04F
2019:   #define PETSC_SMALL                1.e-5F
2020: #elif defined(PETSC_USE_REAL_DOUBLE)
2021:   #define PETSC_MAX_REAL             1.7976931348623157e+308
2022:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2023:   #define PETSC_REAL_MIN             2.225073858507201e-308
2024:   #define PETSC_MACHINE_EPSILON      2.2204460492503131e-16
2025:   #define PETSC_SQRT_MACHINE_EPSILON 1.490116119384766e-08
2026:   #define PETSC_SMALL                1.e-10
2027: #elif defined(PETSC_USE_REAL___FLOAT128)
2028:   #define PETSC_MAX_REAL             FLT128_MAX
2029:   #define PETSC_MIN_REAL             (-FLT128_MAX)
2030:   #define PETSC_REAL_MIN             FLT128_MIN
2031:   #define PETSC_MACHINE_EPSILON      FLT128_EPSILON
2032:   #define PETSC_SQRT_MACHINE_EPSILON 1.38777878078144567552953958511352539e-17Q
2033:   #define PETSC_SMALL                1.e-20Q
2034: #elif defined(PETSC_USE_REAL___FP16)
2035:   #define PETSC_MAX_REAL             65504.0F
2036:   #define PETSC_MIN_REAL             (-PETSC_MAX_REAL)
2037:   #define PETSC_REAL_MIN             .00006103515625F
2038:   #define PETSC_MACHINE_EPSILON      .0009765625F
2039:   #define PETSC_SQRT_MACHINE_EPSILON .03125F
2040:   #define PETSC_SMALL                5.e-3F
2041: #endif

2043: /*MC
2044:   PETSC_INFINITY - a finite number that represents infinity for setting certain bounds in `Tao`

2046:   Level: intermediate

2048:   Note:
2049:   This is not the IEEE infinity value

2051: .seealso: `PETSC_NINFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2052: M*/
2053: #define PETSC_INFINITY (PETSC_MAX_REAL / 4)

2055: /*MC
2056:   PETSC_NINFINITY - a finite number that represents negative infinity for setting certain bounds in `Tao`

2058:   Level: intermediate

2060:   Note:
2061:   This is not the negative IEEE infinity value

2063: .seealso: `PETSC_INFINITY`, `SNESVIGetVariableBounds()`, `SNESVISetComputeVariableBounds()`, `SNESVISetVariableBounds()`
2064: M*/
2065: #define PETSC_NINFINITY (-PETSC_INFINITY)

2067: PETSC_EXTERN PetscBool  PetscIsInfReal(PetscReal);
2068: PETSC_EXTERN PetscBool  PetscIsNanReal(PetscReal);
2069: PETSC_EXTERN PetscBool  PetscIsNormalReal(PetscReal);
2070: static inline PetscBool PetscIsInfOrNanReal(PetscReal v)
2071: {
2072:   return PetscIsInfReal(v) || PetscIsNanReal(v) ? PETSC_TRUE : PETSC_FALSE;
2073: }
2074: static inline PetscBool PetscIsInfScalar(PetscScalar v)
2075: {
2076:   return PetscIsInfReal(PetscAbsScalar(v));
2077: }
2078: static inline PetscBool PetscIsNanScalar(PetscScalar v)
2079: {
2080:   return PetscIsNanReal(PetscAbsScalar(v));
2081: }
2082: static inline PetscBool PetscIsInfOrNanScalar(PetscScalar v)
2083: {
2084:   return PetscIsInfOrNanReal(PetscAbsScalar(v));
2085: }
2086: static inline PetscBool PetscIsNormalScalar(PetscScalar v)
2087: {
2088:   return PetscIsNormalReal(PetscAbsScalar(v));
2089: }

2091: PETSC_EXTERN PetscBool PetscIsCloseAtTol(PetscReal, PetscReal, PetscReal, PetscReal);
2092: PETSC_EXTERN PetscBool PetscEqualReal(PetscReal, PetscReal);
2093: PETSC_EXTERN PetscBool PetscEqualScalar(PetscScalar, PetscScalar);

2095: /*@C
2096:   PetscIsCloseAtTolScalar - Like `PetscIsCloseAtTol()` but for `PetscScalar`

2098:   Input Parameters:
2099: + lhs  - The first number
2100: . rhs  - The second number
2101: . rtol - The relative tolerance
2102: - atol - The absolute tolerance

2104:   Level: beginner

2106:   Note:
2107:   This routine is equivalent to `PetscIsCloseAtTol()` when PETSc is configured without complex
2108:   numbers.

2110: .seealso: `PetscIsCloseAtTol()`
2111: @*/
2112: static inline PetscBool PetscIsCloseAtTolScalar(PetscScalar lhs, PetscScalar rhs, PetscReal rtol, PetscReal atol)
2113: {
2114:   PetscBool close = PetscIsCloseAtTol(PetscRealPart(lhs), PetscRealPart(rhs), rtol, atol);

2116:   if (PetscDefined(USE_COMPLEX)) close = (PetscBool)(close && PetscIsCloseAtTol(PetscImaginaryPart(lhs), PetscImaginaryPart(rhs), rtol, atol));
2117:   return close;
2118: }

2120: /*
2121:     These macros are currently hardwired to match the regular data types, so there is no support for a different
2122:     MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again.
2123:  */
2124: #define MPIU_MATSCALAR MPIU_SCALAR

2126: /*MC
2127:    MatScalar - Datatype used inside matrix implementations to store matrix entries

2129:    Level: developer

2131:    Note:
2132:    `MatScalar` is currently a synonym for `PetscScalar`. It exists so that matrix internals can, in principle, store entries in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

2134: .seealso: `PetscScalar`, `MatReal`, `Mat`, `PETSC_USE_COMPLEX`
2135: M*/
2136: typedef PetscScalar MatScalar;

2138: /*MC
2139:    MatReal - Datatype used inside matrix implementations to store real-valued matrix data

2141:    Level: developer

2143:    Note:
2144:    `MatReal` is currently a synonym for `PetscReal`. It exists so that matrix internals can, in principle, store data in a different precision from the rest of PETSc. No PETSc matrix implementation currently exploits this.

2146: .seealso: `PetscReal`, `MatScalar`, `Mat`
2147: M*/
2148: typedef PetscReal MatReal;

2150: struct petsc_mpiu_2scalar {
2151:   PetscScalar a, b;
2152: };
2153: PETSC_EXTERN MPI_Datatype MPIU_2SCALAR PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2scalar);

2155: /* MPI Datatypes for composite reductions */
2156: struct petsc_mpiu_real_int {
2157:   PetscReal v;
2158:   PetscInt  i;
2159: };

2161: struct petsc_mpiu_scalar_int {
2162:   PetscScalar v;
2163:   PetscInt    i;
2164: };

2166: PETSC_EXTERN MPI_Datatype MPIU_REAL_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_real_int);
2167: PETSC_EXTERN MPI_Datatype MPIU_SCALAR_INT PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_scalar_int);

2169: #if defined(PETSC_USE_64BIT_INDICES)
2170: struct /* __attribute__((packed, aligned(alignof(PetscInt *)))) */ petsc_mpiu_2int {
2171:   PetscInt a;
2172:   PetscInt b;
2173: };
2174: struct __attribute__((packed)) petsc_mpiu_int_mpiint {
2175:   PetscInt    a;
2176:   PetscMPIInt b;
2177: };
2178: /*
2179:  static_assert(sizeof(struct petsc_mpiu_2int) == 2 * sizeof(PetscInt), "");
2180:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt *), "");
2181:  static_assert(alignof(struct petsc_mpiu_2int) == alignof(PetscInt[2]), "");

2183:  clang generates warnings that petsc_mpiu_2int is not layout compatible with PetscInt[2] or
2184:  PetscInt *, even though (with everything else uncommented) both of the static_asserts above
2185:  pass! So we just comment it out...
2186: */
2187: PETSC_EXTERN MPI_Datatype MPIU_2INT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_2int) */;
2188: PETSC_EXTERN MPI_Datatype MPIU_INT_MPIINT /* PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(struct petsc_mpiu_int_mpiint) */;
2189: #else
2190:   #define MPIU_2INT       MPI_2INT
2191:   #define MPIU_INT_MPIINT MPI_2INT
2192: #endif
2193: PETSC_EXTERN MPI_Datatype MPI_4INT;
2194: PETSC_EXTERN MPI_Datatype MPIU_4INT;

2196: static inline PetscInt PetscPowInt(PetscInt base, PetscInt power)
2197: {
2198:   PetscInt result = 1;
2199:   while (power) {
2200:     if (power & 1) result *= base;
2201:     power >>= 1;
2202:     if (power) base *= base;
2203:   }
2204:   return result;
2205: }

2207: static inline PetscInt64 PetscPowInt64(PetscInt base, PetscInt power)
2208: {
2209:   PetscInt64 result = 1;
2210:   while (power) {
2211:     if (power & 1) result *= base;
2212:     power >>= 1;
2213:     if (power) base *= base;
2214:   }
2215:   return result;
2216: }

2218: static inline PetscReal PetscPowRealInt(PetscReal base, PetscInt power)
2219: {
2220:   PetscReal result = 1;
2221:   if (power < 0) {
2222:     power = -power;
2223:     base  = ((PetscReal)1) / base;
2224:   }
2225:   while (power) {
2226:     if (power & 1) result *= base;
2227:     power >>= 1;
2228:     if (power) base *= base;
2229:   }
2230:   return result;
2231: }

2233: static inline PetscScalar PetscPowScalarInt(PetscScalar base, PetscInt power)
2234: {
2235:   PetscScalar result = (PetscReal)1;
2236:   if (power < 0) {
2237:     power = -power;
2238:     base  = ((PetscReal)1) / base;
2239:   }
2240:   while (power) {
2241:     if (power & 1) result *= base;
2242:     power >>= 1;
2243:     if (power) base *= base;
2244:   }
2245:   return result;
2246: }

2248: static inline PetscScalar PetscPowScalarReal(PetscScalar base, PetscReal power)
2249: {
2250:   PetscScalar cpower = power;
2251:   return PetscPowScalar(base, cpower);
2252: }

2254: /*MC
2255:    PetscApproximateLTE - Performs a less than or equal to on a given constant with a fudge for floating point numbers

2257:    Synopsis:
2258: #include <petscmath.h>
2259:    bool PetscApproximateLTE(PetscReal x,constant float)

2261:    Not Collective

2263:    Input Parameters:
2264: +   x - the variable
2265: -   b - the constant float it is checking if `x` is less than or equal to

2267:    Level: advanced

2269:    Notes:
2270:    The fudge factor is the value `PETSC_SMALL`

2272:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

2274:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2275:    floating point results.

2277:    Example\:
2278: .vb
2279:   PetscReal x;
2280:   if (PetscApproximateLTE(x, 3.2)) { // replaces if (x <= 3.2) {
2281: .ve

2283: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateGTE()`
2284: M*/
2285: #define PetscApproximateLTE(x, b) ((x) <= (PetscRealConstant(b) + PETSC_SMALL))

2287: /*MC
2288:    PetscApproximateGTE - Performs a greater than or equal to on a given constant with a fudge for floating point numbers

2290:    Synopsis:
2291: #include <petscmath.h>
2292:    bool PetscApproximateGTE(PetscReal x,constant float)

2294:    Not Collective

2296:    Input Parameters:
2297: +   x - the variable
2298: -   b - the constant float it is checking if `x` is greater than or equal to

2300:    Level: advanced

2302:    Notes:
2303:    The fudge factor is the value `PETSC_SMALL`

2305:    The constant numerical value is automatically set to the appropriate precision of PETSc so can just be provided as, for example, 3.2

2307:    This is used in several examples for setting initial conditions based on coordinate values that are computed with i*h that produces inexact
2308:    floating point results.

2310:    Example\:
2311: .vb
2312:   PetscReal x;
2313:   if (PetscApproximateGTE(x, 3.2)) {  // replaces if (x >= 3.2) {
2314: .ve

2316: .seealso: `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2317: M*/
2318: #define PetscApproximateGTE(x, b) ((x) >= (PetscRealConstant(b) - PETSC_SMALL))

2320: /*@C
2321:    PetscCeilInt - Returns the ceiling of the quotation of two positive integers

2323:    Not Collective

2325:    Input Parameters:
2326: +   x - the numerator
2327: -   y - the denominator

2329:    Level: advanced

2331:   Example\:
2332: .vb
2333:   PetscInt n = PetscCeilInt(10, 3); // n has the value of 4
2334: .ve

2336: .seealso: `PetscCeilInt64()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2337: @*/
2338: static inline PetscInt PetscCeilInt(PetscInt x, PetscInt y)
2339: {
2340:   return x / y + (x % y ? 1 : 0);
2341: }

2343: /*@C
2344:    PetscCeilInt64 - Returns the ceiling of the quotation of two positive integers

2346:    Not Collective

2348:    Input Parameters:
2349: +   x - the numerator
2350: -   y - the denominator

2352:    Level: advanced

2354:   Example\:
2355: .vb
2356:   PetscInt64 n = PetscCeilInt64(10, 3); // n has the value of 4
2357: .ve

2359: .seealso: `PetscCeilInt()`, `PetscMax()`, `PetscMin()`, `PetscAbsInt()`, `PetscAbsReal()`, `PetscApproximateLTE()`
2360: @*/
2361: static inline PetscInt64 PetscCeilInt64(PetscInt64 x, PetscInt64 y)
2362: {
2363:   return x / y + (x % y ? 1 : 0);
2364: }

2366: /*@C
2367:    PetscGCD - Returns the greatest common divisor of two integers

2369:    Not Collective

2371:    Input Parameters:
2372: +   a - first number
2373: -   b - second number

2375:    Level: advanced

2377: .seealso: `PetscLCM()`
2378: @*/
2379: static inline PetscInt PetscGCD(PetscInt a, PetscInt b)
2380: {
2381:   a = PetscAbsInt(a);
2382:   b = PetscAbsInt(b);
2383:   while (b != 0) {
2384:     PetscInt tmp = b;

2386:     b = a % b;
2387:     a = tmp;
2388:   }
2389:   return a;
2390: }

2392: /*@C
2393:    PetscLCM - Returns the least common multiple of two integers

2395:    Not Collective

2397:    Input Parameters:
2398: +   a - first number
2399: -   b - second number

2401:    Level: advanced

2403: .seealso: `PetscGCD()`
2404: @*/
2405: static inline PetscInt PetscLCM(PetscInt a, PetscInt b)
2406: {
2407:   PetscInt gcd;

2409:   a = PetscAbsInt(a);
2410:   b = PetscAbsInt(b);

2412:   gcd = PetscGCD(a, b);
2413:   return gcd ? a * (b / gcd) : 0;
2414: }

2416: PETSC_EXTERN PetscErrorCode PetscLinearRegression(PetscInt, const PetscReal[], const PetscReal[], PetscReal *, PetscReal *);