A high-performance general-purpose compute library
pde/swe.cpp
#include <arrayfire.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace af;
Window* win;
array normalize(array a, float max) {
float mx = max * 0.5;
float mn = -max * 0.5;
return (a - mn) / (mx - mn);
}
static void swe(bool console) {
// Grid length, number and spacing
const unsigned Lx = 1600, nx = Lx + 1;
const unsigned Ly = 1600, ny = Ly + 1;
const float dx = Lx / (nx - 1);
const float dy = Ly / (ny - 1);
array ZERO = constant(0, nx, ny);
array um = ZERO, vm = ZERO;
unsigned io = (unsigned)floor(Lx / 6.0f), jo = (unsigned)floor(Ly / 6.0f),
k = 15;
array x = tile(range(nx), 1, ny);
array y = tile(range(dim4(1, ny), 1), nx, 1);
// initial condition
array etam =
0.01f * exp((-((x - io) * (x - io) + (y - jo) * (y - jo))) / (k * k));
float m_eta = max<float>(etam);
array eta = etam;
float dt = 0.5;
// conv kernels
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};
array h_diff_kernel_arr(3, h_diff_kernel);
array h_lap_kernel_arr(3, 3, h_lap_kernel);
if (!console) {
win = new Window(1536, 768, "Shallow Water Equations");
win->grid(2, 2);
}
unsigned iter = 0;
unsigned random_interval = 30;
while (!win->close()) {
if (iter > 2000) {
// Initial condition
etam = 0.01f * exp((-((x - io) * (x - io) + (y - jo) * (y - jo))) /
(k * k));
m_eta = max<float>(etam);
eta = etam;
iter = 0;
}
// raindrops
if (iter % 100 == 0 || iter % 130 == 0 || iter % random_interval == 0) {
unsigned io = (unsigned)floor(rand() % Lx),
jo = (unsigned)floor(rand() % Ly);
random_interval = rand() % 200 + 1;
eta += 0.01f * exp((-((x - io) * (x - io) + (y - jo) * (y - jo))) /
(k * k));
}
// compute
array up = um + convolve(eta, h_diff_kernel_arr);
array vp = um + convolve(eta, h_diff_kernel_arr.T());
array e = convolve(eta, h_lap_kernel_arr);
array etap = 2 * eta - etam + (2 * dt * dt) / (dx * dy) * e;
etam = eta;
eta = etap;
m_eta = max<float>(etam);
if (!console) {
(*win)(0, 0).setColorMap(AF_COLORMAP_BLUE);
array hist_out = histogram(normalize(eta, m_eta), 15);
(*win)(0, 1).setAxesLimits(0, hist_out.elements(), 0,
max<float>(hist_out));
(*win)(0, 0).image(normalize(eta, m_eta));
(*win)(0, 1).hist(hist_out, 0, 1,
"Normalized Pressure Distribution");
(*win)(1, 0).plot(range(up.dims(1)), vp.col(0),
"Pressure at left boundary");
(*win)(1, 1).plot(
flat(eta.col(0)), flat(up.col(0)), flat(vp.col(0)),
"Gradients versus Magnitude at left boundary"); // viz
win->show();
} else
eval(eta, up, vp);
iter++;
}
}
int main(int argc, char* argv[]) {
int device = argc > 1 ? atoi(argv[1]) : 0;
bool console = argc > 2 ? argv[2][0] == '-' : false;
try {
af::setDevice(device);
printf("Simulation of shallow water equations\n");
swe(console);
} catch (af::exception& e) {
fprintf(stderr, "%s\n", e.what());
throw;
}
return 0;
}
Window object to render af::arrays.
Definition: graphics.h:37
A multi dimensional data container.
Definition: array.h:37
dim4 dims() const
Get dimensions of the array.
dim_t elements() const
Get the total number of elements across all dimensions of the array.
Generic object that represents size and shape.
Definition: dim4.hpp:26
An ArrayFire exception class.
Definition: exception.h:22
virtual const char * what() const
Returns an error message for the exception in a string format.
Definition: exception.h:46
@ AF_COLORMAP_BLUE
Blue hue map.
Definition: defines.h:461
AFAPI array exp(const array &in)
C++ Interface to evaluate the exponential.
AFAPI array floor(const array &in)
C++ Interface to floor numbers.
array::array_proxy col(int index)
Returns a reference to a col.
AFAPI array range(const dim4 &dims, const int seq_dim=-1, const dtype ty=f32)
C++ Interface to generate an array with [0, n-1] values along the seq_dim dimension and tiled across ...
array & eval(array &a)
Evaluate an expression (nonblocking).
Definition: array.h:1467
AFAPI void info()
AFAPI void setDevice(const int device)
Sets the current device.
bool close()
Check if window is marked for close.
void grid(const int rows, const int cols)
Setup grid layout for multiview mode in a window.
AFAPI array histogram(const array &in, const unsigned nbins, const double minval, const double maxval)
C++ Interface for histogram.
AFAPI array flat(const array &in)
C++ Interface to flatten an array.
AFAPI array convolve(const array &signal, const array &filter, const convMode mode=AF_CONV_DEFAULT, const convDomain domain=AF_CONV_AUTO)
C++ Interface for convolution any(one through three) dimensional signals.
Definition: algorithm.h:15