// pde_cylinderical_eq.c cylinderical coordinates // solve del^2 U(radius,theta,z) + U(radius,theta,z) = f(r,t,z) // given Dirchlet boundary values Ub(r,t,z), and f(r,t,z) // Much checking in this code, analytic solution is // U(r,t,z) = r^3 + t^3/216 + z^3 // // f(r,t,z) := 12*r + 1/36*t/(r^2) + 6*z // r^3 + 1/216*t^3 + z^3 // // x = r cos theta 0 <= theta < 2 Pi // y = r sin theta r < 0 restriction for derivative // z = z z double // r = sqrt(x^2+y^2+z^2) // theta = arctan(y,x) if theta<0 theta = 2 Pi + arctan(y,x) // z = z // // use existing partial derivative computation in Cartesian coordinates to // compute partial derivatives in cylinderical coordinates // // compute del U(radius,theta,z) r=radius, t=theta angle, z=height // del U = (d/dr U, 1/r d/dt U, d/dz U) // // compute del^2 U(radius,theta,z) r=radius, t=theta angle, z=height // del^2 U = d/dr(r d/dr U) + 1/r^2 d^2/dt^2 U + d^2/dz^2 U // = 2/r d/dr U + d^2/dr^2 U + 1/r^2 d^2/dt^2 U + d^2/dz^2 U #include #include #include #include "nuderiv.h" #include "simeq.h" #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)) #define Nr 5 // number radius #define Nt 7 // number theta angle #define Nz 5 // number Z coordinates #define Nrtz (Nr-2)*(Nt-2)*(Nz-2) // matrix, equations static double A[Nrtz][Nrtz+1]; // no bound, has RHS static double X[Nrtz]; // computed solution to U static double Rg[Nr]; // r grid values static double Tg[Nt]; // theta grid values static double Zg[Nz]; // z grid values static double Ua[Nr*Nt*Nz]; // analytic solution for checking static double Cr[Nr]; // first deriv wrt r static double Crr[Nr]; // second deriv wrt r static double Ctt[Nt]; // second deriv wrt t static double Czz[Nz]; // second deriv wrt z // Ub for computing boundaries and checking computed solution double Ub(double R, double T, double Z) { return R*R*R + T*T*T/216.0 + Z*Z*Z; } // end Ub // analytic derivatives for checking double Ur(double R, double T, double Z) { return 3.0*R*R; } // end Ur double Urr(double R, double T, double Z) { return 6.0*R; } // end Urr double Ut(double R, double T, double Z) { return 3.0*T*T/216.0; } // end Ut double Utt(double R, double T, double Z) { return 6.0*T/216.0; } // end Utt double Uz(double R, double T, double Z) { return 3.0*Z*Z; } // end Uz; double Uzz(double R, double T, double Z) { return 6.0*Z; } // end Uzz double Uuu(double R, double T, double Z) { return 2.0*Ur(R,T,Z)/R + Urr(R,T,Z) + Utt(R,T,Z)/(R*R) + Uzz(R,T,Z); } // end Uuu; double D2(double Urv, double Urrv, double Uttv, double Uzzv, double R) { return 2.0*Urv/R + Urrv + Uttv/(R*R)+ Uzzv; } // end D2 int S(int i, int j, int k) { // index of each grid point return i*Nt*Nz + j*Nz + k; } // end S int Sd(int i, int j, int k) { // index of each grid point inside boundary, A and X return (i-1)*(Nt-2)*(Nz-2) + (j-1)*(Nz-2) + (k-1); } // end Sd double F(double R, double T, double Z) { return 12.0*R + (1.0/36.0)*T/(R*R) + 6.0*Z + R*R*R + (1.0/216.0)*T*T*T + Z*Z*Z; } // end F RHS void build_A() // A is discrete system of equations, including Y { // solution is X, from A*X=Y int Row, Idof, Cs; double Urrs, Utts, Uzzs, Ud2ck, Err; double Err1, Err2, Err3 ; double R, T, Z; int i, j, k, ii, jj, kk; // equation Urrs(r,t,z)+Utts(r,t,z)+Uzzs(r,t,z)+U(r,t,z) = f(r,t,z) // for every (r,t,z) inside boundary printf("building discrete system of %d equations\n", Nrtz); Cs = Nrtz; // RHS // initialize A and X for(i=1; i 0.001) { printf("[%1d][%1d][%1d] Ud2ck=%e, Err=%e\n", i, j, k, Ud2ck, Err); } } // k if(2==2) // debug print { Err1 = 0.0; Err2 = 0.0; Err3 = 0.0; for(ii=1; ii0.0001) printf("R error\n"); Tmp = atan2(Yt,Xt); if(Tmp<0.0) Tmp = 2.0*Pi + Tmp; if(abs(Tmp-T)>0.0001) printf("Theta error\n"); } // k } // j } // i for(i=0; i