Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
courses:a4m36pap:cviceni6 [2010/11/08 21:33] forrest79 vytvořeno |
courses:a4m36pap:cviceni6 [2025/01/03 18:29] (aktuální) |
||
---|---|---|---|
Řádek 55: | Řádek 55: | ||
==== 2. ==== | ==== 2. ==== | ||
- | kdyby někdo věděl jak na ty derivace, budu vděčný... | + | <code cpp> |
+ | #include <stdio.h> | ||
+ | #include <omp.h> | ||
+ | #include <cmath> | ||
+ | |||
+ | double f(double x, double R) { | ||
+ | if (x < 2 * R) { | ||
+ | return 0.5 * (-cos(M_PI * x / R) + 1); | ||
+ | } | ||
+ | return 0.0; | ||
+ | } | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | double g1 = 0.0, g2 = 0.0, L = 0.1, R = 0.02, c = 1.5e8; | ||
+ | const int pocetX = 100, pocetT = 1000; | ||
+ | double dx = L / pocetX; | ||
+ | double dt = 0.9 * sqrt((dx * dx) / (c * c)); | ||
+ | double **pole = NULL; | ||
+ | pole = new double*[pocetX + 1]; | ||
+ | int i; | ||
+ | for (i = 0; i < pocetX + 1; i++) { | ||
+ | pole[i] = new double[pocetT + 1]; | ||
+ | } | ||
+ | int pp = omp_get_num_procs(); | ||
+ | //pp=1; | ||
+ | double konst = -0.5 * c * dt / dx; | ||
+ | double start_time, run_time; | ||
+ | start_time = omp_get_wtime(); | ||
+ | #pragma omp parallel shared(pole, g1, g2, dx, dt, R, konst) private(i) num_threads(pp) | ||
+ | { | ||
+ | #pragma omp for nowait | ||
+ | for (i = 0; i < pocetT + 1; i++) { | ||
+ | // levá a pravá okrajová podmínka | ||
+ | pole[0][i] = g1; | ||
+ | pole[pocetX][i] = g2; | ||
+ | } | ||
+ | #pragma omp for | ||
+ | for (i = 1; i < pocetX; i++) { | ||
+ | // první řádek | ||
+ | pole[i][0] = f(dx*i, R); | ||
+ | } | ||
+ | #pragma omp for nowait | ||
+ | for (i = 1; i < pocetX; i++) { | ||
+ | // druhý řádek, možnost 2 ze cvičení | ||
+ | pole[i][1] = pole[i][0] + konst * (pole[i + 1][0] - pole[i - 1][0]); | ||
+ | } | ||
+ | } | ||
+ | konst = (c * c * dt * dt) / (dx * dx); | ||
+ | for (int j = 2; j < pocetT + 1; j++) { | ||
+ | // první for nelze paralelizovat, hodnoty řádku jsou závislé na přechozích 2 řádcích | ||
+ | #pragma omp parallel for shared(pole, konst, j) private(i) num_threads(pp) | ||
+ | for (i = 1; i < pocetX; i++) { | ||
+ | // diskretizovaná dif. rovnice | ||
+ | pole[i][j] = konst * (pole[i + 1][j - 1] - 2 * pole[i][j - 1] + pole[i - 1][j - 1]) + 2 * pole[i][j - 1] - pole[i][j - 2]; | ||
+ | } | ||
+ | } | ||
+ | run_time = omp_get_wtime() - start_time; | ||
+ | // výstup pro Copy-Paste do MatLabu | ||
+ | printf("X = ["); | ||
+ | for (int j = 0; j < pocetT + 1; j++) { | ||
+ | for (i = 0; i < pocetX + 1; i++) { | ||
+ | printf("%f ", pole[i][j]); | ||
+ | } | ||
+ | printf(";\n"); | ||
+ | } | ||
+ | printf("];\n"); | ||
+ | |||
+ | printf(" Beh sledovane casti programu trval: %f s", run_time); | ||
+ | } | ||
+ | </code> |