⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 f_analytic.c

📁 cfd求解器使用与gmsh网格的求解
💻 C
📖 第 1 页 / 共 2 页
字号:
#define RCSID "$Id: F_Analytic.c,v 1.26 2006/02/26 00:42:53 geuzaine Exp $"/* * Copyright (C) 1997-2006 P. Dular, C. Geuzaine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to <getdp@geuz.org>. * * Contributor(s): *   Ruth Sabariego */#include "GetDP.h"#include "Data_DefineE.h"#include "F_Function.h"#include "GeoData.h"#include "Numeric.h"#include "Numeric_F.h"#include "Get_Geometry.h"#include "Cal_Value.h" #include "CurrentData.h"#include "Legendre.h"#include "SphBessel.h"/* ------------------------------------------------------------------------ *//*  Warning: the pointers A and V can be identical. You must                *//*           use temporary variables in your computations: you can only     *//*           affect to V at the very last time (when you're sure you will   *//*           not use A any more).                                           *//* ------------------------------------------------------------------------ */#define F_ARG    struct Function * Fct, struct Value * A, struct Value * V/* some utility functions to deal with complex numbers */typedef struct {  double r;  double i;} cplx;static cplx Csum(cplx a, cplx b){  cplx s;  s.r = a.r + b.r;  s.i = a.i + b.i;  return(s);}static cplx Csub(cplx a, cplx b){  cplx s;  s.r = a.r - b.r;  s.i = a.i - b.i;  return(s);}static cplx Cprod(cplx a, cplx b){  cplx s;  s.r = a.r * b.r - a.i * b.i;  s.i = a.r * b.i + a.i * b.r;  return(s);}static cplx Cdiv(cplx a, cplx b){  cplx s;  double den;  den = b.r * b.r + b.i * b.i;  s.r = (a.r * b.r + a.i * b.i) / den;  s.i = (a.i * b.r - a.r * b.i) / den;  return(s);}static cplx Cconj(cplx a){  cplx s;  s.r = a.r;  s.i = -a.i;  return(s);}static cplx Cneg(cplx a){  cplx s;  s.r = -a.r;  s.i = -a.i;  return(s);}static double Cmodu(cplx a){  return(sqrt(a.r * a.r + a.i * a.i));}static cplx Cpow(cplx a, double b){  cplx s;  double mod, arg;  mod = a.r * a.r + a.i * a.i;  arg = atan2(a.i,a.r);  mod = pow(mod,0.5*b);  arg *= b;  s.r = mod * cos(arg);  s.i = mod * sin(arg);  return(s);}static cplx Cprodr(double a, cplx b){  cplx s;  s.r = a * b.r;  s.i = a * b.i;  return(s);}/* ------------------------------------------------------------------------ *//*  Exact solutions for spheres                                               *//* ------------------------------------------------------------------------ *//* Solid and hollow sphere, in magnetostatics and magnetodynamics. Returns    field at any point */void  F_Sphere (F_ARG) {  double  x, y, z ;  double  sxr, sxi, syr, syi, szr, szi ;   double  mur, sigma, freq, r0, r1 ;  GetDP_Begin("F_Sphere");  x = Current.x; y = Current.y; z = Current.z;    mur = Fct->Para[1] ; sigma = Fct->Para[2] ; freq = Fct->Para[3] ;  r0  = Fct->Para[4] ; r1    = Fct->Para[5] ;  if (r0 == 0.0){  /* sphere pleine */    if (Fct->Para[0] == 0){ /* induction */      solsph_(&x,&y,&z,&sxr,&sxi,&syr,&syi,&szr,&szi,&mur,&sigma,&freq,&r1);      }    else {      Msg(GERROR, "Not done ...");    }  }  else{  /* sphere creuse */    Msg(GERROR, "Not done ...");  }  if (Current.NbrHar == 1) {    V->Val[0] = sxr ; V->Val[1] = syr ; V->Val[2] = szr ;  }  else {    V->Val[0] = sxr ; V->Val[1] = syr ; V->Val[2] = szr ;    V->Val[MAX_DIM] = sxi ; V->Val[MAX_DIM+1] = syi ; V->Val[MAX_DIM+2] = szi ;  }  V->Type = VECTOR ;  GetDP_End ;}/* Scattering by solid PEC sphere. Returns theta-component of surface   current */void F_JFIE_SphTheta(F_ARG){    double k0, r, kr, e0, eta, theta, phi, a1, b1, c1, d1, den1, P, P0, dP ;  double ctheta, stheta, cteRe1, cteRe2, a2, b2, c2, d2, den2 ;  int i, n ;  GetDP_Begin("F_JFIE_SphTheta") ;    theta = atan2(sqrt( A->Val[0]* A->Val[0] + A->Val[1]*A->Val[1] ),  A->Val[2]);  phi = atan2( A->Val[1], A->Val[0] ) ;  k0  = Fct->Para[0] ;  eta = Fct->Para[1] ;  e0  = Fct->Para[2] ;  r   = Fct->Para[3] ;       kr = k0*r ;  n = 50 ;    V->Val[0] = 0.;  V->Val[MAX_DIM] = 0. ;  if ( theta == 0. ) theta += 1e-7; /* Warning! This is an approximation. */  if ( theta == PI || theta == -PI ) theta -= 1e-7;  for (i = 1 ; i <= n ; i++ ){    ctheta = cos(theta);    stheta = sin(theta);        P =  Legendre(i,1,ctheta);    P0 = Legendre(i,0,ctheta);    dP = (i+1)*i* P0/stheta-(ctheta/(ctheta*ctheta-1))* P;    cteRe1 = (2*i+1) * stheta * dP/i/(i+1);    cteRe2 = (2*i+1) * P/stheta/i/(i+1);    a1 = cos((1-i)*PI/2) ;    b1 = sin((1-i)*PI/2) ;    c1 = -AltSpherical_j_n(i+1, kr) + (i+1) * AltSpherical_j_n(i, kr)/kr ; /* Derivative */    d1 = -(-AltSpherical_y_n(i+1, kr) + (i+1) * AltSpherical_y_n(i, kr)/kr) ;       a2 =  cos((2-i)*PI/2) ;    b2 =  sin((2-i)*PI/2) ;        c2 =  AltSpherical_j_n(i, kr) ;    d2 = -AltSpherical_y_n(i, kr) ;     den1 = c1*c1+d1*d1 ;    den2 = c2*c2+d2*d2 ;        V->Val[0] += cteRe1*(a1*c1+b1*d1)/den1 +  cteRe2*(a2*c2+b2*d2)/den2 ;     V->Val[MAX_DIM] += cteRe1*(b1*c1-a1*d1)/den1 + cteRe2*(b2*c2-a2*d2)/den2 ;  }     V->Val[0] *= e0*cos(phi)/eta/kr ;  V->Val[MAX_DIM] *= e0*cos(phi)/eta/kr  ;    V->Type = SCALAR ;  GetDP_End;} /* Scattering by solid PEC sphere. Returns theta-component of RCS */void F_RCS_SphTheta(F_ARG){    double k0, r, kr, e0, rinf, krinf, theta, phi, a1 =0., b1=0., d1, den1, P, P0, dP ;  double J, J_1, dJ, ctheta, stheta, cteRe1, cteRe2, a2, b2, d2, den2, lambda ;  int i, n ;  GetDP_Begin("F_RCS_SphTheta") ;    theta = atan2(sqrt( A->Val[0]* A->Val[0] + A->Val[1]*A->Val[1] ),  A->Val[2]);  phi = atan2( A->Val[1], A->Val[0] ) ;  k0  = Fct->Para[0] ;  e0 = Fct->Para[1] ;  r  = Fct->Para[2] ;  rinf   = Fct->Para[3] ;       kr = k0*r ;  krinf = k0*rinf ;  lambda = 2*PI/k0 ;  n = 50 ;    if ( theta == 0. ) theta += 1e-7; /* Warning! This is an approximation. */  if ( theta == PI || theta == -PI ) theta -= 1e-7;  for (i = 1 ; i <= n ; i++ ){    ctheta = cos(theta);    stheta = sin(theta);        P =  Legendre(i,1,ctheta);    P0 = Legendre(i,0,ctheta);    dP = (i+1)*i* P0/stheta-(ctheta/(ctheta*ctheta-1))* P;         J = AltSpherical_j_n(i, kr) ;    J_1 = AltSpherical_j_n(i+1, kr) ;    dJ = -J_1 + (i + 1) * J/kr ;     cteRe1 = -(2*i+1) * stheta * dP * dJ /i/(i+1);    cteRe2 = (2*i+1) * P * J /stheta/i/(i+1);    d1 = -(-AltSpherical_y_n(i+1, kr) + (i+1) * AltSpherical_y_n(i, kr)/kr) ;        d2 = -AltSpherical_y_n(i, kr) ;         den1 = dJ*dJ+d1*d1 ;    den2 = J*J+d2*d2 ;        a1 += cteRe1 * dJ /den1 +  cteRe2 * J /den2 ;     b1 += cteRe1*(-d1) /den1 + cteRe2*(-d2) /den2 ;  }  a2 = e0*cos(phi)*sin(krinf)/krinf ;  b2 = e0*cos(phi)*cos(krinf)/krinf ;   V->Val[0] = 10*log10( 4*PI*SQU(rinf/lambda)*(SQU(a1*a2-b1*b2) + SQU(a1*b2+a2*b1)) );  V->Val[MAX_DIM] = 0. ;    V->Type = SCALAR ;  GetDP_End;}/* Scattering by solid PEC sphere. Returns phi-component of surface current */void F_JFIE_SphPhi(F_ARG){    double k0, r, kr, e0, eta, theta, phi, a1, b1, c1, d1, den1, P, P0, dP ;  double ctheta, stheta, cteRe1, cteRe2, a2, b2, c2, d2, den2 ;  int i, n ;  GetDP_Begin("F_JFIE_SphPhi") ;    theta = atan2( sqrt( A->Val[0]*A->Val[0] + A->Val[1]*A->Val[1] ), A->Val[2]);  phi = atan2( A->Val[1], A->Val[0] ) ;  k0  = Fct->Para[0] ;  eta = Fct->Para[1] ;  e0  = Fct->Para[2] ;  r   = Fct->Para[3] ;       kr = k0*r ;  n = 50 ;    V->Val[0] = 0.;  V->Val[MAX_DIM] = 0. ;    if ( theta == 0. ) theta += 1e-7; /* Warning! This is an approximation. */  if ( theta == PI || theta == -PI ) theta -= 1e-7;   for (i = 1 ; i <= n ; i++ ){    ctheta = cos(theta);    stheta = sin(theta);    P =  Legendre(i,1,ctheta);    P0 = Legendre(i,0,ctheta);    dP = (i+1)*i* P0/stheta - ctheta/(ctheta*ctheta-1)*P; /* Derivative */    cteRe1 = (2*i+1) * P /i/(i+1)/stheta;    cteRe2 = (2*i+1) * stheta * dP/i/(i+1);    a1 = cos((1-i)*PI/2) ;    b1 = sin((1-i)*PI/2) ;    c1 = -AltSpherical_j_n(i+1, kr) + (i+1)*AltSpherical_j_n(i, kr)/kr ; /* Derivative */    d1 = -(-AltSpherical_y_n(i+1, kr) + (i+1)*AltSpherical_y_n(i, kr)/kr) ;        a2 =  cos((2-i)*PI/2) ;    b2 =  sin((2-i)*PI/2) ;        c2 =  AltSpherical_j_n(i, kr) ;    d2 =  -AltSpherical_y_n(i, kr) ;         den1 = c1*c1+d1*d1 ;    den2 = c2*c2+d2*d2 ;        V->Val[0] += cteRe1*(a1*c1+b1*d1)/den1 +  cteRe2*(a2*c2+b2*d2)/den2 ;     V->Val[MAX_DIM] += cteRe1*(b1*c1-a1*d1)/den1 + cteRe2*(b2*c2-a2*d2)/den2 ;  }    V->Val[0] *= e0*sin(phi)/eta/kr ;  V->Val[MAX_DIM] *= e0*sin(phi)/eta/kr  ;    V->Type = SCALAR ;  GetDP_End;}/* Scattering by solid PEC sphere. Returns phi-component of RCS */void F_RCS_SphPhi(F_ARG){    double k0, r, kr, e0, rinf, krinf, theta, phi, a1 =0., b1=0., d1, den1, P, P0, dP ;  double J, J_1, dJ, ctheta, stheta, cteRe1, cteRe2, a2, b2, d2, den2, lambda ;  int i, n ;  GetDP_Begin("F_RCS_SphPhi") ;    theta = atan2(sqrt( A->Val[0]* A->Val[0] + A->Val[1]*A->Val[1] ),  A->Val[2]);  phi = PI/2 ;  k0  = Fct->Para[0] ;  e0 = Fct->Para[1] ;  r  = Fct->Para[2] ;  rinf   = Fct->Para[3] ;       kr = k0*r ;  krinf = k0*rinf ;  lambda = 2*PI/k0 ;  n = 50 ;    if ( theta == 0. ) theta += 1e-7; /* Warning! This is an approximation. */  if ( theta == PI || theta == -PI ) theta -= 1e-7;  for (i = 1 ; i <= n ; i++ ){    ctheta = cos(theta);    stheta = sin(theta);        P =  Legendre(i,1,ctheta);    P0 = Legendre(i,0,ctheta);    dP = (i+1)*i* P0/stheta-(ctheta/(ctheta*ctheta-1))* P;         J = AltSpherical_j_n(i, kr) ;    J_1 = AltSpherical_j_n(i+1, kr) ;    dJ = -J_1 + (i + 1) * J/kr ;     cteRe1 = -(2*i+1) * P * dJ /stheta/i/(i+1);    cteRe2 = (2*i+1) * stheta * dP * J/i/(i+1);    d1 = -(-AltSpherical_y_n(i+1, kr) + (i+1) * AltSpherical_y_n(i, kr)/kr) ;    d2 = -AltSpherical_y_n(i, kr) ;         den1 = dJ*dJ+d1*d1 ;    den2 = J*J+d2*d2 ;        a1 += cteRe1 * dJ /den1 +  cteRe2 * J /den2 ;     b1 += cteRe1*(-d1) /den1 + cteRe2*(-d2) /den2 ;  }  a2 = e0*sin(phi)*sin(krinf)/krinf ;  b2 = e0*sin(phi)*cos(krinf)/krinf ;   V->Val[0] = 10*log10( 4*PI*SQU(rinf/lambda)*(SQU(a1*a2-b1*b2) + SQU(a1*b2+a2*b1)) );  V->Val[MAX_DIM] = 0. ;    V->Type = SCALAR ;  GetDP_End;} /* Scattering by solid acoustically soft sphere (exterior Dirichlet   problem) by incident plane wave in the direction of the negative   z-axis. Returns total field at any exterior point.   J.J. Bowman, T.B.A. Senior and P.L.E. Uslenghi, Electromagnetic and   Acoustic Scattering by Simple Shapes, p. 358    In:   k: wave number   a: sphere radius   r: r coord in spherical coords   theta: theta coord in spherical coords   Out:   total field V_i+V_s*/void  F_AcousticSoftSphere(F_ARG){#define N 50  double k, a, r, theta, ka, kr, fact;  int n;  double jnka[N], jnkr[N], hnkar[N], hnkai[N], hnkrr[N], hnkri[N];  struct Value V_tmp, V_tmp2, V_mi, V_jnka, V_jnkr, V_hnka, V_hnkr, V_an;  GetDP_Begin("F_AcousticSoftSphere") ;    k     = A->Val[0];  a     = (A+1)->Val[0];  r     = (A+2)->Val[0];  theta = (A+3)->Val[0];  kr = k*r ;  ka = k*a ;  V->Type         = SCALAR ;  V->Val[0]       = 0.;  V->Val[MAX_DIM] = 0. ;  V_tmp.Type = V_tmp2.Type = SCALAR;  V_mi.Type = V_jnka.Type = V_jnkr.Type = SCALAR;  V_hnka.Type = V_hnkr.Type = V_an.Type = SCALAR;  n = 0;  Spherical_j_nArray(n,kr,N,&jnkr[0]);  Spherical_j_nArray(n,ka,N,&jnka[0]);  Spherical_h_nArray(1,n,kr,N,hnkrr,hnkri);  Spherical_h_nArray(1,n,ka,N,hnkar,hnkai);  /* to compare with gsl/python */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -