\chapter{The heat-\/equation program }
\hypertarget{heat_equation}{}\label{heat_equation}\index{The heat-\/equation program@{The heat-\/equation program}}
The heat equation example.

This example depends on simple-\/solver, three-\/pt-\/stencil-\/solver.

 \label{three_pt_stencil_solver_Intro}%
\Hypertarget{three_pt_stencil_solver_Intro}%
 \label{three_pt_stencil_solver_Introduction}%
\Hypertarget{three_pt_stencil_solver_Introduction}%
\doxysection*{Introduction}

This example solves a 2D heat conduction equation

$    u : [0, d]^2 \rightarrow R\\
    \partial_t u = \delta u + f
$

with Dirichlet boundary conditions and given initial condition and constant-\/in-\/time source function f.

The partial differential equation (PDE) is solved with a finite difference spatial discretization on an equidistant grid:\+ For {\ttfamily n} grid points, and grid distance $h = 1/n$ we write

$    u_{i,j}\textnormal{\textquotesingle} =
    \alpha\frac{u_{i-1,j}+u_{i+1,j}+u_{i,j-1}+u_{i,j+1}-4u_{i,j}}{h^2}+f_{i,j}
$

We then build an implicit Euler integrator by discretizing with time step $\tau$

$    \frac{u_{i,j}^{k+1} - u_{i,j}^k}{\tau} =
    \alpha\frac{u_{i-1,j}^{k+1}+u_{i+1,j}^{k+1}
               -u_{i,j-1}^{k+1}-u_{i,j+1}^{k+1}+4u_{i,j}^{k+1}}{h^2}
    +f_{i,j}
$

and solve the resulting linear system for $ u_{\cdot}^{k+1}$ using Ginkgo\textquotesingle{}s CG solver preconditioned with an incomplete Cholesky factorization for each time step, occasionally writing the resulting grid values into a video file using Open\+CV and a custom color mapping.

The intention of this example is to provide a mini-\/app showing matrix assembly, vector initialization, solver setup and the use of Ginkgo in a more complex setting.

\label{three_pt_stencil_solver_Abouttheexample}%
\Hypertarget{three_pt_stencil_solver_Abouttheexample}%
\doxysubsubsection*{About the example }

\label{three_pt_stencil_solver_CommProg}%
\Hypertarget{three_pt_stencil_solver_CommProg}%
 \doxysection*{The commented program}


\begin{DoxyCode}{0}
\DoxyCodeLine{The\ intention\ of\ \textcolor{keyword}{this}\ example\ is\ to\ provide\ a\ mini-\/app\ showing\ matrix\ assembly,}
\DoxyCodeLine{vector\ initialization,\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ setup\ and\ the\ use\ of\ Ginkgo\ in\ a\ more\ complex}
\DoxyCodeLine{setting.}
\DoxyCodeLine{*****************************<DESCRIPTION>**********************************\ /}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <chrono>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <opencv2/core.hpp>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <opencv2/videoio.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}

\end{DoxyCode}


This function implements a simple Ginkgo-\/themed clamped color mapping for values in the range \+[0,5]\+.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ set\_val(\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}*\ data,\ \textcolor{keywordtype}{double}\ value)}
\DoxyCodeLine{\{}

\end{DoxyCode}


RGB values for the 6 colors used for values 0, 1, ..., 5 We will interpolate linearly between these values.


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ col\_r[]\ =\ \{255,\ 221,\ 129,\ 201,\ 249,\ 255\};}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ col\_g[]\ =\ \{255,\ 220,\ 130,\ 161,\ 158,\ 204\};}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ col\_b[]\ =\ \{255,\ 220,\ 133,\ 93,\ 24,\ 8\};}
\DoxyCodeLine{value\ =\ std::max(0.0,\ value);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ i\ =\ std::max(0,\ std::min(4,\ \textcolor{keywordtype}{int}(value)));}
\DoxyCodeLine{\textcolor{keyword}{auto}\ d\ =\ std::max(0.0,\ std::min(1.0,\ value\ -\/\ i));}

\end{DoxyCode}


Open\+CV uses BGR instead of RGB by default, revert indices


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ data[2]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_r[i\ +\ 1]\ *\ d\ +\ col\_r[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\ \ \ \ data[1]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_g[i\ +\ 1]\ *\ d\ +\ col\_g[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\ \ \ \ data[0]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_b[i\ +\ 1]\ *\ d\ +\ col\_b[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\}}

\end{DoxyCode}


Initialize video output with given dimension and FPS (frames per seconds)


\begin{DoxyCode}{0}
\DoxyCodeLine{std::pair<cv::VideoWriter,\ cv::Mat>\ build\_output(\textcolor{keywordtype}{int}\ n,\ \textcolor{keywordtype}{double}\ fps)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ cv::Size\ videosize\{n,\ n\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ output\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::make\_pair(cv::VideoWriter\{\},\ cv::Mat\{videosize,\ CV\_8UC3\});}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ fourcc\ =\ cv::VideoWriter::fourcc(\textcolor{charliteral}{'a'},\ \textcolor{charliteral}{'v'},\ \textcolor{charliteral}{'c'},\ \textcolor{charliteral}{'1'});}
\DoxyCodeLine{\ \ \ \ output.first.open(\textcolor{stringliteral}{"{}heat.mp4"{}},\ fourcc,\ fps,\ videosize);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ output;}
\DoxyCodeLine{\}}

\end{DoxyCode}


Write the current frame to video output using the above color mapping


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ output\_timestep(std::pair<cv::VideoWriter,\ cv::Mat>\&\ output,\ \textcolor{keywordtype}{int}\ n,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keywordtype}{double}*\ data)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ n;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ row\ =\ output.second.ptr(i);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ j\ =\ 0;\ j\ <\ n;\ j++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ set\_val(\&row[3\ *\ j],\ data[i\ *\ n\ +\ j]);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ output.first.write(output.second);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{int}\ argc,\ \textcolor{keywordtype}{char}*\ argv[])}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Csr}{gko::matrix::Csr<>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<>}};}

\end{DoxyCode}


Problem parameters:\+ simulation length


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ t0\ =\ 5.0;}

\end{DoxyCode}


diffusion factor


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ diffusion\ =\ 0.0005;}

\end{DoxyCode}


scaling factor for heat source


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ source\_scale\ =\ 2.5;}

\end{DoxyCode}


Simulation parameters:\+ inner grid points per discretization direction


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ n\ =\ 256;}

\end{DoxyCode}


number of simulation steps per second


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ steps\_per\_sec\ =\ 500;}

\end{DoxyCode}


number of video frames per second


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ fps\ =\ 25;}

\end{DoxyCode}


number of grid points


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ n2\ =\ n\ *\ n;}

\end{DoxyCode}


grid point distance (ignoring boundary points)


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ h\ =\ 1.0\ /\ (n\ +\ 1);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ h2\ =\ h\ *\ h;}

\end{DoxyCode}


time step size for the simulation


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ tau\ =\ 1.0\ /\ steps\_per\_sec;}

\end{DoxyCode}


create a CUDA executor with an associated Open\+MP host executor


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ exec\ =\ \doxymbox{\hyperlink{classgko_1_1CudaExecutor_a075a1957241de65c0cad59f9534430a2}{gko::CudaExecutor::create}}(0,\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}

\end{DoxyCode}


load heat source and initial state vectors


\begin{DoxyCode}{0}
\DoxyCodeLine{std::ifstream\ initial\_stream(\textcolor{stringliteral}{"{}data/gko\_logo\_2d.mtx"{}});}
\DoxyCodeLine{std::ifstream\ source\_stream(\textcolor{stringliteral}{"{}data/gko\_text\_2d.mtx"{}});}
\DoxyCodeLine{\textcolor{keyword}{auto}\ source\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(source\_stream,\ exec);}
\DoxyCodeLine{\textcolor{keyword}{auto}\ in\_vector\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(initial\_stream,\ exec);}

\end{DoxyCode}


create output vector with initial guess for


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ out\_vector\ =\ in\_vector-\/>clone();}

\end{DoxyCode}


create scalar for source update


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ tau\_source\_scalar\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{source\_scale\ *\ tau\},\ exec);}

\end{DoxyCode}


create stencil matrix as shared\+\_\+ptr for solver


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ stencil\_matrix\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{gko::share}}(mtx::create(exec));}

\end{DoxyCode}


assemble matrix


\begin{DoxyCode}{0}
\DoxyCodeLine{\doxymbox{\hyperlink{structgko_1_1matrix__data}{gko::matrix\_data<>}}\ mtx\_data\{\doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}(n2,\ n2)\};}
\DoxyCodeLine{\textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ n;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ j\ =\ 0;\ j\ <\ n;\ j++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ c\ =\ i\ *\ n\ +\ j;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ c\_val\ =\ diffusion\ *\ tau\ *\ 4.0\ /\ h2\ +\ 1.0;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ off\_val\ =\ -\/diffusion\ *\ tau\ /\ h2;}

\end{DoxyCode}


for each grid point:\+ insert 5 stencil points with Dirichlet boundary conditions, i.\+e. with zero boundary value


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ -\/\ n,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (j\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ -\/\ 1,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c,\ c\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (j\ <\ n\ -\/\ 1)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ +\ 1,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ <\ n\ -\/\ 1)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ +\ n,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\}}
\DoxyCodeLine{stencil\_matrix-\/>read(mtx\_data);}

\end{DoxyCode}


prepare video output


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ output\ =\ build\_output(n,\ fps);}

\end{DoxyCode}


build CG solver on stencil with incomplete Cholesky preconditioner stopping at 1e-\/10 relative accuracy


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ =}
\DoxyCodeLine{\ \ \ \ gko::solver::Cg<>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_preconditioner(gko::preconditioner::Ic<>::build())}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .with\_criteria(gko::stop::ResidualNorm<>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(1e-\/10))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ .on(exec)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ -\/>generate(stencil\_matrix);}

\end{DoxyCode}


time stamp of the last output frame (initialized to a sentinel value)


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordtype}{double}\ last\_t\ =\ -\/t0;}

\end{DoxyCode}


execute implicit Euler method:\+ for each timestep, solve stencil system


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{double}\ t\ =\ 0;\ t\ <\ t0;\ t\ +=\ tau)\ \{}

\end{DoxyCode}


if enough time has passed, output the next video frame


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if}\ (t\ -\/\ last\_t\ >\ 1.0\ /\ fps)\ \{}
\DoxyCodeLine{\ \ \ \ last\_t\ =\ t;}
\DoxyCodeLine{\ \ \ \ std::cout\ <<\ t\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ output\_timestep(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ output,\ n,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_adf2f8602dc9453752a787b40bbf13fcf}{gko::make\_temporary\_clone}}(exec-\/>get\_master(),\ in\_vector)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ -\/>get\_const\_values());}
\DoxyCodeLine{\}}

\end{DoxyCode}


add heat source contribution


\begin{DoxyCode}{0}
\DoxyCodeLine{in\_vector-\/>add\_scaled(tau\_source\_scalar,\ source);}

\end{DoxyCode}


execute Euler step


\begin{DoxyCode}{0}
\DoxyCodeLine{\doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(in\_vector,\ out\_vector);}

\end{DoxyCode}


swap input and output


\begin{DoxyCode}{0}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::swap(in\_vector,\ out\_vector);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\}}

\end{DoxyCode}
 \label{three_pt_stencil_solver_Results}%
\Hypertarget{three_pt_stencil_solver_Results}%
\doxysection*{Results}

The program will generate a video file named heat.\+mp4 and output the timestamp of each generated frame.

\label{three_pt_stencil_solver_Commentsaboutprogramminganddebugging}%
\Hypertarget{three_pt_stencil_solver_Commentsaboutprogramminganddebugging}%
\doxysubsubsection*{Comments about programming and debugging }

\label{three_pt_stencil_solver_PlainProg}%
\Hypertarget{three_pt_stencil_solver_PlainProg}%
 \doxysection*{The plain program}


\begin{DoxyCodeInclude}{0}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{comment}{/*****************************<DESCRIPTION>***********************************}}
\DoxyCodeLine{\textcolor{comment}{This\ example\ solves\ a\ 2D\ heat\ conduction\ equation}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ u\ :\ [0,\ d]\string^2\ \(\backslash\)rightarrow\ R\(\backslash\)\(\backslash\)}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ \(\backslash\)partial\_t\ u\ =\ \(\backslash\)delta\ u\ +\ f}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{with\ Dirichlet\ boundary\ conditions\ and\ given\ initial\ condition\ and}}
\DoxyCodeLine{\textcolor{comment}{constant-\/in-\/time\ source\ function\ f.}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{The\ partial\ differential\ equation\ (PDE)\ is\ solved\ with\ a\ finite\ difference}}
\DoxyCodeLine{\textcolor{comment}{spatial\ discretization\ on\ an\ equidistant\ grid:\ For\ \`{}n`\ grid\ points,}}
\DoxyCodeLine{\textcolor{comment}{and\ grid\ distance\ @f\$h\ =\ 1/n@f\$\ we\ write}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ u\_\{i,j\}'\ =\ \(\backslash\)alpha\ (u\_\{i-\/1,j\}\ +\ u\_\{i+1,j\}\ +\ u\_\{i,j-\/1\}\ +\ u\_\{i,j+1\}}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\/\ 4\ u\_\{i,j\})\ /\ h\string^2}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ +\ f\_\{i,j\}}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{We\ then\ build\ an\ implicit\ Euler\ integrator\ by\ discretizing\ with\ time\ step\ @f\$\(\backslash\)tau@f\$}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ (u\_\{i,j\}\string^\{k+1\}\ -\/\ u\_\{i,j\}\string^k)\ /\ \(\backslash\)tau\ =}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ \(\backslash\)alpha\ (u\_\{i-\/1,j\}\string^\{k+1\}\ -\/\ u\_\{i+1,j\}\string^\{k+1\}}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ \ \ \ \ \ \ +\ u\_\{i,j-\/1\}\string^\{k+1\}\ -\/\ u\_\{i,j+1\}\string^\{k+1\}\ -\/\ 4\ u\_\{i,j\}\string^\{k+1\})\ /\ h\string^2}}
\DoxyCodeLine{\textcolor{comment}{\ \ \ \ +\ f\_\{i,j\}}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{and\ solve\ the\ resulting\ linear\ system\ for\ @f\$\ u\_\{\(\backslash\)cdot\}\string^\{k+1\}@f\$\ using\ Ginkgo's\ CG}}
\DoxyCodeLine{\textcolor{comment}{solver\ preconditioned\ with\ an\ incomplete\ Cholesky\ factorization\ for\ each\ time}}
\DoxyCodeLine{\textcolor{comment}{step,\ occasionally\ writing\ the\ resulting\ grid\ values\ into\ a\ video\ file\ using}}
\DoxyCodeLine{\textcolor{comment}{OpenCV\ and\ a\ custom\ color\ mapping.}}
\DoxyCodeLine{\textcolor{comment}{}}
\DoxyCodeLine{\textcolor{comment}{The\ intention\ of\ this\ example\ is\ to\ provide\ a\ mini-\/app\ showing\ matrix\ assembly,}}
\DoxyCodeLine{\textcolor{comment}{vector\ initialization,\ solver\ setup\ and\ the\ use\ of\ Ginkgo\ in\ a\ more\ complex}}
\DoxyCodeLine{\textcolor{comment}{setting.}}
\DoxyCodeLine{\textcolor{comment}{*****************************<DESCRIPTION>**********************************/}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <chrono>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <iostream>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <opencv2/core.hpp>}}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <opencv2/videoio.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{preprocessor}{\#include\ <ginkgo/ginkgo.hpp>}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ set\_val(\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}*\ data,\ \textcolor{keywordtype}{double}\ value)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ col\_r[]\ =\ \{255,\ 221,\ 129,\ 201,\ 249,\ 255\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ col\_g[]\ =\ \{255,\ 220,\ 130,\ 161,\ 158,\ 204\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ col\_b[]\ =\ \{255,\ 220,\ 133,\ 93,\ 24,\ 8\};}
\DoxyCodeLine{\ \ \ \ value\ =\ std::max(0.0,\ value);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ i\ =\ std::max(0,\ std::min(4,\ \textcolor{keywordtype}{int}(value)));}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ d\ =\ std::max(0.0,\ std::min(1.0,\ value\ -\/\ i));}
\DoxyCodeLine{\ \ \ \ data[2]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_r[i\ +\ 1]\ *\ d\ +\ col\_r[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\ \ \ \ data[1]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_g[i\ +\ 1]\ *\ d\ +\ col\_g[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\ \ \ \ data[0]\ =\ \textcolor{keyword}{static\_cast<}\textcolor{keywordtype}{unsigned}\ \textcolor{keywordtype}{char}\textcolor{keyword}{>}(col\_b[i\ +\ 1]\ *\ d\ +\ col\_b[i]\ *\ (1\ -\/\ d));}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{std::pair<cv::VideoWriter,\ cv::Mat>\ build\_output(\textcolor{keywordtype}{int}\ n,\ \textcolor{keywordtype}{double}\ fps)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ cv::Size\ videosize\{n,\ n\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ output\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::make\_pair(cv::VideoWriter\{\},\ cv::Mat\{videosize,\ CV\_8UC3\});}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ fourcc\ =\ cv::VideoWriter::fourcc(\textcolor{charliteral}{'a'},\ \textcolor{charliteral}{'v'},\ \textcolor{charliteral}{'c'},\ \textcolor{charliteral}{'1'});}
\DoxyCodeLine{\ \ \ \ output.first.open(\textcolor{stringliteral}{"{}heat.mp4"{}},\ fourcc,\ fps,\ videosize);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{return}\ output;}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{void}\ output\_timestep(std::pair<cv::VideoWriter,\ cv::Mat>\&\ output,\ \textcolor{keywordtype}{int}\ n,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{const}\ \textcolor{keywordtype}{double}*\ data)}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ n;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ row\ =\ output.second.ptr(i);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ j\ =\ 0;\ j\ <\ n;\ j++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ set\_val(\&row[3\ *\ j],\ data[i\ *\ n\ +\ j]);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ output.first.write(output.second);}
\DoxyCodeLine{\}}
\DoxyCodeLine{}
\DoxyCodeLine{}
\DoxyCodeLine{\textcolor{keywordtype}{int}\ main(\textcolor{keywordtype}{int}\ argc,\ \textcolor{keywordtype}{char}*\ argv[])}
\DoxyCodeLine{\{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }mtx\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Csr}{gko::matrix::Csr<>}};}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{using\ }vec\ =\ \doxymbox{\hyperlink{classgko_1_1matrix_1_1Dense}{gko::matrix::Dense<>}};}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ t0\ =\ 5.0;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ diffusion\ =\ 0.0005;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ source\_scale\ =\ 2.5;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ n\ =\ 256;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ steps\_per\_sec\ =\ 500;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ fps\ =\ 25;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ n2\ =\ n\ *\ n;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ h\ =\ 1.0\ /\ (n\ +\ 1);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ h2\ =\ h\ *\ h;}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ tau\ =\ 1.0\ /\ steps\_per\_sec;}
\DoxyCodeLine{}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ exec\ =\ \doxymbox{\hyperlink{classgko_1_1CudaExecutor_a075a1957241de65c0cad59f9534430a2}{gko::CudaExecutor::create}}(0,\ \doxymbox{\hyperlink{classgko_1_1OmpExecutor_af977cb680e0427ca4eb71eb7b1266211}{gko::OmpExecutor::create}}());}
\DoxyCodeLine{\ \ \ \ std::ifstream\ initial\_stream(\textcolor{stringliteral}{"{}data/gko\_logo\_2d.mtx"{}});}
\DoxyCodeLine{\ \ \ \ std::ifstream\ source\_stream(\textcolor{stringliteral}{"{}data/gko\_text\_2d.mtx"{}});}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ source\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(source\_stream,\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ in\_vector\ =\ \doxymbox{\hyperlink{namespacegko_abc58509ecdcb48399e12f9a081ed7545}{gko::read<vec>}}(initial\_stream,\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ out\_vector\ =\ in\_vector-\/>clone();}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ tau\_source\_scalar\ =\ \doxymbox{\hyperlink{group__LinOp_ga70851b4c3c9b01bb667b3a8e438fb6d2}{gko::initialize<vec>}}(\{source\_scale\ *\ tau\},\ exec);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ stencil\_matrix\ =\ \doxymbox{\hyperlink{namespacegko_ae99fdd8bfa5ac694adcb7297d432967e}{gko::share}}(mtx::create(exec));}
\DoxyCodeLine{\ \ \ \ \doxymbox{\hyperlink{structgko_1_1matrix__data}{gko::matrix\_data<>}}\ mtx\_data\{\doxymbox{\hyperlink{structgko_1_1dim}{gko::dim<2>}}(n2,\ n2)\};}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ i\ =\ 0;\ i\ <\ n;\ i++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{int}\ j\ =\ 0;\ j\ <\ n;\ j++)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ c\ =\ i\ *\ n\ +\ j;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ c\_val\ =\ diffusion\ *\ tau\ *\ 4.0\ /\ h2\ +\ 1.0;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keyword}{auto}\ off\_val\ =\ -\/diffusion\ *\ tau\ /\ h2;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ -\/\ n,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (j\ >\ 0)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ -\/\ 1,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c,\ c\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (j\ <\ n\ -\/\ 1)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ +\ 1,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (i\ <\ n\ -\/\ 1)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ mtx\_data.\doxymbox{\hyperlink{structgko_1_1matrix__data_a4f6be92270fa96bccdc502c83d248dc0}{nonzeros}}.emplace\_back(c,\ c\ +\ n,\ off\_val);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ stencil\_matrix-\/>read(mtx\_data);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ output\ =\ build\_output(n,\ fps);}
\DoxyCodeLine{\ \ \ \ \textcolor{keyword}{auto}\ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}\ =}
\DoxyCodeLine{\ \ \ \ \ \ \ \ gko::solver::Cg<>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_preconditioner(gko::preconditioner::Ic<>::build())}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .with\_criteria(gko::stop::ResidualNorm<>::build()}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_baseline(gko::stop::mode::rhs\_norm)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ .with\_reduction\_factor(1e-\/10))}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ .on(exec)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ -\/>generate(stencil\_matrix);}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordtype}{double}\ last\_t\ =\ -\/t0;}
\DoxyCodeLine{\ \ \ \ \textcolor{keywordflow}{for}\ (\textcolor{keywordtype}{double}\ t\ =\ 0;\ t\ <\ t0;\ t\ +=\ tau)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (t\ -\/\ last\_t\ >\ 1.0\ /\ fps)\ \{}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ last\_t\ =\ t;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ std::cout\ <<\ t\ <<\ std::endl;}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ output\_timestep(}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ output,\ n,}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_adf2f8602dc9453752a787b40bbf13fcf}{gko::make\_temporary\_clone}}(exec-\/>get\_master(),\ in\_vector)}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ -\/>get\_const\_values());}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{\ \ \ \ \ \ \ \ in\_vector-\/>add\_scaled(tau\_source\_scalar,\ source);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ \doxymbox{\hyperlink{namespacegko_1_1log_a15f71654c6c4f4defc95f9359343fa27a7cbf673200498a0d1324f4330825202a}{solver}}-\/>apply(in\_vector,\ out\_vector);}
\DoxyCodeLine{\ \ \ \ \ \ \ \ std::swap(in\_vector,\ out\_vector);}
\DoxyCodeLine{\ \ \ \ \}}
\DoxyCodeLine{\}}

\end{DoxyCodeInclude}
 