// pde_sphere.c given sphere boundary values, numerically solve PDE // r is radius, t is theta angle from X axis, p is phi angle from Z axis // spherical coordinates x = r*cos(t)*sin(p) r = sqrt(x*x+y*y+z*z) // y = r*sin(t)*sin(p) t = atan2(y,x) // z = r*cos(p) p = atan(sqrt(x*x+y*y)/z) // r > 0 0 <= theta < 2Pi (2Pi==0) 0 < phi < Pi not zero or Pi // infinite del and laplacian // // ^ ^ ^ // del U(r,t,p) = r dU/dr + t 1/r*sin(p) dU/dt + p 1/r dU/dp // // laplacian del^2 U(r,t,p) = 1/(r*r) d/dr(r*r dU/dr) + // 1/(r*r*sin(p)*sin(p)) d^2U/dt^2 // 1/(r*r*sin(p)) d/dp(sin(p) dU/dp) + // simplify: = (2/r) dU/dr + d^2U/dr^2 + // (1/(r*r sin(p)*sin(p))) d^2U/dt^2 + // (cos(p)/(r*r sin(p))) dU/dp + // (1/(r*r)) d^2U/dp^2 #include "deriv.h" #include "simeq.h" #include #include #include #undef abs #define abs(a) ((a)<0.0?(-(a)):(a)) #undef min #define min(a,b) ((a)<(b)?(a):(b)) #undef max #define max(a,b) ((a)>(b)?(a):(b)) static const double Pi = 3.1415926535897932384626433832795028841971; // number of radius #define Nr 5 // number of theta angles #define Nt 6 // number of phi angles #define Np 7 // all points #define Nrtp Nr*Nt*Np // inside boundary #define nrow (Nr-2)*(Nt-2)*(Np-2) #define ncol nrow+1 #define debug 1 static double Cr[Nr]; // first deriv wrt r static double Crr[Nr]; // second deriv wrt r static double Ct[Nt]; // first deriv wrt t static double Ctt[Nt]; // second deriv wrt t static double Cp[Np]; // first deriv wrt p static double Cpp[Np]; // second deriv wrt p static double ut[nrow][ncol]; // simultaneous equation matrix static double Us[nrow]; // solution values inside boundary static double Rg[Nr]; // r grid values static double Tg[Nt]; // theta grid values static double Pg[Np]; // p grid values static int S0(int i, int j, int k) // index into matrix { // index of each grid point return i*Nt*Np + j*Np + k; } // end S static int S(int i, int j, int k) // for zero based matrix i=1..Nr-2 // j=1..Nt-2 k=1..Np-2 { if(i<1 || i>Nr-2 || j<1 || j>Nt-2 || k<1 || k>Np-2) printf("BAD S i=%2d, j=%2d, k=%2d \n", i, j, k); return (i-1)*(Nt-2)*(Np-2)+(j-1)*(Np-2)+(k-1); // index into us and ut } // end S static double xval(double r, double theta, double phi) { return r*cos(theta)*sin(phi); } // end xval static double yval(double r, double theta, double phi) { return r*sin(theta)*sin(phi); } // end yval static double zval(double r, double theta, double phi) { return r*cos(phi); } // end zval static double rval(double x, double y, double z) { return sqrt(x*x+y*y+z*z); } // end rval static double thetaval(double x, double y, double z) { double t = atan2(y,x); if(t<0.0) t = 2.0*Pi+t; return t; } // end thetaval static double phival(double x, double y, double z) { double p = atan(sqrt(x*x+y*y)/z); if(p<0.0) p = Pi+p; return p; } // end phival static void checkxyzrtp(double Rg[], double Tg[], double Pg[]) { double x, y, z, x2, y2, z2; double R, T, P, r, theta, phi; double maxxerr, maxyerr, maxzerr, maxrerr, maxterr, maxperr; int i, j, k; printf("check xval, yval, zval, rval, thetaval, phival \n"); maxxerr = 0.0; maxyerr = 0.0; maxzerr = 0.0; maxrerr = 0.0; maxterr = 0.0; maxperr = 0.0; for(i=0; iNr-2 || j<1 || j>Nt-2 || k<1 || k>Np-2) printf("Ub(%d,%d,%d) = %4.4f \n", i, j, k, Ub(Rg[i],Tg[j],Pg[k])); else printf(" U(%d,%d,%d) = %4.4f %4.4f \n", i, j, k, Us[S(i,j,k)], Ub(Rg[i],Tg[j],Pg[k])); } // k printf(" \n"); } // j printf(" \n"); } // i printf("pde_sphere.c finished \n"); return 0; } // end pde_sphere.c