diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
new file mode 100644
index 0000000..816c82b
--- /dev/null
+++ b/.github/workflows/deploy-docs.yml
@@ -0,0 +1,40 @@
+name: Deploy docs
+
+on:
+ push:
+ branches: [ main ]
+
+jobs:
+ build-and-deploy-docs:
+ runs-on: ubuntu-latest
+ env:
+ docs-directory: /home/runner/work/pressio/pressio-ops/docs
+ python-version: '3.10'
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python ${{ env.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ env.python-version }}
+ architecture: 'x64'
+ - name: Install Python dependencies
+ run: |
+ pip3 install -r ./docs/build_requirements.txt
+ - name: Build documentation
+ working-directory: ${{ env.docs-directory }}
+ run: |
+ make html
+ # .nojekyll file is needed for GitHub Pages to know it's getting a ready webpage
+ # and there is no need to generate anything
+ - name: Generate nojekyll file
+ working-directory: ${{ env.docs-directory }}/generated_docs
+ run: touch .nojekyll
+ # This action moves the content of `generated_docs` to the branch from where
+ # the site is published
+ - name: Deploy docs
+ uses: JamesIves/github-pages-deploy-action@v4
+ with:
+ branch: website-deployment
+ folder: ${{ env.docs-directory }}/generated_docs
+ clean: true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c729ac5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.vscode
+generated_docs
diff --git a/LICENSE b/LICENSE
index 970d619..e33707e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -5,37 +5,37 @@
// Copyright 2019 National Technology & Engineering Solutions of Sandia,LLC
// (NTESS)
//
-// Under the terms of Contract DE-NA0003525 with NTESS, the
+// Under the terms of Contract DE-NA0003525 with NTESS, the
// U.S. Government retains certain rights in this software.
//
// Pressio is licensed under BSD-3-Clause terms of use:
//
// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
+// modification, are permitted provided that the following conditions
// are met:
//
-// 1. Redistributions of source code must retain the above copyright
+// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Francesco Rizzi (fnrizzi@sandia.gov)
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..b95c2f9
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,5 @@
+html:
+ sphinx-build -b html ./source/ ./generated_docs/
+
+clean:
+ rm -rf ./generated_docs/
diff --git a/docs/build_requirements.txt b/docs/build_requirements.txt
new file mode 100644
index 0000000..09de70f
--- /dev/null
+++ b/docs/build_requirements.txt
@@ -0,0 +1,7 @@
+Sphinx==5.0.1
+furo==2022.6.4.1
+myst-parser==0.18.0
+sphinx-copybutton==0.5.0
+m2r2==0.3.2
+sphinx-design
+attrs
diff --git a/docs/source/_static/front_page_schematic/frontpageschem.pdf b/docs/source/_static/front_page_schematic/frontpageschem.pdf
new file mode 100644
index 0000000..90b2a0b
Binary files /dev/null and b/docs/source/_static/front_page_schematic/frontpageschem.pdf differ
diff --git a/docs/source/_static/front_page_schematic/frontpageschem.svg b/docs/source/_static/front_page_schematic/frontpageschem.svg
new file mode 100644
index 0000000..e2e5685
--- /dev/null
+++ b/docs/source/_static/front_page_schematic/frontpageschem.svg
@@ -0,0 +1,866 @@
+
+
diff --git a/docs/source/_static/front_page_schematic/frontpageschem.tex b/docs/source/_static/front_page_schematic/frontpageschem.tex
new file mode 100644
index 0000000..c5f7710
--- /dev/null
+++ b/docs/source/_static/front_page_schematic/frontpageschem.tex
@@ -0,0 +1,359 @@
+
+\documentclass{standalone}
+
+\usepackage{amsfonts}
+\usepackage{graphicx}
+\usepackage{epstopdf}
+\usepackage{algorithmic}
+\usepackage{listings}
+\usepackage{fancyvrb}
+\usepackage{booktabs}
+\usepackage{multirow}
+\usepackage{pgf}
+\usepackage{tikz}
+\usetikzlibrary{shapes, arrows, positioning,fit, automata,
+ arrows.meta, decorations.markings, calc}
+\usepackage{tikzscale}
+\usepackage{xcolor}
+%\usepackage{tikz-uml}
+\usepackage{mathtools}
+\usetikzlibrary{decorations}
+%\usetikzlibrary{decorations.text}
+
+\definecolor{colWhite}{HTML}{FFFFFF}
+
+% general naming macros
+\newcommand{\code}[1]{{\ttfamily\color{black} #1}}
+\newcommand{\pressio}{$\mathbf{Pressio}$}
+\newcommand{\pressioFpy}{$\mathbf{pressio4py}$}
+\newcommand{\modred}{$\mathbf{modred}$}
+\newcommand{\pymor}{$\mathbf{pyMOR}$}
+\newcommand{\pyrom}{$\mathbf{pyROM}$}
+\newcommand{\librom}{$\mathbf{libROM}$}
+% math macros general
+\newcommand{\defeq}{\vcentcolon =}
+\newcommand*{\difftime}[1]{\dot{#1}}
+\newcommand{\tfinal}{T}
+\newcommand{\RR}[1]{\mathbb{R}^{#1}}
+\newcommand{\RRstar}[1]{\mathbb{R}_\star^{#1}}
+\newcommand{\RRplus}{\mathbb{R}_{+}}
+\newcommand{\dstate}{\boldsymbol{\xi}}
+\newcommand{\drdstate}{\hat{\boldsymbol{\xi}}}
+\newcommand{\range}{\text{Ran}}
+\newcommand*{\pseudoInvSymb}{+}
+\newcommand*{\pseudoInv}{^\pseudoInvSymb}
+
+\newcommand{\Boper}{\boldsymbol B}
+
+% FOM math macros
+\newcommand{\fomDof}{N}
+\newcommand{\state}{\boldsymbol y}
+\newcommand{\aprxState}{\tilde{\state}}
+\newcommand{\initState}{\state^{0}}
+\newcommand{\stateRef}{\state_\text{ref}}
+\newcommand{\velocity}{\boldsymbol f}
+\newcommand{\dvelocity}{\boldsymbol v}
+\newcommand{\dtime}{\tau}
+\newcommand{\params}{\boldsymbol \mu}
+\newcommand{\dparams}{\boldsymbol \nu}
+\newcommand{\paramDomain}{\mathcal D}
+\newcommand{\nparams}{n_{\params}}
+\newcommand{\fomJac}{\partial\velocity/\partial \state}
+%\newcommand{\aprxFomJac}{\partial\velocity/\partial \aprxState}
+%\newcommand{\aprxFomJac}{\frac{\partial\velocity}{\partial \state}(\aprxState,t;\params)}
+\newcommand{\fomJacVel}{ \boldsymbol J_{\velocity}}
+\newcommand{\fomJacRes}{ \boldsymbol J_{R}}
+\newcommand{\aprxFomJacFrac}{ \frac{\partial\velocity}{\partial \aprxState}}
+
+% ROM macros
+\newcommand{\dofRom}{p}
+\newcommand{\romState}{\hat{\state}}
+\newcommand{\romToFomMapping}{\boldsymbol g}
+\newcommand{\romBasis}{\boldsymbol{\Phi}}
+\newcommand*{\tangentSpace}[1]{T_{#1}\manifold }
+\newcommand{\manifold}{\mathcal M}
+\newcommand{\gRomState}{\hat{\boldsymbol \xi}}
+\newcommand{\jacOfRomFomMapping}{\boldsymbol{J}}
+\newcommand{\gVelo}{\hat{\boldsymbol{v}}}
+\newcommand{\initRomState}{\romState^{0}}
+%\newcommand{\gaprxstate}{\tilde{\gstate}}
+
+\newcommand{\weightMat}{\boldsymbol{A}}
+\newcommand{\weightMatDiag}{\boldsymbol{D}}
+\newcommand{\identity}{\boldsymbol{I}}
+\newcommand{\collocMat}{\boldsymbol{P}}
+\newcommand{\phires}{{\boldsymbol \Phi}_r}
+\newcommand{\gnatWMat}{(\collocMat \phires)^+ \collocMat}
+
+% Time stepping
+\newcommand{\zero}{\boldsymbol{0}}
+\newcommand{\res}{\boldsymbol{r}}
+\newcommand{\timeStep}{\Delta t}
+\newcommand{\nseq}{{N_t}}
+
+
+\tikzstyle{block} = [draw, rectangle, minimum height=3em, minimum width=6em]
+
+\definecolor{appCol}{HTML}{FFFF00}
+\definecolor{pressioCol}{HTML}{FFFFFF}
+
+\begin{document}
+
+\tikzset{
+ ncbar angle/.initial=90,
+ ncbar/.style={
+ to path=(\tikztostart)
+ -- ($(\tikztostart)!#1!\pgfkeysvalueof{/tikz/ncbar angle}:(\tikztotarget)$)
+ -- ($(\tikztotarget)!($(\tikztostart)!#1!\pgfkeysvalueof{/tikz/ncbar angle}:(\tikztotarget)$)!\pgfkeysvalueof{/tikz/ncbar angle}:(\tikztostart)$)
+ -- (\tikztotarget)
+ },
+ ncbar/.default=0.5cm,
+}
+\tikzset{square left brace/.style={ncbar=0.3cm}}
+
+
+\begin{tikzpicture}[auto, node distance=2cm]
+
+ % application
+ \node [
+ block,
+ draw=appCol,
+ text=appCol,
+ rounded corners,
+ node distance=3cm,
+ minimum width=0.6\textwidth,
+ minimum height=3cm
+ ](app)
+ {
+ \shortstack{
+ \LARGE{Application Code}\\
+ \vspace{0.3cm}
+ \Large{(owns mesh, physics, etc.)}
+ %\Large{$\dot{\state} = \velocity(\state,t;\params)$}
+ %% \Large{$\state(0;\params) = \initState(\params)$}
+ }
+ };
+
+ % adapter
+ \node [
+ block,
+ draw=appCol,
+ text=appCol,
+ below=of app.south east,
+ anchor=north east,
+ node distance=9cm,
+ rounded corners,
+ minimum width=0.29\textwidth,
+ minimum height=3cm,
+ yshift=0.6cm,
+ xshift=-3.75cm
+ ] (adapter)
+ {
+ \shortstack{
+ \Large{Contin.-time}\\
+ \Large{Adapter}
+ }
+ };
+
+ % adapter2
+ \node [
+ block,
+ draw=appCol,
+ text=appCol,
+ below=of app.south east,
+ anchor=north east,
+ node distance=9cm,
+ rounded corners,
+ minimum width=0.29\textwidth,
+ minimum height=3cm,
+ xshift=0cm,
+ yshift=0.6cm
+ ] (adapter2)
+ {
+ \shortstack{
+ \Large{Discrete-time}\\
+ \Large{Adapter}
+ }
+ };
+
+ % MAIN
+ \node [
+ block,
+ draw=appCol,
+ text=appCol,
+ right=of app,
+ anchor=north west,
+ node distance=8cm,
+ rounded corners,
+ minimum width=0.2\textwidth,
+ minimum height=12.45cm,
+ yshift=1.5cm,
+ xshift=-1.5cm
+ ] (main)
+ {
+ \hspace{0.2cm}\Large{\Large{int main()}}\hspace{0.2cm}
+ };
+
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of adapter,
+ rounded corners,
+ node distance=1.2cm,
+ minimum width=0.17\textwidth,
+ yshift=0.6cm,
+ xshift=-0.375cm
+ ](galerkin){GALERKIN};
+
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of adapter,
+ right=of galerkin,
+ rounded corners,
+ node distance=1.2cm,
+ minimum width=0.17\textwidth,
+ xshift=-1.75cm
+ ](lspg){LSPG};
+
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of adapter,
+ right=of lspg,
+ rounded corners,
+ node distance=1.2cm,
+ minimum width=0.17\textwidth,
+ xshift=-1.75cm
+ ](wls){WLS};
+
+ \node [
+ text=pressioCol,
+ draw=black!50,
+ rounded corners,
+ fit={(galerkin) (lspg) (wls)},
+ minimum width=0.6\textwidth
+ ](pressiorom) {};
+
+ % ode
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of adapter,
+ %node distance=9cm,
+ rounded corners,
+ minimum width=0.6\textwidth,
+ yshift=-0.75cm,
+ xshift=1.95cm
+ ] (ode){ODE};
+
+ % nonlinear solvers
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of ode,
+ node distance=9cm, rounded corners,
+ minimum width=0.6\textwidth,
+ yshift=1.82cm
+ ] (solvers){LINEAR/NONLINEAR SOLVERS};
+
+ % all other packages
+ \node [
+ block,
+ draw=pressioCol,
+ text=pressioCol,
+ below=of main,
+ rounded corners,
+ minimum width=0.875\textwidth,
+ yshift=1.8cm,
+ xshift=-3.85cm
+ ] (basicpacks){MPL UTILS CONTAINERS OPS QR ...};
+
+ \node [left=of adapter, text=appCol, yshift=2cm, xshift=0.8cm](pApp) {\rotatebox{90}{\Large{Application}}};
+ \node [left=of ode, text=pressioCol, yshift=-0.5cm, xshift=0.8cm](pPres) {\rotatebox{90}{\Large{\pressio}}};
+ \node [left=of pressiorom, text=pressioCol, xshift=1.85cm](pRoms) {\rotatebox{90}{ROMs}};
+ \node [left=of ode, text=pressioCol, yshift=-1.3cm,xshift=1.85cm](pPack) {\rotatebox{90}{Supporting Packages}};
+ %% \draw [orange, thick] (basicpacks.south west) to [square left brace ] (ode.north west);
+ %% \draw [orange, thick] (pressiorom.south west) to [square left brace ] (pressiorom.north west);
+
+ \draw [pressioCol, thick]
+ ([xshift=-0.7cm]basicpacks.south west)
+ to [square left brace ] ([xshift=-0.7cm]pressiorom.north west);
+
+ %% % box around application
+ %% \node [fit=(main) (adapter) (app),
+ %% pin={[pin distance=0.1cm, yshift=2cm]left:\LARGE{\rotatebox{90}{Application Side}}}] (p5) {};
+
+ %% %% % box for optional part
+ %% %% \node [fit=(adapter),
+ %% %% pin={[pin distance=0.2cm]left:\Large{\rotatebox{90}{Optional}}}] (p5) {};
+
+ \tikzset{myptr/.style={decoration={markings,mark=at position 1 with
+ {\arrow[scale=1.3,>=stealth]{>}}},postaction={decorate}}}
+
+ % rom -> adapter
+ \draw[red, line width=1.5pt, myptr] ([xshift=-0.4cm]pressiorom.north -| adapter)
+ -- node {\begin{tabular}{c} \large{$\aprxState,t$} \\ \large{[,$\Boper$]} \end{tabular}}
+ ([xshift=-0.4cm]adapter.south);
+ % adapter -> rom
+ \draw[green, line width=1.5pt, myptr]([xshift=-0.15cm]adapter.south)
+ -- node [right] {\large{$\velocity [,\fomJacVel \Boper]$}}
+ ([xshift=-0.15cm]pressiorom.north -| adapter);
+ % adapter -> app
+ \draw[appCol, text=appCol, line width=1.5pt, myptr]([xshift=-0.4cm]adapter.north)
+ -- node {\begin{tabular}{c} \large{$\aprxState,t$} \\ \large{[,$\Boper$]} \end{tabular}}
+ ([xshift=-2.26cm]app.south);
+ % app -> adapter
+ \draw[appCol, text=appCol, line width=1.5pt, myptr]([xshift=-2.01cm]app.south)
+ -- node [right] {\large{$\velocity [,\fomJacVel \Boper]$}}
+ ([xshift=-0.15cm]adapter.north);
+
+ % rom -> adapter2
+ \draw[red, line width=1.5pt, myptr] ([xshift=0.15cm]pressiorom.north -| adapter2)
+ -- node {\begin{tabular}{c} \large{$\aprxState_{n,n-1,...}$} \\ \large{$t,\Boper$} \end{tabular}}
+ ([xshift=0.15cm]adapter2.south);
+ % adapter2 -> rom
+ \draw[green, line width=1.5pt, myptr]([xshift=0.4cm]adapter2.south)
+ -- node [right] {\large{$R,\fomJacRes \Boper$}}
+ ([xshift=0.4cm]pressiorom.north -| adapter2);
+ % adapter2 -> app
+ \draw[appCol, text=appCol, line width=1.5pt, myptr]([xshift=0.15cm]adapter2.north)
+ -- node {\begin{tabular}{c} \large{$\aprxState_{n,n-1,...}$} \\ \large{$t,\Boper$} \end{tabular}}
+ ([xshift=2.03cm]app.south);
+ % app -> adapter2
+ \draw[appCol, text=appCol, line width=1.5pt, myptr]([xshift=2.28cm]app.south)
+ -- node [right] {\large{$R,\fomJacRes \Boper$}}
+ ([xshift=0.4cm]adapter2.north);
+
+
+ \node [left=of app.west, yshift=1.65cm, xshift=1cm](p1){};
+ \node [left=of adapter.west, yshift=-1.5cm, xshift=1cm](p2){};
+ \node [right=of adapter2.east, yshift=-1.5cm, xshift=-1.8cm](p3){};
+ \node [left=of main.south west, yshift=-0.1cm, xshift=1.95cm](p4){};
+ \node [right=of main.south east, yshift=-0.1cm, xshift=-1.92cm](p5){};
+ \node [right=of main.north east, yshift=0.15cm, xshift=-1.92cm](p6){};
+
+ \draw [thick, dashed, draw=appCol] (p1) -- (p2) -- (p3) -- (p4) -- (p5) -- (p6) -- (p1);
+
+
+ %% % arrows from main to others
+ %% %\draw[black, arrows={-Circle[black,fill=black]}, line width=2pt]
+ %% \draw[black, arrows={-o}, line width=2pt]
+ %% (main.north) -- ([xshift=-4.79cm]pressiorom.south);
+
+ %% %\draw[black, arrows={-Circle[black,fill=black]}, line width=2pt]
+ %% \draw[black, arrows={-o}, line width=2pt]
+ %% ([yshift=2.55cm]main.east) -- (adapter.west);
+
+ %% %\draw[black, arrows={-Circle[black,fill=black]}, line width=2pt]
+ %% \draw[black, arrows={-o}, line width=2pt ]
+ %% ([yshift=-2.45cm]main.east) -- (app.west);
+
+\end{tikzpicture}
+
+\end{document}
diff --git a/docs/source/_static/frontpageschem.svg b/docs/source/_static/frontpageschem.svg
new file mode 100644
index 0000000..e2e5685
--- /dev/null
+++ b/docs/source/_static/frontpageschem.svg
@@ -0,0 +1,866 @@
+
+
diff --git a/docs/source/_static/hacks.css b/docs/source/_static/hacks.css
new file mode 100644
index 0000000..0b12d62
--- /dev/null
+++ b/docs/source/_static/hacks.css
@@ -0,0 +1,170 @@
+/*
+ * CSS hacks and small modification for my Sphinx website
+ * :copyright: Copyright 2013-2016 Lilian Besson
+ * :license: GPLv3, see LICENSE for details.
+ */
+
+
+/* Colors and text decoration.
+ For example, :black:`text in black` or :blink:`text blinking` in rST. */
+
+.black {
+ color: black;
+}
+
+.gray {
+ color: gray;
+}
+
+.grey {
+ color: gray;
+}
+
+.silver {
+ color: silver;
+}
+
+.white {
+ color: white;
+}
+
+.maroon {
+ color: maroon;
+}
+
+.red {
+ color: red;
+}
+
+.magenta {
+ color: magenta;
+}
+
+.fuchsia {
+ color: fuchsia;
+}
+
+.pink {
+ color: pink;
+}
+
+.orange {
+ color: orange;
+}
+
+.yellow {
+ color: yellow;
+}
+
+.lime {
+ color: lime;
+}
+
+.green {
+ color: green;
+}
+
+.olive {
+ color: olive;
+}
+
+.teal {
+ color: teal;
+}
+
+.cyan {
+ color: cyan;
+}
+
+.aqua {
+ color: aqua;
+}
+
+.blue {
+ color: blue;
+}
+
+.navy {
+ color: navy;
+}
+
+.purple {
+ color: purple;
+}
+
+.under {
+ text-decoration: underline;
+}
+
+.over {
+ text-decoration: overline;
+}
+
+.blink {
+ text-decoration: blink;
+}
+
+.line {
+ text-decoration: line-through;
+}
+
+.strike {
+ text-decoration: line-through;
+}
+
+.it {
+ font-style: italic;
+}
+
+.ob {
+ font-style: oblique;
+}
+
+.small {
+ font-size: small;
+}
+
+.medium {
+ font-size: medium;
+}
+
+.large {
+ font-size: large;
+}
+
+.smallpar {
+ font-size: small;
+}
+
+.packnameindexpage {
+ font-size: large;
+ color: orange;
+}
+
+.summarylineindexpage {
+ font-size: large;
+ font-style: italic;
+ color: olive;
+}
+
+.memberfunction {
+ font-size: large;
+ font-weight: bold;
+ color: olive;
+}
+
+:root {
+ --icon--pied-piper: url('data:image/svg+xml;charset=utf-8,');
+}
+.admonition.pied-piper {
+ border-color: rgb(43, 155, 70);
+}
+.admonition.pied-piper > .admonition-title {
+ background-color: rgba(43, 155, 70, 0.1);
+ border-color: rgb(43, 155, 70);
+}
+.admonition.pied-piper > .admonition-title::before {
+ background-color: rgb(43, 155, 70);
+ -webkit-mask-image: var(--icon--pied-piper);
+ mask-image: var(--icon--pied-piper);
+}
diff --git a/docs/source/_static/logo.png b/docs/source/_static/logo.png
new file mode 100644
index 0000000..cea1d22
Binary files /dev/null and b/docs/source/_static/logo.png differ
diff --git a/docs/source/components/expressions.rst b/docs/source/components/expressions.rst
new file mode 100644
index 0000000..93ed848
--- /dev/null
+++ b/docs/source/components/expressions.rst
@@ -0,0 +1,21 @@
+``expressions``
+===============
+
+Defined in header: ````
+
+Public namespace: ``pressio``
+
+We refer to these as expressions because each function does not allocate
+new memory but only creates an instance of a class that "represents" the given operation.
+
+In all cases, the returned expression remains valid until its operand goes out of scope.
+If the operand goes out of scope, the state of the expression is undefined.
+
+.. toctree::
+ :maxdepth: 1
+
+ expressions/span
+ expressions/subspan
+ expressions/diag
+ expressions/column
+ expressions/is_expression
diff --git a/docs/source/components/expressions/column.rst b/docs/source/components/expressions/column.rst
new file mode 100644
index 0000000..bd58edb
--- /dev/null
+++ b/docs/source/components/expressions/column.rst
@@ -0,0 +1,31 @@
+.. include:: ../../mydefs.rst
+
+``column``
+==========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio {
+
+ template
+ /*impl defined*/ column(T & operand, IndexType colIndex);
+
+ } // end namespace pressio
+
+Description
+-----------
+
+* Takes in an ``operand``, as well as the index of the specified column ``colIndex``
+
+ * ``operand`` is either:
+
+ * an Eigen dense matrix
+
+ * a Tpetra or Tpetra Block multivector
+
+* Returns an expression object that represents the specified column from the ``operand``.
diff --git a/docs/source/components/expressions/diag.rst b/docs/source/components/expressions/diag.rst
new file mode 100644
index 0000000..eae0e39
--- /dev/null
+++ b/docs/source/components/expressions/diag.rst
@@ -0,0 +1,29 @@
+.. include:: ../../mydefs.rst
+
+``diagonal``
+============
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio {
+
+ template
+ /*impl defined*/ diagonal(T & operand);
+
+ } // end namespace pressio
+
+Description
+-----------
+
+* Takes in an ``operand`` that is either:
+
+ * a square Eigen dense matrix, ``pressio::is_dense_matrix_eigen::value == true``
+
+ * a square Kokkos rank-2 view, i.e. ``pressio::is_dense_matrix_kokkos::value == true``
+
+* Returns an expression that represents that diagonal of ``operand``
diff --git a/docs/source/components/expressions/is_expression.rst b/docs/source/components/expressions/is_expression.rst
new file mode 100644
index 0000000..7753a71
--- /dev/null
+++ b/docs/source/components/expressions/is_expression.rst
@@ -0,0 +1,31 @@
+.. include:: ../../mydefs.rst
+
+``is_expression``
+=================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio {
+
+ // For a given type T
+ bool eigen = is_expression_acting_on_eigen::value;
+
+ bool kokkos = is_expression_acting_on_kokkos::value;
+
+ bool tpetra = is_expression_acting_on_tpetra::value;
+ bool tpetra = is_expression_column_acting_on_tpetra::value;
+
+ bool tpetra_block = is_expression_acting_on_tpetra_block::value;
+ bool tpetra_block = is_expression_column_acting_on_tpetra_block::value;
+
+ } // end namespace pressio
+
+Description
+-----------
+
+* Returns a boolean to indicate if the given type ``T`` is the specified expression type
diff --git a/docs/source/components/expressions/span.rst b/docs/source/components/expressions/span.rst
new file mode 100644
index 0000000..713f4ef
--- /dev/null
+++ b/docs/source/components/expressions/span.rst
@@ -0,0 +1,36 @@
+.. include:: ../../mydefs.rst
+
+``span``
+========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio {
+
+ template
+ /*impl defined*/ span(T & operand,
+ std::pair indexRange);
+
+ } // end namespace pressio
+
+Description
+-----------
+
+* Takes in an ``operand`` and an ``indexRange``
+
+ * ``operand`` is either:
+
+ * an Eigen vector object: ``pressio::is_vector_eigen::value == true``
+
+ * a Kokkos rank-1 view, i.e. ``pressio::is_vector_kokkos::value == true``
+
+ * ``indexRange`` is a std::pairidentifying an interval ``[a, b)`` where the second index is exclusive
+
+
+* Returns an expression that represents the target span of the ``operand``.
+
diff --git a/docs/source/components/expressions/subspan.rst b/docs/source/components/expressions/subspan.rst
new file mode 100644
index 0000000..d80a077
--- /dev/null
+++ b/docs/source/components/expressions/subspan.rst
@@ -0,0 +1,33 @@
+.. include:: ../../mydefs.rst
+
+``subspan``
+===========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio {
+
+ template
+ /*impl defined*/ subspan(T & operand,
+ std::pair rowsRange,
+ std::pair colsRange);
+
+ } // end namespace pressio
+
+Description
+-----------
+
+* Takes in an ``operand``, as well as the ``rowsRange`` and ``colsRange`` intervals that will be used in each dimension
+
+ * ``operand`` is either:
+
+ * an Eigen dense matrix, ``pressio::is_dense_matrix_eigen::value == true``
+
+ * a Kokkos rank-2 view, i.e. ``pressio::is_dense_matrix_kokkos::value == true``
+
+* Returns an expression object that represents a subspan of the ``operand``.
diff --git a/docs/source/components/mpl.rst b/docs/source/components/mpl.rst
new file mode 100644
index 0000000..b8c8339
--- /dev/null
+++ b/docs/source/components/mpl.rst
@@ -0,0 +1,114 @@
+.. role:: raw-html-m2r(raw)
+ :format: html
+
+.. include:: ../mydefs.rst
+
+
+``mpl``
+=======
+
+Header: ````
+
+Public namespace: ``pressio::mpl``
+
+
+Scope
+-----
+
+Provides metaprogramming functionalities needed to
+support generic programming, which is a fundamental
+building block of the pressio library.
+If you are familiar with the ```` header from
+the standard library, the ``pressio/mpl`` will look familiar too.
+Some parts of ``pressio/mpl`` have been adapted from the `tinympl project `_.
+The tinympl project appears to be no longer maintained.
+
+The following is a *partial* list only intended to provide a general idea of the supported features.
+
+To find out all supported cases, browse the `source `__.
+
+
+..
+ ``pressio::mpl::not_void``
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ .. code-block:: cpp
+
+ template struct not_void;
+
+ *
+ Provides the static member constant ``value`` that is equal to true, if ``T`` is NOT of
+ the type ``void``\ , ``const void``\ , ``volatile void``\ , or ``const volatile void``.
+ Otherwise, value is true.
+
+ *
+ Example:\ :raw-html-m2r:` `
+
+ .. code-block:: cpp
+
+ namespace pmpl = pressio::mpl;
+ static_assert(pmpl::not_void::value, "" );
+
+
+``pressio::mpl::all_of``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+ template< template class F, class ... Args> struct all_of;
+
+*
+ Determines whether every element in the sequence satisfies the given predicate.
+ The predicate ``F`` must be such that ``F::value`` must be convertible to ``bool``.
+ Provides the static member constant ``value`` that is equal to true iff
+ all the elements in the sequence satisfy the predicate ``F``.
+ Otherwise, value is false.
+
+*
+ Example:\ :raw-html-m2r:` `
+
+ .. code-block:: cpp
+
+ namespace pmpl = pressio::mpl;
+ static_assert(pmpl::all_of::value, "" );
+
+
+``pressio::mpl::any_of``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+ template< template class F, class ... Args> struct any_of;
+
+* Determines whether any element in the sequence satisfies the given predicate.
+ The predicate ``F`` must be such that ``F::value`` must be convertible to ``bool``.
+ Provides the static member constant ``value`` that is equal to true iff
+ at least one element in the sequence satisfies the predicate ``F``.
+ Otherwise, value is equal to false.
+
+
+``pressio::mpl::none_of``
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+ template< template class F, class ... Args> struct none_of;
+
+* Determines whether none of the elements in the sequence satisfy the given predicate.
+ The predicate ``F`` must be such that ``F::value`` must be convertible to ``bool``.
+ Provides the static member constant ``value`` that is equal to true iff
+ none of the elements in the sequence satisfy the predicate ``F``.
+ Otherwise, value is equal to false.
+
+
+``pressio::mpl::is_subscriptable_as``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+ template struct is_subscriptable_as;
+
+* Provides the static member constant ``value`` that is equal to true if
+ ``T`` has subscript operator ``[]``\ , it can be indexed by an instance of ``IndexType``\ ,
+ and the return type is not void.
+ Otherwise, value is equal to false.
diff --git a/docs/source/components/ops.rst b/docs/source/components/ops.rst
new file mode 100644
index 0000000..11ba7bd
--- /dev/null
+++ b/docs/source/components/ops.rst
@@ -0,0 +1,101 @@
+
+.. include:: ../mydefs.rst
+
+``ops``
+=======
+
+Header: ````
+
+Public namespace: ``pressio::ops``
+
+Pressio operations are generalized to work on a variety of container types and backends.
+
+Types
+-----
+
+The following table holds both the types supported throughout the ``ops`` directory and the
+built-in booleans that confirm if a given type ``T`` is the expected type.
+
+All expressions are within the ``pressio`` namespace.
+
+.. list-table::
+ :widths: 10 20 20
+ :header-rows: 1
+ :align: left
+
+ * - Container Type
+ - Rank-1 Check
+ - Rank-2 Check
+
+ * - Eigen
+ - ``is_vector_eigen::value``
+ - ``is_sparse_matrix_eigen::value``, ``is_dense_matrix_eigen::value``
+
+ * - Kokkos
+ - ``is_vector_kokkos::value``
+ - ``is_dense_matrix_kokkos::value``, ``is_sparse_matrix_kokkos::value``
+
+ * - Epetra
+ - ``is_vector_epetra::value``
+ - ``is_multi_vector_epetra::value``
+
+ * - Tpetra
+ - ``is_vector_tpetra::value``
+ - ``is_multi_vector_tpetra::value``
+
+ * - Tpetra Block
+ - ``is_vector_tpetra_block::value``
+ - ``is_multi_vector_tpetra_block::value``
+
+ * - Teuchos
+ - ``is_dense_vector_teuchos::value``
+ - ``is_dense_matrix_teuchos::value``
+
+Additionally, because Pressio features expressions for containers built on Eigen, Kokkos, and Tpetra, you can check whether or not a container is native with:
+
+.. list-table::
+ :widths: 10 20 20
+ :header-rows: 1
+ :align: left
+
+ * - Container Type
+ - Native
+ - Pressio Expression
+
+ * - Eigen
+ - ``is_native_container_eigen::value``
+ - ``is_expression_acting_on_eigen::value``
+
+ * - Kokkos
+ - ``is_native_container_kokkos::value``
+ - ``is_expression_acting_on_kokkos::value``
+
+ * - Tpetra
+ -
+ - ``is_expression_column_acting_on_tpetra::value``
+
+Navigation
+----------
+
+Use the links below to view details about each operation.
+
+.. toctree::
+ :maxdepth: 1
+
+ ops/abs
+ ops/add_to_diagonal
+ ops/clone
+ ops/deep_copy
+ ops/dot
+ ops/elementwise_multiply
+ ops/extent
+ ops/fill
+ ops/min_max
+ ops/norms
+ ops/pow
+ ops/matrix_matrix_product
+ ops/matrix_vector_product
+ ops/resize
+ ops/scale
+ ops/set_zero
+ ops/update
diff --git a/docs/source/components/ops/abs.rst b/docs/source/components/ops/abs.rst
new file mode 100644
index 0000000..c7767ae
--- /dev/null
+++ b/docs/source/components/ops/abs.rst
@@ -0,0 +1,44 @@
+.. include:: ../../mydefs.rst
+
+``abs``
+=======
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void abs(T1 & x, const T2 & y);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Computes the element-wise absolute value of each element
+ in the operand x and stores the result in y.
+
+* ``T1`` and ``T2`` must be one-dimensional containers with compatible scalar types:
+
+ * an Eigen vector
+
+ * a Kokkos rank-1 view
+
+ * a Tpetra vector
+
+ * a Tpetra block vector
+
+ * a Epetra vector
+
+ * a Pressio expression, i.e. ``pressio::diag``, ``pressio::span``, ``pressio::subspan``, based on Eigen or Kokkos container
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T1`` and ``T2`` have the correct types.
+
diff --git a/docs/source/components/ops/add_to_diagonal.rst b/docs/source/components/ops/add_to_diagonal.rst
new file mode 100644
index 0000000..dbdfcb2
--- /dev/null
+++ b/docs/source/components/ops/add_to_diagonal.rst
@@ -0,0 +1,34 @@
+.. include:: ../../mydefs.rst
+
+``add_to_diagonal``
+===================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void add_to_diagonal(T1 & operand, const ScalarType & value);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Adds the specified scalar ``value`` to each diagonal element of ``operand``
+
+* ``T`` must be a rank-2 Eigen matrix
+
+* ``ScalarType`` must be convertible to ``pressio::Traits::scalar_type``
+
+Notes
+-----
+
+* If the diagonal entries of ``operand`` are written, then all diagonal entries must already exist.
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T1`` has the correct type.
diff --git a/docs/source/components/ops/clone.rst b/docs/source/components/ops/clone.rst
new file mode 100644
index 0000000..5dcbd86
--- /dev/null
+++ b/docs/source/components/ops/clone.rst
@@ -0,0 +1,66 @@
+.. include:: ../../mydefs.rst
+
+.. role:: cpp(code)
+ :language: cpp
+
+``clone``
+=========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ T clone(const T & operand);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Creates and returns a new instance of :cpp:`T` by making a new allocation
+ and *copying* all values from :cpp:`operand` into it.
+
+ * It is an exact but independent clone of :cpp:`operand`.
+
+* ``T`` must be:
+
+ * an Eigen vector or matrix object
+
+ * a Kokkos view
+
+ * a Teuchos vector
+
+ * or an Epetra vector or multi-vector
+
+ * or a Tpetra vector or multi-vector
+
+ * or a Tpetra block vector or multi-vector
+
+Notes
+-----
+
+* This is a blocking operation, i.e. the kernel completes before returning.
+
+* This kernel has value semantics, even for types that, by default,
+ have view semantics like Kokkos, Tpetra or TpetraBlock.
+ This means the following:
+ let :cpp:`auto result = clone(operand)`, then any operation applied
+ to :cpp:`operand` *after* calling clone will NOT
+ have any impact on ``result``.
+ And any operation applied to ``result`` will not have any impact on ``operand``.
+
+* For types that have value semantics, for example ``Eigen::Matrix<...>``,
+ Epetra vector or MV, this kernel can be implemented by calling the copy constructor
+ and returning the copy
+
+* For Kokkos, Tpetra, or TpetraBlock data types, which by default have view semantics
+ (i.e. a copy is a shallow copy), the operation can be implemented by first making a new
+ object with extents identical to ``operand``, followed by a deep copy, and then return the result.
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T`` has the correct type.
diff --git a/docs/source/components/ops/deep_copy.rst b/docs/source/components/ops/deep_copy.rst
new file mode 100644
index 0000000..40481b8
--- /dev/null
+++ b/docs/source/components/ops/deep_copy.rst
@@ -0,0 +1,46 @@
+.. include:: ../../mydefs.rst
+
+``deep_copy``
+=============
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void deep_copy(T2 & dest, const T1 & src);
+
+ template
+ void deep_copy(T & dest, const T & src);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Copies all elements from ``src`` into ``dst``, so that ``dst`` is fully independent of ``src``.
+
+* ``T1`` and ``T2`` must have the same rank, and must be:
+
+ * Two Eigen-based containers (either a native Eigen container or a Pressio expression based on an Eigen container)
+
+ * Two Kokkos-based containers (either a native Kokkos view or a Pressio expression based on a Kokkos container)
+
+* ``T`` must be:
+
+ * a Tpetra vector or multi-vector
+
+ * a Tpetra block vector or multi-vector
+
+ * a Epetra vector or multi-vector
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T``, ``T1``, and ``T2`` have the correct types.
+
diff --git a/docs/source/components/ops/dot.rst b/docs/source/components/ops/dot.rst
new file mode 100644
index 0000000..d6902c6
--- /dev/null
+++ b/docs/source/components/ops/dot.rst
@@ -0,0 +1,47 @@
+.. include:: ../../mydefs.rst
+
+``dot``
+=======
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void dot(const T1 & vecA, const T2 & vecB, DotResult & result);
+
+ template
+ scalar_type dot(const T1 & vecA, const T2 & vecB);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Computes the dot product of two compatible vectors (``vecA`` and ``vecB``)
+
+ * Stores the result in ``result`` if provided; otherwise, returns the result
+
+* ``T1`` and ``T2`` must be one-dimensional containers with compatible scalar types:
+
+ * an Eigen vector
+
+ * a Kokkos rank-1 view
+
+ * a Tpetra vector
+
+ * a Tpetra block vector
+
+ * a Epetra vector
+
+ * a pressio expression, i.e. ``pressio::diag``, ``pressio::span``, ``pressio::subspan``, based on Eigen or Kokkos container
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T1`` and ``T2`` have the correct types.
diff --git a/docs/source/components/ops/elementwise_multiply.rst b/docs/source/components/ops/elementwise_multiply.rst
new file mode 100644
index 0000000..7c35179
--- /dev/null
+++ b/docs/source/components/ops/elementwise_multiply.rst
@@ -0,0 +1,48 @@
+.. include:: ../../mydefs.rst
+
+``elementwise_multiply``
+========================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void elementwise_multiply(
+ const alpha_t & alpha,
+ const T & x,
+ const T1 & z,
+ const beta_t & beta,
+ T2 & y
+ );
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Computes ``y = beta * y + alpha * (x ⊙ z)``, where ``⊙`` denotes element-wise multiplication, and stores the result in y
+
+* ``T``, ``T1``, and ``T2`` must be one-dimensional containers with compatible scalar types:
+
+ * an Eigen vector
+
+ * a Kokkos rank-1 view
+
+ * a Tpetra vector
+
+ * a Tpetra block vector
+
+ * a Epetra vector
+
+ * a pressio expression, i.e. ``pressio::diag``, ``pressio::span``, ``pressio::subspan``, based on Eigen or Kokkos container
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T``, ``T1``, and ``T2`` have the correct types.
diff --git a/docs/source/components/ops/extent.rst b/docs/source/components/ops/extent.rst
new file mode 100644
index 0000000..3d65644
--- /dev/null
+++ b/docs/source/components/ops/extent.rst
@@ -0,0 +1,44 @@
+.. include:: ../../mydefs.rst
+
+``extent``
+==========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ std::size_t extent(const T & objectIn, const IndexType i);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Returns the size or dimension of a container ``objectIn`` along a specified axis ``i``
+
+* ``T`` must be one of the following:
+
+ * an Eigen vector or matrix object
+
+ * a Kokkos view
+
+ * a Teuchos vector
+
+ * a Tpetra vector or multi-vector
+
+ * a Tpetra block vector or multi-vector
+
+ * a Epetra vector or multi-vector
+
+ * a pressio expression, i.e. ``pressio::diag``, ``pressio::span``, ``pressio::subspan``, based on an Eigen, Tpetra Block, or Kokkos container
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T`` has the correct type.
diff --git a/docs/source/components/ops/fill.rst b/docs/source/components/ops/fill.rst
new file mode 100644
index 0000000..79a17a9
--- /dev/null
+++ b/docs/source/components/ops/fill.rst
@@ -0,0 +1,46 @@
+.. include:: ../../mydefs.rst
+
+``fill``
+========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void fill(T & operand, ScalarType const & value);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Overwrites each element of ``operand`` with ``value``.
+
+* ``T`` must be:
+
+ * an Eigen vector or matrix object
+
+ * a Kokkos rank-1 or rank-2 view
+
+ * a Teuchos vector
+
+ * a Tpetra vector or multi-vector
+
+ * a Tpetra block vector or multi-vector
+
+ * a Epetra vector or multi-vector
+
+ * a pressio expression, i.e. ``pressio::diag``, ``pressio::span``, ``pressio::subspan``, based on an Eigen or Kokkos container
+
+* ``ScalarType`` must be convertible to ``pressio::Traits::scalar_type``
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``T1`` and ``T2`` have the correct types.
diff --git a/docs/source/components/ops/matrix_matrix_product.rst b/docs/source/components/ops/matrix_matrix_product.rst
new file mode 100644
index 0000000..96b7dcd
--- /dev/null
+++ b/docs/source/components/ops/matrix_matrix_product.rst
@@ -0,0 +1,88 @@
+.. include:: ../../mydefs.rst
+
+``product`` (matrix-matrix)
+===========================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // op(A) = A^T and op(B) = B
+ template <
+ class A_type, class B_type, class C_type,
+ class alpha_t, class beta_t
+ >
+ void product(::pressio::transpose /*unused*/,
+ ::pressio::nontranspose /*unused*/,
+ const alpha_t & alpha,
+ const A_type & A,
+ const B_type & B,
+ const beta_t & beta,
+ C_type & C);
+
+ // op(A) = A and op(B) = B
+ template <
+ class A_type, class B_type, class C_type,
+ class alpha_t, class beta_t
+ >
+ void product(::pressio::nontranspose /*unused*/,
+ ::pressio::nontranspose /*unused*/,
+ const alpha_t & alpha,
+ const A_type & A,
+ const B_type & B,
+ const beta_t & beta,
+ C_type & C);
+
+ // A == B and op(A) = A^T
+ template
+ void product(::pressio::transpose /*unused*/,
+ ::pressio::nontranspose /*unused*/,
+ const alpha_t & alpha,
+ const A_type & A,
+ const beta_t & beta,
+ C_type & C);
+
+ // Construct result
+ template
+ C_type product(::pressio::transpose modeA,
+ ::pressio::nontranspose modeB,
+ const alpha_t & alpha,
+ const A_type & A);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Performs matrix-vector multiplication according to ``C = beta * C + alpha * op(A) * op(B)``
+
+ * ``op(X)`` indicates either ``X`` or ``X^T``
+
+* ``alpha_t`` and ``beta_t`` are scalar types
+
+* ``A_type``, ``B_type``, and ``C_type`` are rank-2 containers
+
+Types
+-----
+
+The matrix-matrix product works for the following matrix types:
+
+* Eigen (all containers are rank-2 Eigen matrices)
+
+* Epetra (``A`` and ``B`` are Epetra multi-vectors; ``C`` is a rank-2 Eigen matrix)
+
+* Kokkos (all containers are rank-2 Kokkos views)
+
+* Tpetra (``A`` and ``B`` are Tpetra multi-vectors; ``C`` is either a rank-2 Eigen matrix or a rank-2 Kokkos view)
+
+* Tpetra Block (``A`` and ``B`` are Tpetra Block multi-vectors; ``C`` is either a rank-2 Eigen matrix or a rank-2 Kokkos view)
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``A``, ``B``, and ``C``` have the correct types.
diff --git a/docs/source/components/ops/matrix_vector_product.rst b/docs/source/components/ops/matrix_vector_product.rst
new file mode 100644
index 0000000..af8e344
--- /dev/null
+++ b/docs/source/components/ops/matrix_vector_product.rst
@@ -0,0 +1,112 @@
+.. include:: ../../mydefs.rst
+
+``product`` (matrix-vector)
+===========================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // op(A) = A
+ template <
+ class A_type, class x_type, class y_type,
+ class alpha_t, class beta_t
+ >
+ void product(::pressio::nontranspose /*unused*/,
+ const alpha_t & alpha,
+ const A_type & A,
+ const x_type & x,
+ const beta_t & beta,
+ y_type & y);
+
+ // op(A) = A , construct result
+ template <
+ class y_type, class A_type, class x_type, class alpha_t
+ >
+ y_type product(::pressio::nontranspose mode,
+ const alpha_t & alpha,
+ const A_type & A,
+ const x_type & x);
+
+ // op(A) = A^T
+ template <
+ class y_type, class A_type, class x_type, class alpha_t
+ >
+ void product(::pressio::transpose /*unused*/,
+ const alpha_t & alpha,
+ const A_type & A,
+ const x_type & x,
+ const beta_t & beta,
+ y_type & y);
+
+ // op(A) = A^T , construct result
+ template
+ y_type product(::pressio::transpose mode,
+ const alpha_t & alpha,
+ const A_type & A,
+ const x_type & x);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Performs matrix-vector multiplication according to ``y = beta * y + alpha * op(A) * x``
+ * ``op(A)`` indicates either ``A`` or ``A^T``
+
+* ``alpha_t`` and ``beta_t`` are scalar types
+
+* ``x_type`` and ``y_type`` are rank-1 containers
+
+* ``A_type`` is a rank-2 container
+
+* The following combinations of container types are supported for each ``A_type``:
+
+ * Eigen
+
+ * All container types are either Eigen containers or Pressio expressions of Eigen containers,
+
+ * Epetra
+
+ * ``A_type`` is an Epetra rank-2 container
+ * Either ``x_type`` or ``y_type`` is a rank-1 Epetra container
+ * The other non-Epetra container is a rank-1 Teuchos or Eigen container
+
+ * Kokkos
+
+ * All container types are either Kokkos views or Pressio expressions of Eigen views
+
+ * Teuchos (does not support constructed results)
+
+ * ``A_type`` is a rank-2 Teuchos container
+ * ``x_type`` and ``y_type`` are rank-1 Eigen containers
+
+ * Tpetra
+
+ * ``A_type`` is a rank-2 Tpetra container
+
+ * ``x_type`` is a rank-1 Eigen, Kokkos, Teuchos, or Tpetra container
+
+ * ``y_type`` is a rank-1 container.
+ If ``x_type`` is Tpetra, it may be either a Kokkos or Eigen container (or a Pressio expression of a Kokkos or Eigen container)
+ Otherwise, ``y_type`` is a Tpetra container or a Pressio column expression
+
+ * Tpetra Block
+
+ * ``A_type`` is a rank-2 Tpetra Block container
+
+ * ``x_type`` is a rank-1 Eigen, Kokkos, Teuchos, or Tpetra Block container
+
+ * ``y_type`` is a rank-1 container.
+ If ``x_type`` is a Tpetra Block vector, ``y_type`` may be either an Eigen vector or a rank-1 Kokkos view
+ Otherwise, ``y_type`` is a Tpetra Block vector or column expression
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking that ``A_type``, ``x_type``, and ``y_type``` have the correct types.
diff --git a/docs/source/components/ops/min_max.rst b/docs/source/components/ops/min_max.rst
new file mode 100644
index 0000000..cf1c715
--- /dev/null
+++ b/docs/source/components/ops/min_max.rst
@@ -0,0 +1,28 @@
+.. include:: ../../mydefs.rst
+
+``min`` & ``max``
+=================
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ scalar_type max(const T & obj);
+
+ template
+ scalar_type min(const T & obj);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Returns the maximum or minimum value of the given container
+
+* Works for all container types other than Teuchos arrays
diff --git a/docs/source/components/ops/norms.rst b/docs/source/components/ops/norms.rst
new file mode 100644
index 0000000..a0b1728
--- /dev/null
+++ b/docs/source/components/ops/norms.rst
@@ -0,0 +1,42 @@
+.. include:: ../../mydefs.rst
+
+``norms``
+=========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // L1 Norm
+ template
+ scalar_type norm1(const T & a);
+
+ // L2 Norm
+ template
+ scalar_type norm2(const T & a);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Returns the desired norm of the given container ``a``
+
+* L1 norm is given by
+
+.. math::
+
+ \| a \|_1 = \sum_{i} |a_i|
+
+* L2 norm is given by:
+
+.. math::
+
+ \|\mathbf{a}\|_2 = \sqrt{\sum_{i=1}^{n} a_i^2}
+
+* ``a`` must be rank-1 container of any type
diff --git a/docs/source/components/ops/pow.rst b/docs/source/components/ops/pow.rst
new file mode 100644
index 0000000..d6dde4e
--- /dev/null
+++ b/docs/source/components/ops/pow.rst
@@ -0,0 +1,47 @@
+.. include:: ../../mydefs.rst
+
+``pow``
+=======
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // x^exponent
+ template
+ void pow(T & x, const scalar_type & exponent);
+
+ // y = x^exponent
+ template
+ void pow(T1 & y, const T2 & x, const scalar_type & exponent);
+
+ // y = |x|^exponent (exponent > 0)
+ template
+ abs_pow(T1 & y,
+ const T2 & x,
+ const typename ::pressio::Traits::scalar_type & exponent
+ );
+
+ // y = |x|^exponent (exponent < 0)
+ template
+ abs_pow(T1 & y,
+ const T2 & x,
+ const typename ::pressio::Traits::scalar_type & exponent,
+ const typename ::pressio::Traits::scalar_type & eps
+ );
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Raises each element of a rank-1 container ``x`` to the specified power ``exponent``
+
+* Stores the result in ``y`` if provided; otherwise, acts in place on ``x``
+
+* ``x`` may be any type of rank-1 container other than a Teuchos vector
diff --git a/docs/source/components/ops/resize.rst b/docs/source/components/ops/resize.rst
new file mode 100644
index 0000000..f0a824f
--- /dev/null
+++ b/docs/source/components/ops/resize.rst
@@ -0,0 +1,36 @@
+.. include:: ../../mydefs.rst
+
+``resize``
+==========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // T is rank-1
+ template
+ void resize(T & o, ::pressio::ops::impl::ordinal_t newSize);
+
+ // T is rank-2
+ template
+ void resize(T & o,
+ const ::pressio::ops::impl::ordinal_t newRows,
+ const ::pressio::ops::impl::ordinal_t newCols);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Resizes ``o`` to the specified dimensions
+
+* ``o`` may be either of the following types:
+
+ * A dynamic Eigen container
+
+ * A dynamic Kokkos view
diff --git a/docs/source/components/ops/scale.rst b/docs/source/components/ops/scale.rst
new file mode 100644
index 0000000..9cf787a
--- /dev/null
+++ b/docs/source/components/ops/scale.rst
@@ -0,0 +1,42 @@
+.. include:: ../../mydefs.rst
+
+``scale``
+=========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void scale(T & o, const ScalarType & value);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Multiplies every entry in ``o`` by ``value``
+
+* ``o`` may be a rank-1 or rank-2 container of the following types:
+
+ * Eigen (or a Pressio expression acting on an Eigen container)
+
+ * Epetra
+
+ * Kokkos (or a Pressio expression acting on a Kokkos container)
+
+ * Teuchos
+
+ * Tpetra (or a Pressio expression acting on a Tpetra container)
+
+ * Tpetra Block (or a Pressio expression acting on a Tpetra Block container)
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking for the correct types.
diff --git a/docs/source/components/ops/set_zero.rst b/docs/source/components/ops/set_zero.rst
new file mode 100644
index 0000000..50ab31d
--- /dev/null
+++ b/docs/source/components/ops/set_zero.rst
@@ -0,0 +1,42 @@
+.. include:: ../../mydefs.rst
+
+``set_zero``
+============
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ template
+ void set_zero(T & o);
+
+ }} // end namespace pressio::ops
+
+Description
+-----------
+
+* Sets every entry in ``o`` to zero
+
+* ``o`` may be a container of the following types:
+
+ * Eigen (or a Pressio expression acting on an Eigen container)
+
+ * Epetra (rank-1 only)
+
+ * Kokkos (or a Pressio expression acting on a Kokkos container)
+
+ * Teuchos (rank-1 only)
+
+ * Tpetra (or a Pressio expression acting on a Tpetra container)
+
+ * Tpetra Block (or a Pressio expression acting on a Tpetra Block container)
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking for the correct types.
diff --git a/docs/source/components/ops/update.rst b/docs/source/components/ops/update.rst
new file mode 100644
index 0000000..957b56d
--- /dev/null
+++ b/docs/source/components/ops/update.rst
@@ -0,0 +1,81 @@
+.. include:: ../../mydefs.rst
+
+``update``
+==========
+
+Header: ````
+
+API
+---
+
+.. code-block:: cpp
+
+ namespace pressio { namespace ops{
+
+ // V = a * V + b * V1
+ template
+ void update(T & v, const a_Type & a,
+ const T1 & v1, const b_Type & b);
+
+ // V = a * V + b * V1 + c * V2
+ template<
+ class T, class T1, class T2,
+ class a_Type, class b_Type, class c_Type
+ >
+ void update(T & v, const a_Type &a,
+ const T1 & v1, const b_Type &b,
+ const T2 & v2, const c_Type &c);
+
+ // V = a * V + b * V1 + c * V2 + d * V3
+ template<
+ class T, class T1, class T2, class T3,
+ class a_Type, class b_Type, class c_Type, class d_Type
+ >
+ void update(T & v, const a_Type &a,
+ const T1 & v1, const b_Type &b,
+ const T2 & v2, const c_Type &c,
+ const T3 & v3, const d_Type &d);
+
+ // V = a * V + b * V1 + c * V2 + d * V3 + e * V4
+ template<
+ class T, class T1, class T2, class T3, class T4,
+ class a_Type, class b_Type, class c_Type, class d_Type, class e_Type
+ >
+ void update(T & v, const a_Type &a,
+ const T1 & v1, const b_Type &b,
+ const T2 & v2, const c_Type &c,
+ const T3 & v3, const d_Type &d,
+ const T4 & v4, const e_Type &e);
+
+ // Rank-2 overload (Eigen and Kokkos only)
+ // MV = a * MV + b * MV1
+ template
+ void update(T & mv, const alpha_t &a,
+ const T1 & mv1, const beta_t &b)
+
+ }} // end namespace pressio::ops
+
+
+Description
+-----------
+
+* Performs a combined scaling and addition on vector ``v`` using the given scalars (``a``, ``b``, ... , ``e``) and auxiliary vectors (``v1``, ... , ``v4``)
+
+* Stores the result in ``v``
+
+* All vectors should have the same size and the same type. They may be:
+
+ * Rank-1 or Rank-2 (see specific overload) Eigen containers or Pressio expressions of Eigen containers
+
+ * Rank-1 Epetra containers
+
+ * Rank-1 or Rank-2 (see specific overload) Kokkos containers or Pressio expressions of Kokkos containers
+
+ * Rank-1 Tpetra containers or Pressio column expressions acting on Tpetra
+
+ * Rank-1 Tpetra Block containers or Pressio column expressions acting on Tpetra Block
+
+Notes
+-----
+
+* See the :doc:`ops homepage <../ops>` for a table of booleans to use when checking for the correct types.
diff --git a/docs/source/components/type_traits.rst b/docs/source/components/type_traits.rst
new file mode 100644
index 0000000..9c29d49
--- /dev/null
+++ b/docs/source/components/type_traits.rst
@@ -0,0 +1,130 @@
+.. role:: raw-html-m2r(raw)
+ :format: html
+
+.. include:: ../mydefs.rst
+
+``type_traits``
+===============
+
+Header: ````
+
+Public namespace: ``pressio``
+
+
+Scope
+-----
+
+Provides functionalities for type introspection and detection.
+One of the main design features of pressio is that it supports arbitrary
+types via generic programming and type introspection, but also
+provides special support for some data types commonly used.
+
+
+Traits class
+------------
+
+\todo: finish
+
+One of the most important things inside ``type_traits`` is the ``Traits`` class:
+
+.. code-block:: cpp
+
+ namespace pressio{
+ template struct Traits;
+ }
+
+To understand the purpose and usage of the traits pattern in C++ there are several resources online.
+Quoting Bjarne Stroustrup: "Think of a trait as a small object whose main purpose
+is to carry information used by another object or algorithm
+to determine "policy" or "implementation details".
+Pressio uses specializations of this class to gather *in a uniform way*
+compile-time information enabling it to reason about types.
+The key point here is that *different TPLs use a variety of naming conventions
+for nested typedefs and related things*\ , so there is not easy way to access
+similar information from types of various libraries.
+This is what motivated us to implement this ``type_traits`` component.
+We need a standard, uniform way to query types for compile-time information.
+We currently have traits specialized for types of a few TPLs, like Trilinos, Kokkos, Eigen.
+An example of one such specialization (in this case for Eigen) is:
+
+.. code-block:: cpp
+
+ template
+ struct Traits<
+ T, std::enable_if_t::value>
+ >
+ {
+ using scalar_type = typename T::Scalar;
+ static constexpr int rank = 1;
+ };
+
+This ``Traits`` class play a key role when users want to use arbitrary types (i.e. types
+which are not known to presso) and to do so, users shoud specialize this class and make
+these specialization visibile to pressio to provide information about their generic types. :raw-html-m2r:` `
+
+For practical examples of how this class is used, see:
+
+:red:`finish`
+
+..
+ * `Newton-Raphson solver `_
+ * `ode explicit steppers `_
+ * `ode implicit steppers `_
+
+
+
+Type detection and identification
+---------------------------------
+
+We support several metafunctions for detecting
+data types commonly used from existing TPLs.
+The following list is partial, and more will be added as we continue the development.
+
+.. list-table::
+ :widths: 45 55
+ :header-rows: 1
+
+ * - Name
+ - Description
+ * - ``template`` :raw-html-m2r:` ` ``struct is_static_vector_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static Eigen vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dynamic_vector_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dynamic Eigen vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_vector_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static or dynamic Eigen vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_sparse_matrix_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static or dynamic sparse Eigen matrix. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_static_dense_matrix_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static dense Eigen matrix. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dynamic_dense_matrix_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dynamic dense Eigen matrix. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dense_matrix_eigen;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static or dynamic dense Eigen matrix. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_EIGEN==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dense_vector_teuchos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dense Teuchos vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dense_matrix_teuchos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dense Teuchos matrix. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_vector_epetra;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is Epetra vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_multi_vector_epetra;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is an Epetra multi vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_vector_tpetra;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a Tpetra vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_multi_vector_tpetra;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a Tpetra multi vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_vector_tpetra_block;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a Tpetra-block vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_multi_vector_tpetra_block;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a Tpetra-block multi vector. :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_TRILINOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_static_vector_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static Kokkos vector (rank-1 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dynamic_vector_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dynamic Kokkos vector (rank-1 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_vector_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static or dynamic Kokkos vector (rank-1 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_static_dense_matrix_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static dense Kokkos matrix (rank-2 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dynamic_dense_matrix_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a dynamic dense Kokkos matrix (rank-2 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
+ * - ``template`` :raw-html-m2r:` ` ``struct is_dense_matrix_kokkos;``
+ - Provides static member constant ``value`` equal to ``true`` if ``T`` is a static or dynamic dense Kokkos matrix (rank-2 View). :raw-html-m2r:` ` Requires: ``PRESSIO_ENABLE_TPL_KOKKOS==On``
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..3af5bb6
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,136 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import datetime
+import os
+import sys
+sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+# The master toctree document.
+master_doc = "index"
+
+project = 'pressio-ops'
+# copyright = f'{datetime.datetime.now().year}, 2021, National Technology & Engineering Solutions of Sandia, LLC (NTESS)'
+copyright = u"2021, National Technology & Engineering Solutions of Sandia, LLC (NTESS)"
+author = 'Francesco Rizzi'
+
+# The default replacements for |version| and |release|, also used in various
+# other places throughout the built documents.
+def get_version():
+ version_splits = []
+ with open("../../include/pressio/ops_macros.hpp") as version_file:
+ for line in version_file:
+ splits = line.strip().split()
+ if len(splits) == 3 and "VERSION" in splits[1]:
+ version_splits.append(splits[2])
+ return ".".join(version_splits)
+
+# The full version, including alpha/beta/rc tags
+release = get_version()
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ "myst_parser", \
+ "sphinx.ext.autodoc", \
+ "sphinx.ext.viewcode", \
+ "sphinx.ext.intersphinx", \
+ "sphinx_copybutton"]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+today_fmt = "%B %d, %Y"
+
+# -- Options for HTML output -------------------------------------------------
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = "tango"
+pygments_dark_style = "monokai"
+#from pygments.styles import get_all_styles
+#styles = list(get_all_styles())
+#print(styles)
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+
+html_title = project + "-"+release
+
+html_theme = 'furo'
+
+html_theme_options = {
+ "sidebar_hide_name": False,
+ "light_css_variables": {
+ "color-brand-primary": "#336790", # blue
+ "color-brand-content": "#336790"
+ },
+ "dark_css_variables": {
+ "color-brand-primary": "#E5B62F", # yellow1
+ "color-brand-content": "#E5B62F"
+ #"color-brand-primary": "#F4EB4D", # yellow2
+ #"color-brand-content": "#F4EB4D"
+ #"color-brand-primary": "#F39C12", # orange
+ #"color-brand-content": "#F39C12",
+ #"color-brand-primary": "#00FF40", # lime
+ #"color-brand-content": "#00FF40"
+ #"color-brand-primary": "#6ed0f5", # cyan
+ #"color-brand-content": "#6ed0f5"
+ },
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+html_css_files = ['hacks.css']
+
+source_suffix = {
+ '.rst': 'restructuredtext',
+ '.md': 'markdown',
+}
+
+# If not '', a "Last updated on:" timestamp is inserted at every page bottom,
+# using the given strftime format.
+html_last_updated_fmt = "%b %d, %Y"
+
+# need to figure out why this does not work
+# rst_prolog = """
+# .. include:: special.rst
+# """
+
+html_sidebars = {
+ "**": [
+ "sidebar/scroll-start.html",
+ "sidebar/brand.html",
+ "sidebar/search.html",
+ "sidebar/navigation.html",
+ "sidebar/ethical-ads.html",
+ "sidebar/scroll-end.html",
+ ]
+}
+
+html_logo = "_static/logo.png"
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 0000000..5698002
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,124 @@
+.. role:: raw-html-m2r(raw)
+ :format: html
+
+.. include:: mydefs.rst
+
+pressio-ops C++ library
+=======================
+
+This library aims to provide a unified free-function-based interface
+to facilitate usability and interoperability of widely-used linear algebra software libraries.
+
+Motivation
+----------
+
+Linear algebra underpins many applications fundamental to science and industry.
+Currently, there are multiple open-source libraries offering shared- and distributed-memory
+linear algebra data structures (vectors, matrices, etc.) and/or kernel operations to manipulate them.
+For example, Trilinos, PETSc, Kokkos/Kokkos-kernels, Eigen, Blitz++, Armadillo, mlpack, BLAS/LAPACK.
+These libraries serve as foundations to many applications.
+Compound this mutiplicity of efforts by the lack of interest and/or resources
+to improve their usability and inteoperabability, and the result is a plethora
+of linear algebra libraries that shared some key aspects:
+
+- **diverse API**: every library has its own custom API for doing, after all, the same set of operations.
+ This poses a major limitation to existing software stacks relying on them because it inhibits an easy transition to a different choice.
+ What would happen if one of these fundamental libraries were discontinued?
+ It would lead to *many* applications having to be refactored, a huge investment of resouces and development hours.
+ Also, this constitutes a problem for any new application that will being developed, since one would need to choose one library from the start
+ and stick to it, or reimplemnet support for multiple backends from scratch every time.
+
+- **hard-to-use API**: some of these libraries adopted an API that closely adheres to the BLAS standard, thus making them harder
+ to use for a generic user. It is well-known and accepted that the BLAS standard defines
+ an API is hard to read and use: one reason is that its API defines functions accepting several arguments,
+ with adjacent parameters that can be invoked by the same arguments in either order with different meaning.
+ This makes them hard to be used correctly---this was also a key motivation of the standardization effort that led to the C++26 stdBLAS feature.
+
+- **hard to extend/customize**: in some cases, e.g. Trilinos, the design is such that operations to manipulate data
+ are methods of the data structures classes themselves rather than free fucntions. In C++, such design precludes
+ the flexibility of doing user-level overloading or specialization of these "operations".
+
+- **minimal or non-existent interoperability**: the intoperability between some of these libraries is minimal or even non-existent.
+ Several factors contributed to this, inlcuding that some of the libraries were intended for heterogenous hardware, while some only work for CPUs; some only operate on a single node while others support distributed memory. This makes it really hard to couple different applications, exchange data, and operated on-line on different data structures.
+
+What pressio-ops offers
+-----------------------
+
+This library tries to address some of issues above by providing a unified free-function-based interface
+to facilitate usability and interoperability of widely-used linear algebra software libraries.
+The supported capabilities are shown in the table below.
+Each component (level) of the stack depends on the ones below it.
+
+|
+
+.. list-table::
+ :widths: 10 48 42
+ :header-rows: 1
+ :align: left
+
+ * -
+ - Description
+ - Header(s)
+
+ * - ``ops``
+ - shared-memory/distributed linear algebra kernels specializations
+ - ````
+
+ * - ``expressions``
+ - expressions templates, e.g.: span, diagonal, subspan
+ - ````
+
+ * - ``type_traits``
+ - type traits and detection
+ - ````
+
+ * - ``mpl``
+ - metaprogramming functionalities
+ - ````
+
+
+Get Started
+-----------
+
+* `Install `_: (currently) header-only, should be trivial
+
+
+License and Citation
+--------------------
+
+The full license (BSD-3) is available `here `_.
+
+Sooner or later we will publish this... in the meantime, you can find on arXiv
+an (outdated) preprint at: https://arxiv.org/abs/2003.07798
+
+Questions?
+----------
+
+Find us on Slack: https://pressioteam.slack.com or
+open an issue on `github `_.
+
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ installation
+
+.. toctree::
+ :caption: API
+ :maxdepth: 1
+ :hidden:
+
+ ./components/ops
+ ./components/expressions
+ ./components/type_traits
+ ./components/mpl
+
+.. toctree::
+ :caption: Miscellanea
+ :maxdepth: 1
+ :hidden:
+
+ GitHub Repo
+ Open an issue/feature req.
+ license
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
new file mode 100644
index 0000000..b24a3ee
--- /dev/null
+++ b/docs/source/installation.rst
@@ -0,0 +1,115 @@
+.. role:: raw-html-m2r(raw)
+ :format: html
+
+Installation and Dependencies
+=============================
+
+Installation
+------------
+
+.. tip::
+
+ pressio-ops is header-only, so it does not need to be precompiled and linked to.
+ However, since we use preprocessor directives to conditionally
+ enable/disable code based on target third-party libraries,
+ one needs to account for this. See below for the details.
+
+.. warning::
+
+ To use pressio-ops, you need at least a C++17 compiler.
+
+Dependencies
+------------
+
+Some parts contain code that are specific to third-party libraries (TPLs).
+Currently, the list of TPLs supported is shown below:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 10 50 40
+ :align: left
+
+ * - TPL Name
+ - Optional/Required
+ - Version Known to Work/run in CI
+ * - Eigen
+ - Required
+ - 3.3.7
+ * - Trilinos
+ - Optional
+ - commit: ef73d14babf6e7556b0420add98cce257ccaa56b
+ * - MPI
+ - Optional
+ - --
+ * - Kokkos
+ - Optional
+ - 3.1.0
+ * - BLAS
+ - Optional
+ - --
+ * - LAPACK
+ - Optional
+ - --
+ * - GoogleTest
+ - Optional
+ - 1.10.0
+
+Eigen is the only required dependency because it is the
+default choice for instantiating the ROM data structures
+and solving the (dense) ROM problem used in `pressio `_.
+
+CMake Keywords
+~~~~~~~~~~~~~~
+
+Enabling/disabling specific dependencies can be done via the following cmake variables:
+
+.. list-table::
+ :widths: 30 60 10
+ :header-rows: 1
+ :align: left
+
+ * - Variable
+ - Description
+ - Default
+
+ * - ``PRESSIO_ENABLE_TPL_EIGEN``
+ - self-explanatory
+ - ``ON``
+
+ * - ``PRESSIO_ENABLE_TPL_TRILINOS``
+ - self-explanatory
+ - ``OFF``
+
+ * - ``PRESSIO_ENABLE_TPL_MPI``
+ - self-explanatory
+ - ``OFF`` but automatically ``ON`` if ``PRESSIO_ENABLE_TPL_TRILINOS=ON``
+
+ * - ``PRESSIO_ENABLE_TPL_KOKKOS``
+ - self-explanatory
+ - ``OFF`` but automatically ``ON`` if ``PRESSIO_ENABLE_TPL_TRILINOS=ON``
+
+ * - ``PRESSIO_ENABLE_TEUCHOS_TIMERS``
+ - self-explanatory
+ - ``OFF`` but automatically ``ON`` if ``PRESSIO_ENABLE_TPL_TRILINOS=ON``
+
+
+Obviously, the choice of which TPLs to enable is related to
+your application's dependency requirements.
+For example, if you have an application that relies on
+Trilinos data structures and want to use ``pressio``\ ,
+then it makes sense to enable the Trilinos dependency.
+On the contrary, if you have an application that relies only on
+Eigen data structures, then it makes sense to only leave only Eigen on
+and disable the rest.
+
+Also, we note that some of the cmake variables listed above are connected
+and cannot be turned on individualy.
+For example, if we enable Trilinos then ``pressio`` automatically
+enables also Kokkos, BLAS, LAPACK and MPI.
+
+
+.. important::
+
+ All CMake keywords are prefixed with ``PRESSIO_`` which is case-sensitive.
+
+ Recall that to set a keyword in CMake you used the syntax ``-Dkeyword_name``.
diff --git a/docs/source/license.rst b/docs/source/license.rst
new file mode 100644
index 0000000..881ae5b
--- /dev/null
+++ b/docs/source/license.rst
@@ -0,0 +1,51 @@
+License
+=======
+
+.. highlight:: none
+
+::
+
+ //@HEADER
+ // ************************************************************************
+ //
+ // Pressio
+ // Copyright 2019 National Technology & Engineering Solutions of Sandia,LLC
+ // (NTESS)
+ //
+ // Under the terms of Contract DE-NA0003525 with NTESS, the
+ // U.S. Government retains certain rights in this software.
+ //
+ // Pressio is licensed under BSD-3-Clause terms of use:
+ //
+ // Redistribution and use in source and binary forms, with or without
+ // modification, are permitted provided that the following conditions
+ // are met:
+ //
+ // 1. Redistributions of source code must retain the above copyright
+ // notice, this list of conditions and the following disclaimer.
+ //
+ // 2. Redistributions in binary form must reproduce the above copyright
+ // notice, this list of conditions and the following disclaimer in the
+ // documentation and/or other materials provided with the distribution.
+ //
+ // 3. Neither the name of the copyright holder nor the names of its
+ // contributors may be used to endorse or promote products derived
+ // from this software without specific prior written permission.
+ //
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ // IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ // POSSIBILITY OF SUCH DAMAGE.
+ //
+ // Questions? Contact Francesco Rizzi (fnrizzi@sandia.gov)
+ //
+ // ************************************************************************
+ //@HEADER
diff --git a/docs/source/mydefs.rst b/docs/source/mydefs.rst
new file mode 100644
index 0000000..43eccbf
--- /dev/null
+++ b/docs/source/mydefs.rst
@@ -0,0 +1,50 @@
+.. Color profiles for Sphinx.
+.. Has to be used with hacks.css
+.. (https://bitbucket.org/lbesson/web-sphinx/src/master/.static/hacks.css)
+
+.. role:: black
+.. role:: gray
+.. role:: grey
+.. role:: silver
+.. role:: white
+.. role:: maroon
+.. role:: red
+.. role:: magenta
+.. role:: fuchsia
+.. role:: pink
+.. role:: orange
+.. role:: yellow
+.. role:: lime
+.. role:: green
+.. role:: olive
+.. role:: teal
+.. role:: cyan
+.. role:: aqua
+.. role:: blue
+.. role:: navy
+.. role:: purple
+
+.. role:: under
+.. role:: over
+.. role:: blink
+.. role:: line
+.. role:: strike
+
+.. role:: it
+.. role:: ob
+
+.. role:: small
+.. role:: medium
+.. role:: large
+
+.. role:: packnameindexpage
+.. role:: summarylineindexpage
+
+.. role:: center
+.. role:: left
+.. role:: right
+
+.. role:: memberfunction
+
+
+.. Adapted from (c) Lilian Besson, 2011-2016, https://bitbucket.org/lbesson/web-sphinx/