/* pde_spherical_eq.c sphereical coordinates * solve del^2 U(radius,theta,phi) + U(radius,theta,phi) = f(r,t,p) * given Dirchlet boundary values Ub(r,t,p), and f(r,t,p) * much checking in this code * analytical solution is U(r,t,p)=r^3 + t^3/216 + p^3/27 * * x = r cos(theta) sin(phi) 0 <= theta < 2 Pi * y = r sin(theta) sin(phi) 0 < phi <= Pi restricted for derivatives * z = r cos(phi) r < 0 restricted for derivatives * r = sqrt(x^2+y^2+z^2) * theta = arctan(y,x) if theta<0 then theta = 2 Pi + arctan(y,x) * phi = arctan(sqrt(x^2+y^2),z) * * use existing partial derivative computation in Cartesian coordinates to * compute partial derivatives in spherical coordinates * * compute del U(radius,theta,phi) r=radius, t=theta angle, p=phi angle * del U = (d/dr U, 1/(r sin(p) d/dt U 1/r^2 d/dp U) * * compute del^2 U(radius,theta,phi) r=radius, t=theta angle, p=phi angle * del^2 U = 1/r^2 d/dr(r^2 d/dr U) + 1/(r^2 sin(p)^2) d^2/dt^2 U + * 1/(r^2 sin(p)) d/dp(sin(p) d/dp U * = (2/r) d/dr U + d^2/dr^2 U + (1/(r^2 sin(p)^2)) d^2/dt^2 U + * (cos(p)/(r^2 sin(p)) d/dp U + (1/r^2) d^2/dp^2 U * * f(r,t,p) := 12*r + (1/36)*t/(r^2*sin(p)^2) + * (1/9)*cos(p)*p^2/(r^2*sin(p)) + (2/9)*p/r^2 + * r^3 + (1/216)*t^3 + (1/27)*p^3 */ #include #include #include #include "simeq.h" #include "nuderiv.h" #undef max #define max(a,b) ((a)>(b)?(a):(b)) #undef abs #define abs(a) ((a)<0.0?(-(a)):(a)) #define Nr 5 #define Nt 7 #define Np 5 #define Nrtp (Nr-2)*(Nt-2)*(Np-2) /* DOF */ static double Rg[Nr]; /* r grid values */ static double Tg[Nt]; /* theta grid values */ static double Pg[Np]; /* p grid values */ static double Ua[Nr*Nt*Np]; /* boundary and analytic solution for check */ static double Ud2[Nr*Nt*Np]; /* del^2 for check */ 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 A[Nrtp][Nrtp+1]; /* no bound, has RHS */ static double X[Nrtp]; static double Ub(double R, double T, double P); /* boundary values */ static double Ur(double R, double T, double P); static double Urr(double R, double T, double P); static double Ut(double R, double T, double P); static double Utt(double R, double T, double P); static double Up(double R, double T, double P); static double Upp(double R, double T, double P); static double Uuu(double R, double T, double P); static double D2(double Urv, double Urrv, double Uttv, double Upv, double Uppv, double R, double P); static int S(int I, int J, int K); static int Sd(int I, int J, int K); static double f(double r, double t, double p); /* RHS */ static void build_A(); int main(int argc, char *argv[]) { double Pi = 3.1415926535897932384626433832795028841971; double Rmin = 0.3; double Rmax = 1.0; double Tmin = 0.1; double Tmax = 300.0*Pi/180.0; double Pmin = 0.2; double Pmax = Pi-0.5; double R, T, P, Ana, Cmp, Err; double Urv, Urrv, Uttv, Upv, Uppv; /* computed derivatives */ double Maxerrur=0.0, Maxerrurr=0.0, Maxerrutt=0.0; double Maxerrup=0.0, Maxerrupp=0.0, Maxerr=0.0; int I, J, K, Ii, Jj, Kk; printf("pde_spherical_eq.c starting\n"); printf("r gird values, not equally spaced\n"); Rg[0] = 0.3; Rg[1] = 0.5; Rg[2] = 0.7; Rg[3] = 0.9; Rg[4] = 1.0; for(I=0; I 0.001) printf("[%1d,%1d,%1d] Ud2ck=%g, Err=%g\n", I, J, K, Ud2ck, Err); if(row==2) /* debug print */ { Err1 = 0.0; Err2 = 0.0; Err3 = 0.0; for(Ii=1; Ii