<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>http://www.openpipeflow.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Apwillis</id>
	<title>openpipeflow.org - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="http://www.openpipeflow.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Apwillis"/>
	<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Special:Contributions/Apwillis"/>
	<updated>2026-10-09T03:52:00Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1129</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1129"/>
		<updated>2026-10-05T09:48:11Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extensions for extra fields and geometries.  All work in a very similar way, they inherit much of the same code, with similar optional parallelisation.&lt;br /&gt;
&lt;br /&gt;
- [[Download - Heated pipe|Heated pipe - Download]]&lt;br /&gt;
&lt;br /&gt;
- Leeds Spherical Dynamo (LDS) code https://github.com/Leeds-Spherical-Dynamo/leeds-code&lt;br /&gt;
&lt;br /&gt;
- Taylor-Couette flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Plane-Couette and Plane-Poiseuille flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Rayleigh-Benard convection.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Periodic box.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Jacobian-free Newton-Krylov code (non problem-specific) https://github.com/apwillis1/JFNK-Hookstep&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1128</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1128"/>
		<updated>2026-07-13T20:57:38Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
Please download [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|this paper]] on the model, and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
The boundary condition for the temperature may be either fixed temperature or fixed heat-flux.&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Use of the Heated pipe codes is essentially the same as the &#039;standard&#039; (isothermal) code.  If you&#039;ve not used the standard code before, see [[Getting_started]], then try the [[Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]  Download [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF HERE]]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1127</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1127"/>
		<updated>2026-07-13T20:56:39Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
Please download [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|this paper]] on the model, and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
The boundary condition for the temperature may be either fixed temperature or fixed heat-flux.&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Use of the Heated pipe codes is essentially the same as the &#039;standard&#039; (isothermal) code.  If you&#039;ve not used the standard code before, see [[Getting_started]], then try the [[Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]   [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1126</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1126"/>
		<updated>2026-07-13T20:56:07Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
Please download [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|this paper]] on the model, and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
The boundary condition for the temperature may be either fixed temperature or fixed heat-flux.&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Use of the Heated pipe codes is essentially the same as the &#039;standard&#039; (isothermal) code.  If you&#039;ve not used the standard code before, see [[Getting_started]], then try the [[Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]   [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1125</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1125"/>
		<updated>2026-07-13T19:51:27Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
Please download this paper on the model [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]], and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
Either the fixed temperature or fixed heat-flux boundary condition may be chosen.&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Use of the Heated pipe codes is essentially the same as the &#039;standard&#039; (isothermal) code.  If you&#039;ve not used the standard code before, see [[Getting_started]], then try the [[Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]   [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1124</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1124"/>
		<updated>2026-01-27T13:16:07Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Use of the Heated pipe codes is essentially the same as the &#039;standard&#039; (isothermal) code.  If you&#039;ve not used the standard code before, see [[Getting_started]], then try the [[Tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
Please download the [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]], and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1123</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1123"/>
		<updated>2026-01-27T11:13:50Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Notes on the Heated pipe version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;standard&#039; (isothermal) pipe code.  It will assume that there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow profile.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
Please download the [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]], and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1122</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1122"/>
		<updated>2026-01-27T11:11:15Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Paper on Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
Please download the [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]], and NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1121</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1121"/>
		<updated>2026-01-27T10:19:41Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Paper on Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
Please download the [[Media:ChuMarensiWillis25Mathematics_CORR.pdf|PDF here]].  Please NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1120</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1120"/>
		<updated>2026-01-27T10:17:36Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Notes on the Heated pipe version */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature profile, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
[[Media:ChuMarensiWillis25Mathematics_CORR.pdf|Link to PDF here]].  Please NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1119</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1119"/>
		<updated>2026-01-27T10:15:32Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Paper on Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
[[Media:ChuMarensiWillis25Mathematics_CORR.pdf|Link to PDF here]].  Please NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
Both fixed temperature and fixed heat-flux models are described.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1118</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1118"/>
		<updated>2026-01-27T10:14:06Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Paper on Model ==&lt;br /&gt;
&lt;br /&gt;
[[Media:ChuMarensiWillis25Mathematics_CORR.pdf|Link to PDF here]].  Please NOTE that this PDF includes a small but important correction at Figure 3.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=File:ChuMarensiWillis25Mathematics_CORR.pdf&amp;diff=1117</id>
		<title>File:ChuMarensiWillis25Mathematics CORR.pdf</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=File:ChuMarensiWillis25Mathematics_CORR.pdf&amp;diff=1117"/>
		<updated>2026-01-27T10:09:21Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: Paper on heated pipe, including both fixed temperature and fixed heat-flux models.
Note correction at Figure 3.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Paper on heated pipe, including both fixed temperature and fixed heat-flux models.&lt;br /&gt;
Note correction at Figure 3.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download&amp;diff=1116</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download&amp;diff=1116"/>
		<updated>2026-01-27T10:00:13Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please download the Current version of openpipeflow below.  See here for [[Related Codes]] (Couette, channel, heated pipe, etc.)&lt;br /&gt;
&lt;br /&gt;
== Virtual machine option ==&lt;br /&gt;
&lt;br /&gt;
If you just want a quick try, or if you are not running a linux environment, then you could try  [http://www.virtualbox.org virtualbox] and the [[Xubuntu-Openpipeflow_virtual_disk_image]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.22&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.22.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Some additions to utils/&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2023/03  Option to calculate pressure in prim2matlab.f90, courtesy of Jie Yao.&lt;br /&gt;
** 2023/04  Two versions of util: prim2ascii_coll.f90, prim2ascii_phys.f90.&lt;br /&gt;
** 2023/06  Generic functions related to slicing, predrag_slice_mod.f90.&lt;br /&gt;
&lt;br /&gt;
== Older versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please download the latest version above!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Added transforms direct between phys-coll types, so don&#039;t need to handle intermediate spec type.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/10/11 See tra_coll2phys(...), tra_phys2coll(...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.20&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.20.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Slight update to axis treatment. Symmetry property used in all calculations of derivatives.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/08/08 Symmetry parameter now used in var_meshmult(...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.12&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.12.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** LES and nonnewtonian (shear-thinning) utils added.&lt;br /&gt;
** Radial points may be loaded from mesh.in, see mes_precompute().&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/05/08 No changes to core code except mesh.in option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.11c&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.11c.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Newton-Krylov utility added, see - utils/newton.f90.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2016/12/13 No changes to core code.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.11b&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.11b.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Minor update to significant revision-1.10 (Double parallelisation).  Please see comments for version 1.10.  &lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2015/11/26 Check for radial split _Np&amp;gt;i_N corrected to _Nr&amp;gt;i_N.&lt;br /&gt;
** 2015/08/05 Fixed bug preventing serial use in parallel macros.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.10&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.10.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;:&lt;br /&gt;
** Double parallelisation: in physical space data is split into _Nr sections radially and (new option) _Ns sections axially.  Total number of cores used is _Np=_Nr*_Ns.&lt;br /&gt;
** It is recommended that for a modest number of cores, vary _Nr and keep _Ns=1 (split radially only).&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** Double parallelisation.&lt;br /&gt;
** Minor updates to var_null, var_imposesymm functions.&lt;br /&gt;
** Interpolation correction for prim2matlab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.02b&#039;&#039;&#039;:&lt;br /&gt;
* Tarball [[File:Openpipeflow-1.02b.tgz]]&lt;br /&gt;
* Manual  [[File:Openpipeflow-1.02b-doc.pdf]].  The [[Manual|Online Manual]] is now more comprehensive.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=File:Arnoldi.f&amp;diff=1115</id>
		<title>File:Arnoldi.f</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=File:Arnoldi.f&amp;diff=1115"/>
		<updated>2025-11-20T12:07:45Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
&lt;br /&gt;
== The Arnoldi Method ==&lt;br /&gt;
&lt;br /&gt;
The Arnoldi method is a method for calculating the eigenvalues and eigenvectors of a matrix, i.e. for calculating the scalar $\sigma$ and $n$-vectors $\vec{x}$ that satisfy&lt;br /&gt;
$&lt;br /&gt;
\sigma\,\vec{x} = A\,\vec{x}&lt;br /&gt;
$&lt;br /&gt;
for a given $n\times n$ matrix $A$.&lt;br /&gt;
&lt;br /&gt;
The main advantage of the method is that it only requires calculations of multiplies by $A$ for a given $\vec{x}$ -- it does not need to know $A$ itself.  This means that $A$ need not even be stored, and could correspond to a very complex linear &#039;action&#039; on $\vec{x}$, e.g. a time integral with initial condition $\vec{x}$.  Given a starting vector $\vec{x}_0$, the method seeks eigenvectors $\vec{x}$ in $\mathrm{span}\{\vec{x}_0,\,A\vec{x}_0,\,A^2\vec{x}_0,...\}$, but uses Gram-Schmidt orthogonalisation to improve the numerical suitability of this basis set.  The set of orthogonalised vectors is called the Krylov-subspace.  In practice we need to limit the size of this space to m vectors, but if this number is reached, it is possible to restart without losing information. Restarts are not implemented here; see the following which can dramatically reduce the number of multiplies by $A$ required.&lt;br /&gt;
&lt;br /&gt;
===Time Integration and Exponentiation===&lt;br /&gt;
&lt;br /&gt;
The method finds the eigenvalues most separated in the complex plane first.  If $A$ is expected to have many negative eigenvalues of little interest, it may be better to work with $\tilde{A}=\mathrm{e}^A=1+A+\frac{1}{2!}A^2+...$, i.e. the eigenproblem $\mathrm{e}^\sigma\vec{x}=\mathrm{e}^A\vec{x}$.  This problem&lt;br /&gt;
shares the same eigenvectors as the original problem, but its eigenvalues, $\tilde{\sigma}=\mathrm{e}^\sigma$, are often better suited to the Arnoldi method.  The negative eigenvalues $\sigma$, which typically correspond to modes of little interest, now correspond to eigenvalues $\tilde{\sigma}$ bunched close to the origin.  The Arnoldi method favours the $\tilde{\sigma}$ most separated in the complex plane, being the $\sigma$ with largest real parts.&lt;br /&gt;
&lt;br /&gt;
Note that for the system $\partial_t \vec{x} = A\,\vec{x}$, time integration corresponds to exponentiation: &lt;br /&gt;
First, for eigenvector $\vec{x}_0$ with eigenvalue $\sigma$ we may write $\sigma\, \vec{x}_0 = A\,\vec{x}_0$.  &lt;br /&gt;
Also, taking $\vec{x}_0$ as an intial condition, after a time $T$ it will have grown or decayed to &lt;br /&gt;
$\vec{x}_T=\mathrm{e}^{\sigma T}\vec{x}_0 =\vec{x}_0 + \int_0^T A\,\vec{x}\,dt$.  We may write this as&lt;br /&gt;
$\mathrm{e}^{\sigma T}\vec{x}_0 \equiv B\,\vec{x}_0$, where $B$ is the time integration operator.&lt;br /&gt;
Then $\vec{x}_0$ is an eigenvector of both $A$ and $B$, where its eigenvalue for $B$ is $\tilde{\sigma}=\mathrm{e}^{\sigma T}$.&lt;br /&gt;
We apply the Arnoldi method to $B$, then recover $\sigma$ from $\tilde{\sigma}$.&lt;br /&gt;
&lt;br /&gt;
Now let&#039;s consider the case of a perturbation $\vec{\delta x}$ linearised about a solution $\vec{x}_0$.  Evolution of the perturbation is given by $\partial_t \vec{\delta x} = A(\vec{x}_0)\,\vec{\delta x}$.  Let $\vec{X}(\vec{x})$ be the result of time integration of $\vec{x}$. For this system, the result of $B\,\vec{\delta x}$ for a given $\vec{\delta x}$ may be approximated by $\frac{1}{\epsilon}(\vec{X}(\vec{x}_0+\epsilon\,\vec{\delta x})-\vec{X}(\vec{x}_0))$ for some small value $\epsilon$.  (Although we expect that $\vec{X}(\vec{x}_0)=\vec{x}_0$ for a solution $\vec{x}_0$, numerical accuracy is likely to be better with the given form.)  Note that to find the eigenvalues $\tilde{\sigma}=\mathrm{e}^{\sigma T}$ of $B$ with the Arnoldi method, only a routine for time integration of a given initial condition is required.&lt;br /&gt;
&lt;br /&gt;
== How to use the code ==&lt;br /&gt;
&lt;br /&gt;
To download, click the link above.  The Lapack package is also required.&lt;br /&gt;
&lt;br /&gt;
The subroutine &amp;lt;tt&amp;gt;arnold(...)&amp;lt;/tt&amp;gt; needs to be passed a subroutine that calculates the dot product of two eigenvectors.  It should look like, for example,&lt;br /&gt;
 double precision function dotprod(n,a,b)&lt;br /&gt;
    implicit none&lt;br /&gt;
    integer :: n&lt;br /&gt;
    double precision :: a(n), b(n)&lt;br /&gt;
    dotprod = sum(a*b)&lt;br /&gt;
 end function dotprod&lt;br /&gt;
&amp;lt;tt&amp;gt;arnold(...)&amp;lt;/tt&amp;gt; needs to be called repeatedly.  It communicates the status of the computation via the flag &amp;lt;tt&amp;gt;ifail&amp;lt;/tt&amp;gt;, which tells the user how many eigenvalues are converged up to a given tolerance, to multiply a vector by $A$ again, or tells the user if the method has failed, e.g. reached maximum number of vector that can be stored.&lt;br /&gt;
&lt;br /&gt;
An example of use of the code:&lt;br /&gt;
   ! declare workspace vectors, h, q, b... - see header of arnoldi.f&lt;br /&gt;
   sv = ... ! random initial vector x&lt;br /&gt;
   k = 0    ! initialise iteration counter&lt;br /&gt;
   do while(.true.)&lt;br /&gt;
      call arnold(n,k,kmax,ncgd,dotprod,tol,sv,h,q,b,wr,wi,ifail)&lt;br /&gt;
      if(ifail==-1) then&lt;br /&gt;
         print*, &#039; arnoldi converged!&#039;&lt;br /&gt;
         exit&lt;br /&gt;
      else if(ifail==0) then&lt;br /&gt;
         call multA(sv, sv)      ! possibly complicated routine that multiplies sv by A&lt;br /&gt;
      else if(ifail==1) then&lt;br /&gt;
         print*, &#039;WARNING: arnoldi reached max its&#039;&lt;br /&gt;
         exit&lt;br /&gt;
      else if(ifail&amp;gt;=2) then&lt;br /&gt;
         print*, &#039;WARNING: arnoldi error:&#039;, ifail&lt;br /&gt;
         exit&lt;br /&gt;
      end if   &lt;br /&gt;
   end do&lt;br /&gt;
On exit, the eigenvectors are stored in columns of &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;, in order corresponding to eigenvalues in &amp;lt;tt&amp;gt;wr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;wi&amp;lt;/tt&amp;gt;.  If the first eigenvalue is real (&amp;lt;tt&amp;gt;wi(1)==0.&amp;lt;/tt&amp;gt;), the eigenvector occupies the first column of &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; only.  If the next eigenvalue is complex, the real and imaginary parts will occupy the next two columns of &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Parallel use ==&lt;br /&gt;
&lt;br /&gt;
No special adaptations are required for parallel (MPI) use -- let each thread pass its subsection for the vector &amp;lt;tt&amp;gt;sv&amp;lt;/tt&amp;gt;, and let the &amp;lt;tt&amp;gt;dotprod&amp;lt;/tt&amp;gt; function &amp;lt;tt&amp;gt;allreduce&amp;lt;/tt&amp;gt; the result of the dot product.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=File:Openpipeflow-hp-1.21.tgz&amp;diff=1114</id>
		<title>File:Openpipeflow-hp-1.21.tgz</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=File:Openpipeflow-hp-1.21.tgz&amp;diff=1114"/>
		<updated>2025-11-11T14:02:53Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: Apwillis uploaded a new version of File:Openpipeflow-hp-1.21.tgz&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
First distrib version of Heated pipe code.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1113</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1113"/>
		<updated>2025-11-11T14:00:46Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** Manual|Manual&lt;br /&gt;
** Download|Download code&lt;br /&gt;
** Related Codes|Related codes&lt;br /&gt;
** Tutorial|Tutorial&lt;br /&gt;
** FAQ|FAQ&lt;br /&gt;
** Utilities|Utilities&lt;br /&gt;
** Database|Database&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** helppage|help&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1112</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1112"/>
		<updated>2025-08-28T13:31:38Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** Manual|Manual&lt;br /&gt;
** Download|Download code&lt;br /&gt;
** Related_codes|Related codes&lt;br /&gt;
** Tutorial|Tutorial&lt;br /&gt;
** FAQ|FAQ&lt;br /&gt;
** Utilities|Utilities&lt;br /&gt;
** Database|Database&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** helppage|help&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1111</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=MediaWiki:Sidebar&amp;diff=1111"/>
		<updated>2025-08-28T13:29:30Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** Manual|Manual&lt;br /&gt;
** Download|Download&lt;br /&gt;
** Tutorial|Tutorial&lt;br /&gt;
** FAQ|FAQ&lt;br /&gt;
** Utilities|Utilities&lt;br /&gt;
** Database|Database&lt;br /&gt;
** Related_codes|Related codes&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** helppage|help&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1110</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1110"/>
		<updated>2025-07-03T12:05:25Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extensions for extra fields and geometries.  All work in a very similar way, they inherit much of the same code, with similar optional parallelisation.&lt;br /&gt;
&lt;br /&gt;
- [[Download - Heated pipe|Heated pipe - Download]]&lt;br /&gt;
&lt;br /&gt;
- Taylor-Couette flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Plane-Couette and Plane-Poiseuille flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Rayleigh-Benard convection.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Periodic box.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Jacobian-free Newton-Krylov code (non problem-specific) https://github.com/apwillis1/JFNK-Hookstep&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Core_implementation&amp;diff=1109</id>
		<title>Core implementation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Core_implementation&amp;diff=1109"/>
		<updated>2025-06-12T08:32:52Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* How the parallelisation works */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
&lt;br /&gt;
= Spatial representation =&lt;br /&gt;
&lt;br /&gt;
== Finite difference stencil — $r$ ==&lt;br /&gt;
&lt;br /&gt;
A function $p(r)$ is represented by the values $p_n=p(r_n)$, where $p(r)$ is evaluated on the $N$ radial points $r_n$; $n=1..N$.&lt;br /&gt;
There is no point on the axis $r=0$ to avoid singularities in $1/r$ terms.&lt;br /&gt;
The points are located at the roots of a Tchebyshev polynomial, such that they are clustered near the wall, and slightly so near the axis to compensate for loss of order in the calculation of derivatives. (They are calculated using banded matrices, implying use of fewer points at the axis and boundary).&lt;br /&gt;
&lt;br /&gt;
=== Differentiation ===&lt;br /&gt;
&lt;br /&gt;
Consider Taylor expansions about central point $x_0$, with $k$ neighbouring points each side&lt;br /&gt;
&lt;br /&gt;
[[File:fd_deriv.png|500px]]&lt;br /&gt;
&lt;br /&gt;
These expansions can be written&lt;br /&gt;
&lt;br /&gt;
[[File:fd_deriv_vec.png||500px]]&lt;br /&gt;
&lt;br /&gt;
Derivatives are calculated using weights from the appropriate row of $A^{-1}$.&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
Integrating the expansions above, from $x_0$ to $x$, the indefinite integral may be approximated about $x_0$:&lt;br /&gt;
&lt;br /&gt;
[[File:fd_int.png|500px]]&lt;br /&gt;
&lt;br /&gt;
The total integral is approximated by&lt;br /&gt;
&lt;br /&gt;
$   \frac1{2} \sum_n \int_{x_{n-1}}^{x_{n+1}} f(x) \, {\mathrm d}x$&lt;br /&gt;
&lt;br /&gt;
=== Matrix representation of linear operators ===&lt;br /&gt;
&lt;br /&gt;
Linear equations can be written in the matrix form&lt;br /&gt;
&lt;br /&gt;
$\mat{L} \,\vec{p} = \mat{M}\, \vec{q} + \vec{s}.$&lt;br /&gt;
&lt;br /&gt;
$\mat{L}$ and $\mat{M}$ are $N\times N$ matrices representing linear operators. If $\vec{q}$ and $\vec{s}$ are known then the right-hand side is simple to evaluate. Consider the equation&lt;br /&gt;
&lt;br /&gt;
$\label{eq:matmod}&lt;br /&gt;
\mat{L}\, \vec{p} = \vec{q},$&lt;br /&gt;
&lt;br /&gt;
where $\vec{p}$ is unknown. If the matrix operators are formed by linear combinations of the weights in [[#Differentiation]], using only $k$ neighbouring points to each side, they are banded. Boundary conditions are formed in the same way and are placed in the end rows. The equation is solved by forward-backward substitution, using the banded LU-factorisation of $\mat{L}$.&lt;br /&gt;
&lt;br /&gt;
figure=LU.eps, scale=0.65&lt;br /&gt;
&lt;br /&gt;
== Fourier representaion — $\theta$, $z$ ==&lt;br /&gt;
&lt;br /&gt;
=== Expansion of variables ===&lt;br /&gt;
&lt;br /&gt;
$A(\theta,z) =&lt;br /&gt;
\sum_{|k|&amp;lt;K}\sum_{|m|&amp;lt;M}\, A_{km} {\mathrm e}^{{\mathrm i} (\alpha kz + m_0 m\theta)}$&lt;br /&gt;
&lt;br /&gt;
$A$ real implies $A_{km} = A_{-k,-m}^*$ (coefficients are conjugate-symmetric). It is sufficient to keep only $m\ge 0$, and for $m=0$ keep $k\ge 0$.&lt;br /&gt;
&lt;br /&gt;
=== Implied conditions on the axis ===&lt;br /&gt;
&lt;br /&gt;
The geometry enforces conditions on each variable at the axis when expanded over Fourier modes in $\theta$. For scalars and the $z$-component of a vector $A_z$, each mode is even in $r$ if $m$ is even, and is odd if $m$ is odd. Each mode for $A_r$ and $A_\theta$ is even in $r$ if $m$ is odd, and is odd if $m$ is even.  This implies that either the function or its derivative is zero on the axis.&lt;br /&gt;
&lt;br /&gt;
=== Orthogonality ===&lt;br /&gt;
&lt;br /&gt;
Exponentials&lt;br /&gt;
&lt;br /&gt;
$\int_0^{2\pi} {\mathrm e}^{{\mathrm i}(m+n)} \, {\mathrm d}\theta &lt;br /&gt;
= 2\pi \, \delta_{m,-n}\, ,&lt;br /&gt;
\qquad&lt;br /&gt;
\int_0^{\frac{2\pi}{\alpha}} {\mathrm e}^{{\mathrm i}\alpha(k+j)} \, {\mathrm d}z &lt;br /&gt;
= \frac{2\pi}{\alpha} \, \delta_{k,-j}$&lt;br /&gt;
&lt;br /&gt;
=== Volume integral ===&lt;br /&gt;
&lt;br /&gt;
$E \, = \, &lt;br /&gt;
\int A \, {\mathrm d}V &lt;br /&gt;
\, = \,&lt;br /&gt;
\frac{4\pi^2}{\alpha} \, \int A_{00} \, r\,{\mathrm d}r$&lt;br /&gt;
&lt;br /&gt;
=== Energy integral ===&lt;br /&gt;
&lt;br /&gt;
$E \, = \, &lt;br /&gt;
{\textstyle \frac1{2}} \int \vec{A} \cdot \vec{A} \, {\mathrm d}V &lt;br /&gt;
\, = \,&lt;br /&gt;
\frac{2\pi^2}{\alpha} \, \sum_{km}&lt;br /&gt;
\int |\vec{A}_{km}|^2 \, r\,{\mathrm d}r$&lt;br /&gt;
&lt;br /&gt;
$E = \sum_{m\ge 0} E_m,&lt;br /&gt;
\qquad&lt;br /&gt;
E_m =&lt;br /&gt;
\left\{&lt;br /&gt;
\begin{array}{ll}&lt;br /&gt;
\displaystyle&lt;br /&gt;
\frac{2\pi^2}{\alpha}\int\vec{A}_{00}^2 \, r \, {\mathrm d}r&lt;br /&gt;
+ \frac{4\pi^2}{\alpha} \sum_{k&amp;gt;0}&lt;br /&gt;
\int|\vec{A}_{k0}^2| \, r \, {\mathrm d}r,&lt;br /&gt;
&amp;amp; m=0, \\[15pt]&lt;br /&gt;
\displaystyle&lt;br /&gt;
\frac{4\pi^2}{\alpha} \sum_k &lt;br /&gt;
\int |\vec{A}_{km}|^2 \, r \, {\mathrm d}r,&lt;br /&gt;
&amp;amp; m&amp;gt;0 .&lt;br /&gt;
\end{array}&lt;br /&gt;
\right.$&lt;br /&gt;
&lt;br /&gt;
= Temporal discretisation =&lt;br /&gt;
&lt;br /&gt;
Temporal discritisation is via a second-order Predictor-Corrector scheme, with Euler predictor for the nonlinear terms and Crank-Nicolson corrector.  The linear viscous term is treated implicitly with the Crank-Nicolson term.&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
An influence-matrix technique is used to avoid issues in satisfying the boundary conditions.  See [[The_PPE_formulation]].&lt;br /&gt;
&lt;br /&gt;
== Predictor-corrector ==&lt;br /&gt;
&lt;br /&gt;
The model equation for each Fourier mode is&lt;br /&gt;
&lt;br /&gt;
$\label{eq:harmmod}&lt;br /&gt;
(\partial_{t} - \nabla^2) f = N,$&lt;br /&gt;
&lt;br /&gt;
where nonlinear terms have been evaluated on each radial point by the transform method, and is solved as in [[#Matrix_representation_of_linear_operators]]. The predictor at time $t_q$, with Euler nonlinear terms and implicitness $c$&lt;br /&gt;
&lt;br /&gt;
$\frac{f_1^{q+1}-f^q}{\Delta t}&lt;br /&gt;
- \left( c\nabla^2 f_1^{q+1} + (1-c)\nabla^2 f^q \right)&lt;br /&gt;
= N^q ,$&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_1^{q+1}&lt;br /&gt;
= \left( \frac1{\Delta t} + (1-c)\nabla^2 \right) f^q + N^q .$&lt;br /&gt;
&lt;br /&gt;
Corrector iterations are&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_{j+1}^{q+1}&lt;br /&gt;
= \left( \frac1{\Delta t} + (1-c)\nabla^2 \right) f^q&lt;br /&gt;
+ c\,N_j^{q+1} + (1-c)\, N^q ,$&lt;br /&gt;
&lt;br /&gt;
or equivalently, for the correction $f_{corr} = f_{j+1}^{q+1} - f_j^{q+1}$&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_{corr}&lt;br /&gt;
= c\,N_j^{q+1} - c\, N_{j-1}^{q+1} ,$&lt;br /&gt;
&lt;br /&gt;
where $j=1,2,\dots$ and $N_0^{q+1}=N^q$. The size of the correction $\|f_{corr}\|$ must reduce at each iteration. For $c=\frac1{2}$ the scheme is second order such that $\|f_{corr}\| \sim \Delta t^2$.  Stability is improved without observable degradation in accuracy using $c=0.501$ .&lt;br /&gt;
&lt;br /&gt;
== Timestep control ==&lt;br /&gt;
&lt;br /&gt;
$\Delta t = \mathrm{C} \, \min(\Delta \, / \, |\vec{v}| ) ,&lt;br /&gt;
\qquad &lt;br /&gt;
0&amp;lt;\mathrm{C}&amp;lt;1,$&lt;br /&gt;
&lt;br /&gt;
where $\mathrm{C}$ is the Courant number.&lt;br /&gt;
&lt;br /&gt;
The timestep should also be small enough such that the corrector norm $\|f_{corr}\|$ is satisfactorily small. This may be important for integrating initial transients, but ought not to be the limiting factor in general.&lt;br /&gt;
&lt;br /&gt;
= The code structure =&lt;br /&gt;
&lt;br /&gt;
[[File:modules4.png]]&lt;br /&gt;
&lt;br /&gt;
== Overview of program files ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;parameters.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; declaration and values of parameters.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;&#039;&#039;&#039; macros for parallelisation; definition of loops for parallel+serial cases &amp;lt;tt&amp;gt;_loop_km_begin&amp;lt;/tt&amp;gt; etc.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;mpi.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; mpi initialisation.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;main.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; core initialisation, main timestepping loop, clean up at end.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; definition of radial discretisation.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;variables.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; definition of derived types for spectral- and physical-space data.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;transform.fftw3.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; transform from collocated spectral space to physical space.  Uses fftw3 library.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;timestep.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; subroutines to set up time stepping matrices.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;velocity.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; functions related to the velocity field; implementation of the timestepping and influence matrix method.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;io.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; Input-Output: loading and saving of data.&lt;br /&gt;
&lt;br /&gt;
Each of the files contains a &#039;&amp;lt;tt&amp;gt;module&amp;lt;/tt&amp;gt;&#039;, declaring variables that may be used in other code via &#039;&amp;lt;tt&amp;gt;use modulename&amp;lt;/tt&amp;gt;&#039;.  With the exception of the fundamental parameters, the first three letters of the module name are used as a prefix in the name of public variables, to make the location of their declaration clear (see following section).&lt;br /&gt;
&lt;br /&gt;
== Naming conventions ==&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
&lt;br /&gt;
Parameters defined within &amp;lt;tt&amp;gt;parameters.f90&amp;lt;/tt&amp;gt; are given a prefix indicating the data type. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$N$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_N&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;integer&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$\Delta t$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_timestep&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;double&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;fixed flux?&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;b_fixed_flux&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;boolean&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the naming convention frees the variable name for dummy variables, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   integer :: n&lt;br /&gt;
   do n = 1, i_N&lt;br /&gt;
      ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Public variables ===&lt;br /&gt;
&lt;br /&gt;
By default variables declared within a module are accessible to any other module or subroutine that uses the module. To ensure that it is clear where a public variable is declared, variables are given a prefix. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$\Delta t$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;tim_dt&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;timestep.f90&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$u_r$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;vel_r&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;velocity.f90&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ordering the Fourier modes ==&lt;br /&gt;
&lt;br /&gt;
$A = \sum_{|k|&amp;lt;K}\sum_{|m|&amp;lt;M}\, A_{km} {\mathrm e}^{{\mathrm i}(\alpha kz + m_0 m\theta)},$&lt;br /&gt;
&lt;br /&gt;
Coefficients $A_{km}$ are stored in an order according to the following loop, where&lt;br /&gt;
rather than two indices &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;m&amp;lt;/tt&amp;gt;, the single index &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt; labels the modes:&lt;br /&gt;
&lt;br /&gt;
[[File:km_loop_c.png|400px]]&lt;br /&gt;
&lt;br /&gt;
The index nh is as in the following table for the case K=6, M=4:&lt;br /&gt;
&lt;br /&gt;
[[File:Fourier_km.png|404px]]&lt;br /&gt;
&lt;br /&gt;
NOTES:&lt;br /&gt;
* &amp;lt;tt&amp;gt;nh = (2*K-1)*m + k&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Loops for &amp;lt;tt&amp;gt;m&amp;lt;0&amp;lt;/tt&amp;gt; are skipped.  Values of coefficients for &amp;lt;tt&amp;gt;m&amp;lt;0&amp;lt;/tt&amp;gt; are inferred from the conjugate symmetric property, $A_{km}=A_{-k,-m}^*$.  Similarly for &amp;lt;tt&amp;gt;k&amp;lt;0&amp;lt;/tt&amp;gt; when &amp;lt;tt&amp;gt;m==0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* This loop is a predefined macro in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;.  The macro &amp;lt;tt&amp;gt;_loop_km_begin&amp;lt;/tt&amp;gt; replaces the double-loop above (or its equivalent for parallel computation).&lt;br /&gt;
&lt;br /&gt;
== Data types ==&lt;br /&gt;
&lt;br /&gt;
The data types below consist of logical data groups to facilitate the passing of data between functions. For clarity, in the following text they are defined as though we were working on a single processor. See [[#Modifications_for_the_parallel_implementation|Parallel]] regarding subtle differences in the definitions due to parallelisation.&lt;br /&gt;
&lt;br /&gt;
The most important data types are &amp;lt;tt&amp;gt;type (coll) &amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt; type (phys)&amp;lt;/tt&amp;gt;.  The transform between the two types is achieved with calls to &amp;lt;tt&amp;gt;tra_coll2phys(...)&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tra_phys2coll(...)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== coll, spec — storage of coefficients ===&lt;br /&gt;
&lt;br /&gt;
The collocated data &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; is the principle type used for mode-independent operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type coll&lt;br /&gt;
      double precision     :: Re(i_N, 0:i_H1)&lt;br /&gt;
      double precision     :: Im(i_N, 0:i_H1)&lt;br /&gt;
   end type coll&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;Re(n,nh)&amp;lt;/tt&amp;gt; is the real part of the &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt;$^{\mathrm{th}}$ harmonic evaluated at $r_n$. &lt;br /&gt;
&lt;br /&gt;
The spectral &amp;lt;tt&amp;gt;type (spec)&amp;lt;/tt&amp;gt; is a data type for operations independent at each radial point. It is rarely used other than as a transitory data format between the &amp;lt;tt&amp;gt;coll&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;phys&amp;lt;/tt&amp;gt; types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type spec&lt;br /&gt;
      double precision     :: Re(0:i_H1, i_N)&lt;br /&gt;
      double precision     :: Im(0:i_H1, i_N)&lt;br /&gt;
   end type spec&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== phys — real space data ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; is used for data in real space.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type phys&lt;br /&gt;
      double precision     :: Re(0:i_Z-1, 0:i_Th-1, i_N)&lt;br /&gt;
   end type phys&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;Re(k,m,n)&amp;lt;/tt&amp;gt; refers to the value at $z_k$, $\theta_m$ and $r_n$.&lt;br /&gt;
&lt;br /&gt;
=== rdom — the radial domain ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;type (rdom)&amp;lt;/tt&amp;gt; contains information about the radial domain. The public variable &amp;lt;tt&amp;gt;mes_D&amp;lt;/tt&amp;gt; is declared in &amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;. Data includes the number of radial points &amp;lt;tt&amp;gt;mes_D%N&amp;lt;/tt&amp;gt;, powers of $r$, $r_n^p$=&amp;lt;tt&amp;gt;mes_D%r(n,p)&amp;lt;/tt&amp;gt;, weights for integration &lt;br /&gt;
$\int_0^1 f(r)\,r\,{\mathrm d}r$=&amp;lt;tt&amp;gt;dot_product(f(1:i_N),mes_D%intrdr)&amp;lt;/tt&amp;gt;, matrices for taking the $p^{\mathrm{th}}$ derivative and more:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type rdom&lt;br /&gt;
      integer          :: N&lt;br /&gt;
      double precision :: r(i_N,i_rpowmin:i_rpowmax)&lt;br /&gt;
      double precision :: intrdr(i_N)&lt;br /&gt;
      type (mesh)      :: dr(i_KL)&lt;br /&gt;
      ...&lt;br /&gt;
   end type rdom&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mesh, lumesh — storage of banded matrices ===&lt;br /&gt;
&lt;br /&gt;
The finite-difference stencil has finite width ([[#Finite_differences_.E2.80.94_.24r.24|Finite_Differences]]) and so matrix operations involve matrices that are banded. The &amp;lt;tt&amp;gt;type (mesh)&amp;lt;/tt&amp;gt;, defined in &amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;, is used for matrices on the radial mesh involving $kl$ points to either side of each node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type mesh&lt;br /&gt;
      double precision :: M(2*i_KL+1, i_N)&lt;br /&gt;
   end type mesh&amp;lt;/pre&amp;gt;&lt;br /&gt;
For a matrix &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, the element &amp;lt;tt&amp;gt;M(KL+1+n-j, j) = A(n,j)&amp;lt;/tt&amp;gt;. See the man page for the lapack routine &amp;lt;tt&amp;gt;dgbtrf&amp;lt;/tt&amp;gt;. The LU-factorisation of a banded matrix is also banded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type lumesh&lt;br /&gt;
      integer          :: ipiv(i_N)&lt;br /&gt;
      double precision :: M(3*i_KL+1, i_N)&lt;br /&gt;
   end type lumesh&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;M(2*KL+1+n-j, j) = A(n,j)&amp;lt;/tt&amp;gt;. Pivoting information is stored along with the matrix.&lt;br /&gt;
&lt;br /&gt;
== Modifications for the parallel implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Practical things to remember ===&lt;br /&gt;
&lt;br /&gt;
The code has been parallelised using the Message Passing Interface (MPI) in a way designed to be as unintrusive as possible. Sections of the code with special MPI function calls are separated from the serial sections by preprocessor directives. The number of processors is given by the parameter &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt; set in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;. The rank of a process is given by &amp;lt;tt&amp;gt;mpi_rnk&amp;lt;/tt&amp;gt; declared in &amp;lt;tt&amp;gt;mpi.f90&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;mpi_sze&amp;lt;/tt&amp;gt;$=$&amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For modest parallelisations, it is recommended to vary &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and to keep &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt; (radial split only).  This ensures a couple of conditions are met that could easily be forgotten when setting up a run, namely that &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; must divide both &amp;lt;tt&amp;gt;i_Z&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;i_M&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How the data is distributed ===&lt;br /&gt;
&lt;br /&gt;
The linear parts of the code (evaluating curls, gradients and matrix inversions for the timestepping) involve operations that do not couple Fourier modes.  The &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; holds all radial points for a subset of Fourier modes - the Fourier modes are distributed over the cores.&lt;br /&gt;
&lt;br /&gt;
Products are evaluated in physical space.  Here the data is split over &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; sections in $r$ and over &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; sections in $z$.  The &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; holds all azimuthal points for a &lt;br /&gt;
given subsection in $r$ and $z$.  The following is an example of rank id numbers (&amp;lt;tt&amp;gt;mpi_rnk&amp;lt;/tt&amp;gt;) for the case &amp;lt;tt&amp;gt;_Nr=3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_Ns=4&amp;lt;/tt&amp;gt; ($r$ downwards, $z$ left to right):&lt;br /&gt;
  0   3   6   9&lt;br /&gt;
  1   4   7  10&lt;br /&gt;
  2   5   8  11&lt;br /&gt;
In physical space,&lt;br /&gt;
* Two cores have data for the same $z$-section if &amp;lt;tt&amp;gt;rank1/_Nr==rank2/_Nr&amp;lt;/tt&amp;gt; (integer arithmetic).&lt;br /&gt;
* Two cores have data for the same $r$-section if &amp;lt;tt&amp;gt;modulo(rank1,_Nr)==modulo(rank2,_Nr)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How the code is adapted ===&lt;br /&gt;
&lt;br /&gt;
In the definition of &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; the parameter &amp;lt;tt&amp;gt;i_H1&amp;lt;/tt&amp;gt; is replaced by &amp;lt;tt&amp;gt;i_pH1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
In the definition of &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; the parameters &amp;lt;tt&amp;gt;i_N,i_Z&amp;lt;/tt&amp;gt; are replaced by &amp;lt;tt&amp;gt;i_pN,i_pZ&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;i_pH1&amp;lt;/tt&amp;gt; is the maximum number of modes on an individual core.  The variable &amp;lt;tt&amp;gt;var_H&amp;lt;/tt&amp;gt; has elements to determine which harmonics are on which processor. The elements &amp;lt;tt&amp;gt;pH0&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pH1&amp;lt;/tt&amp;gt; are the zeroth index and the number of harmonics for the local process, minus one. The corresponding values for all processors are stored in the arrays &amp;lt;tt&amp;gt;pH0_(rank)&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pH1_(rank)&amp;lt;/tt&amp;gt;. For a variable of &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt;, valid values for the harmonic index in &amp;lt;tt&amp;gt;Re(n,nh)&amp;lt;/tt&amp;gt; are &amp;lt;tt&amp;gt;nh=0..pH1&amp;lt;/tt&amp;gt; but refer to the indices  &amp;lt;tt&amp;gt;nh=pH0..pH0+pH1&amp;lt;/tt&amp;gt; of the serial case, see [[#Ordering_the_Fourier_modes]].&lt;br /&gt;
&lt;br /&gt;
In physical space &amp;lt;tt&amp;gt;i_pN&amp;lt;/tt&amp;gt; is the maximum number of radial points for each process. The location of the radial subdomain on the local processor is given by additional elements of the variable &amp;lt;tt&amp;gt;mes_D&amp;lt;/tt&amp;gt;. The elements &amp;lt;tt&amp;gt;pNi&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pN&amp;lt;/tt&amp;gt; are the location of the first (inner) radial point and the number of points. The values for all processors are stored in the arrays &amp;lt;tt&amp;gt;pNi_(rank)&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pN_(rank)&amp;lt;/tt&amp;gt;. For a variable of &amp;lt;tt&amp;gt;type (spec)&amp;lt;/tt&amp;gt;, valid values for the radial index in &amp;lt;tt&amp;gt;Re(nh,n)&amp;lt;/tt&amp;gt; are &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1..pN&amp;lt;/tt&amp;gt; which refer to the indices of $r_n$, where $n$=&amp;lt;tt&amp;gt;pNi..pNi+pN-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Also in physical space &amp;lt;tt&amp;gt;i_pZ&amp;lt;/tt&amp;gt; is exactly the number axial points held by the core.  Logically, the local index &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;[0,i_pZ-1]&amp;lt;/tt&amp;gt;corresponds to index &amp;lt;tt&amp;gt;(mpi_rnk/_Ns)*i_pZ + k&amp;lt;/tt&amp;gt; (integer arithmetic) in &amp;lt;tt&amp;gt;[0,i_Z-1]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The bulk of communication occurs during the data transposes in the functions &amp;lt;tt&amp;gt;var_coll2spec()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;var_spec2coll()&amp;lt;/tt&amp;gt;. For the case &amp;lt;tt&amp;gt;_Np=_Nr, _Ns=1&amp;lt;/tt&amp;gt; the data is transferred in &amp;lt;tt&amp;gt;_Np-1&amp;lt;/tt&amp;gt; steps.  At each step each processor sends and receives a block of data, the source and destination are selected systematically as set in the following loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   do step = 1, mpi_sze-1&lt;br /&gt;
      dest  = modulo(mpi_rnk+step, mpi_sze)&lt;br /&gt;
      src   = modulo(mpi_rnk-step+mpi_sze, mpi_sze) &lt;br /&gt;
      ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How the parallelisation works ===&lt;br /&gt;
&lt;br /&gt;
In the Fourier space, all radial points for a particular Fourier mode are located on the same processor, separate modes may be located on separate processes.  For the case &amp;lt;tt&amp;gt;K=6, M=4, _Nr=3, _Ns=2,&amp;lt;/tt&amp;gt; the modes are split over &amp;lt;tt&amp;gt;_Np=_Nr*_Ns=6&amp;lt;/tt&amp;gt; cores (&amp;lt;tt&amp;gt;mpi_rnk=0..5&amp;lt;/tt&amp;gt;) indicated by the 6 coloured sections (each contiguous in &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt;) in the following table:&lt;br /&gt;
&lt;br /&gt;
[[File:Fourier_km_par.png|404px]]&lt;br /&gt;
&lt;br /&gt;
Here, the m=0,1,2,3 are split into &amp;lt;tt&amp;gt;_Ns=2&amp;lt;/tt&amp;gt; groups, m=0,1 and m=2,3, then each group is split into &amp;lt;tt&amp;gt;_Nr=3&amp;lt;/tt&amp;gt; sections indicated by the colours.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;tt&amp;gt;_Ns=2&amp;lt;/tt&amp;gt;, split the 6 cores into two sets of three, denoted&lt;br /&gt;
$\{c_0,c_1,c_2\}$ and $\{c_3,c_4,c_5\}$.  &lt;br /&gt;
Prior to an FFT, the core $c_0$ gathers all Fourier coefficients from within the first set for a given &lt;br /&gt;
subset of radial points -- doing this for each core constitutes a transpose with in the set.&lt;br /&gt;
Having gathered these coefficients, sufficient data is present to perform the axial FFTs &lt;br /&gt;
(summing over the k for a given m).  &lt;br /&gt;
Now three sets of cores may be identified, arranged to have data for common &lt;br /&gt;
radial points in each set, $\{c_0,c_3\}$, $\{c_1,c_4\}$, $\{c_2,c_5\}$.&lt;br /&gt;
Within each set m is distributed, with&lt;br /&gt;
m=0,1 on one core m=2,3 on the other.  Gathering the m for a&lt;br /&gt;
given subsection of axial points constitutes a second transpose within each of these&lt;br /&gt;
sets.  Finally the azimuthal FFTs may be performed (sum over m).&lt;br /&gt;
The resulting data is split by both radial and axial position, whilst data for all azimuthal points are present on a given core.&lt;br /&gt;
&lt;br /&gt;
In the double parallelisation two transposes are required, and the total data sent is &lt;br /&gt;
doubled.  However, the number of messages required is&lt;br /&gt;
&amp;lt;tt&amp;gt;(_Ns-1)+(_Nr-1)&amp;lt;/tt&amp;gt; where &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Then, for a given $N_p=$&amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt;, there are only approximately $\sqrt{N_p}$ messages when &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; are approximately equal, versus $N_p$ messages when &amp;lt;tt&amp;gt;_Np=_Nr&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
This can substantially reduce time lost in latency, the time setting up communications.  &lt;br /&gt;
There are fewer large messages, rather than many small ones.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1108</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1108"/>
		<updated>2025-04-23T08:45:31Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extensions for extra fields and geometries.  All work in a very similar, inherit much of the same code, with similar parallelisation.&lt;br /&gt;
&lt;br /&gt;
- [[Download - Heated pipe|Heated pipe - Download]]&lt;br /&gt;
&lt;br /&gt;
- Taylor-Couette flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Plane-Couette and Plane-Poiseuille flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Rayleigh-Benard convection.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Periodic box.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Jacobian-free Newton-Krylov code (non problem-specific) https://github.com/apwillis1/JFNK-Hookstep&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1107</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1107"/>
		<updated>2025-04-23T08:44:23Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extensions for extra fields and geometries.  All work in a very similar, inherit much of the same code, with similar parallelisation.&lt;br /&gt;
&lt;br /&gt;
- [[Heated pipe - Download]]&lt;br /&gt;
&lt;br /&gt;
- Taylor-Couette flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Plane-Couette and Plane-Poiseuille flow.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Rayleigh-Benard convection.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Periodic box.  Please contact me.&lt;br /&gt;
&lt;br /&gt;
- Jacobian-free Newton-Krylov code (non problem-specific) https://github.com/apwillis1/JFNK-Hookstep&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1106</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1106"/>
		<updated>2025-03-24T10:06:38Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* PPE-formulation with correct boundary conditions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with corrected boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$. &lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;&#039;Note&#039;&#039;&#039; that more complicated boundary conditions (e.g. partial slip) are easily accommodated, by simply redefining $\vec{g}(\vec{u})$.  It may be desirable to change the boundary condition on $\bar{\vec{u}}$ to $\bar{\vec{u}}=\vec{u}^q$, so that it will be closer to the final value for $\vec{u}^{q+1}$.)&lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1105</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1105"/>
		<updated>2025-03-20T15:18:36Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$. &lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;&#039;Note&#039;&#039;&#039; that more complicated boundary conditions (e.g. partial slip) are easily accommodated, by simply redefining $\vec{g}(\vec{u})$.  It may be desirable to change the boundary condition on $\bar{\vec{u}}$ to $\bar{\vec{u}}=\vec{u}^q$, so that it will be closer to the final value for $\vec{u}^{q+1}$.)&lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1104</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1104"/>
		<updated>2025-03-20T15:15:47Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$. &lt;br /&gt;
&lt;br /&gt;
(Note that more complicated boundary conditions (e.g. partial slip) are easily accommodated, by simply redefining $\vec{g}(\vec{u})$.  It may be desirable to change the boundary condition on $\bar{\vec{u}}$ to $\bar{\vec{u}}=\vec{u}^q$, so that it will be closer to the final value for $\vec{u}^{q+1}$.)&lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1103</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1103"/>
		<updated>2025-03-20T14:23:30Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$. &lt;br /&gt;
&lt;br /&gt;
(Note that, with this approach, more complicated boundary conditions (e.g. partial slip) are easily accommodated, by simply redefining $\vec{g}(\vec{u})$.  It may be desirable to change the boundary condition on $\bar{\vec{u}}$ to $\bar{\vec{u}}=\vec{u}^q$, so that it will be closer to the final value for $\vec{u}^{q+1}$.)&lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1102</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1102"/>
		<updated>2025-03-20T14:21:53Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* PPE-formulation with correct boundary conditions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$. &lt;br /&gt;
&lt;br /&gt;
(Note that, with this approach, more complicated boundary conditions (e.g. partial slip) are easily accommodated, by simply redefining $\vec{g}(\vec{u})$.  Optionally, one may change the boundary condition on $\bar{\vec{u}}$ to $\bar{\vec{u}}=\vec{u}^q$, so that it will be closer to the final value for $\vec{u}^{q+1}$.)&lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1101</id>
		<title>The PPE formulation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=The_PPE_formulation&amp;diff=1101"/>
		<updated>2025-03-20T11:31:06Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
The incompressibility condition may be &#039;replaced&#039; by specifying an equation for the pressure - the Pressure-Poisson Equation (PPE).  Taking the divergence of the Navier--Stokes equation leads to the system&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSeqs}&lt;br /&gt;
(1) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\partial_t \vec{u} &amp;amp; = &amp;amp; L \,\vec{u} + \vec{N} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot\vec{N} ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $L$ is a linear operator and $\vec{N}$ represents nonlinear terms.  The no-slip boundary conditions are $\vec{u}=\vec{0}$,&lt;br /&gt;
and we retain that $\bnabla\cdot\vec{u}=0$ must be satisfied everywhere, i.e. also on the boundary.  There is no boundary condition explicitly on the pressure.&lt;br /&gt;
(See [[Equations_and_parameters#Boundary_conditions|Boundary_conditions]].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
Consider the case where the spatial discretisation splits the Navier--Stokes equations into a set one-dimensional problems, here into problems for radially-dependent Fourier modes.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}$ denote the velocity, $\vec{N}$ denote nonlinear terms, and $\mat{X}$ and $\mat{Y}$ be matrices associated with implicit timestepping of the viscous terms for a particular Fourier mode.&lt;br /&gt;
The time-discretised Navier–Stokes equations for this mode may be written in the form&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSdisc}&lt;br /&gt;
(2) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}^{q+1} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla p \, , \\&lt;br /&gt;
\nabla^2 p &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
where $q$ denotes time $t_q$, which is sixth order in $r$ for $\vec{u}^{q+1}$ and second order for $p$, where the solenoidal condition is not explicitly imposed. Symmetry provides the conditions at the axis. The difficulty is in imposing the remaining four boundary conditions — this system should be inverted, in principle, simultaneously for $p$ and $\vec{u}^{q+1}$ with boundary conditions $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$ (Rempfer 2006). In practice it would be preferable to invert for $p$ first then for $\vec{u}^{q+1}$, but the boundary conditions to not involve $p$ directly.&lt;br /&gt;
&lt;br /&gt;
Note that the $\mat{Y}\,\vec{u}^q$ term has been included in the right-hand side of the pressure-Poisson equation, the divergence of which should be small. Assume that pressure boundary condition is known: the right-hand side of the Navier–Stokes equation is then projected onto the space of solenoidal functions though $p$ and hence after inversion, $\vec{u}^{q+1}$ will be solenoidal.&lt;br /&gt;
&lt;br /&gt;
Consider the ‘bulk’ solution, $\{\bar{\vec{u}},\bar{p}\}$, obtained from solution of the following:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSbulk}&lt;br /&gt;
(3) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \bar{\vec{u}} &amp;amp; = &amp;amp; \mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}} - \bnabla \bar{p} \, , \\&lt;br /&gt;
\nabla^2 \bar{p} &amp;amp; = &amp;amp; \bnabla\cdot(\mat{Y}\, \vec{u}^q &lt;br /&gt;
+ \vec{N}^{q+\frac{1}{2}}) ,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\bar{\vec{u}}=\vec{0}$ and $\partial_{r}\bar{p}=0$. Introduce the following systems:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSp0}&lt;br /&gt;
(4) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\,\vec{u}&#039; &amp;amp; = &amp;amp; -\bnabla p&#039; \, , \\&lt;br /&gt;
\nabla^2 p&#039; &amp;amp; = &amp;amp; 0,&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $\vec{u}&#039;=\vec{0}$ and $\partial_{r}p&#039;=1$ on $r=R$, and&lt;br /&gt;
&lt;br /&gt;
$\label{eq:NSu0}&lt;br /&gt;
(5) \qquad&lt;br /&gt;
\left\{\begin{array}{rcl}&lt;br /&gt;
\mat{X}\, \vec{u}&#039; &amp;amp; = &amp;amp; \vec{0},&lt;br /&gt;
\end{array}\right.$&lt;br /&gt;
&lt;br /&gt;
with boundary conditions $u&#039;_+=1$, $u&#039;_-=1$, $u&#039;_z=\mathrm{i}$ on $r=R$ (see [[Equations_and_parameters#Decoupling_the_equations|Decoupling_the_equations]]). The system $(4)$ provides a linearly independent function $\vec{u}&#039;_4$ that may be added to $\bar{\vec{u}}$ without affecting the right-hand side in $(3)$, but altering (to correct) the boundary condition applied. &lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
($\mat{X}$ has been dropped on the left-hand side of $(4)$ since $\mat{X}$ represents a combination of the identity and the Laplace operator, but $\bnabla^2(\bnabla p&#039;)=\bnabla(\nabla^2 p&#039;)-\bnabla \wedge\bnabla \wedge\bnabla p&#039;=0$, i.e., only the identity is left behind.)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Similarly the system $(5)$ provides a further three functions $\vec{u}&#039;_j$ for $j=1,2,3$, where each has only one non-zero component, $u_+$, $u_-$ or $u_z$.  The superposition&lt;br /&gt;
&lt;br /&gt;
$\label{eq:usuperpos}&lt;br /&gt;
(6) \qquad&lt;br /&gt;
\vec{u}^{q+1} = \bar{\vec{u}} + \sum_{j=1}^4 a_j\, \vec{u}&#039;_j \,$&lt;br /&gt;
&lt;br /&gt;
may be formed in order to satisfy the four boundary conditions, $\vec{u}^{q+1}=\vec{0}$ and $\bnabla\cdot\vec{u}^{q+1}=0$ on $r=R$.  Let $\vec{g}(\vec{u})$ be a 4-vector composed of these boundary conditions, such that they are satisfied when $\vec{g}(\vec{u})=\vec{0}$.  Substituting the superposition $(6)$ into the boundary conditions, they may be written &lt;br /&gt;
&lt;br /&gt;
$\label{eq:velBCs}&lt;br /&gt;
(7) \qquad&lt;br /&gt;
\mat{A}\,\vec{a} = -\vec{g}(\bar{\vec{u}}) ,$&lt;br /&gt;
&lt;br /&gt;
where $\mat{A}=\mat{A}(\vec{g}(\vec{u}&#039;))$ is a 4$\times$4 matrix and the 4-vector $\vec{a}$ is composed of the $a_j$.  Thus, the appropriate coefficients required to satisfy the boundary conditions are recovered from solution of this small system for $\vec{a}$.  &lt;br /&gt;
&lt;br /&gt;
The error in the boundary conditions $g_j(\vec{u}^{q+1})$ using the influence-matrix technique is at the level of the machine epsilon, typically order 1e-16.&lt;br /&gt;
The functions $u&#039;_j(r)$, the matrix $\mat{A}$ and its inverse may all be precomputed. The boundary conditions for $\vec{u}&#039;$ have been chosen so that that $u&#039;_\pm$ are pure real, $u&#039;_z$ is pure imaginary, and $\mat{A}$ is real. For each timestep, this application of the influence matrix technique requires only evaluation of the deviation from the boundary condition, multiplication by a 4$\times$4 real matrix, and the addition of only two functions to each component of $\vec{u}$, each either pure real or pure imaginary. Compared to the evaluation of nonlinear terms, the computational overhead is negligible.&lt;br /&gt;
&lt;br /&gt;
If needed, the pressure may be calculated &lt;br /&gt;
using the same $a_1$ as in $(6)$ using the $p&#039;$ from $(4)$:&lt;br /&gt;
&lt;br /&gt;
$\label{eq:pressure}   &lt;br /&gt;
(8a) \qquad&lt;br /&gt;
\tilde{p} = \bar{p} + a_1\, p&#039; \, \qquad$ (for each Fourier mode, then)&lt;br /&gt;
&lt;br /&gt;
$&lt;br /&gt;
(8b) \qquad p = \tilde{p} - \frac{1}{2}\vec{u}\cdot\vec{u}\, \qquad$ (in physical space).&lt;br /&gt;
&lt;br /&gt;
The adjustment in $(8b)$ arises when the Navier-Stokes equations are in rotational form (see [[Equations_and_parameters]]).&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1100</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1100"/>
		<updated>2025-02-07T11:03:45Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Citation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|details;bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1099</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1099"/>
		<updated>2025-02-07T10:57:07Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Citation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ev:youtube|http://youtu.be/hSj0VnmSQro|280|right|Slow streaks (blue) and vortex structures (yellow)}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[File:6551noshiftloop.mp4|280|right|Slow streaks (blue) and vortex structures (yellow)]]&lt;br /&gt;
[[File:OpenPFlogo1.png|thumb|right|Slow streaks (blue) and vortex structures (yellow)]] &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Quicklinks ====&lt;br /&gt;
[[Download]] | [[Manual]] | [[Tutorial]] | [[Database]] | [[Related Codes]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&#039;&#039;&#039;openpipeflow.org is a free resource for researchers, engineers, educators and the interested public.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pipe flow is a simple and familiar set up, yet the flow patterns exhibit [[Fun_stuff|rich chaotic dynamics]].  This provides a setting for investigating the principles of simulation at one level, and at another, for developing new methods designed to probe fundamental properties of dynamical systems.  &lt;br /&gt;
&lt;br /&gt;
The majority of mathematical techniques described on these pages are applicable to a huge range of problems, and [[Manual|subroutines for well-known methods]] are designed to be callable from any code.  The core [[Manual|pipe flow code]] is designed to be flexible yet very fast.  See here for [[Related Codes]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aims&#039;&#039;&#039;&lt;br /&gt;
* To make accessible a range of modelling techniques.&lt;br /&gt;
* To facilitate rapid entry into the world of numerical simulation and fluid dynamics.&lt;br /&gt;
* To provide flexible modules for more the use and development of advanced techniques in research.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code features&#039;&#039;&#039; &lt;br /&gt;
* Primitive-variable pipe-flow code for incompressible flow.&lt;br /&gt;
* Simple scripts for visualisation with Matlab/Octave/Visit.&lt;br /&gt;
* Readable Fortran 90, uses modules and derived types, no esoteric extensions.&lt;br /&gt;
* Core program &amp;lt;3000 lines.&lt;br /&gt;
* Spatial discretisation: double-Fourier (theta,z) + finite difference (r).&lt;br /&gt;
* PPE formulation; influence matrix corrects boundary conditions to machine precision.&lt;br /&gt;
* Second-order predictor-corrector method, automatic timestep control.&lt;br /&gt;
* May be run on a single core or in parallel (with MPI).  Essentially linear scaling with number of cores.&lt;br /&gt;
* &#039;2-dimensional&#039; parallelisation, radial+axial split.&lt;br /&gt;
* Jacobian-Free Newton-Krylov (JFNK) solver.  Now at https://github.com/apwillis1/JFNK-Hookstep .&lt;br /&gt;
Details for the above can be found in the [[Manual]].&lt;br /&gt;
This article, [[File:TheOpenpipeflowSolver.pdf]], provides an overview of the code and its context.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
The [[Database]] provides sample parameters and initial conditions from which to launch new simulations.  In general, simulations start most reliably from an initial state computed for similar parameters.  A range of starting points are provided.  &lt;br /&gt;
&lt;br /&gt;
==Features to appear/wishlist==&lt;br /&gt;
* Module for the immersed boundary method (IBM).&lt;br /&gt;
* More FAQ + documentation.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* tutorial, inc. matlab example.&lt;br /&gt;
* Utilities for Krylov methods -- Newton-Krylov, Arnoldi.&lt;br /&gt;
* phys-statefiles for direct upload to matlab/visit etc.&lt;br /&gt;
&lt;br /&gt;
==Related codes==&lt;br /&gt;
Closely related codes are currently obtained by request.&lt;br /&gt;
* Taylor--Couette flow.&lt;br /&gt;
* Flow in a periodic box.&lt;br /&gt;
* Pipeflow, potential formulation.&lt;br /&gt;
&lt;br /&gt;
==Problem-independent codes==&lt;br /&gt;
To be uploaded&lt;br /&gt;
* GMRES&lt;br /&gt;
* Newton-Hookstep&lt;br /&gt;
* Arnoldi&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Citation==&lt;br /&gt;
Please cite this article: [[File:TheOpenpipeflowSolver.pdf]] ;  [[:File:TheOpenpipeflowSolver.pdf|bibtex]]&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
:       [http://maths.dept.shef.ac.uk/maths/staff_info_402.html Ashley P. Willis],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths School of Mathematics and Statistics (SoMaS)],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths University of Sheffield, U.K.]&lt;br /&gt;
:       a.p.willis/at/sheffield.ac.uk&lt;br /&gt;
&lt;br /&gt;
==Thanks==&lt;br /&gt;
* John Gibson ([http://channelflow.org/gibson channelflow.org])&lt;br /&gt;
* Predrag Cvitanović ([http://www.cns.gatech.edu/~predrag/ GaTech] [http://chaosbook.org chaosbook.org])&lt;br /&gt;
* Rich Kerswell ([http://www.damtp.cam.ac.uk/user/rrk26/ Cambridge])&lt;br /&gt;
* many other people!&lt;br /&gt;
* EPSRC GR/S76144/01, EP/K03636X/1&lt;br /&gt;
* The [http://www.sheffield.ac.uk/maths University of Sheffield].&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1098</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1098"/>
		<updated>2025-02-07T10:50:56Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Citation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ev:youtube|http://youtu.be/hSj0VnmSQro|280|right|Slow streaks (blue) and vortex structures (yellow)}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[File:6551noshiftloop.mp4|280|right|Slow streaks (blue) and vortex structures (yellow)]]&lt;br /&gt;
[[File:OpenPFlogo1.png|thumb|right|Slow streaks (blue) and vortex structures (yellow)]] &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Quicklinks ====&lt;br /&gt;
[[Download]] | [[Manual]] | [[Tutorial]] | [[Database]] | [[Related Codes]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&#039;&#039;&#039;openpipeflow.org is a free resource for researchers, engineers, educators and the interested public.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pipe flow is a simple and familiar set up, yet the flow patterns exhibit [[Fun_stuff|rich chaotic dynamics]].  This provides a setting for investigating the principles of simulation at one level, and at another, for developing new methods designed to probe fundamental properties of dynamical systems.  &lt;br /&gt;
&lt;br /&gt;
The majority of mathematical techniques described on these pages are applicable to a huge range of problems, and [[Manual|subroutines for well-known methods]] are designed to be callable from any code.  The core [[Manual|pipe flow code]] is designed to be flexible yet very fast.  See here for [[Related Codes]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aims&#039;&#039;&#039;&lt;br /&gt;
* To make accessible a range of modelling techniques.&lt;br /&gt;
* To facilitate rapid entry into the world of numerical simulation and fluid dynamics.&lt;br /&gt;
* To provide flexible modules for more the use and development of advanced techniques in research.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code features&#039;&#039;&#039; &lt;br /&gt;
* Primitive-variable pipe-flow code for incompressible flow.&lt;br /&gt;
* Simple scripts for visualisation with Matlab/Octave/Visit.&lt;br /&gt;
* Readable Fortran 90, uses modules and derived types, no esoteric extensions.&lt;br /&gt;
* Core program &amp;lt;3000 lines.&lt;br /&gt;
* Spatial discretisation: double-Fourier (theta,z) + finite difference (r).&lt;br /&gt;
* PPE formulation; influence matrix corrects boundary conditions to machine precision.&lt;br /&gt;
* Second-order predictor-corrector method, automatic timestep control.&lt;br /&gt;
* May be run on a single core or in parallel (with MPI).  Essentially linear scaling with number of cores.&lt;br /&gt;
* &#039;2-dimensional&#039; parallelisation, radial+axial split.&lt;br /&gt;
* Jacobian-Free Newton-Krylov (JFNK) solver.  Now at https://github.com/apwillis1/JFNK-Hookstep .&lt;br /&gt;
Details for the above can be found in the [[Manual]].&lt;br /&gt;
This article, [[File:TheOpenpipeflowSolver.pdf]], provides an overview of the code and its context.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
The [[Database]] provides sample parameters and initial conditions from which to launch new simulations.  In general, simulations start most reliably from an initial state computed for similar parameters.  A range of starting points are provided.  &lt;br /&gt;
&lt;br /&gt;
==Features to appear/wishlist==&lt;br /&gt;
* Module for the immersed boundary method (IBM).&lt;br /&gt;
* More FAQ + documentation.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* tutorial, inc. matlab example.&lt;br /&gt;
* Utilities for Krylov methods -- Newton-Krylov, Arnoldi.&lt;br /&gt;
* phys-statefiles for direct upload to matlab/visit etc.&lt;br /&gt;
&lt;br /&gt;
==Related codes==&lt;br /&gt;
Closely related codes are currently obtained by request.&lt;br /&gt;
* Taylor--Couette flow.&lt;br /&gt;
* Flow in a periodic box.&lt;br /&gt;
* Pipeflow, potential formulation.&lt;br /&gt;
&lt;br /&gt;
==Problem-independent codes==&lt;br /&gt;
To be uploaded&lt;br /&gt;
* GMRES&lt;br /&gt;
* Newton-Hookstep&lt;br /&gt;
* Arnoldi&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Citation==&lt;br /&gt;
Please cite [[:File:TheOpenpipeflowSolver.pdf|this article.]]&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
:       [http://maths.dept.shef.ac.uk/maths/staff_info_402.html Ashley P. Willis],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths School of Mathematics and Statistics (SoMaS)],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths University of Sheffield, U.K.]&lt;br /&gt;
:       a.p.willis/at/sheffield.ac.uk&lt;br /&gt;
&lt;br /&gt;
==Thanks==&lt;br /&gt;
* John Gibson ([http://channelflow.org/gibson channelflow.org])&lt;br /&gt;
* Predrag Cvitanović ([http://www.cns.gatech.edu/~predrag/ GaTech] [http://chaosbook.org chaosbook.org])&lt;br /&gt;
* Rich Kerswell ([http://www.damtp.cam.ac.uk/user/rrk26/ Cambridge])&lt;br /&gt;
* many other people!&lt;br /&gt;
* EPSRC GR/S76144/01, EP/K03636X/1&lt;br /&gt;
* The [http://www.sheffield.ac.uk/maths University of Sheffield].&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1097</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1097"/>
		<updated>2025-02-07T10:49:05Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Citation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access) [https://scholar.googleusercontent.com/scholar.bib?q=info:cMCTaKms3nwJ:scholar.google.com/&amp;amp;output=citation&amp;amp;scisdr=ClGyFW5MEO25wx3izYs:AFWwaeYAAAAAZ6Xk1YvVYp2sEuQD-ZaVHK-c4c4&amp;amp;scisig=AFWwaeYAAAAAZ6Xk1fMDCpw10EBJoeEXDw0Zn6o&amp;amp;scisf=4&amp;amp;ct=citation&amp;amp;cd=-1&amp;amp;hl=en bibtex]&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access) [[:File:TheOpenpipeflowSolver.pdf|bibtex]]&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1096</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1096"/>
		<updated>2025-02-07T10:35:58Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature, and that 1-r^2 is no longer the laminar flow.  To compute the laminar temperature and flow profiles, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will very quickly approach the laminar temperature and flow profiles.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access)&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1095</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1095"/>
		<updated>2025-02-07T10:32:04Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature, r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
Note that the base temperature r^2 is not the laminar temperature.  To quickly compute the laminar temperature, set i_K=i_M=1, so that only the mean mode k=m=0 is simulated.  This will quickly approach the laminar flow.&lt;br /&gt;
&lt;br /&gt;
== Citation ==&lt;br /&gt;
&lt;br /&gt;
Please cite something like, &lt;br /&gt;
&amp;quot;... heated-pipe code [1] based on Openpipeflow [2].&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[1]: DOI: https://doi.org/10.3390/math13020293 (open access)&lt;br /&gt;
&lt;br /&gt;
[2]: DOI: https://doi.org/10.1016/j.softx.2017.05.003 (open access)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1094</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1094"/>
		<updated>2025-01-07T16:20:16Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Extentions for extra fields and geometries, e.g. the Heated pipe, Taylor-Couette flow, Rayleigh-Benard convection, a periodic box, etc.  If not listed below, please contact me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Download - Heated pipe]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://github.com/apwillis1/JFNK-Hookstep (non problem-specific Jacobian-free Newton-Krylov code)&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1093</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1093"/>
		<updated>2025-01-07T13:24:07Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ev:youtube|http://youtu.be/hSj0VnmSQro|280|right|Slow streaks (blue) and vortex structures (yellow)}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[File:6551noshiftloop.mp4|280|right|Slow streaks (blue) and vortex structures (yellow)]]&lt;br /&gt;
[[File:OpenPFlogo1.png|thumb|right|Slow streaks (blue) and vortex structures (yellow)]] &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Quicklinks ====&lt;br /&gt;
[[Download]] | [[Manual]] | [[Tutorial]] | [[Database]] | [[Related Codes]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&#039;&#039;&#039;openpipeflow.org is a free resource for researchers, engineers, educators and the interested public.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pipe flow is a simple and familiar set up, yet the flow patterns exhibit [[Fun_stuff|rich chaotic dynamics]].  This provides a setting for investigating the principles of simulation at one level, and at another, for developing new methods designed to probe fundamental properties of dynamical systems.  &lt;br /&gt;
&lt;br /&gt;
The majority of mathematical techniques described on these pages are applicable to a huge range of problems, and [[Manual|subroutines for well-known methods]] are designed to be callable from any code.  The core [[Manual|pipe flow code]] is designed to be flexible yet very fast.  See here for [[Related Codes]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aims&#039;&#039;&#039;&lt;br /&gt;
* To make accessible a range of modelling techniques.&lt;br /&gt;
* To facilitate rapid entry into the world of numerical simulation and fluid dynamics.&lt;br /&gt;
* To provide flexible modules for more the use and development of advanced techniques in research.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code features&#039;&#039;&#039; &lt;br /&gt;
* Primitive-variable pipe-flow code for incompressible flow.&lt;br /&gt;
* Simple scripts for visualisation with Matlab/Octave/Visit.&lt;br /&gt;
* Readable Fortran 90, uses modules and derived types, no esoteric extensions.&lt;br /&gt;
* Core program &amp;lt;3000 lines.&lt;br /&gt;
* Spatial discretisation: double-Fourier (theta,z) + finite difference (r).&lt;br /&gt;
* PPE formulation; influence matrix corrects boundary conditions to machine precision.&lt;br /&gt;
* Second-order predictor-corrector method, automatic timestep control.&lt;br /&gt;
* May be run on a single core or in parallel (with MPI).  Essentially linear scaling with number of cores.&lt;br /&gt;
* &#039;2-dimensional&#039; parallelisation, radial+axial split.&lt;br /&gt;
* Jacobian-Free Newton-Krylov (JFNK) solver.  Now at https://github.com/apwillis1/JFNK-Hookstep .&lt;br /&gt;
Details for the above can be found in the [[Manual]].&lt;br /&gt;
This article, [[File:TheOpenpipeflowSolver.pdf]], provides an overview of the code and its context.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
The [[Database]] provides sample parameters and initial conditions from which to launch new simulations.  In general, simulations start most reliably from an initial state computed for similar parameters.  A range of starting points are provided.  &lt;br /&gt;
&lt;br /&gt;
==Features to appear/wishlist==&lt;br /&gt;
* Module for the immersed boundary method (IBM).&lt;br /&gt;
* More FAQ + documentation.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* tutorial, inc. matlab example.&lt;br /&gt;
* Utilities for Krylov methods -- Newton-Krylov, Arnoldi.&lt;br /&gt;
* phys-statefiles for direct upload to matlab/visit etc.&lt;br /&gt;
&lt;br /&gt;
==Related codes==&lt;br /&gt;
Closely related codes are currently obtained by request.&lt;br /&gt;
* Taylor--Couette flow.&lt;br /&gt;
* Flow in a periodic box.&lt;br /&gt;
* Pipeflow, potential formulation.&lt;br /&gt;
&lt;br /&gt;
==Problem-independent codes==&lt;br /&gt;
To be uploaded&lt;br /&gt;
* GMRES&lt;br /&gt;
* Newton-Hookstep&lt;br /&gt;
* Arnoldi&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Citation==&lt;br /&gt;
Please cite this article: [[File:TheOpenpipeflowSolver.pdf]]&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
:       [http://maths.dept.shef.ac.uk/maths/staff_info_402.html Ashley P. Willis],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths School of Mathematics and Statistics (SoMaS)],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths University of Sheffield, U.K.]&lt;br /&gt;
:       a.p.willis/at/sheffield.ac.uk&lt;br /&gt;
&lt;br /&gt;
==Thanks==&lt;br /&gt;
* John Gibson ([http://channelflow.org/gibson channelflow.org])&lt;br /&gt;
* Predrag Cvitanović ([http://www.cns.gatech.edu/~predrag/ GaTech] [http://chaosbook.org chaosbook.org])&lt;br /&gt;
* Rich Kerswell ([http://www.damtp.cam.ac.uk/user/rrk26/ Cambridge])&lt;br /&gt;
* many other people!&lt;br /&gt;
* EPSRC GR/S76144/01, EP/K03636X/1&lt;br /&gt;
* The [http://www.sheffield.ac.uk/maths University of Sheffield].&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1092</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Main_Page&amp;diff=1092"/>
		<updated>2025-01-07T13:22:36Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Quicklinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ev:youtube|http://youtu.be/hSj0VnmSQro|280|right|Slow streaks (blue) and vortex structures (yellow)}}&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
[[File:6551noshiftloop.mp4|280|right|Slow streaks (blue) and vortex structures (yellow)]]&lt;br /&gt;
[[File:OpenPFlogo1.png|thumb|right|Slow streaks (blue) and vortex structures (yellow)]] &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Quicklinks ====&lt;br /&gt;
[[Download]] | [[Manual]] | [[Tutorial]] | [[Database]] | [[Related Codes]]&lt;br /&gt;
&lt;br /&gt;
==Overview==&lt;br /&gt;
&#039;&#039;&#039;openpipeflow.org is a free resource for researchers, engineers, educators and the interested public.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pipe flow is a simple and familiar set up, yet the flow patterns exhibit [[Fun_stuff|rich chaotic dynamics]].  This provides a setting for investigating the principles of simulation at one level, and at another, for developing new methods designed to probe fundamental properties of dynamical systems.  &lt;br /&gt;
&lt;br /&gt;
The majority of mathematical techniques described on these pages are applicable to a huge range of problems, and [[Manual|subroutines for well-known methods]] are designed to be callable from any code.  The core [[Manual|pipe flow code]] is designed to be flexible yet very fast.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Aims&#039;&#039;&#039;&lt;br /&gt;
* To make accessible a range of modelling techniques.&lt;br /&gt;
* To facilitate rapid entry into the world of numerical simulation and fluid dynamics.&lt;br /&gt;
* To provide flexible modules for more the use and development of advanced techniques in research.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Code features&#039;&#039;&#039; &lt;br /&gt;
* Primitive-variable pipe-flow code for incompressible flow.&lt;br /&gt;
* Simple scripts for visualisation with Matlab/Octave/Visit.&lt;br /&gt;
* Readable Fortran 90, uses modules and derived types, no esoteric extensions.&lt;br /&gt;
* Core program &amp;lt;3000 lines.&lt;br /&gt;
* Spatial discretisation: double-Fourier (theta,z) + finite difference (r).&lt;br /&gt;
* PPE formulation; influence matrix corrects boundary conditions to machine precision.&lt;br /&gt;
* Second-order predictor-corrector method, automatic timestep control.&lt;br /&gt;
* May be run on a single core or in parallel (with MPI).  Essentially linear scaling with number of cores.&lt;br /&gt;
* &#039;2-dimensional&#039; parallelisation, radial+axial split.&lt;br /&gt;
* Jacobian-Free Newton-Krylov (JFNK) solver.  Now at https://github.com/apwillis1/JFNK-Hookstep .&lt;br /&gt;
Details for the above can be found in the [[Manual]].&lt;br /&gt;
This article, [[File:TheOpenpipeflowSolver.pdf]], provides an overview of the code and its context.&lt;br /&gt;
&lt;br /&gt;
==Database==&lt;br /&gt;
The [[Database]] provides sample parameters and initial conditions from which to launch new simulations.  In general, simulations start most reliably from an initial state computed for similar parameters.  A range of starting points are provided.  &lt;br /&gt;
&lt;br /&gt;
==Features to appear/wishlist==&lt;br /&gt;
* Module for the immersed boundary method (IBM).&lt;br /&gt;
* More FAQ + documentation.&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
* tutorial, inc. matlab example.&lt;br /&gt;
* Utilities for Krylov methods -- Newton-Krylov, Arnoldi.&lt;br /&gt;
* phys-statefiles for direct upload to matlab/visit etc.&lt;br /&gt;
&lt;br /&gt;
==Related codes==&lt;br /&gt;
Closely related codes are currently obtained by request.&lt;br /&gt;
* Taylor--Couette flow.&lt;br /&gt;
* Flow in a periodic box.&lt;br /&gt;
* Pipeflow, potential formulation.&lt;br /&gt;
&lt;br /&gt;
==Problem-independent codes==&lt;br /&gt;
To be uploaded&lt;br /&gt;
* GMRES&lt;br /&gt;
* Newton-Hookstep&lt;br /&gt;
* Arnoldi&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Citation==&lt;br /&gt;
Please cite this article: [[File:TheOpenpipeflowSolver.pdf]]&lt;br /&gt;
&lt;br /&gt;
==Author==&lt;br /&gt;
:       [http://maths.dept.shef.ac.uk/maths/staff_info_402.html Ashley P. Willis],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths School of Mathematics and Statistics (SoMaS)],&lt;br /&gt;
:       [http://www.sheffield.ac.uk/maths University of Sheffield, U.K.]&lt;br /&gt;
:       a.p.willis/at/sheffield.ac.uk&lt;br /&gt;
&lt;br /&gt;
==Thanks==&lt;br /&gt;
* John Gibson ([http://channelflow.org/gibson channelflow.org])&lt;br /&gt;
* Predrag Cvitanović ([http://www.cns.gatech.edu/~predrag/ GaTech] [http://chaosbook.org chaosbook.org])&lt;br /&gt;
* Rich Kerswell ([http://www.damtp.cam.ac.uk/user/rrk26/ Cambridge])&lt;br /&gt;
* many other people!&lt;br /&gt;
* EPSRC GR/S76144/01, EP/K03636X/1&lt;br /&gt;
* The [http://www.sheffield.ac.uk/maths University of Sheffield].&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1091</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1091"/>
		<updated>2025-01-07T13:07:55Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
== Notes on the Heated pipe version ==&lt;br /&gt;
&lt;br /&gt;
This code will load state files from the &#039;ordinary&#039; code.  It will assume there is no perturbation to the base temperature =r^2; a turbulent flow will quickly mix this up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1090</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1090"/>
		<updated>2025-01-07T12:59:22Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Other versions exist, e.g. for Taylor-Couette flow, Rayleigh-Benard convection, a periodic box, etc.  If not listed below, please contact me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Download - Heated pipe]]&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=File:Openpipeflow-hp-1.21.tgz&amp;diff=1089</id>
		<title>File:Openpipeflow-hp-1.21.tgz</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=File:Openpipeflow-hp-1.21.tgz&amp;diff=1089"/>
		<updated>2025-01-07T12:57:21Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: First distrib version of Heated pipe code.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
First distrib version of Heated pipe code.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1088</id>
		<title>Download - Heated pipe</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download_-_Heated_pipe&amp;diff=1088"/>
		<updated>2025-01-07T12:55:50Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: Created page with &amp;quot;== Installation ==  If you already have a Fortran compiler, then you only need download the current version (link below), and unpack   tar -xvvzf Openpipeflow-hp-x.xx.tgz  The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.    Next see Getting_started, then try the Tutorial.     == Current version ==  &amp;#039;&amp;#039;&amp;#039;Openpipeflow-hp-1.21&amp;#039;&amp;#039;&amp;#039;: * &amp;#039;&amp;#039;&amp;#039;Download&amp;#039;&amp;#039;&amp;#039;: File:O...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-hp-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-hp-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-hp-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** First distrib version.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1087</id>
		<title>Related Codes</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Related_Codes&amp;diff=1087"/>
		<updated>2025-01-07T12:53:26Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: Created page with &amp;quot;Other versions exist, e.g. for Taylor-Couette flow, Rayleigh-Benard convection, etc.  If not listed below, please contact me.   Download - Heated pipe&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Other versions exist, e.g. for Taylor-Couette flow, Rayleigh-Benard convection, etc.  If not listed below, please contact me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Download - Heated pipe]]&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Download&amp;diff=1086</id>
		<title>Download</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Download&amp;diff=1086"/>
		<updated>2025-01-07T12:48:20Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Please download the Current version of openpipeflow below.  See here for [[Related Codes]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Virtual machine option ==&lt;br /&gt;
&lt;br /&gt;
If you just want a quick try, or if you are not running a linux environment, then you could try  [http://www.virtualbox.org virtualbox] and the [[Xubuntu-Openpipeflow_virtual_disk_image]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you already have a Fortran compiler, then you only need download the current version (link below), and unpack&lt;br /&gt;
  tar -xvvzf Openpipeflow-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers are included: &amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
Next see [[Getting_started]], then try the [[Tutorial]].  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Current version ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.22&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.22.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Some additions to utils/&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2023/03  Option to calculate pressure in prim2matlab.f90, courtesy of Jie Yao.&lt;br /&gt;
** 2023/04  Two versions of util: prim2ascii_coll.f90, prim2ascii_phys.f90.&lt;br /&gt;
** 2023/06  Generic functions related to slicing, predrag_slice_mod.f90.&lt;br /&gt;
&lt;br /&gt;
== Older versions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Please download the latest version above!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.21&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.21.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Added transforms direct between phys-coll types, so don&#039;t need to handle intermediate spec type.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/10/11 See tra_coll2phys(...), tra_phys2coll(...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.20&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.20.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Slight update to axis treatment. Symmetry property used in all calculations of derivatives.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/08/08 Symmetry parameter now used in var_meshmult(...)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.12&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.12.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** LES and nonnewtonian (shear-thinning) utils added.&lt;br /&gt;
** Radial points may be loaded from mesh.in, see mes_precompute().&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2017/05/08 No changes to core code except mesh.in option.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.11c&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.11c.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Newton-Krylov utility added, see - utils/newton.f90.&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2016/12/13 No changes to core code.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.11b&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.11b.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;: &lt;br /&gt;
** Minor update to significant revision-1.10 (Double parallelisation).  Please see comments for version 1.10.  &lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** 2015/11/26 Check for radial split _Np&amp;gt;i_N corrected to _Nr&amp;gt;i_N.&lt;br /&gt;
** 2015/08/05 Fixed bug preventing serial use in parallel macros.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.10&#039;&#039;&#039;:&lt;br /&gt;
* &#039;&#039;&#039;Download&#039;&#039;&#039;: [[File:Openpipeflow-1.10.tgz]]&lt;br /&gt;
* &#039;&#039;&#039;Comments&#039;&#039;&#039;:&lt;br /&gt;
** Double parallelisation: in physical space data is split into _Nr sections radially and (new option) _Ns sections axially.  Total number of cores used is _Np=_Nr*_Ns.&lt;br /&gt;
** It is recommended that for a modest number of cores, vary _Nr and keep _Ns=1 (split radially only).&lt;br /&gt;
* &#039;&#039;&#039;Changelog&#039;&#039;&#039;:&lt;br /&gt;
** Double parallelisation.&lt;br /&gt;
** Minor updates to var_null, var_imposesymm functions.&lt;br /&gt;
** Interpolation correction for prim2matlab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Openpipeflow-1.02b&#039;&#039;&#039;:&lt;br /&gt;
* Tarball [[File:Openpipeflow-1.02b.tgz]]&lt;br /&gt;
* Manual  [[File:Openpipeflow-1.02b-doc.pdf]].  The [[Manual|Online Manual]] is now more comprehensive.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Getting_started&amp;diff=1085</id>
		<title>Getting started</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Getting_started&amp;diff=1085"/>
		<updated>2024-12-03T17:23:08Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Typical setup commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
If you just want a quick try, or if you are not running a linux environment, then you could try  [http://www.virtualbox.org virtualbox] and the [[Xubuntu-Openpipeflow_virtual_disk_image]].&lt;br /&gt;
&lt;br /&gt;
The following few commands are for installation in a linux environment.  (On a Mac you could try &#039;brew install ...&#039; [https://brew.sh/].)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve not already, [[download]] the code and unpack the tarball: &lt;br /&gt;
  :~&amp;gt; tar -xvvzf Openpipeflow-x.xx.tgz&lt;br /&gt;
&lt;br /&gt;
If you have administrator privilages, with linux try&lt;br /&gt;
  :~&amp;gt; sudo apt-get install gfortran&lt;br /&gt;
  :~&amp;gt; sudo apt-get install liblapack-dev&lt;br /&gt;
  :~&amp;gt; sudo apt-get install libfftw3-dev&lt;br /&gt;
  :~&amp;gt; sudo apt-get install libnetcdf-dev&lt;br /&gt;
  :~&amp;gt; sudo apt-get install libnetcdff-dev&lt;br /&gt;
  # optionally, for parallel MPI use:&lt;br /&gt;
  :~&amp;gt; sudo apt-get install libopenmpi-dev&lt;br /&gt;
&lt;br /&gt;
Then &lt;br /&gt;
  :~&amp;gt; cd openpipeflow-x.xx/&lt;br /&gt;
  :~&amp;gt; make&lt;br /&gt;
If this does not end with an error message, then you can skip the section on libraries!  Next&lt;br /&gt;
  :~&amp;gt; make clean&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: If you wish to run in parallel, then you will need an mpi-fortran compiler. BUT, the code is sufficiently parallelized that it does NOT require parallel versions of LAPACK, netCDF or FFTW3.  Each thread calls the serial implementation of each library.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Next&#039;&#039;&#039; try the [[Tutorial]], or take a look below if there were problems with libraries.&lt;br /&gt;
&lt;br /&gt;
== Overview of files ==&lt;br /&gt;
&lt;br /&gt;
[[File:Modules4.png]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt;&#039;&#039;&#039; is likely to require modification for your compiler and libraries (see [[#Libraries]]).  It has been set up for &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt;, but compile flags for several compilers (&amp;lt;tt&amp;gt;g95, gfortran, ifort, pathf90, pgf90&amp;lt;/tt&amp;gt;) can be found at the top of the file.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;&#039;&#039;&#039; Ensure &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; are both set to &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; if you do not have MPI. This file contains macros for parallelisation that are only invoked if the number of processes &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt; is greater than 1.  Unless you need many cores, vary &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; only, keep &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt; .&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;program/parameters.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039;. Reynolds number, resolution, timestep, etc.  See [[#Parameters]]&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;utils/&amp;lt;/tt&amp;gt;&#039;&#039;&#039; contains a number of utilities. Almost anything can be done in a util, both post-processing and analysing data at runtime. There should be no need to alter the core code. See [[#Making_utils]]&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;matlab/&amp;lt;/tt&amp;gt;&#039;&#039;&#039;, a few scripts. See &amp;lt;tt&amp;gt;matlab/Readme.txt&amp;lt;/tt&amp;gt; .&lt;br /&gt;
&lt;br /&gt;
== Makefile ==&lt;br /&gt;
A quick description of the Makefile below.  There are suggested flags for several compilers at the top of this file, but the last group (compiler and paths) is the most important section if compiling for the first time.  Note the include/link paths specified with &amp;lt;tt&amp;gt;-I&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;-L&amp;lt;path&amp;gt;&amp;lt;/tt&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
 INSTDIR         = ./install/    [no need to change; where to put main.out and main.info files]&lt;br /&gt;
 PROGDIR         = ./program/    [no need to change; where code is located]&lt;br /&gt;
 UTILDIR         = ./utils/      [no need to change; where utility programs are located]&lt;br /&gt;
 UTIL            = prim2matlab   [See [[#Making_utils]]; name of utility to build]&lt;br /&gt;
&lt;br /&gt;
 TRANSFORM       = fftw3         [no need to change; name of FFT library]&lt;br /&gt;
 MODSOBJ         = io.o meshs.o mpi.o parameters.o \&lt;br /&gt;
                  timestep.o transform.o variables.o velocity.o&lt;br /&gt;
&lt;br /&gt;
 #COMPILER       = g95 #-C         [sample flags for several compilers]&lt;br /&gt;
 #COMPFLAGS      = -cpp -c -O3&lt;br /&gt;
 #COMPILER       = ifort -i-dynamic #-C #-static &lt;br /&gt;
 #COMPFLAGS      = -cpp -c -O3 -heap-arrays 1024 -mcmodel=medium&lt;br /&gt;
 #COMPILER       = pgf90 #-C&lt;br /&gt;
 #COMPFLAGS      = -Mpreprocess -c -fast #-mcmodel=medium&lt;br /&gt;
 #COMPILER       = pathf90 #-pg -C&lt;br /&gt;
 #COMPFLAGS      = -cpp -c -O3 -OPT:Ofast -march=opteron -fno-second-underscore&lt;br /&gt;
&lt;br /&gt;
 COMPILER        = gfortran                     [***CHANGE TO mpif90 FOR PARALLEL USE***]&lt;br /&gt;
 COMPFLAGS       = -ffree-line-length-none -x f95-cpp-input -c -O3 \&lt;br /&gt;
                  -I/usr/include \              [***MIGHT NEED TO UPDATE INCLUDE PATH***]&lt;br /&gt;
                  #-C #-pg                      [     See info in following section     ] &lt;br /&gt;
 LIBS            = \&lt;br /&gt;
                  -L/home/ash/lib \             [***MIGHT NEED TO UPDATE LIBRARY PATH***]&lt;br /&gt;
                  cheby.o -lfftw3 -llapack -lnetcdff -lnetcdf \&lt;br /&gt;
                  # -lblas -lcurl&lt;br /&gt;
&lt;br /&gt;
== Libraries ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The code uses freely availably libraries LAPACK, netCDF and FFTW3.  If compiling for the first time, consider trying the &amp;lt;tt&amp;gt;gfortran&amp;lt;/tt&amp;gt; + &#039;&#039;precompiled binaries&#039;&#039; combination.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE: The code is sufficiently parallelized that it does not require parallel versions of LAPACK, netCDF or FFTW3.  Each thread can calls the serial implementation.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the openpipeflow directory, try &amp;lt;tt&amp;gt;make&amp;lt;/tt&amp;gt;, looking for errors indicating missing libraries&lt;br /&gt;
 &amp;gt; make&lt;br /&gt;
 ...&lt;br /&gt;
 Fatal Error: Can&#039;t open module file &#039;netcdf.mod&#039;&lt;br /&gt;
 /usr/bin/ld: cannot find -llapack&lt;br /&gt;
 /usr/bin/ld: cannot find -lfftw3&lt;br /&gt;
&lt;br /&gt;
If you get something like&lt;br /&gt;
 Error: Can&#039;t open included file &#039;mpif.h&#039;&lt;br /&gt;
it is possible that &amp;lt;tt&amp;gt;_Np (=_Nr*_Ns)&amp;lt;/tt&amp;gt; is not &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;, but the &amp;lt;tt&amp;gt;COMPILER&amp;lt;/tt&amp;gt; has not been changed to &amp;lt;tt&amp;gt;mpif90&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Precompiled binaries ===&lt;br /&gt;
&lt;br /&gt;
If using a linux environment, install the LAPACK, FFTW3 and netCDF packages with your package manager or &#039;software center&#039;.  If you have sudo privileges, it may be sufficient to try&lt;br /&gt;
 :~&amp;gt; sudo apt-get install ...&lt;br /&gt;
commands listed at the top of this page.  Then&lt;br /&gt;
 :~&amp;gt; cd openpipeflow-x.xx/&lt;br /&gt;
 :~&amp;gt; make&lt;br /&gt;
&lt;br /&gt;
If libraries are missing for netCDF, find the location of &amp;lt;tt&amp;gt;netcdf.mod&amp;lt;/tt&amp;gt; &lt;br /&gt;
 :~&amp;gt; cd /&lt;br /&gt;
 :/&amp;gt; ls */netcdf.mod &lt;br /&gt;
 :/&amp;gt; ls */*/netcdf.mod&lt;br /&gt;
 /usr/include/netcdf.mod &lt;br /&gt;
Ensure that the file is in the include path in &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt;, here &amp;lt;tt&amp;gt;-I/usr/include&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Often the package manager supplies several versions of a package, distinguished by extra extensions.  If a library has been installed but is not found, then search for the library, e.g.&lt;br /&gt;
 :/&amp;gt; ls  */*/liblapack*  */*/*/libfftw3* */*/*/libnetcdf*&lt;br /&gt;
 etc/alternatives/liblapack.so.3&lt;br /&gt;
 etc/alternatives/liblapack.so.3gf&lt;br /&gt;
 usr/lib/i386-linux-gnu/libfftw3_omp.so.3&lt;br /&gt;
 usr/lib/i386-linux-gnu/libfftw3_omp.so.3.3.2&lt;br /&gt;
 usr/lib/i386-linux-gnu/libfftw3.so.3&lt;br /&gt;
 usr/lib/i386-linux-gnu/libfftw3.so.3.3.2&lt;br /&gt;
 usr/lib/i386-linux-gnu/libnetcdff.so.6&lt;br /&gt;
 usr/lib/i386-linux-gnu/libnetcdf.so.11&lt;br /&gt;
Create a symbolic link to one of the versions for each package&lt;br /&gt;
 :~&amp;gt; mkdir /home/ash/lib &lt;br /&gt;
 :~&amp;gt; ln -s /etc/alternatives/liblapack.so.3 /home/ash/lib/liblapack.so&lt;br /&gt;
 :~&amp;gt; ln -s /usr/lib/i386-linux-gnu/libfftw3.so.3 /home/ash/lib/libfftw3.so&lt;br /&gt;
 :~&amp;gt; ln -s /usr/lib/i386-linux-gnu/libnetcdff.so.6 /home/ash/lib/libnetcdff.so&lt;br /&gt;
 :~&amp;gt; ln -s /usr/lib/i386-linux-gnu/libnetcdf.so.11 /home/ash/lib/libnetcdf.so&lt;br /&gt;
Ensure that they are in the link path in &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt;,  &amp;lt;tt&amp;gt;-L/home/ash/lib&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Some extra libraries may or may not be needed, depending on compiler/distribution.  Try simply omitting the link flags&lt;br /&gt;
&amp;lt;tt&amp;gt;-lblas&amp;lt;/tt&amp;gt; and/or &amp;lt;tt&amp;gt;-lcurl&amp;lt;/tt&amp;gt; at first, for example.&lt;br /&gt;
&lt;br /&gt;
=== Compiling libraries ===&lt;br /&gt;
&lt;br /&gt;
If it is not possible to link with precompiled libraries, or if special flags are necessary, e.g. for a very large memory model,&lt;br /&gt;
then it may be necessary to build LAPACK and NetCDF with the compiler and compile flags that will be used for the main simulation code.&lt;br /&gt;
&lt;br /&gt;
The default procedure for building a package (applicable to FFTW3 and netCDF) is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;tar -xvvzf package.tar.gz&lt;br /&gt;
cd package/&lt;br /&gt;
[set environment variables if necessary]&lt;br /&gt;
./configure --prefix=&amp;amp;lt;path to put libraries&amp;amp;gt;&lt;br /&gt;
make&lt;br /&gt;
make install&amp;lt;/pre&amp;gt;&lt;br /&gt;
– &#039;&#039;&#039;FFTW3&#039;&#039;&#039;. This usually requires no special treatment. Install with your package manager or build with the default settings.&lt;br /&gt;
&lt;br /&gt;
– &#039;&#039;&#039;LAPACK&#039;&#039;&#039;. If using gfortran you might be able to use the binary version supplied for your linux distribution. Otherwise, edit the file make.inc that comes with LAPACK, setting the fortran compiler and flags to those you plan to use. Type ‘make’. Once finished, copy the following binaries into your library path (see Makefile LIBS -L$&amp;lt;$path$&amp;gt;$/lib/)&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;cp lapack.a &amp;amp;lt;path&amp;amp;gt;/lib/liblapack.a&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;cp blas.a &amp;amp;lt;path&amp;amp;gt;/lib/libblas.a&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
– &#039;&#039;&#039;netCDF&#039;&#039;&#039;. If using gfortran you might be able to use the supplied binary version for your linux distribution. Several versions can be found at &amp;lt;tt&amp;gt;http://www.unidata.ucar.edu/downloads/netcdf/current/index.jsp&amp;lt;/tt&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Version &#039;&#039;&#039;4.1.3&#039;&#039;&#039; is relatively straight forward to install, the following typical environment variables required to build netCDF should be sufficient:&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;CXX=&amp;amp;quot;&amp;amp;quot;&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;FC=/opt/intel/fc/10.1.018/bin/ifort&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;FFLAGS=&amp;amp;quot;-O3 -mcmodel=medium&amp;amp;quot;&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;export CXX FC FFLAGS&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
After building, ensure that files &amp;lt;tt&amp;gt;netcdf.mod&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;typesizes.mod&amp;lt;/tt&amp;gt; appear in your include path (see Makefile COMPFLAGS -I$&amp;lt;$path$&amp;gt;$/include/).  &lt;br /&gt;
&lt;br /&gt;
For more recent versions, netCDF installation is slightly trickier [currently netcdf-4.3.0.tar.gz 2015-07-20]. First&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;./configure --disable-netcdf-4 --prefix=&amp;amp;lt;path&amp;amp;gt;&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
which disables HDF5 support (not currently required, see comment on [[Parallel_i/o]]). Also, Fortran is no longer bundled, so get netcdf-fortran-4.2.2.tar.gz or a more recent version from here&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;http://www.unidata.ucar.edu/downloads/netcdf/index.jsp&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Build with the environment variables above, and in addition&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;CPPFLAGS=-I&amp;amp;lt;path&amp;amp;gt;/include&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;export CPPFLAGS&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Finally, add the link flag &amp;lt;tt&amp;gt;-lnetcdff&amp;lt;/tt&amp;gt; immediately &#039;&#039;before&#039;&#039; &amp;lt;tt&amp;gt;-lnetcdf&amp;lt;/tt&amp;gt; in your &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;tt&amp;gt;./parallel.h&amp;lt;/tt&amp;gt;&#039;&#039;&#039;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt; _Nr&amp;lt;/tt&amp;gt;   split in radius&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt; _Ns&amp;lt;/tt&amp;gt;   split axially&amp;lt;br /&amp;gt;&lt;br /&gt;
Number of cores is &amp;lt;tt&amp;gt;_Np = _Nr * _Ns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Set both &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; for serial use. MPI not required in that case.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Unless a large number of cores is required, it is recommended to vary only &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and to keep &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt;, i.e. split radially only.  Prior to openpipeflow-1.10, only &amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt; was available, equivalent to the current &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; is &#039;optimal&#039; if it is a divisor of &amp;lt;tt&amp;gt;i_N&amp;lt;/tt&amp;gt; or only slightly larger than a divisor.  &lt;br /&gt;
To keep code simple, &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; must divide both &amp;lt;tt&amp;gt;i_Z&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;i_M&amp;lt;/tt&amp;gt; parameters below (easier to leave &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt; if not needed).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;tt&amp;gt;./program/parameters.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039;:&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_N&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Number of radial points $n\in[1,N]$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_K&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Maximum k (axial), $k\in(-K,\,K)$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_M&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Maximum m (azimuthal), $m\in[0,\,M)$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_Mp&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Azimuthal periodicity, i.e. $m=0,M_p,2M_p,\dots,(M-1)M_p$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;(set =1 for no symmetry assumption)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_Re&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Reynolds number $Re$ or $Rm_m$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_alpha&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Axial wavenumber $\alpha=2\pi/L_z$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;b_const_flux&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Enforce constant flux $U_b=\frac1{2}$.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_save_rate1&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Save frequency for snapshot data files (timesteps between saves)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_save_rate2&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Save frequency for time-series data&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_maxtstep&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Maximum number of timesteps (no limit if set &amp;lt;tt&amp;gt;=-1&amp;lt;/tt&amp;gt;)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_cpuhours&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Maximum number of cpu hours&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_time&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Start time (taken from &amp;lt;tt&amp;gt;state.cdf.in&amp;lt;/tt&amp;gt; if set &amp;lt;tt&amp;gt;=-1d0&amp;lt;/tt&amp;gt;)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_timestep&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Fixed timestep (typically &amp;lt;tt&amp;gt;=0.01d0&amp;lt;/tt&amp;gt; or dynamically controlled if set &amp;lt;tt&amp;gt;=-1d0&amp;lt;/tt&amp;gt;)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_dterr&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Maximum corrector norm, $\|f_{corr}\|$ (typically &amp;lt;tt&amp;gt;=1d-5&amp;lt;/tt&amp;gt; or set &amp;lt;tt&amp;gt;=1d1&amp;lt;/tt&amp;gt; to avoid extra corrector iterations) &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_courant&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Courant number $\mathrm{C}$ (unlikely to need changing)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_implicit&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;Implicitness $c$ (unlikely to need changing)&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note the default cases&#039;&#039;&#039;, usually if the parameter is set to -1.&lt;br /&gt;
&lt;br /&gt;
== Input files ==&lt;br /&gt;
&lt;br /&gt;
State files are stored in the NetCDF data format are binary yet can be transferred across different architectures safely. The program &amp;lt;tt&amp;gt;main.out&amp;lt;/tt&amp;gt; runs with the compiled parameters (see &amp;lt;tt&amp;gt;main.info&amp;lt;/tt&amp;gt;) but will load states of other truncations. For example, an output state file &amp;lt;tt&amp;gt;state0018.cdf.dat&amp;lt;/tt&amp;gt; can be copied to an input &amp;lt;tt&amp;gt;state.cdf.in&amp;lt;/tt&amp;gt;, and when loaded it will be interpolated if necessary.&lt;br /&gt;
&lt;br /&gt;
Sample initial conditions are available in the [[Database]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;state.cdf.in&amp;lt;/tt&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
$t$ – &#039;&#039;&#039;Start time&#039;&#039;&#039;. Overridden by &amp;lt;tt&amp;gt;d_time&amp;lt;/tt&amp;gt; if &amp;lt;tt&amp;gt;d_time&amp;lt;/tt&amp;gt;$\ge$0&amp;lt;br /&amp;gt;&lt;br /&gt;
$\Delta t$ – &#039;&#039;&#039;Timestep&#039;&#039;&#039;. Ignored, see parameter &amp;lt;tt&amp;gt;d_timestep&amp;lt;/tt&amp;gt;.&amp;lt;br /&amp;gt;&lt;br /&gt;
$N, M_p, r_n$ – &#039;&#039;&#039;Number of radial points, azimuthal periodicity, radial values&#039;&#039;&#039; of the input state.&amp;lt;br /&amp;gt;&lt;br /&gt;
– If the input radial points differ from the runtime points, then the fields are interpolated onto the new points automatically.&amp;lt;br /&amp;gt;&lt;br /&gt;
$u_r,\,u_\theta,\, u_z$ – &#039;&#039;&#039;Field vectors&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
– If $K\ne\,$&amp;lt;tt&amp;gt;i_K&amp;lt;/tt&amp;gt; or $M\ne\,$&amp;lt;tt&amp;gt;i_M&amp;lt;/tt&amp;gt;, then Fourier modes are truncated or zeros appended.&lt;br /&gt;
&lt;br /&gt;
== Output ==&lt;br /&gt;
&lt;br /&gt;
=== Snapshot data ===&lt;br /&gt;
&lt;br /&gt;
Data saved every &amp;lt;tt&amp;gt;i_save_rate1&amp;lt;/tt&amp;gt; timesteps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   state????.cdf.dat&lt;br /&gt;
   vel_spec????.dat&amp;lt;/pre&amp;gt;&lt;br /&gt;
All output is sent to the current directory, and &amp;lt;tt&amp;gt;????&amp;lt;/tt&amp;gt; indicates numbers &amp;lt;tt&amp;gt;0000&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0001&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;0002&amp;lt;/tt&amp;gt;,…. Each state file can be copied to a &amp;lt;tt&amp;gt;state.cdf.in&amp;lt;/tt&amp;gt; should a restart be necessary. To list times $t$ for each saved state file,&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;   &amp;amp;gt; grep state OUT&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
The spectrum files are overwritten each save as they are retrievable from the state data. To verify sufficient truncation, a quick profile of the energy spectrum can be plotted with&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;   gnuplot&amp;amp;gt; set log&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;   gnuplot&amp;amp;gt; plot &#039;vel_spec0002.dat&#039; w lp&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Time-series data ===&lt;br /&gt;
&lt;br /&gt;
Data saved every &amp;lt;tt&amp;gt;i_save_rate2&amp;lt;/tt&amp;gt; timesteps:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;tim_step.dat&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$t$, $\Delta t$, $\Delta t_{\|f\|}$, $\Delta t_{CFL}$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;current and limiting step sizes&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;vel_energy.dat&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$t$, $E$, $E_{k=0}$, $E_{m=0}$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;energies. Streamwise-dependent component of energy = $E-E_{k=0}$.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;vel_friction.dat&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$t$, $U_b$ or $\beta$, $\langle u_z(r=0)\rangle_z$, $u_\tau$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;bulk speed or pressure measure $1+\beta=Re/Re_m$, mean centreline speed, friction vel.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;vel_totEID.dat&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$t$, $E/E_{lam}$, $I/I_{lam}$, $D/D_{lam}$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;total energy, input, dissipation; each normalised by laminar value.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Typical usage ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See the [[Tutorial]] for the fundamentals of setting up, launching, monitoring and ending a job.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== Serial and parallel use ====&lt;br /&gt;
&lt;br /&gt;
* To launch a serial job&lt;br /&gt;
 &amp;gt; nohup ./main.out &amp;gt; OUT 2&amp;gt; OUT.err &amp;amp;&lt;br /&gt;
* The number of cores is set in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt; (all other parameters are in &amp;lt;tt&amp;gt;program/parameters.f90&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* For serial use, both &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; should be &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* For parallel use, in &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; the &amp;lt;tt&amp;gt;COMPILER&amp;lt;/tt&amp;gt; needs to be changed to e.g. &amp;lt;tt&amp;gt;mpif90&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* MPI is required if, and only if, &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt; is greater than &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* For modest parallelisation, &amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt;&amp;lt;=32, it is recommended to change &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; only.  Leave &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; set to &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; (i.e. &amp;lt;tt&amp;gt;_Np==_Nr&amp;lt;/tt&amp;gt;).&lt;br /&gt;
* For high parallelisation, &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; should be of the same order.&lt;br /&gt;
* To launch a parallel job on 8 cores&lt;br /&gt;
 &amp;gt; nohup mpirun -np 8 ./main.out &amp;gt; OUT 2&amp;gt; OUT.err &amp;amp;&lt;br /&gt;
* Note that, rather than keep changing &amp;lt;tt&amp;gt;COMPILER&amp;lt;/tt&amp;gt; when switching between parallel and serial use, it may be more convenient to simply launch with &amp;lt;tt&amp;gt;-np 1&amp;lt;/tt&amp;gt; in the parallel launch command.&lt;br /&gt;
&lt;br /&gt;
==== Initial conditions ====&lt;br /&gt;
&lt;br /&gt;
The best initial condition is the state with most similar parameters.  Some are supplied in the [[Database]].  &lt;br /&gt;
Any output state, e.g. state0012.cdf.dat can be copied to &amp;lt;tt&amp;gt;state.cdf.in&amp;lt;/tt&amp;gt; to be used as an initial condition.  If resolutions do not match, they are &#039;&#039;&#039;automatically interpolated or truncated&#039;&#039;&#039;.   If none is appropriate, then, it may be necessary to create a utility. See [[Utilities]].&lt;br /&gt;
&lt;br /&gt;
==== Typical setup commands ====&lt;br /&gt;
&lt;br /&gt;
 &amp;gt; nano program/parameters.f90                  [set up parameters and compile]&lt;br /&gt;
 &amp;gt; make&lt;br /&gt;
 &amp;gt; make install&lt;br /&gt;
 &amp;gt;                                              [prepare a directory for the job]&lt;br /&gt;
 &amp;gt; mkdir ~/runs&lt;br /&gt;
 &amp;gt; mv install ~/runs/job0009&lt;br /&gt;
 &amp;gt; cd ~/runs/job0009&lt;br /&gt;
 &amp;gt;                                              [get input state.cdf.in from somewhere... e.g. another job]&lt;br /&gt;
 &amp;gt; diff ../job0008/main.info main.info            [compare parameters with a similar job - a good check]&lt;br /&gt;
 &amp;gt; cp ../job0008/state0052.cdf.dat state.cdf.in&lt;br /&gt;
 &amp;gt;                                                [or get a state.cdf.in from &lt;br /&gt;
 &amp;gt;                                                  http://www.openpipeflow.org/index.php?title=Database]&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
 &amp;gt;                                              [Run!...]&lt;br /&gt;
 &amp;gt; nohup ./main.out &amp;gt; OUT 2&amp;gt; OUT.err &amp;amp;                  [run serial]&lt;br /&gt;
 &amp;gt; nohup mpirun -np 8 ./main.out &amp;gt; OUT 2&amp;gt; OUT.err &amp;amp;     [run parallel]&lt;br /&gt;
 &amp;gt;&lt;br /&gt;
 &amp;gt; head OUT                   [check for warnings/errors]&lt;br /&gt;
 &amp;gt; tail OUT                   [see how far job has got]&lt;br /&gt;
 &amp;gt; &lt;br /&gt;
 &amp;gt; rm RUNNING                 [end the job cleanly] &lt;br /&gt;
&lt;br /&gt;
If a job does not launch correctly, the problem can usually be found in the output&lt;br /&gt;
 &amp;gt; less OUT                   [&#039;q&#039; to quit]&lt;br /&gt;
 &amp;gt; less OUT.err&lt;br /&gt;
&lt;br /&gt;
== Data processing ==&lt;br /&gt;
&lt;br /&gt;
Almost anything can be done either at runtime or as post-processing by creating a utility.&lt;br /&gt;
It very rare that the core code in &amp;lt;tt&amp;gt;program/&amp;lt;/tt&amp;gt; should need to be changed. &lt;br /&gt;
&lt;br /&gt;
There are many examples in &amp;lt;tt&amp;gt;utils/&amp;lt;/tt&amp;gt;. Further information can be found on the [[Utilities]] page.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1084</id>
		<title>Equations and parameters</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1084"/>
		<updated>2024-11-05T14:52:21Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Non-dimensionalisation / scales */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
(As implemented in openpipeflow.org.  For a reminder of the code parameter names see [[Getting_started#parameters]].)&lt;br /&gt;
&lt;br /&gt;
== Governing equations ==&lt;br /&gt;
&lt;br /&gt;
=== Non-dimensionalisation / scales ===&lt;br /&gt;
&lt;br /&gt;
The scales used are &lt;br /&gt;
* $R$, the radius of the pipe.  ($R=D/2$, where $D$ is the diameter.)&lt;br /&gt;
* $U_{cl}$, the centre-line velocity for laminar flow.&lt;br /&gt;
* $R/U_{cl}$ for time.&lt;br /&gt;
&lt;br /&gt;
In computational units, &lt;br /&gt;
* the non-dimensional radius is 1,&lt;br /&gt;
* the non-dimensional laminar flow is $W(r)=1-r^2$,&lt;br /&gt;
* the non-dimensional bulk speed, when fixed, is $\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
Note that when the mean axial flow speed $U_b$ is constant, we have $U_{cl}=2U_b$.&lt;br /&gt;
&lt;br /&gt;
The streamwise wavenumber is $\alpha=2\pi/L$, where $L$ is the periodic length in units $R$.  In papers where $D$ has been used as the scale, $\alpha$ may have been defined to give consistent values, i.e. $\alpha=\pi/L$.&lt;br /&gt;
&lt;br /&gt;
For &#039;lab-units&#039;, based on $D$ and $U_b$, see [[Table of unit conversions]].&lt;br /&gt;
1 advection time unit $D/U_b$ is equivalent to 4 code time units $R/U_{cl}$.&lt;br /&gt;
&lt;br /&gt;
=== Dimensionless parameters ===&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed flux, $Re_m = 2 U_b R / \nu = DU_b / \nu$, where the kinematic viscosity $\nu = \mu / \rho$.&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed pressure, $Re = U_{cl} R / \nu$.&lt;br /&gt;
&lt;br /&gt;
For fixed flux (constant flow rate), $U_{cl}=2\,U_b$ at all times.  The Reynolds number $Re_m$ is more commonly defined in terms of the constant mean speed $U_b$.&lt;br /&gt;
&lt;br /&gt;
For fixed pressure gradient, $U_b$ is a time-dependent quantity that depends on the flow pattern.  We define the Reynolds number $Re$ in terms of the unique $U_{cl}$ for the given pressure gradient.&lt;br /&gt;
&lt;br /&gt;
$1+\beta = Re / Re_m$ is an observed quantity.  For fixed flux, $1+\beta=\langle\partial p/\partial z\rangle \,/\, (dP/dz)$, where $(dP/dz)$ is the laminar pressure gradient and $\langle\partial p/\partial z\rangle$ is the average pressure gradient observed.  For fixed pressure, $1+\beta=U_{cl}/(2U_b)$, where $U_b$ is the observed bulk speed.&lt;br /&gt;
&lt;br /&gt;
The &#039;wall-Reynolds number&#039; $Re_\tau=u_\tau R/\nu$, where $u_\tau$ is the &#039;wall-velocity&#039; [https://en.wikipedia.org/wiki/Shear_velocity], &lt;br /&gt;
is given by $Re_\tau = (2\,Re_m\,(1+\beta))^\frac{1}{2}=(2\,Re)^\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
=== Evolution equations ===&lt;br /&gt;
&lt;br /&gt;
Fixed flux,&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey_m}\,(1+\beta)\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey_m}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Fixed pressure&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey}\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}=W(r)\vechat{z}+\vec{u}&#039;$. Using the scaling above, the laminar flow is $W(r) = 1-r^2$. The&lt;br /&gt;
equation, in rotational form, for the evolution of the perturbation $\vec{u}&#039;$ is then&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} - \frac{1}{\Rey_m}\bnabla^2)\,\vec{u}&#039; &lt;br /&gt;
= \vec{u}&#039; \wedge (\bnabla \wedge\vec{u}&#039;) &lt;br /&gt;
- \frac{\mathrm{d}W}{\mathrm{d}r}\,u&#039;_r \vechat{z}&lt;br /&gt;
- W\,\partial_{z}\vec{u}&#039; + \frac{4\,\beta}{\Rey_m}\vechat{z} - \bnabla\hat{p}&#039; \, . $&lt;br /&gt;
&lt;br /&gt;
== Boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
The no-slip boundary conditions are $\vec{u}=\vec{0}$ at the wall, $r=1$.&lt;br /&gt;
There is no boundary condition explicitly on the pressure.  Indirectly, the pressure must ensure that &lt;br /&gt;
$\bnabla\cdot\vec{u}=0$ is satisfied everywhere, i.e. also on the boundary.  &lt;br /&gt;
&lt;br /&gt;
At the axis $r=0$, symmetry implies that functions are odd or even across the axis.  For a Fourier mode with azimuthal index $m$, each mode is odd/even if $m$ is odd/even for the variables $u_z$ and $p$ (and other scalars).  For $u_r$ and $u_\theta$, each mode is even/odd if $m$ is odd/even.&lt;br /&gt;
&lt;br /&gt;
== Decoupling the equations ==&lt;br /&gt;
&lt;br /&gt;
The equations for $u_r$ and $u_\theta$ are coupled in the [[Differential_operators_in_cylindrical_coordinates#Laplacian|Laplacian]]. They can be separated in a Fourier decompositon by considering&lt;br /&gt;
&lt;br /&gt;
$u_\pm = u_r \pm \mathrm{i} \, u_\theta,$&lt;br /&gt;
&lt;br /&gt;
for which the $\pm$ are considered respectively. Original variables are easily recovered&lt;br /&gt;
&lt;br /&gt;
$u_r = \frac{1}{2} ( u_+ + u_-),&lt;br /&gt;
\qquad&lt;br /&gt;
u_\theta = -\,\frac{\mathrm{i}}{2}(u_+ - u_- ) .$&lt;br /&gt;
&lt;br /&gt;
Governing equations are then decoupled in the linear part and take the form&lt;br /&gt;
&lt;br /&gt;
$\begin{eqnarray*}&lt;br /&gt;
(\partial_{t} - \nabla^2_\pm)\, u_\pm&lt;br /&gt;
&amp;amp; = &amp;amp;  N_\pm - (\bnabla p)_\pm , \\&lt;br /&gt;
(\partial_{t} - \nabla^2 )\, u_z&lt;br /&gt;
&amp;amp; = &amp;amp;  N_z - (\bnabla p)_z ,\end{eqnarray*}$&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
$\nabla^2_\pm = \nabla^2 - \frac{1}{r^2} &lt;br /&gt;
\pm \frac{2\,\mathrm{i}}{r^2}\partial_{\theta}$&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1083</id>
		<title>Equations and parameters</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1083"/>
		<updated>2024-11-05T14:47:53Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Non-dimensionalisation / scales */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
(As implemented in openpipeflow.org.  For a reminder of the code parameter names see [[Getting_started#parameters]].)&lt;br /&gt;
&lt;br /&gt;
== Governing equations ==&lt;br /&gt;
&lt;br /&gt;
=== Non-dimensionalisation / scales ===&lt;br /&gt;
&lt;br /&gt;
The scales used are &lt;br /&gt;
* $R$, the radius of the pipe.&lt;br /&gt;
* $U_{cl}$, the centre-line velocity for laminar flow.&lt;br /&gt;
* $R/U_{cl}$ for time.&lt;br /&gt;
&lt;br /&gt;
In computational units, &lt;br /&gt;
* the non-dimensional radius is 1,&lt;br /&gt;
* the non-dimensional laminar flow is $W(r)=1-r^2$,&lt;br /&gt;
* the bulk velocity is $\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
Note that $R=D/2$, where $D$ is the diameter.  When the bulk flow rate is fixed, so that the mean axial flow speed $U_b$ is constant, we have $U_{cl}=2U_b$.&lt;br /&gt;
&lt;br /&gt;
The streamwise wavenumber is $\alpha=2\pi/L$, where $L$ is the periodic length in units $R$.  In papers where $D$ has been used as the scale, $\alpha$ may have been defined to give consistent values, i.e. $\alpha=\pi/L$.&lt;br /&gt;
&lt;br /&gt;
For &#039;lab-units&#039;, based on $D$ and $U_b$, 1 advection time unit $D/U_b$ is equivalent to 4 code time units $R/U_{cl}$.  See [[Table of unit conversions]].&lt;br /&gt;
&lt;br /&gt;
=== Dimensionless parameters ===&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed flux, $Re_m = 2 U_b R / \nu = DU_b / \nu$, where the kinematic viscosity $\nu = \mu / \rho$.&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed pressure, $Re = U_{cl} R / \nu$.&lt;br /&gt;
&lt;br /&gt;
For fixed flux (constant flow rate), $U_{cl}=2\,U_b$ at all times.  The Reynolds number $Re_m$ is more commonly defined in terms of the constant mean speed $U_b$.&lt;br /&gt;
&lt;br /&gt;
For fixed pressure gradient, $U_b$ is a time-dependent quantity that depends on the flow pattern.  We define the Reynolds number $Re$ in terms of the unique $U_{cl}$ for the given pressure gradient.&lt;br /&gt;
&lt;br /&gt;
$1+\beta = Re / Re_m$ is an observed quantity.  For fixed flux, $1+\beta=\langle\partial p/\partial z\rangle \,/\, (dP/dz)$, where $(dP/dz)$ is the laminar pressure gradient and $\langle\partial p/\partial z\rangle$ is the average pressure gradient observed.  For fixed pressure, $1+\beta=U_{cl}/(2U_b)$, where $U_b$ is the observed bulk speed.&lt;br /&gt;
&lt;br /&gt;
The &#039;wall-Reynolds number&#039; $Re_\tau=u_\tau R/\nu$, where $u_\tau$ is the &#039;wall-velocity&#039; [https://en.wikipedia.org/wiki/Shear_velocity], &lt;br /&gt;
is given by $Re_\tau = (2\,Re_m\,(1+\beta))^\frac{1}{2}=(2\,Re)^\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
=== Evolution equations ===&lt;br /&gt;
&lt;br /&gt;
Fixed flux,&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey_m}\,(1+\beta)\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey_m}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Fixed pressure&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey}\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}=W(r)\vechat{z}+\vec{u}&#039;$. Using the scaling above, the laminar flow is $W(r) = 1-r^2$. The&lt;br /&gt;
equation, in rotational form, for the evolution of the perturbation $\vec{u}&#039;$ is then&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} - \frac{1}{\Rey_m}\bnabla^2)\,\vec{u}&#039; &lt;br /&gt;
= \vec{u}&#039; \wedge (\bnabla \wedge\vec{u}&#039;) &lt;br /&gt;
- \frac{\mathrm{d}W}{\mathrm{d}r}\,u&#039;_r \vechat{z}&lt;br /&gt;
- W\,\partial_{z}\vec{u}&#039; + \frac{4\,\beta}{\Rey_m}\vechat{z} - \bnabla\hat{p}&#039; \, . $&lt;br /&gt;
&lt;br /&gt;
== Boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
The no-slip boundary conditions are $\vec{u}=\vec{0}$ at the wall, $r=1$.&lt;br /&gt;
There is no boundary condition explicitly on the pressure.  Indirectly, the pressure must ensure that &lt;br /&gt;
$\bnabla\cdot\vec{u}=0$ is satisfied everywhere, i.e. also on the boundary.  &lt;br /&gt;
&lt;br /&gt;
At the axis $r=0$, symmetry implies that functions are odd or even across the axis.  For a Fourier mode with azimuthal index $m$, each mode is odd/even if $m$ is odd/even for the variables $u_z$ and $p$ (and other scalars).  For $u_r$ and $u_\theta$, each mode is even/odd if $m$ is odd/even.&lt;br /&gt;
&lt;br /&gt;
== Decoupling the equations ==&lt;br /&gt;
&lt;br /&gt;
The equations for $u_r$ and $u_\theta$ are coupled in the [[Differential_operators_in_cylindrical_coordinates#Laplacian|Laplacian]]. They can be separated in a Fourier decompositon by considering&lt;br /&gt;
&lt;br /&gt;
$u_\pm = u_r \pm \mathrm{i} \, u_\theta,$&lt;br /&gt;
&lt;br /&gt;
for which the $\pm$ are considered respectively. Original variables are easily recovered&lt;br /&gt;
&lt;br /&gt;
$u_r = \frac{1}{2} ( u_+ + u_-),&lt;br /&gt;
\qquad&lt;br /&gt;
u_\theta = -\,\frac{\mathrm{i}}{2}(u_+ - u_- ) .$&lt;br /&gt;
&lt;br /&gt;
Governing equations are then decoupled in the linear part and take the form&lt;br /&gt;
&lt;br /&gt;
$\begin{eqnarray*}&lt;br /&gt;
(\partial_{t} - \nabla^2_\pm)\, u_\pm&lt;br /&gt;
&amp;amp; = &amp;amp;  N_\pm - (\bnabla p)_\pm , \\&lt;br /&gt;
(\partial_{t} - \nabla^2 )\, u_z&lt;br /&gt;
&amp;amp; = &amp;amp;  N_z - (\bnabla p)_z ,\end{eqnarray*}$&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
$\nabla^2_\pm = \nabla^2 - \frac{1}{r^2} &lt;br /&gt;
\pm \frac{2\,\mathrm{i}}{r^2}\partial_{\theta}$&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1082</id>
		<title>Equations and parameters</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Equations_and_parameters&amp;diff=1082"/>
		<updated>2024-11-05T14:45:31Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* Non-dimensionalisation / scales */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
(As implemented in openpipeflow.org.  For a reminder of the code parameter names see [[Getting_started#parameters]].)&lt;br /&gt;
&lt;br /&gt;
== Governing equations ==&lt;br /&gt;
&lt;br /&gt;
=== Non-dimensionalisation / scales ===&lt;br /&gt;
&lt;br /&gt;
The scales used are &lt;br /&gt;
* $R$, the radius of the pipe.&lt;br /&gt;
* $U_{cl}$, the centre-line velocity for laminar flow.&lt;br /&gt;
* $R/U_{cl}$ for time.&lt;br /&gt;
&lt;br /&gt;
In computational units, &lt;br /&gt;
* the non-dimensional radius is 1 and &lt;br /&gt;
* the non-dimensional laminar flow is $W(r)=1-r^2$.&lt;br /&gt;
&lt;br /&gt;
Note that $R=D/2$, where $D$ is the diameter.  When the bulk flow rate is fixed, so that the mean axial flow speed $U_b$ is constant, we have $U_{cl}=2U_b$.&lt;br /&gt;
&lt;br /&gt;
The streamwise wavenumber is $\alpha=2\pi/L$, where $L$ is the periodic length in units $R$.  In papers where $D$ has been used as the scale, $\alpha$ may have been defined to give consistent values, i.e. $\alpha=\pi/L$.&lt;br /&gt;
&lt;br /&gt;
For &#039;lab-units&#039;, based on $D$ and $U_b$,&lt;br /&gt;
* 1 advection time unit $D/U_b$ is equivalent to 4 code time units $R/U_{cl}$,&lt;br /&gt;
* the bulk velocity corresponds to $\frac{1}{2}$ in code units.&lt;br /&gt;
[[Table of unit conversions]].&lt;br /&gt;
&lt;br /&gt;
=== Dimensionless parameters ===&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed flux, $Re_m = 2 U_b R / \nu = DU_b / \nu$, where the kinematic viscosity $\nu = \mu / \rho$.&lt;br /&gt;
&lt;br /&gt;
Reynolds number, fixed pressure, $Re = U_{cl} R / \nu$.&lt;br /&gt;
&lt;br /&gt;
For fixed flux (constant flow rate), $U_{cl}=2\,U_b$ at all times.  The Reynolds number $Re_m$ is more commonly defined in terms of the constant mean speed $U_b$.&lt;br /&gt;
&lt;br /&gt;
For fixed pressure gradient, $U_b$ is a time-dependent quantity that depends on the flow pattern.  We define the Reynolds number $Re$ in terms of the unique $U_{cl}$ for the given pressure gradient.&lt;br /&gt;
&lt;br /&gt;
$1+\beta = Re / Re_m$ is an observed quantity.  For fixed flux, $1+\beta=\langle\partial p/\partial z\rangle \,/\, (dP/dz)$, where $(dP/dz)$ is the laminar pressure gradient and $\langle\partial p/\partial z\rangle$ is the average pressure gradient observed.  For fixed pressure, $1+\beta=U_{cl}/(2U_b)$, where $U_b$ is the observed bulk speed.&lt;br /&gt;
&lt;br /&gt;
The &#039;wall-Reynolds number&#039; $Re_\tau=u_\tau R/\nu$, where $u_\tau$ is the &#039;wall-velocity&#039; [https://en.wikipedia.org/wiki/Shear_velocity], &lt;br /&gt;
is given by $Re_\tau = (2\,Re_m\,(1+\beta))^\frac{1}{2}=(2\,Re)^\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
=== Evolution equations ===&lt;br /&gt;
&lt;br /&gt;
Fixed flux,&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey_m}\,(1+\beta)\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey_m}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Fixed pressure&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} + \vec{u}\cdot\bnabla) \vec{u}&lt;br /&gt;
= -\bnabla \hat{p} + \frac{4}{\Rey}\vechat{z}&lt;br /&gt;
+ \frac{1}{\Rey}\bnabla^2 \vec{u} $&lt;br /&gt;
and&lt;br /&gt;
$\bnabla\cdot\vec{u}=0$.&lt;br /&gt;
&lt;br /&gt;
Let $\vec{u}=W(r)\vechat{z}+\vec{u}&#039;$. Using the scaling above, the laminar flow is $W(r) = 1-r^2$. The&lt;br /&gt;
equation, in rotational form, for the evolution of the perturbation $\vec{u}&#039;$ is then&lt;br /&gt;
&lt;br /&gt;
$ (\partial_{t} - \frac{1}{\Rey_m}\bnabla^2)\,\vec{u}&#039; &lt;br /&gt;
= \vec{u}&#039; \wedge (\bnabla \wedge\vec{u}&#039;) &lt;br /&gt;
- \frac{\mathrm{d}W}{\mathrm{d}r}\,u&#039;_r \vechat{z}&lt;br /&gt;
- W\,\partial_{z}\vec{u}&#039; + \frac{4\,\beta}{\Rey_m}\vechat{z} - \bnabla\hat{p}&#039; \, . $&lt;br /&gt;
&lt;br /&gt;
== Boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
The no-slip boundary conditions are $\vec{u}=\vec{0}$ at the wall, $r=1$.&lt;br /&gt;
There is no boundary condition explicitly on the pressure.  Indirectly, the pressure must ensure that &lt;br /&gt;
$\bnabla\cdot\vec{u}=0$ is satisfied everywhere, i.e. also on the boundary.  &lt;br /&gt;
&lt;br /&gt;
At the axis $r=0$, symmetry implies that functions are odd or even across the axis.  For a Fourier mode with azimuthal index $m$, each mode is odd/even if $m$ is odd/even for the variables $u_z$ and $p$ (and other scalars).  For $u_r$ and $u_\theta$, each mode is even/odd if $m$ is odd/even.&lt;br /&gt;
&lt;br /&gt;
== Decoupling the equations ==&lt;br /&gt;
&lt;br /&gt;
The equations for $u_r$ and $u_\theta$ are coupled in the [[Differential_operators_in_cylindrical_coordinates#Laplacian|Laplacian]]. They can be separated in a Fourier decompositon by considering&lt;br /&gt;
&lt;br /&gt;
$u_\pm = u_r \pm \mathrm{i} \, u_\theta,$&lt;br /&gt;
&lt;br /&gt;
for which the $\pm$ are considered respectively. Original variables are easily recovered&lt;br /&gt;
&lt;br /&gt;
$u_r = \frac{1}{2} ( u_+ + u_-),&lt;br /&gt;
\qquad&lt;br /&gt;
u_\theta = -\,\frac{\mathrm{i}}{2}(u_+ - u_- ) .$&lt;br /&gt;
&lt;br /&gt;
Governing equations are then decoupled in the linear part and take the form&lt;br /&gt;
&lt;br /&gt;
$\begin{eqnarray*}&lt;br /&gt;
(\partial_{t} - \nabla^2_\pm)\, u_\pm&lt;br /&gt;
&amp;amp; = &amp;amp;  N_\pm - (\bnabla p)_\pm , \\&lt;br /&gt;
(\partial_{t} - \nabla^2 )\, u_z&lt;br /&gt;
&amp;amp; = &amp;amp;  N_z - (\bnabla p)_z ,\end{eqnarray*}$&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
$\nabla^2_\pm = \nabla^2 - \frac{1}{r^2} &lt;br /&gt;
\pm \frac{2\,\mathrm{i}}{r^2}\partial_{\theta}$&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Table_of_unit_conversions&amp;diff=1081</id>
		<title>Table of unit conversions</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Table_of_unit_conversions&amp;diff=1081"/>
		<updated>2024-11-05T14:39:37Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
&lt;br /&gt;
To convert the value of a dimensionless variable in &#039;code&#039; units to &#039;lab&#039; units, multiply by $C$ from the following table&lt;br /&gt;
(&#039;code&#039; units are based on $R$ and $U_{cl}$, &#039;lab&#039; units are based on $D$ and $U_b$).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
E.g. for the variable $z$:   $~~z_\mathrm{lab} \,(D) = z_\mathrm{code} \,(R) = z_\mathrm{code} \,(\frac{1}{2}D)&lt;br /&gt;
~~\Rightarrow~~z_\mathrm{lab} = z_\mathrm{code} \times \frac{1}{2},~~$&lt;br /&gt;
i.e. $~z_\mathrm{lab} = z_\mathrm{code} \times C$  with $C=\frac{1}{2}$.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: For consistent streamwise wavenumber $\alpha$, papers using the length scale $R$ write $L=2\pi/\alpha$, while papers using $D$ usually write $L=\pi/\alpha$.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$\begin{array}{ccccl}&lt;br /&gt;
variable &amp;amp; \mbox{&#039;code&#039; units} &amp;amp; \mbox{&#039;lab&#039; units} &amp;amp; \mbox{conversion factor}~C &amp;amp; \mbox{comment}\\&lt;br /&gt;
\hline&lt;br /&gt;
r,z &amp;amp; R &amp;amp; D &amp;amp; \frac{1}{2} &amp;amp; \mbox{length}\\&lt;br /&gt;
\vec{u} &amp;amp; U_{cl} &amp;amp; U_b &amp;amp; 2 &amp;amp; \mbox{speed} \\&lt;br /&gt;
t &amp;amp; R/U_{cl} &amp;amp; D/U_b &amp;amp; \frac{1}{4} &amp;amp; \mbox{time} \\&lt;br /&gt;
\sigma &amp;amp; U_{cl}/R &amp;amp; U_b/D &amp;amp; 4 &amp;amp; \mbox{growth rate} \\&lt;br /&gt;
E &amp;amp; \rho\,U_{cl}^2\, R^3 &amp;amp; \rho\,U_b^2\,D^3 &amp;amp; \frac{1}{2} &amp;amp; \mbox{kinetic energy} \\&lt;br /&gt;
D &amp;amp; \rho\,U_{cl}^3\, R^2 &amp;amp; \rho\,U_b^3\,D^2 &amp;amp; 2 &amp;amp; \mbox{dissipation rate} \\&lt;br /&gt;
E&#039; &amp;amp; \rho\,U_{cl}^2\, R^2 &amp;amp; \rho\,U_b^2\,D^2 &amp;amp; 1 &amp;amp; \mbox{energy per unit length} \\&lt;br /&gt;
\tilde{E} &amp;amp; \rho\,U_{cl}^2 &amp;amp; \rho\,U_b^2 &amp;amp; 4 &amp;amp; \mbox{energy density}&lt;br /&gt;
\end{array}$&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
	<entry>
		<id>http://www.openpipeflow.org/index.php?title=Core_implementation&amp;diff=1080</id>
		<title>Core implementation</title>
		<link rel="alternate" type="text/html" href="http://www.openpipeflow.org/index.php?title=Core_implementation&amp;diff=1080"/>
		<updated>2024-03-27T22:59:45Z</updated>

		<summary type="html">&lt;p&gt;Apwillis: /* How the parallelisation works */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{latexPreamble}}&lt;br /&gt;
&lt;br /&gt;
= Spatial representation =&lt;br /&gt;
&lt;br /&gt;
== Finite difference stencil — $r$ ==&lt;br /&gt;
&lt;br /&gt;
A function $p(r)$ is represented by the values $p_n=p(r_n)$, where $p(r)$ is evaluated on the $N$ radial points $r_n$; $n=1..N$.&lt;br /&gt;
There is no point on the axis $r=0$ to avoid singularities in $1/r$ terms.&lt;br /&gt;
The points are located at the roots of a Tchebyshev polynomial, such that they are clustered near the wall, and slightly so near the axis to compensate for loss of order in the calculation of derivatives. (They are calculated using banded matrices, implying use of fewer points at the axis and boundary).&lt;br /&gt;
&lt;br /&gt;
=== Differentiation ===&lt;br /&gt;
&lt;br /&gt;
Consider Taylor expansions about central point $x_0$, with $k$ neighbouring points each side&lt;br /&gt;
&lt;br /&gt;
[[File:fd_deriv.png|500px]]&lt;br /&gt;
&lt;br /&gt;
These expansions can be written&lt;br /&gt;
&lt;br /&gt;
[[File:fd_deriv_vec.png||500px]]&lt;br /&gt;
&lt;br /&gt;
Derivatives are calculated using weights from the appropriate row of $A^{-1}$.&lt;br /&gt;
&lt;br /&gt;
=== Integration ===&lt;br /&gt;
&lt;br /&gt;
Integrating the expansions above, from $x_0$ to $x$, the indefinite integral may be approximated about $x_0$:&lt;br /&gt;
&lt;br /&gt;
[[File:fd_int.png|500px]]&lt;br /&gt;
&lt;br /&gt;
The total integral is approximated by&lt;br /&gt;
&lt;br /&gt;
$   \frac1{2} \sum_n \int_{x_{n-1}}^{x_{n+1}} f(x) \, {\mathrm d}x$&lt;br /&gt;
&lt;br /&gt;
=== Matrix representation of linear operators ===&lt;br /&gt;
&lt;br /&gt;
Linear equations can be written in the matrix form&lt;br /&gt;
&lt;br /&gt;
$\mat{L} \,\vec{p} = \mat{M}\, \vec{q} + \vec{s}.$&lt;br /&gt;
&lt;br /&gt;
$\mat{L}$ and $\mat{M}$ are $N\times N$ matrices representing linear operators. If $\vec{q}$ and $\vec{s}$ are known then the right-hand side is simple to evaluate. Consider the equation&lt;br /&gt;
&lt;br /&gt;
$\label{eq:matmod}&lt;br /&gt;
\mat{L}\, \vec{p} = \vec{q},$&lt;br /&gt;
&lt;br /&gt;
where $\vec{p}$ is unknown. If the matrix operators are formed by linear combinations of the weights in [[#Differentiation]], using only $k$ neighbouring points to each side, they are banded. Boundary conditions are formed in the same way and are placed in the end rows. The equation is solved by forward-backward substitution, using the banded LU-factorisation of $\mat{L}$.&lt;br /&gt;
&lt;br /&gt;
figure=LU.eps, scale=0.65&lt;br /&gt;
&lt;br /&gt;
== Fourier representaion — $\theta$, $z$ ==&lt;br /&gt;
&lt;br /&gt;
=== Expansion of variables ===&lt;br /&gt;
&lt;br /&gt;
$A(\theta,z) =&lt;br /&gt;
\sum_{|k|&amp;lt;K}\sum_{|m|&amp;lt;M}\, A_{km} {\mathrm e}^{{\mathrm i} (\alpha kz + m_0 m\theta)}$&lt;br /&gt;
&lt;br /&gt;
$A$ real implies $A_{km} = A_{-k,-m}^*$ (coefficients are conjugate-symmetric). It is sufficient to keep only $m\ge 0$, and for $m=0$ keep $k\ge 0$.&lt;br /&gt;
&lt;br /&gt;
=== Implied conditions on the axis ===&lt;br /&gt;
&lt;br /&gt;
The geometry enforces conditions on each variable at the axis when expanded over Fourier modes in $\theta$. For scalars and the $z$-component of a vector $A_z$, each mode is even in $r$ if $m$ is even, and is odd if $m$ is odd. Each mode for $A_r$ and $A_\theta$ is even in $r$ if $m$ is odd, and is odd if $m$ is even.  This implies that either the function or its derivative is zero on the axis.&lt;br /&gt;
&lt;br /&gt;
=== Orthogonality ===&lt;br /&gt;
&lt;br /&gt;
Exponentials&lt;br /&gt;
&lt;br /&gt;
$\int_0^{2\pi} {\mathrm e}^{{\mathrm i}(m+n)} \, {\mathrm d}\theta &lt;br /&gt;
= 2\pi \, \delta_{m,-n}\, ,&lt;br /&gt;
\qquad&lt;br /&gt;
\int_0^{\frac{2\pi}{\alpha}} {\mathrm e}^{{\mathrm i}\alpha(k+j)} \, {\mathrm d}z &lt;br /&gt;
= \frac{2\pi}{\alpha} \, \delta_{k,-j}$&lt;br /&gt;
&lt;br /&gt;
=== Volume integral ===&lt;br /&gt;
&lt;br /&gt;
$E \, = \, &lt;br /&gt;
\int A \, {\mathrm d}V &lt;br /&gt;
\, = \,&lt;br /&gt;
\frac{4\pi^2}{\alpha} \, \int A_{00} \, r\,{\mathrm d}r$&lt;br /&gt;
&lt;br /&gt;
=== Energy integral ===&lt;br /&gt;
&lt;br /&gt;
$E \, = \, &lt;br /&gt;
{\textstyle \frac1{2}} \int \vec{A} \cdot \vec{A} \, {\mathrm d}V &lt;br /&gt;
\, = \,&lt;br /&gt;
\frac{2\pi^2}{\alpha} \, \sum_{km}&lt;br /&gt;
\int |\vec{A}_{km}|^2 \, r\,{\mathrm d}r$&lt;br /&gt;
&lt;br /&gt;
$E = \sum_{m\ge 0} E_m,&lt;br /&gt;
\qquad&lt;br /&gt;
E_m =&lt;br /&gt;
\left\{&lt;br /&gt;
\begin{array}{ll}&lt;br /&gt;
\displaystyle&lt;br /&gt;
\frac{2\pi^2}{\alpha}\int\vec{A}_{00}^2 \, r \, {\mathrm d}r&lt;br /&gt;
+ \frac{4\pi^2}{\alpha} \sum_{k&amp;gt;0}&lt;br /&gt;
\int|\vec{A}_{k0}^2| \, r \, {\mathrm d}r,&lt;br /&gt;
&amp;amp; m=0, \\[15pt]&lt;br /&gt;
\displaystyle&lt;br /&gt;
\frac{4\pi^2}{\alpha} \sum_k &lt;br /&gt;
\int |\vec{A}_{km}|^2 \, r \, {\mathrm d}r,&lt;br /&gt;
&amp;amp; m&amp;gt;0 .&lt;br /&gt;
\end{array}&lt;br /&gt;
\right.$&lt;br /&gt;
&lt;br /&gt;
= Temporal discretisation =&lt;br /&gt;
&lt;br /&gt;
Temporal discritisation is via a second-order Predictor-Corrector scheme, with Euler predictor for the nonlinear terms and Crank-Nicolson corrector.  The linear viscous term is treated implicitly with the Crank-Nicolson term.&lt;br /&gt;
&lt;br /&gt;
== PPE-formulation with correct boundary conditions ==&lt;br /&gt;
&lt;br /&gt;
An influence-matrix technique is used to avoid issues in satisfying the boundary conditions.  See [[The_PPE_formulation]].&lt;br /&gt;
&lt;br /&gt;
== Predictor-corrector ==&lt;br /&gt;
&lt;br /&gt;
The model equation for each Fourier mode is&lt;br /&gt;
&lt;br /&gt;
$\label{eq:harmmod}&lt;br /&gt;
(\partial_{t} - \nabla^2) f = N,$&lt;br /&gt;
&lt;br /&gt;
where nonlinear terms have been evaluated on each radial point by the transform method, and is solved as in [[#Matrix_representation_of_linear_operators]]. The predictor at time $t_q$, with Euler nonlinear terms and implicitness $c$&lt;br /&gt;
&lt;br /&gt;
$\frac{f_1^{q+1}-f^q}{\Delta t}&lt;br /&gt;
- \left( c\nabla^2 f_1^{q+1} + (1-c)\nabla^2 f^q \right)&lt;br /&gt;
= N^q ,$&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_1^{q+1}&lt;br /&gt;
= \left( \frac1{\Delta t} + (1-c)\nabla^2 \right) f^q + N^q .$&lt;br /&gt;
&lt;br /&gt;
Corrector iterations are&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_{j+1}^{q+1}&lt;br /&gt;
= \left( \frac1{\Delta t} + (1-c)\nabla^2 \right) f^q&lt;br /&gt;
+ c\,N_j^{q+1} + (1-c)\, N^q ,$&lt;br /&gt;
&lt;br /&gt;
or equivalently, for the correction $f_{corr} = f_{j+1}^{q+1} - f_j^{q+1}$&lt;br /&gt;
&lt;br /&gt;
$\left( \frac1{\Delta t} - c\nabla^2 \right) f_{corr}&lt;br /&gt;
= c\,N_j^{q+1} - c\, N_{j-1}^{q+1} ,$&lt;br /&gt;
&lt;br /&gt;
where $j=1,2,\dots$ and $N_0^{q+1}=N^q$. The size of the correction $\|f_{corr}\|$ must reduce at each iteration. For $c=\frac1{2}$ the scheme is second order such that $\|f_{corr}\| \sim \Delta t^2$.  Stability is improved without observable degradation in accuracy using $c=0.501$ .&lt;br /&gt;
&lt;br /&gt;
== Timestep control ==&lt;br /&gt;
&lt;br /&gt;
$\Delta t = \mathrm{C} \, \min(\Delta \, / \, |\vec{v}| ) ,&lt;br /&gt;
\qquad &lt;br /&gt;
0&amp;lt;\mathrm{C}&amp;lt;1,$&lt;br /&gt;
&lt;br /&gt;
where $\mathrm{C}$ is the Courant number.&lt;br /&gt;
&lt;br /&gt;
The timestep should also be small enough such that the corrector norm $\|f_{corr}\|$ is satisfactorily small. This may be important for integrating initial transients, but ought not to be the limiting factor in general.&lt;br /&gt;
&lt;br /&gt;
= The code structure =&lt;br /&gt;
&lt;br /&gt;
[[File:modules4.png]]&lt;br /&gt;
&lt;br /&gt;
== Overview of program files ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;parameters.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; declaration and values of parameters.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;&#039;&#039;&#039; macros for parallelisation; definition of loops for parallel+serial cases &amp;lt;tt&amp;gt;_loop_km_begin&amp;lt;/tt&amp;gt; etc.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;mpi.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; mpi initialisation.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;main.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; core initialisation, main timestepping loop, clean up at end.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; definition of radial discretisation.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;variables.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; definition of derived types for spectral- and physical-space data.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;transform.fftw3.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; transform from collocated spectral space to physical space.  Uses fftw3 library.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;timestep.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; subroutines to set up time stepping matrices.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;velocity.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; functions related to the velocity field; implementation of the timestepping and influence matrix method.&lt;br /&gt;
* &#039;&#039;&#039;&amp;lt;tt&amp;gt;io.f90&amp;lt;/tt&amp;gt;&#039;&#039;&#039; Input-Output: loading and saving of data.&lt;br /&gt;
&lt;br /&gt;
Each of the files contains a &#039;&amp;lt;tt&amp;gt;module&amp;lt;/tt&amp;gt;&#039;, declaring variables that may be used in other code via &#039;&amp;lt;tt&amp;gt;use modulename&amp;lt;/tt&amp;gt;&#039;.  With the exception of the fundamental parameters, the first three letters of the module name are used as a prefix in the name of public variables, to make the location of their declaration clear (see following section).&lt;br /&gt;
&lt;br /&gt;
== Naming conventions ==&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
&lt;br /&gt;
Parameters defined within &amp;lt;tt&amp;gt;parameters.f90&amp;lt;/tt&amp;gt; are given a prefix indicating the data type. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$N$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;i_N&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;integer&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$\Delta t$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;d_timestep&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;double&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;fixed flux?&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;b_fixed_flux&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;boolean&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the naming convention frees the variable name for dummy variables, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   integer :: n&lt;br /&gt;
   do n = 1, i_N&lt;br /&gt;
      ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Public variables ===&lt;br /&gt;
&lt;br /&gt;
By default variables declared within a module are accessible to any other module or subroutine that uses the module. To ensure that it is clear where a public variable is declared, variables are given a prefix. Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;odd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$\Delta t$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;tim_dt&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;timestep.f90&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr class=&amp;quot;even&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;$u_r$&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;vel_r&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&amp;lt;tt&amp;gt;velocity.f90&amp;lt;/tt&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Ordering the Fourier modes ==&lt;br /&gt;
&lt;br /&gt;
$A = \sum_{|k|&amp;lt;K}\sum_{|m|&amp;lt;M}\, A_{km} {\mathrm e}^{{\mathrm i}(\alpha kz + m_0 m\theta)},$&lt;br /&gt;
&lt;br /&gt;
Coefficients $A_{km}$ are stored in an order according to the following loop, where&lt;br /&gt;
rather than two indices &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;m&amp;lt;/tt&amp;gt;, the single index &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt; labels the modes:&lt;br /&gt;
&lt;br /&gt;
[[File:km_loop_c.png|400px]]&lt;br /&gt;
&lt;br /&gt;
The index nh is as in the following table for the case K=6, M=4:&lt;br /&gt;
&lt;br /&gt;
[[File:Fourier_km.png|404px]]&lt;br /&gt;
&lt;br /&gt;
NOTES:&lt;br /&gt;
* &amp;lt;tt&amp;gt;nh = (2*K-1)*m + k&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* Loops for &amp;lt;tt&amp;gt;m&amp;lt;0&amp;lt;/tt&amp;gt; are skipped.  Values of coefficients for &amp;lt;tt&amp;gt;m&amp;lt;0&amp;lt;/tt&amp;gt; are inferred from the conjugate symmetric property, $A_{km}=A_{-k,-m}^*$.  Similarly for &amp;lt;tt&amp;gt;k&amp;lt;0&amp;lt;/tt&amp;gt; when &amp;lt;tt&amp;gt;m==0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* This loop is a predefined macro in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;.  The macro &amp;lt;tt&amp;gt;_loop_km_begin&amp;lt;/tt&amp;gt; replaces the double-loop above (or its equivalent for parallel computation).&lt;br /&gt;
&lt;br /&gt;
== Data types ==&lt;br /&gt;
&lt;br /&gt;
The data types below consist of logical data groups to facilitate the passing of data between functions. For clarity, in the following text they are defined as though we were working on a single processor. See [[#Modifications_for_the_parallel_implementation|Parallel]] regarding subtle differences in the definitions due to parallelisation.&lt;br /&gt;
&lt;br /&gt;
The most important data types are &amp;lt;tt&amp;gt;type (coll) &amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt; type (phys)&amp;lt;/tt&amp;gt;.  The transform between the two types is achieved with calls to &amp;lt;tt&amp;gt;tra_coll2phys(...)&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;tra_phys2coll(...)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== coll, spec — storage of coefficients ===&lt;br /&gt;
&lt;br /&gt;
The collocated data &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; is the principle type used for mode-independent operations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type coll&lt;br /&gt;
      double precision     :: Re(i_N, 0:i_H1)&lt;br /&gt;
      double precision     :: Im(i_N, 0:i_H1)&lt;br /&gt;
   end type coll&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;Re(n,nh)&amp;lt;/tt&amp;gt; is the real part of the &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt;$^{\mathrm{th}}$ harmonic evaluated at $r_n$. &lt;br /&gt;
&lt;br /&gt;
The spectral &amp;lt;tt&amp;gt;type (spec)&amp;lt;/tt&amp;gt; is a data type for operations independent at each radial point. It is rarely used other than as a transitory data format between the &amp;lt;tt&amp;gt;coll&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;phys&amp;lt;/tt&amp;gt; types.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type spec&lt;br /&gt;
      double precision     :: Re(0:i_H1, i_N)&lt;br /&gt;
      double precision     :: Im(0:i_H1, i_N)&lt;br /&gt;
   end type spec&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== phys — real space data ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; is used for data in real space.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type phys&lt;br /&gt;
      double precision     :: Re(0:i_Z-1, 0:i_Th-1, i_N)&lt;br /&gt;
   end type phys&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;Re(k,m,n)&amp;lt;/tt&amp;gt; refers to the value at $z_k$, $\theta_m$ and $r_n$.&lt;br /&gt;
&lt;br /&gt;
=== rdom — the radial domain ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;type (rdom)&amp;lt;/tt&amp;gt; contains information about the radial domain. The public variable &amp;lt;tt&amp;gt;mes_D&amp;lt;/tt&amp;gt; is declared in &amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;. Data includes the number of radial points &amp;lt;tt&amp;gt;mes_D%N&amp;lt;/tt&amp;gt;, powers of $r$, $r_n^p$=&amp;lt;tt&amp;gt;mes_D%r(n,p)&amp;lt;/tt&amp;gt;, weights for integration &lt;br /&gt;
$\int_0^1 f(r)\,r\,{\mathrm d}r$=&amp;lt;tt&amp;gt;dot_product(f(1:i_N),mes_D%intrdr)&amp;lt;/tt&amp;gt;, matrices for taking the $p^{\mathrm{th}}$ derivative and more:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type rdom&lt;br /&gt;
      integer          :: N&lt;br /&gt;
      double precision :: r(i_N,i_rpowmin:i_rpowmax)&lt;br /&gt;
      double precision :: intrdr(i_N)&lt;br /&gt;
      type (mesh)      :: dr(i_KL)&lt;br /&gt;
      ...&lt;br /&gt;
   end type rdom&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mesh, lumesh — storage of banded matrices ===&lt;br /&gt;
&lt;br /&gt;
The finite-difference stencil has finite width ([[#Finite_differences_.E2.80.94_.24r.24|Finite_Differences]]) and so matrix operations involve matrices that are banded. The &amp;lt;tt&amp;gt;type (mesh)&amp;lt;/tt&amp;gt;, defined in &amp;lt;tt&amp;gt;meshs.f90&amp;lt;/tt&amp;gt;, is used for matrices on the radial mesh involving $kl$ points to either side of each node.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type mesh&lt;br /&gt;
      double precision :: M(2*i_KL+1, i_N)&lt;br /&gt;
   end type mesh&amp;lt;/pre&amp;gt;&lt;br /&gt;
For a matrix &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, the element &amp;lt;tt&amp;gt;M(KL+1+n-j, j) = A(n,j)&amp;lt;/tt&amp;gt;. See the man page for the lapack routine &amp;lt;tt&amp;gt;dgbtrf&amp;lt;/tt&amp;gt;. The LU-factorisation of a banded matrix is also banded:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   type lumesh&lt;br /&gt;
      integer          :: ipiv(i_N)&lt;br /&gt;
      double precision :: M(3*i_KL+1, i_N)&lt;br /&gt;
   end type lumesh&amp;lt;/pre&amp;gt;&lt;br /&gt;
The element &amp;lt;tt&amp;gt;M(2*KL+1+n-j, j) = A(n,j)&amp;lt;/tt&amp;gt;. Pivoting information is stored along with the matrix.&lt;br /&gt;
&lt;br /&gt;
== Modifications for the parallel implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Practical things to remember ===&lt;br /&gt;
&lt;br /&gt;
The code has been parallelised using the Message Passing Interface (MPI) in a way designed to be as unintrusive as possible. Sections of the code with special MPI function calls are separated from the serial sections by preprocessor directives. The number of processors is given by the parameter &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt; set in &amp;lt;tt&amp;gt;parallel.h&amp;lt;/tt&amp;gt;. The rank of a process is given by &amp;lt;tt&amp;gt;mpi_rnk&amp;lt;/tt&amp;gt; declared in &amp;lt;tt&amp;gt;mpi.f90&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;mpi_sze&amp;lt;/tt&amp;gt;$=$&amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For modest parallelisations, it is recommended to vary &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and to keep &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt; (radial split only).  This ensures a couple of conditions are met that could easily be forgotten when setting up a run, namely that &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; must divide both &amp;lt;tt&amp;gt;i_Z&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;i_M&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How the data is distributed ===&lt;br /&gt;
&lt;br /&gt;
The linear parts of the code (evaluating curls, gradients and matrix inversions for the timestepping) involve operations that do not couple Fourier modes.  The &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; holds all radial points for a subset of Fourier modes - the Fourier modes are distributed over the cores.&lt;br /&gt;
&lt;br /&gt;
Products are evaluated in physical space.  Here the data is split over &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; sections in $r$ and over &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; sections in $z$.  The &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; holds all azimuthal points for a &lt;br /&gt;
given subsection in $r$ and $z$.  The following is an example of rank id numbers (&amp;lt;tt&amp;gt;mpi_rnk&amp;lt;/tt&amp;gt;) for the case &amp;lt;tt&amp;gt;_Nr=3&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;_Ns=4&amp;lt;/tt&amp;gt; ($r$ downwards, $z$ left to right):&lt;br /&gt;
  0   3   6   9&lt;br /&gt;
  1   4   7  10&lt;br /&gt;
  2   5   8  11&lt;br /&gt;
In physical space,&lt;br /&gt;
* Two cores have data for the same $z$-section if &amp;lt;tt&amp;gt;rank1/_Nr==rank2/_Nr&amp;lt;/tt&amp;gt; (integer arithmetic).&lt;br /&gt;
* Two cores have data for the same $r$-section if &amp;lt;tt&amp;gt;modulo(rank1,_Nr)==modulo(rank2,_Nr)&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== How the code is adapted ===&lt;br /&gt;
&lt;br /&gt;
In the definition of &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt; the parameter &amp;lt;tt&amp;gt;i_H1&amp;lt;/tt&amp;gt; is replaced by &amp;lt;tt&amp;gt;i_pH1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
 &lt;br /&gt;
In the definition of &amp;lt;tt&amp;gt;type (phys)&amp;lt;/tt&amp;gt; the parameters &amp;lt;tt&amp;gt;i_N,i_Z&amp;lt;/tt&amp;gt; are replaced by &amp;lt;tt&amp;gt;i_pN,i_pZ&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;i_pH1&amp;lt;/tt&amp;gt; is the maximum number of modes on an individual core.  The variable &amp;lt;tt&amp;gt;var_H&amp;lt;/tt&amp;gt; has elements to determine which harmonics are on which processor. The elements &amp;lt;tt&amp;gt;pH0&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pH1&amp;lt;/tt&amp;gt; are the zeroth index and the number of harmonics for the local process, minus one. The corresponding values for all processors are stored in the arrays &amp;lt;tt&amp;gt;pH0_(rank)&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pH1_(rank)&amp;lt;/tt&amp;gt;. For a variable of &amp;lt;tt&amp;gt;type (coll)&amp;lt;/tt&amp;gt;, valid values for the harmonic index in &amp;lt;tt&amp;gt;Re(n,nh)&amp;lt;/tt&amp;gt; are &amp;lt;tt&amp;gt;nh=0..pH1&amp;lt;/tt&amp;gt; but refer to the indices  &amp;lt;tt&amp;gt;nh=pH0..pH0+pH1&amp;lt;/tt&amp;gt; of the serial case, see [[#Ordering_the_Fourier_modes]].&lt;br /&gt;
&lt;br /&gt;
In physical space &amp;lt;tt&amp;gt;i_pN&amp;lt;/tt&amp;gt; is the maximum number of radial points for each process. The location of the radial subdomain on the local processor is given by additional elements of the variable &amp;lt;tt&amp;gt;mes_D&amp;lt;/tt&amp;gt;. The elements &amp;lt;tt&amp;gt;pNi&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pN&amp;lt;/tt&amp;gt; are the location of the first (inner) radial point and the number of points. The values for all processors are stored in the arrays &amp;lt;tt&amp;gt;pNi_(rank)&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;pN_(rank)&amp;lt;/tt&amp;gt;. For a variable of &amp;lt;tt&amp;gt;type (spec)&amp;lt;/tt&amp;gt;, valid values for the radial index in &amp;lt;tt&amp;gt;Re(nh,n)&amp;lt;/tt&amp;gt; are &amp;lt;tt&amp;gt;n&amp;lt;/tt&amp;gt;=&amp;lt;tt&amp;gt;1..pN&amp;lt;/tt&amp;gt; which refer to the indices of $r_n$, where $n$=&amp;lt;tt&amp;gt;pNi..pNi+pN-1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Also in physical space &amp;lt;tt&amp;gt;i_pZ&amp;lt;/tt&amp;gt; is exactly the number axial points held by the core.  Logically, the local index &amp;lt;tt&amp;gt;k&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;[0,i_pZ-1]&amp;lt;/tt&amp;gt;corresponds to index &amp;lt;tt&amp;gt;(mpi_rnk/_Ns)*i_pZ + k&amp;lt;/tt&amp;gt; (integer arithmetic) in &amp;lt;tt&amp;gt;[0,i_Z-1]&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The bulk of communication occurs during the data transposes in the functions &amp;lt;tt&amp;gt;var_coll2spec()&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;var_spec2coll()&amp;lt;/tt&amp;gt;. For the case &amp;lt;tt&amp;gt;_Np=_Nr, _Ns=1&amp;lt;/tt&amp;gt; the data is transferred in &amp;lt;tt&amp;gt;_Np-1&amp;lt;/tt&amp;gt; steps.  At each step each processor sends and receives a block of data, the source and destination are selected systematically as set in the following loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;   do step = 1, mpi_sze-1&lt;br /&gt;
      dest  = modulo(mpi_rnk+step, mpi_sze)&lt;br /&gt;
      src   = modulo(mpi_rnk-step+mpi_sze, mpi_sze) &lt;br /&gt;
      ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== How the parallelisation works ===&lt;br /&gt;
&lt;br /&gt;
In the Fourier space, all radial points for a particular Fourier mode are located on the same processor, separate modes may be located on separate processes.  For the case &amp;lt;tt&amp;gt;K=6, M=4, _Nr=3, _Ns=2,&amp;lt;/tt&amp;gt; the modes are split over &amp;lt;tt&amp;gt;_Np=_Nr*_Ns=6&amp;lt;/tt&amp;gt; cores (&amp;lt;tt&amp;gt;mpi_rnk=0..5&amp;lt;/tt&amp;gt;) indicated by the 6 coloured sections (each contiguous in &amp;lt;tt&amp;gt;nh&amp;lt;/tt&amp;gt;) in the following table:&lt;br /&gt;
&lt;br /&gt;
[[File:Fourier_km_par.png|404px]]&lt;br /&gt;
&lt;br /&gt;
Here, the m=0,1,2,3 are split into for &amp;lt;tt&amp;gt;_Ns=2&amp;lt;/tt&amp;gt; groups, m=0,1 and m=2,3, then each group is split into &amp;lt;tt&amp;gt;_Nr=3&amp;lt;/tt&amp;gt; sections indicated by the colours.&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;tt&amp;gt;_Ns=2&amp;lt;/tt&amp;gt;, split the 6 cores into two sets of three, denoted&lt;br /&gt;
$\{c_0,c_1,c_2\}$ and $\{c_3,c_4,c_5\}$.  &lt;br /&gt;
Prior to an FFT, the core $c_0$ gathers all Fourier coefficients from within the first set for a given &lt;br /&gt;
subset of radial points -- doing this for each core constitutes a transpose with in the set.&lt;br /&gt;
Having gathered these coefficients, sufficient data is present to perform the axial FFTs &lt;br /&gt;
(summing over the k for a given m).  &lt;br /&gt;
Now three sets of cores may be identified, arranged to have data for common &lt;br /&gt;
radial points in each set, $\{c_0,c_3\}$, $\{c_1,c_4\}$, $\{c_2,c_5\}$.&lt;br /&gt;
Within each set m is distributed, with&lt;br /&gt;
m=0,1 is on one core m=2,3 on the other.  Gathering the m for a&lt;br /&gt;
given subsection of axial points, constitutes a second transpose within each of these&lt;br /&gt;
sets.  Finally the azimuthal FFTs may be performed (sum over m).&lt;br /&gt;
The resulting data is split by both radial and axial position, whilst data for all azimuthal points are present on a given core.&lt;br /&gt;
&lt;br /&gt;
In the double parallelisation two transposes are required, and the total data sent is &lt;br /&gt;
doubled.  However, the number of messages required is&lt;br /&gt;
&amp;lt;tt&amp;gt;(_Ns-1)+(_Nr-1)&amp;lt;/tt&amp;gt; where &amp;lt;tt&amp;gt;_Np=_Nr*_Ns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Then, for a given $N_p=$&amp;lt;tt&amp;gt;_Np&amp;lt;/tt&amp;gt;, there are only approximately $\sqrt{N_p}$ messages when &amp;lt;tt&amp;gt;_Nr&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;_Ns&amp;lt;/tt&amp;gt; are approximately equal, versus $N_p$ messages when &amp;lt;tt&amp;gt;_Np=_Nr&amp;lt;/tt&amp;gt; (and &amp;lt;tt&amp;gt;_Ns=1&amp;lt;/tt&amp;gt;).&lt;br /&gt;
This can substantially reduce time lost in latency, the time setting up communications.  &lt;br /&gt;
There are fewer large messages, rather than many small ones.&lt;/div&gt;</summary>
		<author><name>Apwillis</name></author>
	</entry>
</feed>