1#include <stdio.h>
2#include <stdlib.h>
3
4#include <omp.h>
5
6#include <math.h>
7#include <gsl/gsl_vector.h>
8#include <gsl/gsl_blas.h>
9
10// fonte
11double f(double t, double x) {
12 return (M_PI*M_PI-1.) *
13 exp(-t) * sin(M_PI * x);
14}
15
16int main()
17{
18 // parâmetros no tempo
19 double tf = 1.;
20 int nt = 100;
21 double ht = tf / nt;
22
23 // parâmetros no espaço
24 int nx = 10;
25 double hx = 1./nx;
26
27 // parâmetros Jacobi
28 int maxit = 1000;
29 double tol = 1.49e-8;
30
31 // auxiliar
32 double r = ht/(hx*hx);
33
34 // malha
35 gsl_vector *x = gsl_vector_alloc(nx+1);
36 #pragma omp parallel for
37 for (int i = 0; i <= nx; i++) {
38 gsl_vector_set(x, i, i*hx);
39 }
40
41 gsl_vector *u0 = gsl_vector_alloc(nx+1);
42 gsl_vector *u = gsl_vector_calloc(nx+1);
43
44 // auxiliares
45 double norm;
46 gsl_vector *u00 = gsl_vector_alloc(nx+1);
47 gsl_vector *diff = gsl_vector_calloc(nx+1);
48
49 // inicialização
50 double t = 0.;
51 #pragma omp parallel for
52 for (int i = 0; i <= nx; i++) {
53 gsl_vector_set(u0, i,
54 sin(M_PI *
55 gsl_vector_get(x, i)));
56 }
57
58 // u00 = u0
59 gsl_vector_memcpy(u00, u0);
60
61 // armazena malha
62 FILE *fx = fopen("results/x.dat", "wb");
63 gsl_vector_fwrite(fx, x);
64 fclose(fx);
65
66 // armazena solução
67 char str[21];
68 sprintf(str, "results/u_%06d.dat", 0);
69 printf("t = %g, [%s]\n", t, str);
70
71 FILE *fu = fopen(str, "wb");
72 gsl_vector_fwrite(fu, u0);
73 fclose(fu);
74
75 #pragma omp parallel
76 {
77 // iteração no tempo
78 for (int k=0; k < nt; k++) {
79
80 #pragma omp single
81 {
82 t += ht;
83 printf("%d: t = %g\n", k+1, t);
84 }
85
86 // iteração de Jacobi
87 for (int it=0; it < maxit; it++) {
88
89 #pragma omp for
90 for (int i=1; i < nx; i++) {
91 gsl_vector_set(u, i, 1./(2.*r + 1.) *
92 (r * (gsl_vector_get(u00, i-1) +
93 gsl_vector_get(u00, i+1)) +
94 gsl_vector_get(u0, i) +
95 + ht * f(t, gsl_vector_get(x, i))));
96
97 gsl_vector_set(diff, i, gsl_vector_get(u, i) -
98 gsl_vector_get(u00, i));
99 }
100
101 #pragma omp single
102 {
103 norm = gsl_blas_dnrm2(diff);
104 printf("\t%d: norm=%.2e\n", it, norm);
105
106 gsl_vector_memcpy(u00, u);
107 }
108
109 if (norm < tol) {
110 break;
111 }
112
113 }
114
115 #pragma omp single
116 {
117 sprintf(str, "results/u_%06d.dat", k+1);
118 printf("t = %g, [%s]\n", t, str);
119 fu = fopen(str, "wb");
120 gsl_vector_fwrite(fu, u0);
121 fclose(fu);
122
123 // u0 = u
124 gsl_vector_memcpy(u0, u);
125 }
126
127 }
128
129 }
130
131 gsl_vector_free(x);
132 gsl_vector_free(u);
133 gsl_vector_free(u0);
134 gsl_vector_free(u00);
135 gsl_vector_free(diff);
136
137 return 0;
138}