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;
}
af::dim4
Generic object that represents size and shape.
Definition: dim4.hpp:33
af::range
AFAPI array range(const dim4 &dims, const int seq_dim=-1, const dtype ty=f32)
af::exp
AFAPI array exp(const array &in)
C++ Interface for exponential of an array.
af::info
AFAPI void info()
af::constant
array constant(T val, const dim4 &dims, const dtype ty=(af_dtype) dtype_traits< T >::ctype)
af::setDevice
AFAPI void setDevice(const int device)
Sets the current device.
af::array::col
array::array_proxy col(int index)
Returns a reference to a col.
af::array
A multi dimensional data container.
Definition: array.h:35
af
Definition: algorithm.h:15
af::max
AFAPI array max(const array &in, const int dim=-1)
C++ Interface for maximum values in an array.
af::array::elements
dim_t elements() const
Get the total number of elements across all dimensions of the array.
af::Window::close
bool close()
Check if window is marked for close.
af::flat
AFAPI array flat(const array &in)
af::exception
An ArrayFire exception class.
Definition: exception.h:29
af::tile
AFAPI array tile(const array &in, const unsigned x, const unsigned y=1, const unsigned z=1, const unsigned w=1)
af::array::dims
dim4 dims() const
Get dimensions of the array.
AF_COLORMAP_BLUE
@ AF_COLORMAP_BLUE
Blue hue map.
Definition: defines.h:460
af::floor
AFAPI array floor(const array &in)
C++ Interface for flooring an array of numbers.
arrayfire.h
af::eval
array & eval(array &a)
Evaluate an expression (nonblocking).
Definition: array.h:1354
af::exception::what
virtual const char * what() const
Returns an error message for the exception in a string format.
Definition: exception.h:60
af::convolve
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.
af::Window
Window object to render af::arrays.
Definition: graphics.h:37
af::Window::grid
void grid(const int rows, const int cols)
Setup grid layout for multiview mode in a window.
af::histogram
AFAPI array histogram(const array &in, const unsigned nbins, const double minval, const double maxval)
C++ Interface for histogram.