diff options
| -rw-r--r-- | doc/analytic-k2.png | bin | 0 -> 11210 bytes | |||
| -rw-r--r-- | doc/analytic.png | bin | 0 -> 17892 bytes | |||
| -rw-r--r-- | doc/excerpt.cc | 19 | ||||
| -rw-r--r-- | doc/excerpt2.cc | 14 | ||||
| -rw-r--r-- | doc/line-sol-k2.png | bin | 0 -> 14810 bytes | |||
| -rw-r--r-- | doc/line-supg-sol-k2.png | bin | 0 -> 8614 bytes | |||
| -rw-r--r-- | doc/paper-excerpt1.cc | 24 | ||||
| -rw-r--r-- | doc/paper-excerpt2.cc | 19 | ||||
| -rw-r--r-- | doc/report.pdf | bin | 222163 -> 314605 bytes | |||
| -rw-r--r-- | doc/report.tex | 270 | ||||
| -rw-r--r-- | doc/sources.bib | 32 |
11 files changed, 340 insertions, 38 deletions
diff --git a/doc/analytic-k2.png b/doc/analytic-k2.png new file mode 100644 index 0000000..6389688 --- /dev/null +++ b/doc/analytic-k2.png | |||
| Binary files differ | |||
diff --git a/doc/analytic.png b/doc/analytic.png new file mode 100644 index 0000000..83078d0 --- /dev/null +++ b/doc/analytic.png | |||
| Binary files differ | |||
diff --git a/doc/excerpt.cc b/doc/excerpt.cc new file mode 100644 index 0000000..5a57a0d --- /dev/null +++ b/doc/excerpt.cc | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | for (int i = 0; i < ir->GetNPoints(); ++i) { | ||
| 2 | // Get shape functions, coefficients at this integration point. | ||
| 3 | ... | ||
| 4 | |||
| 5 | // Calculate phi_grad. | ||
| 6 | phi_grad = 0.0; | ||
| 7 | for (int b = 0; b < nen; ++b) { | ||
| 8 | for (int j = 0; j < nsd; ++j) { | ||
| 9 | phi_grad(j) += dshape(b, j) * elfun(b); | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | // Calculate SUPG term. | ||
| 14 | for (int a = 0; a < nen; ++a) { | ||
| 15 | dshape.GetRow(a, Na_grad); | ||
| 16 | double tau_tmp = (A_ip*Na_grad)*tau_ip; | ||
| 17 | elvec(a) += tau_tmp * (A_ip * phi_grad) * wdetj; | ||
| 18 | } | ||
| 19 | } | ||
diff --git a/doc/excerpt2.cc b/doc/excerpt2.cc new file mode 100644 index 0000000..765e338 --- /dev/null +++ b/doc/excerpt2.cc | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | for (int i = 0; i < ir->GetNPoints(); ++i) { | ||
| 2 | // Get shape functions, coefficients at this integration point. | ||
| 3 | ... | ||
| 4 | |||
| 5 | // Calculate tangent matrix. | ||
| 6 | for (int a = 0; a < nen; ++a) { | ||
| 7 | dshape.GetRow(a, Na_grad); | ||
| 8 | double tau_tmp = (A_ip*Na_grad)*tau_ip; | ||
| 9 | for (int b = 0; b < nen; ++b) { | ||
| 10 | dshape.GetRow(b, Nb_grad); | ||
| 11 | elmat(a, b) += tau_tmp * (A_ip * Nb_grad) * wdetj; | ||
| 12 | } | ||
| 13 | } | ||
| 14 | } | ||
diff --git a/doc/line-sol-k2.png b/doc/line-sol-k2.png new file mode 100644 index 0000000..aba807f --- /dev/null +++ b/doc/line-sol-k2.png | |||
| Binary files differ | |||
diff --git a/doc/line-supg-sol-k2.png b/doc/line-supg-sol-k2.png new file mode 100644 index 0000000..1acd732 --- /dev/null +++ b/doc/line-supg-sol-k2.png | |||
| Binary files differ | |||
diff --git a/doc/paper-excerpt1.cc b/doc/paper-excerpt1.cc new file mode 100644 index 0000000..d34bce3 --- /dev/null +++ b/doc/paper-excerpt1.cc | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | for (int i = 0; i < ir->GetNPoints(); ++i) { | ||
| 2 | // Get shape functions, coefficients at this integration point. | ||
| 3 | const IntegrationPoint& ip = ir->IntPoint(i); | ||
| 4 | Tr.SetIntPoint(&ip); | ||
| 5 | el.CalcPhysDShape(Tr, dshape); | ||
| 6 | A_ir.GetColumn(i, A_ip); | ||
| 7 | double tau_ip = tau->Eval(Tr, ip); | ||
| 8 | const double wdetj = ip.weight * Tr.Weight(); | ||
| 9 | |||
| 10 | // Calculate phi_grad. | ||
| 11 | phi_grad = 0.0; | ||
| 12 | for (int b = 0; b < nen; ++b) { | ||
| 13 | for (int j = 0; j < nsd; ++j) { | ||
| 14 | phi_grad(j) += dshape(b, j) * elfun(b); | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | // Calculate SUPG term. | ||
| 19 | for (int a = 0; a < nen; ++a) { | ||
| 20 | dshape.GetRow(a, Na_grad); | ||
| 21 | double tau_tmp = (A_ip*Na_grad)*tau_ip; | ||
| 22 | elvec(a) += tau_tmp * (A_ip * phi_grad) * wdetj; | ||
| 23 | } | ||
| 24 | } | ||
diff --git a/doc/paper-excerpt2.cc b/doc/paper-excerpt2.cc new file mode 100644 index 0000000..5843c4d --- /dev/null +++ b/doc/paper-excerpt2.cc | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | for (int i = 0; i < ir->GetNPoints(); ++i) { | ||
| 2 | // Get shape functions, coefficients at this integration point. | ||
| 3 | const IntegrationPoint& ip = ir->IntPoint(i); | ||
| 4 | Tr.SetIntPoint(&ip); | ||
| 5 | el.CalcPhysDShape(Tr, dshape); | ||
| 6 | A_ir.GetColumn(i, A_ip); | ||
| 7 | double tau_ip = tau->Eval(Tr, ip); | ||
| 8 | double wdetj = ip.weight * Tr.Weight(); | ||
| 9 | |||
| 10 | // Calculate tangent matrix. | ||
| 11 | for (int a = 0; a < nen; ++a) { | ||
| 12 | dshape.GetRow(a, Na_grad); | ||
| 13 | double tau_tmp = (A_ip*Na_grad)*tau_ip; | ||
| 14 | for (int b = 0; b < nen; ++b) { | ||
| 15 | dshape.GetRow(b, Nb_grad); | ||
| 16 | elmat(a, b) += tau_tmp * (A_ip * Nb_grad) * wdetj; | ||
| 17 | } | ||
| 18 | } | ||
| 19 | } | ||
diff --git a/doc/report.pdf b/doc/report.pdf index c45cdcc..e9709a0 100644 --- a/doc/report.pdf +++ b/doc/report.pdf | |||
| Binary files differ | |||
diff --git a/doc/report.tex b/doc/report.tex index 9c72b59..510637f 100644 --- a/doc/report.tex +++ b/doc/report.tex | |||
| @@ -5,13 +5,15 @@ | |||
| 5 | \usepackage{amsmath} | 5 | \usepackage{amsmath} |
| 6 | \usepackage{graphicx} | 6 | \usepackage{graphicx} |
| 7 | \usepackage{hyperref} | 7 | \usepackage{hyperref} |
| 8 | \usepackage{tabularx} | ||
| 9 | \usepackage{listings} | ||
| 8 | 10 | ||
| 9 | \usepackage[backend=biber]{biblatex} | 11 | \usepackage[backend=biber]{biblatex} |
| 10 | \addbibresource{sources.bib} | 12 | \addbibresource{sources.bib} |
| 11 | 13 | ||
| 12 | \title{% | 14 | \title{ |
| 13 | Term Project Report \\ | 15 | SUPG Stabilization for Advection-Diffusion with MFEM \\ |
| 14 | MANE 6660: Finite Element Method | 16 | \large{MANE 6660: Finite Element Method Final Project Report} |
| 15 | } | 17 | } |
| 16 | \author{Aiden Woodruff} | 18 | \author{Aiden Woodruff} |
| 17 | \date{\today} | 19 | \date{\today} |
| @@ -19,67 +21,102 @@ MANE 6660: Finite Element Method | |||
| 19 | \begin{document} | 21 | \begin{document} |
| 20 | \maketitle | 22 | \maketitle |
| 21 | 23 | ||
| 22 | \section*{MFEM SUPG miniapp} | 24 | \section{Introduction} |
| 23 | My project proposal for the FEM term project is a SUPG miniapp implemented | ||
| 24 | with MFEM. This is an independent project related to my graduate research | ||
| 25 | (which has focused on shock processing). | ||
| 26 | 25 | ||
| 27 | \subsection*{Advection-diffusion equation} | 26 | The advection-diffusion equation, also known as the |
| 28 | The complete strong form of the advection-diffusion equation is given: | 27 | convection-diffusion equation, is a PDE that combines advection and diffusion |
| 28 | to describe fluid flow: | ||
| 29 | 29 | ||
| 30 | \begin{gather} | 30 | \begin{gather} \label{eq:pde} |
| 31 | \frac{\delta\phi}{\delta t} + \nabla\cdot\pmb F(\phi) = s \\ | 31 | \frac{\delta\phi}{\delta t} + \nabla\cdot\pmb F(\phi) = s \\ |
| 32 | \pmb F(\phi) = \pmb F^\text{adv} + \pmb F^\text{diff} = | 32 | \pmb F(\phi) = \pmb F^\text{adv}(\phi) + \pmb F^\text{diff}(\phi) = |
| 33 | \pmb a\phi + (-\kappa\nabla\phi) | 33 | \pmb a\phi + (-\kappa\nabla\phi) |
| 34 | \end{gather} | 34 | \end{gather} |
| 35 | 35 | ||
| 36 | Where \(\phi\) is the solution variable (i.e. pressure or temperature), | 36 | The solution variable \(\phi\) may be a number of quantities such as pressure, |
| 37 | \(\pmb a\) is the advection velocity vector, \(\kappa\) is diffusivity, and | 37 | temperature, or species concentration. \(\pmb a\) is the advection velocity, |
| 38 | \(s\) is the source term. I make the following simplifying assumptions: | 38 | \(\kappa\) is diffusivity, and \(s\) is the source term. In this project, a |
| 39 | simplified form of the equation is solved with the following assumptions: | ||
| 39 | 40 | ||
| 40 | \begin{itemize} | 41 | \begin{itemize} |
| 41 | \item No time dependent term. | 42 | \item No time dependent term. |
| 42 | \item Constant \(\pmb a\) and \(\kappa\). | 43 | \item Constant \(\pmb a\) and \(\kappa\) (w.r.t. \(\phi\)). |
| 43 | \item No source term; \(s=0\). | 44 | \item No source term, i.e. \(s=0\). |
| 44 | \item Only Dirichlet boundary conditions. | 45 | \item Only Dirichlet boundary conditions. |
| 45 | \item Linear finite elements. | 46 | \item Linear finite elements. |
| 46 | \end{itemize} | 47 | \end{itemize} |
| 47 | 48 | ||
| 48 | Then the simplified strong form residual follows: | 49 | The resulting strong form residual is: |
| 49 | 50 | ||
| 50 | \begin{equation} | 51 | \begin{equation} \label{eq:strong} |
| 51 | R(\phi) = \nabla\cdot\left(\pmb a\phi - \kappa\nabla\phi\right) = 0 | 52 | R(\phi) = \nabla\cdot\left(\pmb a\phi - \kappa\nabla\phi\right) = 0 |
| 52 | \end{equation} | 53 | \end{equation} |
| 53 | 54 | ||
| 54 | Using index notation: | 55 | The strong form residual \eqref{eq:strong} is expressed in index notation as |
| 55 | 56 | ||
| 56 | \begin{equation} | 57 | \begin{equation} \label{eq:strong-idx} |
| 57 | R(\phi) = a_i \phi,_i - \left(\kappa\phi,_i\right),_i | 58 | R(\phi) = a_i \phi,_i - \left(\kappa\phi,_i\right),_i |
| 58 | \end{equation} | 59 | \end{equation} |
| 59 | 60 | ||
| 60 | Apply the method of weighted residuals and integration by parts to obtain the | 61 | The solution can be obtained analytically for the 1D case using separation of |
| 61 | weak form: | 62 | variables: |
| 62 | 63 | ||
| 63 | \begin{equation} | 64 | \begin{equation} |
| 64 | \int_\Omega -w,_i a_i \phi + w,_i \kappa \phi,_i d\Omega = 0 | 65 | \phi = \frac{\kappa}{a}e^{\frac{a}{k}x + c_1} + c_2 |
| 66 | \end{equation} | ||
| 67 | |||
| 68 | Where \(c_1\) and \(c_2\) are solved based on the boundary conditions | ||
| 69 | \((x_L,\phi_L)\) and \((x_R,\phi_R)\): | ||
| 70 | |||
| 71 | \begin{equation} | ||
| 72 | c_1 = \ln\left( | ||
| 73 | \frac{a}{\kappa} \cdot | ||
| 74 | \frac{\phi_R - \phi_L}{e^{\frac{a}{\kappa}x_R} - e^{\frac{a}{\kappa}x_L}} | ||
| 75 | \right) | ||
| 76 | \quad | ||
| 77 | c_2 = \phi_L - \frac{\phi_R - \phi_L}{ | ||
| 78 | e^{\frac{a}{\kappa}x_R} - e^{\frac{a}{\kappa}x_L} | ||
| 79 | } | ||
| 65 | \end{equation} | 80 | \end{equation} |
| 66 | 81 | ||
| 67 | \subsection*{Stabilization} | 82 | An analytical solution is shown in Figure \ref{fig:analytic}. |
| 83 | |||
| 84 | \begin{figure} | ||
| 85 | \centering | ||
| 86 | \includegraphics[width=0.45\linewidth]{analytic-k1.png} | ||
| 87 | \caption{ | ||
| 88 | Analytic solution with \(a_x = 1\), \(\kappa = 0.1\), and boundary | ||
| 89 | conditions \(\phi(0) = 0.2; \phi(1.6) = 1.4\) | ||
| 90 | } | ||
| 91 | \label{fig:analytic} | ||
| 92 | \end{figure} | ||
| 93 | |||
| 94 | The finite element method is typically used to solve cases in higher dimensions | ||
| 95 | with general domains. The weak form is obtained from \eqref{eq:strong} by | ||
| 96 | applying the method of weighted residuals and integration by parts: | ||
| 97 | |||
| 98 | \begin{equation} | ||
| 99 | \int_\Omega -w,_i a_i \phi + w,_i \kappa \phi,_i d\Omega = 0 | ||
| 100 | \end{equation} | ||
| 68 | 101 | ||
| 69 | Using the standard Galerkin approach in advection dominated cases results in an | 102 | Then linear finite elements can be used. However, using the standard Galerkin |
| 70 | ill-conditioned matrix. See Figure \ref{fig:fem-unstable} for an example of an | 103 | approach in advection dominated cases results in an ill-conditioned matrix and |
| 71 | unstable advection-dominated solution. | 104 | numerical instability. See Figure \ref{fig:fem-unstable} for a comparison |
| 105 | of a stable FEM solution and an unstable advection-dominated FEM solution. | ||
| 72 | 106 | ||
| 73 | \begin{figure} | 107 | \begin{figure} |
| 74 | \centering | 108 | \centering |
| 75 | \includegraphics[width=0.45\textwidth]{line-sol-k1e0.png} | 109 | \includegraphics[width=0.45\textwidth]{lecsoln-k1.png} |
| 76 | \includegraphics[width=0.45\textwidth]{line-sol-k1e-3.png} | 110 | \includegraphics[width=0.45\textwidth]{lecsoln-k2.png} |
| 77 | \caption{Stable solution (kappa=1) and unstable solution (kappa=1e-3)} | 111 | \caption{ |
| 112 | Stable solution (kappa=0.1) and unstable solution (kappa=0.01) from a | ||
| 113 | reference FEM implementation with exact solution shown | ||
| 114 | } | ||
| 78 | \label{fig:fem-unstable} | 115 | \label{fig:fem-unstable} |
| 79 | \end{figure} | 116 | \end{figure} |
| 80 | 117 | ||
| 81 | One approach to remedy this instability is to introduce a stabilization term | 118 | One approach to remedy this instability is to introduce a stabilization term |
| 82 | (artifical numerical diffusion). A simple formulation is called Streamlined- | 119 | (artificial numerical diffusion). A simple formulation is called Streamlined- |
| 83 | Upwind Petrov-Galerkin (SUPG). Here, an extra term is added to the weak form: | 120 | Upwind Petrov-Galerkin (SUPG). Here, an extra term is added to the weak form: |
| 84 | \(a({\pmb F}^\text{adv}(w), -\tau R(\phi))\). In the linear finite element | 121 | \(a({\pmb F}^\text{adv}(w), -\tau R(\phi))\). In the linear finite element |
| 85 | case, the diffusive term of the strong form residual can be dropped if care is | 122 | case, the diffusive term of the strong form residual can be dropped if care is |
| @@ -96,23 +133,180 @@ form is: | |||
| 96 | The stabilizing term depends on the residual so that it goes to zero when the | 133 | The stabilizing term depends on the residual so that it goes to zero when the |
| 97 | solution is achieved. The parameter \(\tau\) is of special importance, as too | 134 | solution is achieved. The parameter \(\tau\) is of special importance, as too |
| 98 | small or too large \(\tau\) can result in an ineffective method. Shakib and | 135 | small or too large \(\tau\) can result in an ineffective method. Shakib and |
| 99 | Hughes \cite{shakib_1991} identify an optimal value based on the cell Peclet | 136 | Hughes \cite{shakib_1991} identify an optimal value in 1D based on the cell |
| 100 | number. However, this value is computationally inefficient, so an approximation | 137 | P\'{e}clet number. |
| 101 | is also available: | 138 | |
| 139 | \begin{equation} | ||
| 140 | \tau_{skb} = \frac{h}{2|a_x|} \cdot \left(\coth(Pe) - \frac{q}{Pe}\right) | ||
| 141 | \quad | ||
| 142 | Pe = \frac{|a_x|h}{2\kappa} | ||
| 143 | \end{equation} | ||
| 144 | |||
| 145 | However, this value is computationally inefficient, so an approximation | ||
| 146 | is also made available: | ||
| 102 | 147 | ||
| 103 | \begin{equation} | 148 | \begin{equation} |
| 104 | \tau_{skb} = \left[ | 149 | \tau_{skb,alg} = \left[ |
| 105 | \left(\frac{2|a_x|}{h}\right)^2 | 150 | \left(\frac{2|a_x|}{h}\right)^2 |
| 106 | +\left(\frac{4\kappa}{h^2}\right)^2 | 151 | +9\left(\frac{4\kappa}{h^2}\right)^2 |
| 107 | \right]^{-1/2} | 152 | \right]^{-1/2} |
| 108 | \end{equation} | 153 | \end{equation} |
| 109 | 154 | ||
| 110 | \begin{figure} | 155 | An FEM solution with SUPG stabilization is shown in Figure \ref{fig:fem-supg}. |
| 111 | \includegraphics[width=\textwidth]{line-supg-sol-k1e-3.png} | 156 | |
| 157 | \begin{figure}[htp] | ||
| 158 | \centering | ||
| 159 | \includegraphics[width=0.45\textwidth]{lecsoln-k2-supg.png} | ||
| 112 | \caption{SUPG stabilized solution (kappa=1e-3)} | 160 | \caption{SUPG stabilized solution (kappa=1e-3)} |
| 113 | \label{fig:fem-supg} | 161 | \label{fig:fem-supg} |
| 114 | \end{figure} | 162 | \end{figure} |
| 115 | 163 | ||
| 164 | In this project I use MFEM, a C++ framework for finite elements | ||
| 165 | \cite{mfem-web}, to solve the advection-diffusion equation in an | ||
| 166 | advection-dominated case. I compare my results to the exact solution and the | ||
| 167 | reference FEM solution. | ||
| 168 | |||
| 169 | \section{Methods} | ||
| 170 | |||
| 171 | The MFEM library allows specification of the weak form using pre-defined | ||
| 172 | \texttt{Integrator}s. Two such classes are readily available for solving | ||
| 173 | the advection-diffusion equation: \texttt{ConservativeConvectionIntegrator} and | ||
| 174 | \texttt{DiffusionIntegrator}. Implementing the SUPG term requires the addition | ||
| 175 | of a custom integrator, \texttt{SUPGIntegrator}. Additionally, because the SUPG | ||
| 176 | term includes the solution variable, it is implemented by extending | ||
| 177 | \texttt{NonlinearFormIntegrator} instead of \texttt{BilinearFormIntegrator}, | ||
| 178 | which changes the problem setup for the stabilized case. See Listing | ||
| 179 | \ref{inp:ex1} for the code for the nonlinear residual and Listing \ref{inp:ex2} | ||
| 180 | for code for the nonlinear jacobian. | ||
| 181 | |||
| 182 | \lstinputlisting[ | ||
| 183 | basicstyle=\ttfamily\small,tabsize=2,frame=single, | ||
| 184 | caption={Key lines of code for the SUPG nonlinear residual}, | ||
| 185 | label={inp:ex1} | ||
| 186 | ]{paper-excerpt1.cc} | ||
| 187 | |||
| 188 | \lstinputlisting[ | ||
| 189 | basicstyle=\ttfamily\small,tabsize=2,frame=single, | ||
| 190 | caption={Key lines of code for the SUPG nonlinear jacobian}, | ||
| 191 | label={inp:ex2} | ||
| 192 | ]{paper-excerpt2.cc} | ||
| 193 | |||
| 194 | \section{Results} | ||
| 195 | |||
| 196 | The custom \texttt{SUPGIntegrator} provided stabilization and accurate results | ||
| 197 | for advection-dominated cases, except when the left boundary condition was | ||
| 198 | enforced -- note that \ref{tbl:k2} and the right of Figure \ref{fig:mfem-supg} | ||
| 199 | start from \(\phi = 0.0\) whereas the left and \ref{tbl:k0} start from \(\phi = | ||
| 200 | 0.2\). The cause for this is unclear, as the implementation uses physical | ||
| 201 | gradients and includes the inverse jacobian determinant. | ||
| 202 | |||
| 203 | \begin{figure}[htp] | ||
| 204 | \centering | ||
| 205 | \includegraphics[width=0.45\textwidth]{line-sol-k0.png} | ||
| 206 | \includegraphics[width=0.45\textwidth]{line-supg-sol-k2.png} | ||
| 207 | \caption{ | ||
| 208 | MFEM solution for \(a_x=1\), \(\kappa=1\) (left) and \(a_x=1\), | ||
| 209 | \(\kappa=0.01\) (right) | ||
| 210 | } | ||
| 211 | \label{fig:mfem-supg} | ||
| 212 | \end{figure} | ||
| 213 | |||
| 214 | \begin{table} | ||
| 215 | \centering | ||
| 216 | \begin{tabular}{c|c|c} | ||
| 217 | \small | ||
| 218 | Exact solution & Reference FEM solution & MFEM solution \\ | ||
| 219 | \hline | ||
| 220 | 0.2 & 0.2 & 0.2 \\ | ||
| 221 | \hline | ||
| 222 | 0.23192615 & 0.23192615 & 0.2318994842537078 \\ | ||
| 223 | \hline | ||
| 224 | 0.26721 & 0.26721 & 0.2671570027631416 \\ | ||
| 225 | \hline | ||
| 226 | 0.30620469 & 0.30620469 & 0.3061264579767903 \\ | ||
| 227 | \hline | ||
| 228 | 0.34930048 & 0.34930048 & 0.3491981952038976 \\ | ||
| 229 | \hline | ||
| 230 | 0.3969287 & 0.3969287 & 0.3968037571864139 \\ | ||
| 231 | \hline | ||
| 232 | 0.44956602 & 0.44956602 & 0.4494211044369776 \\ | ||
| 233 | \hline | ||
| 234 | 0.50773925 & 0.50773926 & 0.5075777552014797 \\ | ||
| 235 | \hline | ||
| 236 | 0.57203062 & 0.57203063 & 0.5718563242761415 \\ | ||
| 237 | \hline | ||
| 238 | 0.64308357 & 0.64308358 & 0.6429009576212408 \\ | ||
| 239 | \hline | ||
| 240 | 0.72160923 & 0.72160923 & 0.7214237583971538 \\ | ||
| 241 | \hline | ||
| 242 | 0.8083935 & 0.8083935 & 0.8082118551597843 \\ | ||
| 243 | \hline | ||
| 244 | 0.90430495 & 0.90430496 & 0.904135215032668 \\ | ||
| 245 | \hline | ||
| 246 | 1.0103035 & 1.0103035 & 1.010155960623283 \\ | ||
| 247 | \hline | ||
| 248 | 1.12745001 & 1.12745001 & 1.12733665457002 \\ | ||
| 249 | \hline | ||
| 250 | 1.25691693 & 1.25691693 & 1.256851800816963 \\ | ||
| 251 | \hline | ||
| 252 | 1.4 & 1.4 & 1.4 | ||
| 253 | \end{tabular} | ||
| 254 | \caption{Comparison of nodal values for \(a_x=1\), \(\kappa=1\)} | ||
| 255 | \label{tbl:k0} | ||
| 256 | \end{table} | ||
| 257 | |||
| 258 | \begin{table} | ||
| 259 | \centering | ||
| 260 | \begin{tabular}{c|c|c} | ||
| 261 | \small | ||
| 262 | Exact solution & Reference FEM solution & MFEM solution \\ | ||
| 263 | \hline | ||
| 264 | 7.07789169e-85 & 0.00000000e+00 & 0 \\ | ||
| 265 | \hline | ||
| 266 | 1.00446783e-65 & 6.72915553e-24 & 1.344027471478775e-21 \\ | ||
| 267 | \hline | ||
| 268 | 2.21258808e-61 & 2.47544695e-22 & -3.440531560398167e-19 \\ | ||
| 269 | \hline | ||
| 270 | 4.87354958e-57 & 8.86558356e-21 & -5.957125219217317e-19 \\ | ||
| 271 | \hline | ||
| 272 | 1.07347073e-52 & 3.17278380e-19 & 5.144414882568559e-17 \\ | ||
| 273 | \hline | ||
| 274 | 2.36447663e-48 & 1.13544128e-17 & 1.095961397199189e-16 \\ | ||
| 275 | \hline | ||
| 276 | 5.20810637e-44 & 4.06339111e-16 & -5.302401810502381e-15 \\ | ||
| 277 | \hline | ||
| 278 | 1.14716177e-39 & 1.45416125e-14 & 4.901903445752921e-15 \\ | ||
| 279 | \hline | ||
| 280 | 2.52679194e-35 & 5.20399065e-13 & 1.007010439154497e-12 \\ | ||
| 281 | \hline | ||
| 282 | 5.56562963e-31 & 1.86234634e-11 & 1.920121752194572e-11 \\ | ||
| 283 | \hline | ||
| 284 | 1.22591151e-26 & 6.66475808e-10 & 6.356196583077191e-10 \\ | ||
| 285 | \hline | ||
| 286 | 2.70024979e-22 & 2.38510955e-08 & 2.383479327580857e-08 \\ | ||
| 287 | \hline | ||
| 288 | 5.94769596e-18 & 8.53556496e-07 & 8.549283844700147e-07 \\ | ||
| 289 | \hline | ||
| 290 | 1.31006722e-13 & 3.05461312e-05 & 3.054579043392884e-05 \\ | ||
| 291 | \hline | ||
| 292 | 2.88561507e-09 & 1.09315099e-03 & 0.001093115172881016 \\ | ||
| 293 | \hline | ||
| 294 | 6.35599017e-05 & 3.91204728e-02 & 0.03912052192397422 \\ | ||
| 295 | \hline | ||
| 296 | 1.40000000e+00 & 1.40000000e+00 & 1.4 | ||
| 297 | \end{tabular} | ||
| 298 | \caption{Comparison of nodal values for \(a_x=1\), \(\kappa=0.01\)} | ||
| 299 | \label{tbl:k2} | ||
| 300 | \end{table} | ||
| 301 | |||
| 302 | \section{Lessons learned} | ||
| 303 | |||
| 304 | Using MFEM turned out to be the most difficult part of the project. Initially, | ||
| 305 | 2D cases were also planned for, but had to be abandoned due to time | ||
| 306 | constraints. It was unclear that a \texttt{NonlinearFormIntegrator} was | ||
| 307 | required, and since the needs of this project differed from the provided | ||
| 308 | examples, it was somewhat unclear what to do. | ||
| 309 | |||
| 116 | Code is available at \url{https://git.aidenw.net/rpi/mfem-supg}. | 310 | Code is available at \url{https://git.aidenw.net/rpi/mfem-supg}. |
| 117 | 311 | ||
| 118 | \printbibliography | 312 | \printbibliography |
diff --git a/doc/sources.bib b/doc/sources.bib index 84d577c..58efee9 100644 --- a/doc/sources.bib +++ b/doc/sources.bib | |||
| @@ -1,3 +1,35 @@ | |||
| 1 | @article{mfem-2024, | ||
| 2 | title = {High-Performance Finite Elements with {MFEM}}, | ||
| 3 | author = {J. Andrej and N. Atallah and J.-P. Bäcker and J.-S. Camier and | ||
| 4 | D. Copeland and V. Dobrev and Y. Dudouit and T. Duswald and | ||
| 5 | B. Keith and D. Kim and T. Kolev and B. Lazarov and K. Mittal and | ||
| 6 | W. Pazner and S. Petrides and S. Shiraiwa and M. Stowell and V. Tomov}, | ||
| 7 | journal={The International Journal of High Performance Computing Applications}, | ||
| 8 | volume={38}, | ||
| 9 | number={5}, | ||
| 10 | pages={447-467}, | ||
| 11 | year={2024}, | ||
| 12 | publisher={SAGE Publications Sage UK: London, England} | ||
| 13 | } | ||
| 14 | |||
| 15 | @article{mfem-2021, | ||
| 16 | title = {{MFEM}: A Modular Finite Element Methods Library}, | ||
| 17 | author = {R. Anderson and J. Andrej and A. Barker and J. Bramwell and J.-S. Camier and | ||
| 18 | J. Cerveny and V. Dobrev and Y. Dudouit and A. Fisher and Tz. Kolev and W. Pazner and | ||
| 19 | M. Stowell and V. Tomov and I. Akkerman and J. Dahm and D. Medina and S. Zampini}, | ||
| 20 | journal = {Computers \& Mathematics with Applications}, | ||
| 21 | doi = {10.1016/j.camwa.2020.06.009}, | ||
| 22 | volume = {81}, | ||
| 23 | pages = {42-74}, | ||
| 24 | year = {2021} | ||
| 25 | } | ||
| 26 | |||
| 27 | @misc{mfem-web, | ||
| 28 | key = {mfem}, | ||
| 29 | title = {{MFEM}: Modular Finite Element Methods {[Software]}}, | ||
| 30 | howpublished = {\url{mfem.org}}, | ||
| 31 | doi = {10.11578/dc.20171025.1248} | ||
| 32 | } | ||
| 1 | 33 | ||
| 2 | @article{shakib_1991, | 34 | @article{shakib_1991, |
| 3 | title = {A new finite element formulation for computational fluid dynamics: X. The compressible Euler and Navier-Stokes equations}, | 35 | title = {A new finite element formulation for computational fluid dynamics: X. The compressible Euler and Navier-Stokes equations}, |
