ΠΑΡΑΔΕΙΓΜΑ 17 ΥΠΟΛΟΓΙΣΤΙΚΕΣ ΜΕΘΟΔΟΙ, 005-006, 5 Ο ΕΞΑΜΗΝΟ ΕΡΓΑΣΙΑ #: ΣΥΝΗΘΕΙΣ ΔΙΑΦΟΡΙΚΕΣ ΕΞΙΣΩΣΕΙΣ ΠΡΟΒΛΗΜΑΤΑ ΟΡΙΑΚΩΝ ΤΙΜΩΝ Επιμέλεια απαντήσεων: Ιωάννης Λυχναρόπουλος Ομάδα Α: Άσκηση Έχουμε να επιλύσουμε την εξίσωση: du 1 du u 1 1 dr r dr (Α1) du με οριακές συνθήκες u(1) 0 και u (0) πεπερασμένη ή 0 (συνθήκη dr r 0 συμμετρίας). Η αναλυτική λύση της διαφορικής εξίσωσης δίνεται με τη βοήθεια του Mathematica: DSolveu''r 1 u'r1, u10, u'00,ur,r r 1 και είναι: ur () (1 r) 4 Αρχικά διακριτοποιούμε το πεδίο ορισμού: Χωρίζουμε την ακτίνα σε Ν ίσα 1 διαστήματα (Ν+1 κόμβους) πλάτους r N 0 r 1 1 N N+1 r=0 i-1 i i+1 r=1 Έτσι για τη ζητούμενη παροχή θα έχουμε: Q uda Q ru( r) dr 1 0 Η αναλυτική τιμή της Q είναι ίση με 0.39699 8 Προσεγγίζουμε τη διαφορική εξίσωση (Α1) στον τυχαίο κόμβο i : u u u 1 u u i1 i i1 i1 i1 r ri r 1
1 1 1 1 ui 1 ui u i1 1 r ri r r, (Α) r rir για τους εσωτερικούς κόμβους i,..., N όπου r ( i1) r Για i N 1 έχουμε: u 1 0 N Για i 1 θα χρησιμοποιήσουμε την οριακή συνθήκη μαζί με την διαφορική εξίσωση: du d u 1 du d u Παρατηρούμε ότι το limr 0 lim dr r 0 lim dr r0 rdr r 1 dr du uo u1u 1 Έτσι η (1) γράφεται: 1 (Α3) dr r du u u0 Η οριακή συνθήκη: 0 0uo u (Α4) dr r0 r Ό κόμβος i 0 είναι φανταστικός. Οι (Α3) και (Α4) δίνουν τελικά: 4u 4u r 1 (Α5) i Το σύστημα που προκύπτει είναι τριδιαγώνιο και θα επιλυθεί με την μέθοδο Τhomas. Για το ολοκλήρωμα της παροχής Q χρησιμοποιούμε κανόνα τραπεζίου: R r Q ru( r) dr [ ru 1 1 ru... rnun rn 1uN1] 0 Έστω ένα αραιό πλέγμα με Ν=3 (Δr =1/3). Τότε έχουμε να λύσουμε το σύστημα: 4 4 0 u1 1/9 4.5 18 13.5 u 1 0 6.75 18u 3 1 To οποίο δίνει: u 0.5 u u 1 3 0. 0.138889 u (από οριακή συνθήκη) 4 0 Οι τιμές ταυτίζονται με αυτές της αναλυτικής λύσης στα σημεία 0, 1/3, /3, 1. 1 Q [0(0.5) (1/ 3)(0.) ( / 3)(0.138889) 1(0)] 0.348734 3
Το πρόγραμμα σε Fortran είναι το ακόλουθο: Program Poisson (σε 1 διάσταση) implicit none doubleprecision,allocatable::a(:),b(:),c(:),d(:),x(:),r(:) doubleprecision:: dr,q,s integer::n,i,status n=3!arithmos diasthmatwn -> n+1 komboi allocate(a(n),b(n),c(n-1),x(n+1),d(n),r(n+1)) if (status/=0) Stop 'Not enough memory' dr=1./n do i=1,n+1 r(i)=(i-1)*dr x(n+1)=0 b(1)=4. c(1)=-4. a(i)=1./dr**-1./(.*r(i)*dr) b(i)=-./dr** if (i<n) then c(i)=1./dr**+1./(.*r(i)*dr) d(1)=dr** d(i)=-1 print*, '-------------' call Thomas(n,a,b,c,d,x) do i=1,n print '(I3,4H u(,f10.5,4h) =,D0.5,D0.5)',i,r(i),x(i),(1-r(i)**)/4 print '(I3,4H u(,f10.5,4h) =,D0.5,D0.5)',n+1,r(n+1),0,0 s=0 s=s+*r(i)*x(i) s=s+r(1)*x(1)+r(n+1)*x(n+1) q= 3.14 * dr * s print*, 'q=',s,q contains subroutine Thomas(n,a,b,c,d,x) integer,intent(in) :: n doubleprecision, INTENT(INOUT) ::a(n),b(n),c(n),d(n) doubleprecision, INTENT(OUT) ::x(n) integer::i doubleprecision ::t(n),u(n) t(1)=b(1) u(1)=d(1)/t(1) t(i)=b(i)-a(i)*c(i-1)/t(i-1) u(i)=(d(i)-a(i)*u(i-1))/t(i)
end x(n)=u(n) do i=n-1,1,-1 x(i)=u(i)-c(i)/t(i)*x(i+1) end subroutine Thomas Δίνουμε ενδεικτικά αποτέλεσματα για Ν=100. Δίπλα στις αριθμητικές τιμές παρουσιάζονται οι αντίστοιχες αναλυτικές οι οποίες ταυτίζονται!!! 1 u(0.00000) = 0.5000D+00 0.5000D+00 u(0.01000) = 0.4997D+00 0.4998D+00 3 u(0.0000) = 0.4990D+00 0.4990D+00 4 u(0.03000) = 0.4977D+00 0.4977D+00 5 u(0.04000) = 0.4960D+00 0.4960D+00 6 u(0.05000) = 0.4937D+00 0.4938D+00 7 u(0.06000) = 0.4910D+00 0.4910D+00 8 u(0.07000) = 0.4877D+00 0.4877D+00 9 u(0.08000) = 0.4840D+00 0.4840D+00 10 u(0.09000) = 0.4797D+00 0.4798D+00 11 u(0.10000) = 0.4750D+00 0.4750D+00 1 u(0.11000) = 0.4697D+00 0.4698D+00 13 u(0.1000) = 0.4640D+00 0.4640D+00 14 u(0.13000) = 0.4577D+00 0.4577D+00 15 u(0.14000) = 0.4510D+00 0.4510D+00 16 u(0.15000) = 0.4437D+00 0.4438D+00 17 u(0.16000) = 0.4360D+00 0.4360D+00 18 u(0.17000) = 0.477D+00 0.477D+00 19 u(0.18000) = 0.4190D+00 0.4190D+00 0 u(0.19000) = 0.4097D+00 0.4097D+00 1 u(0.0000) = 0.4000D+00 0.4000D+00 u(0.1000) = 0.3897D+00 0.3897D+00 3 u(0.000) = 0.3790D+00 0.3790D+00 4 u(0.3000) = 0.3677D+00 0.3678D+00 5 u(0.4000) = 0.3560D+00 0.3560D+00 6 u(0.5000) = 0.3437D+00 0.3438D+00 7 u(0.6000) = 0.3310D+00 0.3310D+00 8 u(0.7000) = 0.3177D+00 0.3178D+00 9 u(0.8000) = 0.3040D+00 0.3040D+00 30 u(0.9000) = 0.897D+00 0.898D+00 31 u(0.30000) = 0.750D+00 0.750D+00 3 u(0.31000) = 0.597D+00 0.598D+00 33 u(0.3000) = 0.440D+00 0.440D+00 34 u(0.33000) = 0.77D+00 0.78D+00 35 u(0.34000) = 0.110D+00 0.110D+00 36 u(0.35000) = 0.1937D+00 0.1937D+00 37 u(0.36000) = 0.1760D+00 0.1760D+00 38 u(0.37000) = 0.1577D+00 0.1577D+00 39 u(0.38000) = 0.1390D+00 0.1390D+00 40 u(0.39000) = 0.1197D+00 0.1197D+00 41 u(0.40000) = 0.1000D+00 0.1000D+00 4 u(0.41000) = 0.0797D+00 0.0797D+00 43 u(0.4000) = 0.0590D+00 0.0590D+00 44 u(0.43000) = 0.0377D+00 0.0378D+00 45 u(0.44000) = 0.0160D+00 0.0160D+00 46 u(0.45000) = 0.19937D+00 0.19937D+00 47 u(0.46000) = 0.19710D+00 0.19710D+00 48 u(0.47000) = 0.19477D+00 0.19477D+00 49 u(0.48000) = 0.1940D+00 0.1940D+00 50 u(0.49000) = 0.18997D+00 0.18998D+00 51 u(0.50000) = 0.18750D+00 0.18750D+00 5 u(0.51000) = 0.18497D+00 0.18498D+00 53 u(0.5000) = 0.1840D+00 0.1840D+00 54 u(0.53000) = 0.17977D+00 0.17977D+00 55 u(0.54000) = 0.17710D+00 0.17710D+00 56 u(0.55000) = 0.17437D+00 0.17438D+00 57 u(0.56000) = 0.17160D+00 0.17160D+00 58 u(0.57000) = 0.16877D+00 0.16877D+00 59 u(0.58000) = 0.16590D+00 0.16590D+00 60 u(0.59000) = 0.1697D+00 0.1698D+00 61 u(0.60000) = 0.16000D+00 0.16000D+00
6 u(0.61000) = 0.15697D+00 0.15698D+00 63 u(0.6000) = 0.15390D+00 0.15390D+00 64 u(0.63000) = 0.15077D+00 0.15077D+00 65 u(0.64000) = 0.14760D+00 0.14760D+00 66 u(0.65000) = 0.14437D+00 0.14437D+00 67 u(0.66000) = 0.14110D+00 0.14110D+00 68 u(0.67000) = 0.13777D+00 0.13777D+00 69 u(0.68000) = 0.13440D+00 0.13440D+00 70 u(0.69000) = 0.13097D+00 0.13097D+00 71 u(0.70000) = 0.1750D+00 0.1750D+00 7 u(0.71000) = 0.1397D+00 0.1398D+00 73 u(0.7000) = 0.1040D+00 0.1040D+00 74 u(0.73000) = 0.11677D+00 0.11678D+00 75 u(0.74000) = 0.11310D+00 0.11310D+00 76 u(0.75000) = 0.10937D+00 0.10938D+00 77 u(0.76000) = 0.10560D+00 0.10560D+00 78 u(0.77000) = 0.10177D+00 0.10178D+00 79 u(0.78000) = 0.97900D-01 0.97900D-01 80 u(0.79000) = 0.93975D-01 0.93975D-01 81 u(0.80000) = 0.90000D-01 0.90000D-01 8 u(0.81000) = 0.85975D-01 0.85975D-01 83 u(0.8000) = 0.81900D-01 0.81900D-01 84 u(0.83000) = 0.77775D-01 0.77775D-01 85 u(0.84000) = 0.73600D-01 0.73600D-01 86 u(0.85000) = 0.69375D-01 0.69375D-01 87 u(0.86000) = 0.65100D-01 0.65100D-01 88 u(0.87000) = 0.60775D-01 0.60775D-01 89 u(0.88000) = 0.56400D-01 0.56400D-01 90 u(0.89000) = 0.51975D-01 0.51975D-01 91 u(0.90000) = 0.47500D-01 0.47500D-01 9 u(0.91000) = 0.4975D-01 0.4975D-01 93 u(0.9000) = 0.38400D-01 0.38400D-01 94 u(0.93000) = 0.33775D-01 0.33775D-01 95 u(0.94000) = 0.9100D-01 0.9100D-01 96 u(0.95000) = 0.4375D-01 0.4375D-01 97 u(0.96000) = 0.19600D-01 0.19600D-01 98 u(0.97000) = 0.14775D-01 0.14775D-01 99 u(0.98000) = 0.99000D-0 0.99000D-0 100 u(0.99000) = 0.49750D-0 0.49750D-0 101 u(1.00000) = 0.00000D+00 0.00000D+00 ΠΑΡΟΧΗ: q = 0.39460763111710 Ομάδα Β Θεωρούμε ότι η τετραγωνική πλάκα έχει πλευρά ίση με 1m. Επίσης h=5 W/m C, k=300 W/m C και T 5 C. Έχουμε να επιλύσουμε τη διαφορική εξίσωση Laplace: T T T 0 0 (Β1) x y με οριακές συνθήκες: T T( x,0) 50, T( x,1) 100, T(1, y) 50 και για x 0 : k h( T T ). x Διακριτοποιούμε το πεδίο ορισμού 0 x, y 1: xωρίζουμε την κάθε πλευρά σε Ν ίσα 1 διαστήματα (N+1 κόμβους) πλάτους H N Έτσι για τις οριακές συνθήκες έχουμε: T( x,1) 100 T(1, j) 100 T( x,0) 50 T( n1, j) 50 T(1, y) 50 T( i, n1) 50
T Για x 0 διακριτοποιούμε την k h( T T ) με πεπερασμένες διαφορές στον x κόμβο (1, j ) και παίρνουμε: T, j T1, j hh hh k h( T1, j T) T, j T1, j T1, j T H k k hh hh T1, j ( T, j T )/(1 ) για j=,,n (Β) k k Επίσης διακριτοποιούμε την (Β1) στον τυχαίο κόμβο (, i j) και παίρνουμε τον τύπο των 5 σημείων: 1 Ti, j ( Ti 1, jti1, jti, j1 Ti, j1 ) γιαi,..., N και j,..., N (Β3) 4 Έτσι θα έχουμε για τις διάφορες μεθόδους επίλυσης συστημάτων: Μέθοδος Jacobi ( n1) ( n) hh hh T1, j ( T, j T )/(1 ) για j,..., N ( i 1) k k ( n1) 1 ( ) ( ) ( ) ( ), ( n n n n Ti j Ti 1, j Ti 1, j Ti, j1 Ti, j1 ) για i,..., N και j,..., N 4 Μέθοδος Gauss-Seidel ( n1) ( n) hh hh T1, j ( T, j T )/(1 ) για j,..., N ( i 1) k k ( n1) 1 ( ) ( 1) ( ) ( 1), ( n n n n Ti j Ti 1, j Ti 1, j Ti, j1 Ti, j1 ) γιαi,..., N και 4 j,..., N (Ο υπολογισμός γίνεται από το πάνω μέρος της τετραγωνικής πλάκας προς τα κάτω και από αριστερά προς τα δεξιά) Μέθοδος SOR ( n1) ( n) hh hh ( n) T1, j ( T, j T )/(1 ) (1 ) T1, j για j,..., N ( i 1) k k ( n1) 1 ( ) ( 1) ( ) ( 1) ( ), ( n n n n 1, 1,, 1, 1 ) (1 ) n Ti j Ti j Ti j Ti j Ti j Ti, j 4 γιαi,..., N και j,..., N Το πρόγραμμα σε Fortran είναι: Μέθοδοι Jacobi, Gauss-Seidel, SOR Program Jacobi_GaussSeidel_SOR implicit none doubleprecision,allocatable::t(:,:),told(:,:) integer::n,i,j,k,kk,h,status,maxi,done,method doubleprecision::s,rel,err,max doubleprecision::t0,hh,w
n=50 allocate(t(n+1,n+1),told(n+1,n+1)) if (status/=0) Stop 'Not enough memory' maxi=150000 rel=0.00000001 print*, 'n=',n,'rel=',rel hh=1./n h=5 kk=300 t0=5 do method=1,3!1=jacobi, =gauss-seidel, 3=SOR if (method==1) then t(:,:)=0. t(1,:)=100. t(n+1,:)=50. t(:,n+1)=50. told(:,:)=t(:,:)! print*,x0(:)!read* k=1 done=0 do while (k<=maxi.and. done==0) do j=1,n if (j==1) then t(i,1)=(told(i,)-(h*hh/kk)*t0)/(1-(h*hh/kk)) else t(i,j)= 0.5*(told(i,j+1)+told(i,j-1)+told(i+1,j)+told (i-1,j))! elenxos gia termatismo max=-1 do j=1,n err = abs((t(i,j) - told(i,j))/t(i,j)) if (err>max) then max=err if (max<rel) then done=1 told(:,:)=t(:,:) k=k+1 open(11,file='res_jacobi.txt',recl=10000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(11,*) t(i,:) print*, 'Jacobi' print*, k-1,max print*,'------------------------'
elseif (method==) then!gauss-seidel t(:,:)=0. t(1,:)=100. t(n+1,:)=50. t(:,n+1)=50. k=1 done=0 do while (k<=maxi.and. done==0) told(:,:)=t(:,:) do j=1,n if (j==1) then t(i,1)=(t(i,)-(h*hh/kk)*t0)/(1-(h*hh/kk)) else t(i,j)= 0.5*(t(i,j+1)+t(i,j-1)+t(i+1,j)+t(i-1,j))! elenxos gia termatismo max=-1 do j=1,n err = abs((t(i,j) - told(i,j))/t(i,j)) if (err>max) then max=err if (max<rel) then done=1 k=k+1 open(1,file='res_gauss.txt',recl=1000) do i=n+1,1,-1 write(1,*) t(i,:) print*, 'Gauss Seidel' print*, k-1,max print*, '-------------------------------' elseif (method==3) then!sor do w=1.88,1.99,0.01 k=1 done=0 t(:,:)=0. t(1,:)=100. t(n+1,:)=50. t(:,n+1)=50. do while (k<=maxi.and. done==0) told(:,:)=t(:,:) do j=1,n if (j==1) then t(i,1)=w*(t(i,)-(h*hh/kk)*t0)/(1-(h*hh/kk))+(1-w)*t(i,1) else t(i,j)= 0.5*w*(t(i,j+1)+t(i,j-1)+t(i+1,j)+t(i-1,j))+(1-w)*t(i,j)
! elenxos gia termatismo max=-1 do j=1,n err = abs((t(i,j) - told(i,j))/t(i,j)) if (err>max) then max=err if (max<rel) then done=1 k=k+1 open(13,file='res_sor.txt',recl=1000) do i=n+1,1,-1 write(13,*) t(i,:) print*, 'SOR' print*, k-1,w end Ο έλεγχος σύγκλισης γίνεται με κριτήριο το μέγιστο σχετικό σφάλμα από όλα τα στοιχεία του πίνακα να είναι μικρότερο από μία δεδομένη τιμή. Ανοίγοντας το αρχείο res_jacobi.txt μέσα από το πρόγραμμα Compaq Array Visualizer και επιλέγοντας τύπο γραφήματος Image Map παίρνουμε τα ακόλουθα γραφήματα: N=51
Ν=101 Ν=01 Αντίστοιχα γραφήματα παίρνουμε για όλες τις μεθόδους.
Στον επόμενο πίνακα φαίνεται συγκεντρωτικά ο αριθμός επαναλήψεων μέχρι την σύγκλιση ανά μέθοδο και πλήθος κόμβων: Κριτήριο τερματισμού: Σχετικό σφάλμα < 10-4 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 537 154 146 ( 1.89) 19 ( 1.90) 111 ( 1.91) 117 ( 1.9) 139 ( 1.93) 101x101 6099 4009 374 ( 1.9) 330 ( 1.93) 8 ( 1.94) 8 ( 1.95) 37 ( 1.96) 01x01 1190 8794 650 ( 1.96) 499 ( 1.97) 485 ( 1.98) 98 ( 1.99) Κριτήριο τερματισμού: Σχετικό σφάλμα < 10-6 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 685 3430 31 ( 1.89) 197 ( 1.90) 176 ( 1.91) 01 ( 1.9) 101x101 0469 11376 569 ( 1.93) 471 ( 1.94) 36 ( 1.95) 401 ( 1.96) 01x01 63556 36303 105 ( 1.96) 865 ( 1.97) 801 ( 1.98) 153 ( 1.99) Κριτήριο τερματισμού: Σχετικό σφάλμα < 10-8 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 10093 5335 316 ( 1.89) 65 ( 1.90) 08 ( 1.91) 35 ( 1.9) 101x101 35645 18967 659 ( 1.94) 476 ( 1.95) 475 ( 1.96) 65 ( 1.97) 01x01 1404 66588 1761 ( 1.96) 13 ( 1.97) 971 ( 1.98) 001 ( 1.99)
Μέθοδος ADI Για απλούστευση θα μελετήσουμε την περίπτωση που έχουμε αριστερά την απλή οριακή συνθήκη τύπου Dirichlet T(0,y) = 50. ( n 1 ) ( n) i1, j( ) i, j i1, j i, j1 ( ) i, j i, j1 T T T T T T γιαi,..., N και j,..., N ( n1) ( n1 ) i, j1 ( ) i, j i, j1 i1, j( ) i, j i1, j T T T T T T γιαi,..., N και j,..., N Στον παρακάτω αλγόριθμο σε κάθε βήμα αντί να λύσουμε δύο τριδιαγώνια συστήματα n-1xn-1 αγνώστων (ένα για την κατεύθυνση x και ένα για την κατεύθυνση y), λύνουμε n-1 τριδιαγώνια συστήματα n-1 αγνώστων στην κατεύθυνση x και n-1 τριδιαγώνια συστήματα n-1 αγνώστων στην κατεύθυνση y. Program ADI implicit none doubleprecision,allocatable::a(:),b(:),c(:),d(:),x(:),t(:,:),tnew(:,:),told(:,:) integer::nn=10,n,m,i,j,k,l,status=0,maxl,done doubleprecision::s,max,rel,err,rr n=nn- allocate(a(n),b(n),c(n-1),x(n),d(n),t(nn,nn),tnew(nn,nn),told(nn,nn)) if (status/=0) Stop 'Not enough memory' T(:,:)=50. T(1,:)=100. T(nn,:)=100. T(:,1)=50. T(:,nn)=50. Tnew(:,:)=T(:,:) rr=0.1 A(:)=1. B(:)=-(.+rr) C(:)=1. maxl=30000 rel=0.01 l=1 done=0 do while (l<=maxl.and. done==0 ) Told(:,:)= T(:,:) do k=,nn-1 do j=,nn-1 s=-(t(k-1,j)-(.-rr)*t(k,j)+t(k+1,j)) if (j==) then D(j-1)=s-T(k,j-1) elseif (j==nn-1) then D(j-1)=s-T(k,j+1) else D(j-1)=s
call Thomas(n,a,b,c,d,x) Tnew(k,:nn-1)=x! print*, 'd=', d(:)! print*, 'x=',x(:)!read* T(:,:)=Tnew(:,:) do k=,nn-1 n-1 s=-(t(i,k-1)-(.-rr)*t(i,k)+t(i,k+1)) if (i==) then D(i-1)=s-T(i-1,k) elseif (i==nn-1) then D(i-1)=s-T(i+1,k) else D(i-1)=s call Thomas(n,a,b,c,d,x) Tnew(:nn-1,k)=x T(:,:)=Tnew(:,:)! elenxos gia termatismo max=-1 do i=1,nn do j=1,nn err = abs((t(i,j) - told(i,j))/t(i,j)) * 100. if (err>max) then max=err if (max<rel) then done=1 l=l+1 print*, '-------------'!do i=1,nn! print*, T(i,:)! open(14,file='res_adi.txt',recl=10000) do i=nn,1,-1 write(14,*) t(i,:) print*, l-1,max contains subroutine Thomas(n,a,b,c,d,x) integer,intent(in) :: n
doubleprecision, INTENT(IN) ::a(n),b(n),c(n),d(n) doubleprecision, INTENT(OUT) ::x(n) doubleprecision ::t(n),u(n) integer :: i t(1)=b(1) u(1)=d(1)/t(1) t(i)=b(i)-a(i)*c(i-1)/t(i-1) u(i)=(d(i)-a(i)*u(i-1))/t(i) x(n)=u(n) do i=n-1,1,-1 x(i)=u(i)-c(i)/t(i)*x(i+1) end subroutine Thomas end H ADI συγκλίνει σε 5 επαναλήψεις και για Ν=50 δίνει το παρακάτω γράφημα:
Ομάδα Γ: Άσκηση 1 Επιλύουμε τη διαφορική εξίσωση Poisson: u u u 1 1 x y με οριακές συνθήκες ux (,0) ux (,1) u(0, y) u(1, y) 0. (Γ1) Αρχικά διακριτοποιούμε το πεδίο ορισμού 0 x, y 1: xωρίζουμε την κάθε πλευρά 1 σε Ν ίσα διαστήματα (N+1 κόμβους) πλάτους h N Στη συνέχεια διακριτοποιούμε την (Γ1) στον τυχαίο κόμβο (, i j) και παίρνουμε τον τύπο των 5 σημείων: 1 ui, j ( ui 1, jui1, jui, j1 ui, j1 h ) για i,..., N και j,..., N (Γ) 4 Για την επίλυση του συστήματος θα χρησιμοποιήσουμε τις μεθόδους Jacobi, Gauss- Seidel και SOR Jacobi ( n1) 1 ( ) ( ) ( ) ( ), ( n n n n ui j ui 1, j ui 1, j ui, j1 ui, j1 h ) γιαi,..., N και 4 j,..., N Gauss-Seidel ( n1) 1 ( ) ( 1) ( ) ( 1), ( n n n n ui j ui 1, j ui 1, j ui, j1 ui, j1 h ) γιαi,..., N και 4 j,..., N (Ο υπολογισμός γίνεται από πάνω προς τα κάτω και από αριστερά προς τα δεξιά) SOR u 1 ( u 4 u u u h ) (1 ) u γιαi,..., N και j,..., N ( n1) ( n) ( n1) ( n) ( n1) ( n) i, j i1, j i1, j i, j1 i, j1 i, j Για τον υπολογισμό της ζητούμενης παροχής θα έχουμε: 1 1 Q uda Q u( x, y) dxdy 0 0 και βάσει του κανόνα του τραπεζίου θα είναι: h Q [ u1,1u1, N1uN1,1uN1, N1 4 N N N N N N u u u u 4 u ] 1, j N1, j i,1 i, N1 i, j j j i i i j
Program Jacobi_GaussSeidel_SOR implicit none doubleprecision,allocatable::u(:,:),uold(:,:) integer::n,i,j,k,kk,h,status,maxi,done,method,l doubleprecision::s,rel,err,max,s1,s,q doubleprecision::hh,w n=50 allocate(u(n+1,n+1),uold(n+1,n+1)) if (status/=0) Stop 'Not enough memory' maxi=50000 rel=0.00000001 hh=1./n do method=1,3!1=jacobi, =gauss-seidel, 3=SOR u(:,:)=0. if (method==1) then uold(:,:)=u(:,:)! print*,x0(:)!read* k=1 done=0 do while (k<=maxi.and. done==0) do j=,n u(i,j)= 0.5*(uold(i,j+1)+uold(i,j-1)+uold(i+1,j)+uold (i-1,j)+hh**)! elenxos gia termatismo max=-1 do j=,n err = abs((u(i,j) - uold(i,j))/u(i,j)) if (err>max) then max=err if (max<rel) then done=1 uold(:,:)=u(:,:) k=k+1 open(11,file='res_jacobi.txt',recl=10000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(11,*) u(i,:) print*, 'Jacobi' print*, k-1,max print*,'------------------------' elseif (method==) then!gauss-seidel k=1 done=0
do while (k<=maxi.and. done==0) uold(:,:)=u(:,:) do j=,n u(i,j)= 0.5*(u(i,j+1)+u(i,j-1)+u(i+1,j)+u(i-1,j)+hh**)! elenxos gia termatismo max=-1 do j=,n err = abs((u(i,j) - uold(i,j))/u(i,j)) if (err>max) then max=err if (max<rel) then done=1 k=k+1 open(1,file='res_gauss.txt',recl=1000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(1,*) u(i,:) print*, 'Gauss Seidel' print*, k-1,max print*, '-------------------------------' elseif (method==3) then!sor do w=1.8,1.99,0.01 k=1 done=0 u(:,:)=0.!w=1.90 do while (k<=maxi.and. done==0) uold(:,:)=u(:,:) do j=,n u(i,j)= 0.5*w*(u(i,j+1)+u(i,j-1)+u(i+1,j)+u(i-1,j)+hh**)+(1-w)*u(i,j)! elenxos gia termatismo max=-1 do j=,n err = abs((u(i,j) - uold(i,j))/u(i,j)) if (err>max) then max=err if (max<rel) then done=1
k=k+1 open(13,file='res_sor.txt',recl=1000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(13,*) u(i,:) print*, 'SOR' print*, k-1,w!ypologismos ths paroxhs q s1=0 do l=,n s1=s1+u(l,1)+u(l,n+1)+u(1,l)+u(n+1,l) s=0 do i=,n do j=,n s=s+u(i,j) q=(u(1,1)+u(1,n+1)+u(n+1,1)+u(n+1,n+1)+*s1+4*s)*hh**/4 print*,q end Ενδεικτικά για N=4 (πλέγμα 5x5) θα έχουμε με τη Jacobi τα εξής αποτελέσματα: Ταχύτητες (u ) 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 4.96074E-0 5.4677963E-0 4.96074E-0 0.0000000E+00 0.0000000E+00 5.4677963E-0 7.099149E-0 5.4677963E-0 0.0000000E+00 0.0000000E+00 4.96074E-0 5.4677963E-0 4.96074E-0 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 Παροχή: Q=0.088037
Στον επόμενο πίνακα φαίνεται συγκεντρωτικά ο αριθμός επαναλήψεων μέχρι την σύγκλιση ανά μέθοδο και πλήθος κόμβων: Σχετικό σφάλμα< 10-4 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 1591 967 117 ( 1.86) 108 ( 1.87) 10 ( 1.88) 104 ( 1.89) 101x101 389 59 34 ( 1.9) 05 ( 1.93) 04 ( 1.94) 08 ( 1.95) 01x01 7301 547 411 ( 1.96) 404 ( 1.97) 450 ( 1.98) 908 ( 1.99) Σχετικό σφάλμα< 10-6 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 3898 16 165( 1.87) 14( 1.88) 13 ( 1.89) 144 ( 1.90) 101x101 1790 7098 395 ( 1.9) 33 ( 1.93) 43 ( 1.94) 80 ( 1.95) 01x01 39976 783 93 ( 1.95) 73 ( 1.96) 456 ( 1.97) 804 ( 1.98) Σχετικό σφάλμα< 10-8 Πλέγμα Jacobi Gauss-Seidel SOR 51x51 69 39 53 ( 1.86) 3 ( 1.87) 186 ( 1.88) 0 ( 1.89) 101x101 117 1176 556 ( 1.95) 459 ( 1.96) 38 ( 1.97) 407 ( 1.98) 01x01 7738 41430 1351 ( 1.95) 1035 ( 1.96) 653 ( 1.97) 894 ( 1.98)
Ομάδα Γ: Άσκηση 7 Επιλέγουμε l1ll3 1 δηλαδή έναν κύβο με ακμές από 0 έως 1, με f( x, y) 100. Επιλύουμε τη διαφορική εξίσωση Laplace: T T T 0 0 x y z T (Γ3) με οριακές συνθήκες: T( x, y,1) 100, T( x, y,0) T( x,0, z) T( x,1, z) T(0, y, z) T(1, y, z) 0. Διακριτοποιούμε το πεδίο ορισμού 0 x, yz, 1: χωρίζουμε την κάθε πλευρά σε Ν 1 ίσα διαστήματα (N+1 κόμβους) πλάτους h. N Διακριτοποιούμε την (Γ3) στον τυχαίο κόμβο (, i j, k) και παίρνουμε τον τύπο των 7 σημείων: 1 Ti, j, k ( Ti 1, j, k Ti 1, j, k Ti, j1, k Ti, j1, k Ti, j, k1 Ti, j, k1 ), 6 για i,..., N, j,..., N και k,..., N (Γ4) Επιλύουμε το σύστημα με τις μεθόδους Jacobi, Gauss-Seidel και SOR. Jacobi ( n1) 1 ( ) ( ) ( ) ( ) ( ) ( ),, ( n n n n n n ui jk ui 1, jk, ui 1, jk, ui, j1, k ui, j1, k ui, jk, 1 ui, jk, 1 ) 6 γιαi,..., N, j,..., N και k,..., N Gauss-Seidel ( n 1) 1 ( ) ( 1) ( ) ( 1) ( 1) ( ),, ( n n n n n n u i j k ui 1, j, k u i 1, j, k ui, j 1, k u i, j 1, k u i, j, k1 ui, j, k1 ) 6 γιαi,..., N, j,..., N και k,..., N SOR u 1 ( u 6 u u u u u ) (1 ) u γιαi,..., N, j,..., N και k,..., N ( n1) ( n) ( n1) ( n) ( n1) ( n1) ( n) ( n) ijk,, i1,, jk i1,, jk ij, 1, k ij, 1, k ijk,, 1 ijk,, 1 ijk,, Program Jacobi_GaussSeidel_SOR implicit none doubleprecision,allocatable::t(:,:,:),told(:,:,:) integer::n,i,j,k,kk,h,status,maxi,done,method,l,m,z doubleprecision::s,rel,err,max,s1,s,q doubleprecision::t0,hh,w n=10 allocate(t(n+1,n+1,n+1),told(n+1,n+1,n+1)) if (status/=0) Stop 'Not enough memory'
hh=1./n maxi=130000 rel=0.00000001 do method=1,3!1=jacobi, =gauss-seidel, 3=SOR t(:,:,:)=0. t(:,1,:)=100. if (method==1) then told(:,:,:)=t(:,:,:)! print*,x0(:)!read* m=1 done=0 do while (m<=maxi.and. done==0) do j=,n do k=,n t(i,j,k)= (1./6.)*(told(i,j+1,k)+told(i,j-1,k)+told(i+1,j,k)+told (i- 1,j,k)+told (i,j,k-1)+told (i,j,k+1))! elenxos gia termatismo max=-1 do j=,n do k=,n err = abs((t(i,j,k) - told(i,j,k))/t(i,j,k)) if (err>max) then max=err if (max<rel) then done=1 told(:,:,:)=t(:,:,:) m=m+1 open(11,file='res_jacobi1.txt',recl=10000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(11,*) t(i,:,:) do i=1,n+1,1 do j=1,n+1,1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! do k=1,n+1,1 write(11,*) t(i,j,k)!write(11,*) z,'--------------------------------' print*, 'Jacobi' print*, m-1,max print*,'------------------------'
elseif (method==) then!gauss-seidel m=1 done=0 do while (m<=maxi.and. done==0) told(:,:,:)=t(:,:,:) do j=,n do k=,n t(i,j,k)= (1./6.)*(t(i,j+1,k)+t(i,j-1,k)+t(i+1,j,k)+t(i-1,j,k)+t(i,j,k- 1)+t(i,j,k+1))! elenxos gia termatismo max=-1 do j=,n do k=,n err = abs((t(i,j,k) - told(i,j,k))/t(i,j,k)) if (err>max) then max=err if (max<rel) then done=1 m=m+1 open(1,file='res_gauss.txt',recl=1000)!xwris to RECL=1000 to megisto platos xwraei monon 5 sthles toy pinaka do i=n+1,1,-1! ta typwnoyme anapoda gia na ta deiksei o array visualizer swsta! write(1,*) t(i,:,:) print*, 'Gauss Seidel' print*, m-1,max print*,'------------------------' elseif (method==3) then!sor do w=1.1,1.9,0.1 t(:,:,:)=0. t(:,1,:)=100. m=1 done=0 do while (m<=maxi.and. done==0) told(:,:,:)=t(:,:,:) do j=,n do k=,n t(i,j,k)= (1./6.)*(t(i,j+1,k)+t(i,j-1,k)+t(i+1,j,k)+t(i-1,j,k)+t(i,j,k- 1)+t(i,j,k+1))+(1-w)*t(i,j,k)! elenxos gia termatismo max=-1
do j=,n do k=,n err = abs((t(i,j,k) - told(i,j,k))/t(i,j,k)) if (err>max) then max=err if (max<rel) then done=1 m=m+1 open(13,file='res_sor.txt',recl=1000) do k=1,n+1 do i=1,n+1 do j=1,n+1 write(13,*) i,'/',j,'/',k,'/',t(i,j,k) print*, 'SOR' print*, w, m-1 print*,'------------------------' end
Σχετικό σφάλμα< 10-4 Πλέγμα Jacobi Gauss-Seidel SOR 11x11x11 160 87 35 ( 1.10) 19 ( 1.0) 3 ( 1.30) 9 ( 1.40) 35 ( 1.50) 51x51x51 460 1397 56 ( 1.0) 39 ( 1.30) 65 ( 1.35) Σχετικό σφάλμα< 10-6 Πλέγμα Jacobi Gauss-Seidel SOR 11x11x11 54 133 47 ( 1.10) 4 ( 1.0) 6 ( 1.30) 36 ( 1.40) 51x51x51 4848 58 14 ( 1.10) 68 ( 1.0) 5 ( 1.30) >500 ( 1.40) Σχετικό σφάλμα< 10-8 Πλέγμα Jacobi Gauss-Seidel SOR 11x11x11 344 179 60 ( 1.10) 9 ( 1.0) 9 ( 1.30) 35 ( 1.40) 51x51x51 7114 377 167 ( 1.10) 79 ( 1.0) 64 ( 1.30) 13 ( 1.40)
Ενδεικτικά αποτελέσματα για N=50 με Gauss-Seidel και σχετικό σφάλμα 10 (ανά 10 κόμβους): i j k T i, j, k 1 1 1 100.0000 1 11 1 0 1 1 1 0 1 31 1 0 1 41 1 0 1 51 1 0 11 1 1 100.0000 11 11 1 0 11 1 1 0 11 31 1 0 11 41 1 0 11 51 1 0 1 1 1 100.0000 1 11 1 0 1 1 1 0 1 31 1 0 1 41 1 0 1 51 1 0 31 1 1 100.0000 31 11 1 0 31 1 1 0 31 31 1 0 31 41 1 0 31 51 1 0 41 1 1 100.0000 41 11 1 0 41 1 1 0 41 31 1 0 41 41 1 0 41 51 1 0 51 1 1 100.0000 51 11 1 0 51 1 1 0 51 31 1 0 51 41 1 0 51 51 1 0 1 1 11 100.0000 1 11 11 0 1 1 11 0 1 31 11 0 1 41 11 0 1 51 11 0 11 1 11 100.0000 11 11 11 31.95000 11 1 11 10.60381 11 31 11 3.905077 11 41 11 1.36879 11 51 11 0 1 1 11 100.0000 1 11 11 40.4871 1 1 11 15.7056 1 31 11 6.13081 1 41 11.13003 1 51 11 0 31 1 11 100.0000 31 11 11 40.4881 31 1 11 15.70705 31 31 11 6.1315 31 41 11.1384 31 51 11 0 41 1 11 100.0000 41 11 11 31.95169 41 1 11 10.60647 41 31 11 3.907665 41 41 11 1.38435 41 51 11 0
51 1 11 100.0000 51 11 11 0 51 1 11 0 51 31 11 0 51 41 11 0 51 51 11 0 1 1 1 100.0000 1 11 1 0 1 1 1 0 1 31 1 0 1 41 1 0 1 51 1 0 11 1 1 100.0000 11 11 1 40.4871 11 1 1 15.7056 11 31 1 6.13081 11 41 1.13003 11 51 1 0 1 1 1 100.0000 1 11 1 5.49630 1 1 1 3.45880 1 31 1 9.64451 1 41 1 3.398317 1 51 1 0 31 1 1 100.0000 31 11 1 5.49775 31 1 1 3.46107 31 31 1 9.646464 31 41 1 3.399648 31 51 1 0 41 1 1 100.0000 41 11 1 40.48989 41 1 1 15.70985 41 31 1 6.13498 41 41 1.15473 41 51 1 0 51 1 1 100.0000 51 11 1 0 51 1 1 0 51 31 1 0 51 41 1 0 51 51 1 0 1 1 31 100.0000 1 11 31 0 1 1 31 0 1 31 31 0 1 41 31 0 1 51 31 0 11 1 31 100.0000 11 11 31 40.4881 11 1 31 15.70705 11 31 31 6.1315 11 41 31.1384 11 51 31 0 1 1 31 100.0000 1 11 31 5.49775 1 1 31 3.46107 1 31 31 9.646464 1 41 31 3.399648 1 51 31 0 31 1 31 100.0000 31 11 31 5.49917 31 1 31 3.46331 31 31 31 9.648635 31 41 31 3.400954 31 51 31 0 41 1 31 100.0000 41 11 31 40.49075 41 1 31 15.7110 41 31 31 6.13643 41 41 31.1665 41 51 31 0
51 1 31 100.0000 51 11 31 0 51 1 31 0 51 31 31 0 51 41 31 0 51 51 31 0 1 1 41 100.0000 1 11 41 0 1 1 41 0 1 31 41 0 1 41 41 0 1 51 41 0 11 1 41 100.0000 11 11 41 31.95169 11 1 41 10.60647 11 31 41 3.907665 11 41 41 1.38435 11 51 41 0 1 1 41 100.0000 1 11 41 40.48989 1 1 41 15.70985 1 31 41 6.13498 1 41 41.15473 1 51 41 0 31 1 41 100.0000 31 11 41 40.49075 31 1 41 15.7110 31 31 41 6.13643 31 41 41.1665 31 51 41 0 41 1 41 100.0000 41 11 41 31.9539 41 1 41 10.60898 41 31 41 3.910107 41 41 41 1.39905 41 51 41 0 51 1 41 100.0000 51 11 41 0 51 1 41 0 51 31 41 0 51 41 41 0 51 51 41 0 1 1 51 100.0000 1 11 51 0 1 1 51 0 1 31 51 0 1 41 51 0 1 51 51 0 11 1 51 100.0000 11 11 51 0 11 1 51 0 11 31 51 0 11 41 51 0 11 51 51 0 1 1 51 100.0000 1 11 51 0 1 1 51 0 1 31 51 0 1 41 51 0 1 51 51 0 31 1 51 100.0000 31 11 51 0 31 1 51 0 31 31 51 0 31 41 51 0 31 51 51 0 41 1 51 100.0000 41 11 51 0 41 1 51 0 41 31 51 0 41 41 51 0 41 51 51 0
51 1 51 100.0000 51 11 51 0 51 1 51 0 51 31 51 0 51 41 51 0 51 51 51 0 Γράφημα με το πρόγραμμα MayaVi και την εντολή IsoSurface: Γράφημα με το πρόγραμμα MayaVi και την εντολή ScalarCutPlane:
Η μορφή του αρχείου δεδομένων (επέκταση.vtk) για τα προηγούμενα γραφήματα είναι η ακόλουθη (για Ν=10): # vtk DataFile Version.0 3D Periodic Array ASCII DATASET STRUCTURED_POINTS DIMENSIONS 11 11 11 ORIGIN 0.000 0.000 0.000 SPACING 1.00 1.00 1.00 POINT_DATA 1331 SCALARS temperature float LOOKUP_TABLE default 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 100.0000 0.0000000E+00 0.0000000E+00 0.0000000E+00 κ.ο.κ. Όπου 1331=11*11*11 και τις τιμές (100.000 κοκ) τις παίρνουμε με τον ακόλουθο κώδικα Fortran: do i=1,n+1 do j=1,n+1 do k=1,n+1 write(13,*) t(i,j,k)