Skip to content
Snippets Groups Projects
Select Git revision
  • 5240b7eea1a63233977c6cf84b0f205d0e9cd168
  • master default protected
  • fix-petsc-no-mpi-boris
  • fix-petsc-no-mpi
  • rgpu
  • oras_vs_osm
  • abs-det
  • improvement_dfem
  • simplified
  • debug_jcjc
  • ddm_updates
  • gpu
  • fix-compile-without-mpi
  • lowfreq_PML
  • refactor
  • two_level_geom
  • ddofs_p2p
  • final_ddofs
  • final_ddofs_mr
  • new_ddofs
  • revert-543a9901
  • gmshfem_1_0_0
  • fwi112022
  • LagrangeValidation
24 results

Bessel.cpp

Blame
  • Bessel.cpp 6.86 KiB
    // GetDP - Copyright (C) 1997-2020 P. Dular and C. Geuzaine, University of Liege
    //
    // See the LICENSE.txt file for license information. Please report all
    // issues on https://gitlab.onelab.info/getdp/getdp/issues.
    
    #include "Bessel.h"
    #include <iostream>
    
    #if defined(HAVE_NO_FORTRAN)
    
    static void zbesj_(double*, double*, double*, int*, int*, double*,
        double*, int*, int*)
    {
      std::cerr << "Bessel functions require Fortran compiler" << std::endl;
    }
    
    static void zbesk_(double*, double*, double*, int*, int*, double*,
        double*, int*, int*)
    {
      std::cerr << "Bessel functions require Fortran compiler" << std::endl;
    }
    
    static void zbesy_(double*, double*, double*, int*, int*, double*,
        double*, int*, double*, double*, int*)
    {
      std::cerr << "Bessel functions require Fortran compiler" << std::endl;
    }
    
    static void zbesh_(double*, double*, double*, int*, int*, int*,
        double*, double*, int*, int*)
    {
      std::cerr << "Bessel functions require Fortran compiler" << std::endl;
    }
    
    static void zairy_(double*, double*, int*, int*, double*,
        double*, int*, int*)
    {
      std::cerr << "Bessel functions require Fortran compiler" << std::endl;
    }
    
    #else
    
    #if defined(HAVE_UNDERSCORE)
    #define zbesj_ zbesj
    #define zbesk_ zbesk
    #define zbesy_ zbesy
    #define zbesh_ zbesh
    #define zairy_ zairy
    #endif
    
    extern "C" {
      void zbesj_(double*, double*, double*, int*, int*, double*,
          double*, int*, int*);
      void zbesk_(double*, double*, double*, int*, int*, double*,
          double*, int*, int*);
    
      void zbesy_(double*, double*, double*, int*, int*, double*,
          double*, int*, double*,
          double*, int*);
      void zbesh_(double*, double*, double*, int*, int*, int*, double*,
          double*, int*, int*);
    
      void zairy_(double*, double*, int*, int*, double*,
          double*, int*, int*);
    }
    
    #endif
    
    static int BesselError(int ierr, const char *str)
    {
      static int warn=0;
    
      switch(ierr){
        case 0 :
          return 0;
        case 1 :
          std::cerr << "Input error in " << str << std::endl;
          return BESSEL_ERROR_INPUT;
        case 2 :
          return BESSEL_OVERFLOW;
        case 3 :
          if(!warn){
            std::cout << "Half machine accuracy lost in " << str << " (large argument or order)" << std::endl;
            warn = 1;
          }
          return BESSEL_HALF_ACCURACY;
        case 4 :
          std::cerr << "Complete loss of significance in " << str << " (argument or order too large)" << std::endl;
          return BESSEL_NO_ACCURACY;
        case 5 :
          std::cerr << "Failed to converge in " << str << std::endl;
          return BESSEL_NO_CONVERGENCE;
        default:
          std::cout << "Unknown Bessel status in " << str << " (" << ierr << ")" << std::endl;
          return ierr;
      }
    }
    
    // First kind Bessel functions
    
    int BesselJn(double n, int num, double x, double *val)
    {
      int nz = 0, ierr = 0, kode = 1;
      double xi = 0.0;
      double* ji = new double[num];
    
      zbesj_(&x, &xi, &n, &kode, &num, val, ji, &nz, &ierr) ;
    
      delete[] ji;
    
      return BesselError(ierr, "BesselJn");
    }
    
    int BesselJnComplex(double n, int num, double xr, double xi, double *valr, double *vali)
    {
      int nz = 0, ierr = 0, kode = 1;
    
      zbesj_(&xr, &xi, &n, &kode, &num, valr, vali, &nz, &ierr) ;
    
      return BesselError(ierr, "BesselJnComplex");
    }
    
    int BesselKnComplex(double n, int num, double xr, double xi, double *valr, double *vali)
    {
      int nz = 0, ierr = 0, kode = 1;
    
      zbesk_(&xr, &xi, &n, &kode, &num, valr, vali, &nz, &ierr) ;
    
      return BesselError(ierr, "BesselKnComplex");
    }
    
    int BesselSphericalJn(double n, int num, double x, double *val)
    {
      int ierr = BesselJn(n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI/x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselSphericalJn");
    }
    
    int BesselAltSphericalJn(double n, int num, double x, double *val)
    {
      int ierr = BesselJn(n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI*x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselAltSphericalJn");
    }
    
    // Second kind Bessel functions
    
    int BesselYn(double n, int num, double x, double *val)
    {
      int nz = 0, ierr = 0, kode = 1;
      double xi = 0.0;
      double* yi = new double[num];
      double* auxyr = new double[num];
      double* auxyi = new double[num];
    
      zbesy_(&x, &xi, &n, &kode, &num, val, yi, &nz, auxyr, auxyi, &ierr);
    
      delete[] yi;
      delete[] auxyr;
      delete[] auxyi;
    
      return BesselError(ierr, "BesselYn");
    }
    
    int BesselYnComplex(double n, int num, double xr, double xi, double *valr, double *vali)
    {
      int nz = 0, ierr = 0, kode = 1;
      double* auxyr = new double[num];
      double* auxyi = new double[num];
    
      zbesy_(&xr, &xi, &n, &kode, &num, valr, vali, &nz, auxyr, auxyi, &ierr) ;
    
      delete[] auxyr;
      delete[] auxyi;
    
      return BesselError(ierr, "BesselYnComplex");
    }
    
    int BesselSphericalYn(double n, int num, double x, double *val)
    {
      int ierr = BesselYn(n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI/x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselSphericalYn");
    }
    
    int BesselAltSphericalYn(double n, int num, double x, double *val)
    {
      int ierr = BesselYn(n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI*x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselAltSphericalYn");
    }
    
    // Hankel functions (type = 1 or 2)
    
    int BesselHn(int type, double n, int num, double x, std::complex<double> *val)
    {
      int nz = 0, ierr = 0, kode = 1;
      double* hr = new double[num];
      double* hi = new double[num];
      double xi = 0.0;
    
      zbesh_(&x, &xi, &n, &kode, &type, &num, hr, hi, &nz, &ierr);
    
      for(int i=0; i < num; i++){
        val[i] = std::complex<double>(hr[i], hi[i]);
      }
    
      delete[] hr;
      delete[] hi;
    
      return BesselError(ierr, "BesselHn");
    }
    
    int BesselSphericalHn(int type, double n, int num, double x, std::complex<double> *val)
    {
      int ierr = BesselHn(type, n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI/x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselSphericalHn");
    }
    
    int BesselAltSphericalHn(int type, double n, int num, double x, std::complex<double> *val)
    {
      int ierr = BesselHn(type, n+0.5, num, x, val);
      double coef = sqrt(0.5*M_PI*x);
      for(int i = 0; i < num; i++){
        val[i] *= coef;
      }
      return BesselError(ierr, "BesselAltSphericalHn");
    }
    
    // Airy Function and derivative (id=1)
    
    int AiryComplex(double xr, double xi, int id, double *valr, double *vali)
    {
      int nz = 0, ierr = 0, kode = 1;
    
      zairy_(&xr, &xi, &id, &kode, valr, vali, &nz, &ierr);
      //val = std::complex<double>(valr, vali);
    
      return BesselError(ierr, "AiryComplex");
    }
    
    // Utilities for backward compatibility
    
    double Spherical_j_n(int n, double x)
    {
      double res;
      BesselSphericalJn(n, 1, x, &res);
      return res;
    }
    
    double AltSpherical_j_n(int n, double x)
    {
      double res;
      BesselAltSphericalJn(n, 1, x, &res);
      return res;
    }
    
    double Spherical_y_n(int n, double x)
    {
      double res;
      BesselSphericalYn(n, 1, x, &res);
      return res;
    }
    
    double AltSpherical_y_n(int n, double x)
    {
      double res;
      BesselAltSphericalYn(n, 1, x, &res);
      return res;
    }