简体   繁体   中英

What should I change in the 'gamma' function?

My algorithm calculates the electromagnetic shielding of multiple glasses, I have a problem with the gamma function, the debugger returns this error:

[Warning] conflicting types for built-in function 'gamma'; expected 'double(double)' [-Wbuiltin-declaration-mismatch].

The error on the debugger is reported on line 34 of the file"struttura_dati.h"

main.c

#include "struttura_dati.h"

int
main (int argc, char *argv[])
{
  struct_layer *layer;
  struct_interf *interf;
  int n_layer = 6, il, nfreq, ifreq;
  double freq = 1.0E9;
  double se;
  double fmin = 100.0E6, fmax = 10.0E9, fstep = 1.0E6;
  FILE *pfo = NULL;
  char string[255];


  /* Structure allocation */
  layer = (struct_layer *) malloc (sizeof (struct_layer) * (size_t) n_layer);
  interf = (struct_interf *) malloc (sizeof (struct_interf) * ((size_t) n_layer - 1));

  /* Layer values (first test) */
  layer[0].epsr = 1.0;
  layer[0].mur = 1.0;
  layer[0].sigma = 0.0;
  layer[0].thick = 0.0;     // infinite thickness
  layer[1].epsr = 5.0;
  layer[1].mur = 1.0;
  layer[1].sigma = 1.0E-3;
  layer[1].thick = 0.004;
  layer[2].epsr = 1.0;
  layer[2].mur = 1.0E3;
  layer[2].sigma = 1.0E4;
  layer[2].thick = 5.0E-6;
  layer[3].epsr = 1.0;
  layer[3].mur = 1.0;
  layer[3].sigma = 0.0;
  layer[3].thick = 0.01;
  layer[4].epsr = 5.0;
  layer[4].mur = 1.0;
  layer[4].sigma = 1.0E-3;
  layer[4].thick = 0.004;
  layer[5].epsr = 1.0;
  layer[5].mur = 1.0;
  layer[5].sigma = 0.0;
  layer[5].thick = 0.0;     // infinite thickness

  /* Layer values (Ezio - AGC values) */
  layer[0].epsr = 1.0;
  layer[0].mur = 1.0;
  layer[0].sigma = 0.0;
  layer[0].thick = 0.0;     // infinite thickness
  layer[1].epsr = 7.0;
  layer[1].mur = 1.0;
  layer[1].sigma = 0.001;
  layer[1].thick = 0.006;
  layer[2].epsr = 1.0;
  layer[2].mur = 1;
  layer[2].sigma = 61730000;
  layer[2].thick = 6.0E-9;
  layer[3].epsr = 1.0;
  layer[3].mur = 1.0;
  layer[3].sigma = 0.0;
  layer[3].thick = 0.015;
  layer[4].epsr = 7.0;
  layer[4].mur = 1.0;
  layer[4].sigma = 0.001;
  layer[4].thick = 0.004;
  layer[5].epsr = 1.0;
  layer[5].mur = 1.0;
  layer[5].sigma = 0.0;
  layer[5].thick = 0.0;     // infinite thickness

  /* Scan of the whole band */
  sprintf (string, "SE_Multilayer_dB.txt");
  if ((pfo = fopen (string, "w")) == NULL)
    exit (EXIT_FAILURE);

  nfreq = (fmax - fmin) / fstep + 1;
  for (ifreq = 0; ifreq < nfreq; ifreq++)
    {
      freq = fmin + ifreq * fstep;

      /* Compute the layer parameters */
      for (il = 0; il < n_layer; il++)
    gamma (&layer[il], freq);

      /* Compute the layer interfaces */
      for (il = 0; il < n_layer - 1; il++)
    interf2layer (&layer[il], &layer[il + 1], &interf[il]);

      /* Compute the layer fields */
      layer[5].e_piu = 1.0 + I * 0.0;
      layer[5].e_meno = 0.0 + I * 0.0;
      //fields_last(&layer[4], &layer[5], &interf[4], (double complex) 1, (double complex) 0);
      for (il = n_layer - 2; il >= 0; il--)
    fields (&layer[il], &layer[il + 1], &interf[il], layer[il + 1].e_piu, layer[il + 1].e_meno);

      se = 20 * log10 (cabs (layer[0].e_piu));

      fprintf (pfo, "%g\t%g\n", freq * 1.0E-9, se);
      printf ("Frequency: %g (GHz) - Shielding Effectiveness (dB): %g \n", freq*1.0E-9,se); 
    }
  fclose (pfo);
  printf ("Computed %d points in the band %g - %g (GHz)\n", nfreq, fmin * 1.0E-9, fmax * 1.0E-9);
  printf ("Results are in the file: %s\n", string);

  /* Structure free */
  free (layer);
  free (interf);
  exit (0);
}

function.c

#include "struttura_dati.h"

void
gamma (struct_layer * layer, double freq)
{
  double omega, epsr2, tgd2;

  omega = 2 * PI * freq;
  epsr2 = layer->sigma / (omega * EPS0);
  tgd2 = epsr2 * epsr2 / (layer->epsr * layer->epsr);
  layer->alfa = omega * sqrt (layer->mur * MU0 * layer->epsr * EPS0 * 0.5 * (sqrt (1 + tgd2) - 1));
  layer->beta = omega * sqrt (layer->mur * MU0 * layer->epsr * EPS0 * 0.5 * (sqrt (1 + tgd2) + 1));
  layer->gamma = layer->alfa + I * layer->beta;
  layer->eta = csqrt (layer->mur * MU0 / ((layer->epsr - I * epsr2) * EPS0));
}

/* evaluates the transmission and reflection coefficients between two layers (from l1 to l2) */
void
interf2layer (struct_layer * l1, struct_layer * l2, struct_interf * interf)
{
  double complex rho, tt;

  rho = (l2->eta - l1->eta) / (l2->eta + l1->eta);
  tt = 1 + rho;
  interf->rho = rho;
  interf->tt = tt;
}

/* evaluates the forward and backward field in a layer from the fields of next layer */
void
fields (struct_layer * l1, struct_layer * l2, struct_interf * interf, double complex enext_piu,
    double complex enext_meno)
{
  double complex exp_piu, exp_meno;

  exp_piu = cexp (l2->gamma * l2->thick);
  exp_meno = cexp (-l2->gamma * l2->thick);

  l1->e_piu = (exp_piu * enext_piu + interf->rho * exp_meno * enext_meno) / interf->tt;
  l1->e_meno = (interf->rho * exp_piu * enext_piu + exp_meno * enext_meno) / interf->tt;

}

/* evaluates the forward and backward field in the second to last layer from the fields of next layer */
void
fields_last (struct_layer * l1, struct_layer * l2, struct_interf * interf, double complex enext_piu,
         double complex enext_meno)
{
  double complex exp_piu, exp_meno;

  exp_piu = 1.0 + I * 0;
  exp_meno = 1.0 + I * 0;

  l1->e_piu = (exp_piu * enext_piu + interf->rho * exp_meno * enext_meno) / interf->tt;
  l1->e_meno = (interf->rho * exp_piu * enext_piu + exp_meno * enext_meno) / interf->tt;

}

struttura_dati.h

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

#define PI 3.1415926535897932384626
#define EPS0 8.8541878176203898505366E-12
#define MU0 1.2566370614359172953E-06
#define C0 299792458.0      /* Mettere il `.0` finale altrimenti lo potrebbe prendere come intero */
#define ETA0 376.7303134617706554682

typedef struct
{
/* Layer values */
  double epsr;
  double mur;
  double sigma;
  double thick;
  double alfa;
  double beta;
  double complex gamma;
  double complex eta;
  double complex e_piu;
  double complex e_meno;
} struct_layer;

typedef struct
{
/* Layer interfaces */
  double complex rho;
  double complex tt;
} struct_interf;

void gamma (struct_layer * layer, double freq);
void interf2layer (struct_layer * l1, struct_layer * l2, struct_interf * interf);
void fields (struct_layer * l1, struct_layer * l2, struct_interf * interf, double complex enext_piu,
         double complex enext_meno);
void fields_last (struct_layer * l1, struct_layer * l2, struct_interf * interf, double complex enext_piu,
          double complex enext_meno);

Name conflict

To avoid the warning

[Warning] conflicting types for built-in function 'gamma'; expected 'double(double)' [-Wbuiltin-declaration-mismatch].

Use a different name. Although gamma() is not in the C17 standard library, it is likely a library extension in OP's math library.

Turn off your library's extension of functions like gamma() .

Alternatively, do not include <math.h> , but that then loses sqrt() , etc.

Could use static gamma() and some other clever name-space tricks, yet certainly easiest to change OPs's gamma() to something else.


namespace pollution

struttura_dati.h defines macros and objects all over the namespace and unnecessarily includes various <.h> files. I'd reduce what is in struttura_dati.h o the minimum and employ a more uniform naming.


Minor: Reduce precision loss

I'd experiment with hypot() to reduce precision loss.

// tgd2 = epsr2 * epsr2 / (layer->epsr * layer->epsr);
// layer->alfa = omega * sqrt (layer->mur * MU0 * layer->epsr * EPS0 * 0.5 * 
//     (sqrt (1 + tgd2) - 1));

double tgd = epsr2 / layer->epsr;
layer->alfa = omega * sqrt (layer->mur * MU0 * layer->epsr * EPS0 * 0.5 * 
    (hypot(1, tgd) - 1));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM