#include <stdio.h>
#include <string.h>
#include <arrayfire.h>
using namespace af;
void swe_demo(bool console)
{
double time_total = 20;
const unsigned Lx = 512, nx = Lx + 1;
const unsigned Ly = 512, ny = Ly + 1;
const float dx = Lx / (nx - 1);
const float dy = Ly / (ny - 1);
array ZERO = zeros(nx,ny);
array um = ZERO, vm = ZERO;
unsigned io = (unsigned)floor(Lx / 5.0f),
jo = (unsigned)floor(Ly / 5.0f),
k=20;
array x, y; grid(x, y, array(seq(1,nx)), array(seq(1,ny)));
array expr = (mul(x-io, x-io) + mul(y-jo, y-jo));
array etam = 0.01f * exp(-expr / (k*k));
array eta = etam;
float dt = 0.5;
unsigned diff_x_dims[] = {3, 1}, diff_y_dims[] = {1, 3}, lap_dims[] = {3, 3};
float h_diff_kernel[] = {9.81f * (dt / dx), 0, -9.81f * (dt / dx)};
float h_lap_kernel[] = {0, 1, 0, 1, -4, 1, 0, 1, 0};
timer time_start, time_last;
time_start = time_last = timer::tic();
int iter = 0, iter_last = 0;
double max_rate = 0;
while (true) {
array up = um + convolve(eta, 2, diff_x_dims, h_diff_kernel, afConvSame);
array vp = um + convolve(eta, 2, diff_y_dims, h_diff_kernel, afConvSame);
array e = convolve(eta, 2, lap_dims, h_lap_kernel, afConvSame);
array etap = 2 * eta - etam + e * (2 * dt * dt) / (dx * dy);
etam = eta;
eta = etap;
if (!console){
subfigure(2,1,1); imgplot(eta); title("wave propogation");
subfigure(2,1,2); points(eta, up, vp); title("gradients versus magnitude");
}
double elapsed = timer::toc(time_last);
if (elapsed > 1) {
double rate = (iter - iter_last) / elapsed;
double total_elapsed = timer::toc(time_start);
time_last = timer::tic();
iter_last = iter;
max_rate = std::max(max_rate, rate);
if (total_elapsed >= time_total)
break;
if (!console)
printf(" iterations per second: %.0f (progress %.0f%%)\n",
rate, 100.0f * total_elapsed / time_total);
}
iter++;
}
if (console)
printf(" ### shallow_water_example: %f Iterations per second\n", max_rate);
}
int main(int argc, char* argv[]) {
bool console = false;
if (argc > 2 || (argc == 2 && strcmp(argv[1],"-"))) {
printf("usage: swe [-]\n");
return -1;
} else if (argc == 2 && !strcmp(argv[1],"-")) {
console = true;
}
printf("simulation of shallow water equations\n");
try {
swe_demo(console);
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
#ifdef WIN32 // pause in Windows
if (!console) {
printf("hit [enter]...");
getchar();
}
#endif
return 0;
}