-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathphd-dissertation-body.tex
1232 lines (888 loc) · 106 KB
/
phd-dissertation-body.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[12pt,upcase]{umlthesis}
\usepackage{lipsum}
\usepackage{natbib}
\usepackage{graphicx}
\usepackage{float}
\usepackage{hyperref}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{booktabs}
\def\code#1{\texttt{#1}}
% use fancyhdr, to enable page style stuff (below)
\usepackage{fancyhdr}
\setlength{\headheight}{15.2pt}
\renewcommand{\headrulewidth}{0pt}
\pagestyle{plain}
\begin{document}
\title{Two-Fluid Collisional Magnetohydrodynamic Modeling}
\author{Qusai Al Shidi}
\prevdegrees{B.S., University of Toledo (2012)}
\department{Department of Physics and Applied Physics}
\degree{Doctor of Philosophy}
\degreemonth{May}
\degreeyear{2019}
\thesisdate{May 1, 2019}
\supervisor{Ofer Cohen}{Assistant Professor}
\maketitle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{abstract}
Since the discovery of space plasmas, which are ionized gasses in outer space, the space science community have been deriving fluid models of plasmas to describe their properties and motion in various space environment and processes. The simplest case is the ideal magnetohydrodynamic (MHD) model which assumes a collisionless perfectly-conducting plasma under the influence of electromagnetic fields. Multi-fluid collisional MHD treats each fluid with its own set of MHD equations while using collisions to describe the mass, momentum, and energy interactions among them in processes such as friction and resistivity. One of the important examples of such multi-fluid plasma medium is the solar chromosphere. The high density and relatively cold plasma result in a partially ionized medium with strong collisions among different species so that the collision times are shorter than characteristic time scales of charged particles moving in the electromagnetic field. Multi-fluid collisional MHD has many cases from the Earth's ionosphere to stellar atmosphere and having a good grasp of the physics is important in studying these plasmas.
In this dissertation I go through the physics of collisional plasmas, designing the Collisional Multi-Fluid ion (CoMFi) code, with scientific computing principles, and its application on the solar chromosphere. With this simulation I found that it is possible for shocks and jets to form in the lower solar chromosphere through frictional heating alone and not with magnetic reconnection.
\end{abstract}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter*{Acknowledgements}
To my partner Alexis Ploss, who believed in me without judgment or apprehension. To my family, that supported me beyond the ocean. To my dog Ada Lovelace, that provided emotional support through the hardships.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\tableofcontents
\listoffigures
\listoftables
\chapter{Introduction}
The word `plasma' was first used by \citet{Langmuir1928} to describe oscillations in a gaseous electron medium~\citep{Tonks1967}. It is a state of matter that is can be described as an ionized gas. It is the most common form of baryonic matter in the universe. We default to plasma descriptions of the medium between stars and planets. The sun is, for example, made mostly of ionized hot plasma. It is made of plasma and shoots out supersonic plasma called the solar wind. This plasma does not entirely contact the Earth due to shielding resulting from the Earth's magnetic field. Due to plasma's ionization, it has a tendency to travel on magnetic field lines. This does not mean the Earth is completely shielded from the solar wind. Many space weather events are due to solar plasma's effect on the Earth and its magnetic field. The sun is a very active star that has spontaneous flares, coronal mass ejections (CME) and active regions. Thus spontaneous storms occur on Earth and our understanding of the sun and space plasmas is essential to protect ourself against storms.
In this dissertation, an attempt will be made to show the benefits and utility of multi-fluid magnetohydrodynamic (MHD) models. We will show that the solar chromosphere is a good case for this. The implementation will also be studied with careful use of good, modern computer science practices.
\section{The Sun}
\begin{figure}[h!]\label{fig:sunstructure}
\centering
\includegraphics[width=1.0\linewidth]{images/sunstructure.png}
\caption{A more complicated view of the sun's structure and layers. [{Image from \url{https://phys.org/}}]} % chktex 8
\end{figure}
Whenever I say `the sun' I do not mean any star---I mean \textit{our} star. The sun is a 4.6 billion year old yellow dwarf. It generates a lot of the energy we use for life on Earth. It creates this energy through nuclear fusion in its core, turning hydrogen into helium. The sun is mostly hydrogen with a small amount of helium and even smaller amounts of metal ions which require tremendous energy to fuse. The sun has six regions (from innermost to outermost): the core, the radiative zone, the convection zone, the photosphere, the chromosphere and the corona. The core is where the fusion happens. Here is where hydrogen is made into helium and other metals. The radiative zone and convection zone is where the energy travels radially upwards to wards the surface, the photosphere. The photosphere is the surface of the Sun. Here photons are trapped but the ones that do escape mimic black-body radiation (not perfectly). It is optically thick and is the white light we see when looking at the Sun. Above the photosphere is the atmospheric layer, the chromosphere, which I will go in much detail about in this dissertation. Above that, is the corona which is what gives the sun its tendrils and the hair we give our cartoon drawings of the sun.
\subsection{The Chromosphere}
The chromosphere is the interface between the surface, the photosphere, and the outer atmosphere, the corona. The plasma in it is partially ionized which means it consists of two kinds of plasma: ionized (charged) plasma, and neutral (uncharged) gas. This means the charged particles are affected by Lorentz forces while the uncharged particles are not. This is a result of the temperature of the chromosphere and the composition of the plasma convected in the convection zone. The plasma has a high temperature in Earth standards but to the sun it is relatively cold. The temperature of the corona, which keep in mind is the outermost layer, is in the million of degrees in Kelvin. While most of the chromosphere and the photosphere is 5000K-6500K. This discrepancy in the temperature of the lower layers to the higher layers is called the coronal heating problem. The coronal heating problem is an outstanding problem in physics which makes understanding the chromosphere of special importance. Why is the corona hotter than the chromosphere? This work aims to shed light on this unsolved problem in solar physics.
\begin{figure}[ht!]\label{fig:chromoprofile}
\centering
\includegraphics[width=0.75\linewidth]{images/chromoprofile.jpg}
\caption{A view of the upper, middle and lower chromosphere. The chromosphere is partially ionized and is much colder than the corona (above the transition region).~\citep{Song2014,Avrett2008}}
\end{figure}
\section{Space Weather}
The term space weather refers to weather effects found above our immediate atmosphere which is conversely named terrestrial weather. It focuses on the conditions and changes found between the Sun, the Earth and even behind the Earth along its night time. The Earth's surface magnetic field strength is in the 0.5G range~\citep{Finlay2010} and that is strong enough to shield most of the solar wind headed our direction. However, magnetic reconnection events between the Earth's magnetosphere (the sphere of Earth's magnetic influence) and the interstellar medium allows solar wind particles to enter the Earth's atmosphere. Massive eruptions from the sun can affect the Earth's magnetic fields. These solar events manifest itself in harmless weather, like auroras, or more harmful weather, like geomagnetic storms.
\subsection{Motivation: A storm is coming}
In 1859, a famous (or infamous) geomagnetic storm hit the Earth. Fortunately, we did not sprawl global electrical power grids at the time or it would have had devastating effects. It was caused by a CME observed by Richard C. Carrington and was thusly named the Carrington Event. Depending on the strength of the geomagnetic storm (which happens frequently at higher/lower latitudes due to night side reconnection) it may reach mid-latitude areas which we inhabit. Here geomagnetic storms due to the quick changes in magnetic fields and the law of induction cause ground induced currents (GIC) that can have damaging effects to any ground based electrical devices.
The Carrington event was our last encounter with a storm of that scale, that does not mean we have not had any near misses. In 2012, a coronal mass ejection that has the strength and size comparable to the previously mentioned Carrington event almost hit the Earth. It missed the Earth by nine days~\citep{Baker2013}. Unlike in 1859, the world of 2012 was filled with electrical power grids. The internet is part of our daily lives and still relies on ground based electrical wiring.
A report by Predictive Science Inc.\ shows that the chance of another Carrington level storm striking the earth between 2012 and 2022 is 12\%~\citep{riley2012}.
\subsection{Where does the chromosphere fit into this?}
Since the chromosphere is the intermediary layer between the surface and the coronal with entirely difference physics, this means it is unfair to disentangle solar events from it.
An important solar event that deals with the chromosphere are solar flares. Solar flares are sometimes accompanied by CMEs. Solar flares are bright flashes that usually occur near sun-spots. They emit electromagnetic energy of the order of $10^{20}$ joules. Their x-rays can cause disruptions in communication devices on Earth like GPS satellites since it can have effects on the Earth's ionosphere.
A magnetic reconnection even close to the upper chromosphere may cause flares, and the physics of the upper chromosphere is very different than that of the corona. For example the former is occuring in partially ionized plasma and the latter in a fully ionized one.
Filaments are a feature found in chromosphere of dense cool plasma that are associated by bright emissions in the chromosphere. These filaments can sometimes shoot off into the solar wind by a CME\@.
\begin{figure}[ht!]
\centering
\includegraphics[width=0.5\textwidth]{images/filament.jpg}
\caption{Filaments. These are images taken in H-alpha. [Image taken from https://solarscience.msfc.nasa.gov/]}\label{fig:filament} % chktex8
\end{figure}
Since the chromosphere is a relatively understudied part of the chromosphere but still has an important role in space weather, this dissertation will focus on how to model, simulate, and study such a region while at the same time focussing on modern techniques of scientific computing.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Methodology}\label{chap:methodology}
Although plasmas are classically defined as charged gasses, they can coexist with neutral plasma based on the temperature and pressure conditions surrounding them. This means I have two gas mediums, one with the ability to feel Lorentz forces and another that acts like a non-charged fluid. This will generate friction between the fluids when they are moving at different velocities. Due to collision rates being proportional to fluid density and temperature, there can exist a limit in which collision rates are larger than ionization/recombination rates of ions and therefore the fluid becomes collisional. In the reverse case a single-fluid is an apt description as the existence of two-fluids matters largely on the chemistry rather than the collisions. We will be focusing on hydrogen plasmas for our chromosphere case in Section~\ref{sec:chromosphere} and in that case two-fluids will be investigated.
\section{Magnetohydrodynamics}\label{sec:mhd}
Magnetohydrodynamics (MHD) is a fluid approximation of plasma popular amongst macroscopic studies of space plasmas. In order to arrive at the fluid approximation I must first look at the particles first and ensure the approximation is appropriate for our case. All of physics is a model and to go from the kinetic theory of plasmas by modeling particles to MHD plasmas by modeling fluids there must be a derivation since there are less assumptions in the kinetic theory than there are in MHD\@.
\subsection{Kinetic Theory}\label{sec:kinetictheory}
We start by assuming an ensemble phase space of particles $f(\textbf{x}, \textbf{v}, t)$ called the distribution function. $\textbf{x}$ is the location of the particle distribution in space, $\textbf{v}$ is the velocity distribution and $t$ is the time. To study the distribution function's evolution through time I take the full derivative with respect to time $\frac{df}{dt}$ which by the product rule turns out to be:
\begin{equation}
\frac{\partial f}{\partial t} + \frac{\partial \textbf{x}}{\partial t} \cdot \nabla_{\textbf{x}} f + \frac{\partial \textbf{v}}{\partial t} \cdot \nabla_{\textbf{v}} f = {(\frac{\delta f}{\delta t})}_{collisions}
\end{equation}
This is called the Boltzmann equation~\citep{lerner2005}. The term on the right hand side exists due to collisions changed the distribution function in its own way, this also include collisional ionization and other collisional effects that would change the distribution of particles. Simplifying the equation further by substituting how I expect the bulk particles to interact with fields I can get:
\begin{equation}
\frac{\partial f}{\partial t} + \textbf{v} \cdot \nabla_{\textbf{x}} f + \frac{q}{m} (\textbf{E} + \textbf{v} \times \textbf{B}) \cdot \nabla_{\textbf{v}} f = {(\frac{\delta f}{\delta t})}_{collisions}
\end{equation}
Where $q$ is the charge of the particle, $m$ is the mass of the particle, $\textbf{E}$ is the electric field and $\textbf{B}$ is the magnetic field.
This is the kinetic theory of plasmas. The assumptions made here are probability distributions of particles instead of singular particle effects. There are simulations and codes that model particles directly but because of the large memory size of such simulations the region of study must be very small.
\subsection{Moments of the Distribution}\label{sec:moments}
In order to arrive at the macroscopic variables I must make an assumption about the distribution of the fluid. This is the most fundamental assumption of MHD is that the distribution of the particles are behaving like a Maxwellian velocity distribution~\citep{mandl1988}. If it is not the case that the velocity distribution is Maxwellian then the approach of MHD is challenged and must be rewritten and integrated differently. The Maxwellian velocity distribution is common in space plasmas that are in thermal equilibrium with itself which lends to the popularity of MHD\@.
\begin{equation}
f(v) = n {(\frac{m}{2\pi k_B T})}^{3/2} \exp{(-\frac{mv^2}{2k_B T})}
\end{equation}
Where $v = |\textbf{v}|$ is the speed, $k_B$ is the Boltzmann constant and $T$ is temperature. This is assuming a Maxwellian velocity distribution over a thermal equilibrium and a thermal speed.
To arrive at the MHD equations I start to take the `velocity moments' of the equations in order to have macroscopic variables that don't depend on phase speed.
\begin{equation}
{Moment}_a(\textbf{x}, t) = \int{\textbf{v}^a f(\textbf{x}, \textbf{v}, t)}d\textbf{v}
\end{equation}
Here $a$ is the order of the moment. The first few moments are of interest. The zeroth moment is the continuity equation.
\begin{equation}\label{eq:continuityequation}
\frac{\partial n_s}{\partial t} + \nabla \cdot (n_s \textbf{v}_s) = {(\frac{\delta n_s}{\delta t})}_{source}
\end{equation}
Each species, $s$, of fluid has its own continuity equations but may be related by the source terms. The source terms come from integrating the collisional ionization, radiative recombination, etc.
The first order moment will give us the momentum equations:
\begin{equation}\label{eq:momentumequation}
\frac{\partial n_s \textbf{v}_s}{\partial t} + \nabla \cdot (n_s \textbf{v}_s \textbf{v}_s + \frac{\textbf{P}_s}{m_s} ) -n_s \frac{q}{m_s}(\textbf{E} + \textbf{v}_s \times \textbf{B}) = {(\frac{\delta n_s \textbf{v}_s}{\delta t})}_{source}
\end{equation}
Where $\textbf{P}_s$ is the kinetic pressure tensor and can be simplified to the ideal gas law $P_s\textbf{I} = n_s k_B T_s \textbf{I}$ if applicable. The source terms due to the zeroth order also exists here as well as frictional terms that may appear in multi-fluid cases. It is apparent that this equation is fluid-like, a form of the Navier-Stokes equation and hence the naming of these equations as hydrodynamic.
To close the system equations I need one more for the pressure shown previously. So integrating for the second moment gives:
\begin{equation}\label{eq:energyequation}
\frac{\partial E_s}{\partial t} + \nabla \cdot (\textbf{v}_s E_s) + \nabla \cdot \textbf{q}_s = {(\frac{\delta E_s}{\delta t})}_{source}
\end{equation}
Where $q$ is the heat flow tensor which can be approached in multiple ways and $E$ is the total energy:
\begin{equation}\label{eq:energy}
E_s = e_s + \frac{1}{2} m_s {v^2}_s + \frac{P_s}{\gamma_s - 1}
\end{equation}
Here $e$ is the internal energy and the potential energy is based on the momentum equation's extra acceleration terms like the fields or gravitational potential energy if included. $\gamma$ is the ratio of specific heats typically related to the degrees of freedom the particles exhibit. For the monoatomic case I use in this dissertation this number becomes $\frac{5}{3}$.
In most cases, the second moment is enough to close the system of equations. Through the energy equation we may derive an `equation of state' for the pressure so we may use it in the momentum equation. The magnetic fields evolve due to Maxwell's equations which will be discussed in Section~\ref{sec:maxwell}.
\subsection{Multi-fluid MHD}\label{sec:multifluidmhd}
In order to make our code capable to solve the equations shown in the previous section (Section~\ref{sec:moments}) further approximations must be done. The three fluids of interest in a hydrogen plasma that includes neutrals are hydrogen ions, electrons and neutral hydrogen. Our plasma is collisional and in partially ionized plasmas I can use the Krook collision term~\citep{bhatnagar1954}.
\begin{equation}\label{eq:krook}
{(\frac{\delta f}{\delta t})}_{collisions} = \nu_n (f_n - f)
\end{equation}
Where subscript $n$ is the neutral species and $\nu$ is the collision rate. We can find the collision rate simply by using the collision cross-section of neutral particles and the average thermal speed. The average thermal speed is used because temperature in the case of MHD is based on the `peculiar' speeds of the particles (i.e.\ particles with velocity other than that of the bulk plasma). This way peculiar velocities contribute to collisions because if both fluids are moving in the same direction.
\begin{equation}\label{eq:collisionrate}
\nu_n = n_n \sigma_n <v>
\end{equation}
The thermal speed is a function of temperature and under the Maxwellian velocity distribution assumption, $\sigma$ is the collisional cross-section which can be found in the literature through experiments. The collisional cross-section between ion and electrons include Coulomb effects as well.
The moment equations (Equation~\ref{eq:continuityequation}-\ref{eq:energyequation}) for the three species will look like this:
\begin{equation}\label{eq:icontinuity}
\frac{\partial n_i}{\partial t} + \nabla \cdot (n_i \textbf{v}_s) = S - L
\end{equation}
\begin{equation}\label{eq:econtinuity}
\frac{\partial n_e}{\partial t} + \nabla \cdot (n_e \textbf{v}_s) = S - L
\end{equation}
\begin{equation}\label{eq:ncontinuity}
\frac{\partial n_n}{\partial t} + \nabla \cdot (n_n \textbf{v}_s) = L - S
\end{equation}
\begin{equation}\label{eq:imomentum}
\begin{aligned}
& \frac{\partial n_i \textbf{v}_i}{\partial t} + \nabla \cdot (n_i \textbf{v}_i \textbf{v}_i + \frac{\textbf{P}_i}{m_i} ) - n_i \frac{q_i}{m_i}(\textbf{E} + \textbf{v}_i \times \textbf{B}) \\
& = - \sum_{i \neq s} [n_i \nu_{is}(\textbf{v}_i - \textbf{v}_s)] + \frac{1}{m_i} (S m_n \textbf{v}_n - S m_e \textbf{v}_e -L m_i \textbf{v}_i)
\end{aligned}
\end{equation}
\begin{equation}\label{eq:emomentum}
\begin{aligned}
& \frac{\partial n_e \textbf{v}_e}{\partial t} + \nabla \cdot (n_e \textbf{v}_e \textbf{v}_e + \frac{\textbf{P}_e}{m_e} ) - n_e \frac{q_e}{m_e}(\textbf{E} + \textbf{v}_e \times \textbf{B}) \\
& = - \sum_{e \neq s} [n_e \nu_{es}(\textbf{v}_e - \textbf{v}_s)] + \frac{1}{m_e} (S m_n \textbf{v}_n - S m_i \textbf{v}_i - L m_e \textbf{v}_e)
\end{aligned}
\end{equation}
\begin{equation}\label{eq:nmomentum}
\begin{aligned}
& \frac{\partial n_n \textbf{v}_n}{\partial t} + \nabla \cdot (n_n \textbf{v}_n \textbf{v}_n + \frac{\textbf{P}_n}{m_n} ) \\
& = - \sum_{n \neq s} [n_n \nu_{es}(\textbf{v}_n - \textbf{v}_s)] + \frac{1}{m_n} (L(m_i\textbf{v}_i+m_e\textbf{v}_e) -S m_n \textbf{v}_n)
\end{aligned}
\end{equation}
The first three equations are the continuity equations describing the number density evolution of the three kinds of species. The last three are the momentum equations describing the forces, pressures and convection for the three kinds of species.
$S$ and $L$ are source and loss terms respectively due to chemistry processes like ionization and recombination. These are three-fluid MHD equations if the only ion considered is the hydrogen ion. They appear in all the equations in some form.
\subsection{Temperature Equation}
We wish to study the thermal evolution of a plasma in Section~\ref{sec:chromosphere}. For this I must transform the energy equation (Equation~\ref{eq:energyequation}) to a form that evolves thermal pressure. We can do this by taking the dot product of the momentum equation and subtracting it from the energy equation. This leaves the energy equation with the thermal energy equation:
\begin{equation}\label{eq:pressureequation}
\frac{\partial }{\partial t}\frac{P_s}{\gamma_s - 1} +\nabla\cdot(\frac{P_s}{\gamma_s -1}\textbf{v}_s) + (1 - \frac{P_s}{\gamma_s - 1}) \nabla\cdot\textbf{v}_s = {(\frac{\delta E_s}{\delta t})}_{source} - \textbf{v}_s \cdot(\frac{\delta m_s n_s\textbf{v}_s}{\delta t})
\end{equation}
Elastic collisions may take the form of~\citep{Banks1973}:
\begin{equation}\label{eq:energycollisions}
{(\frac{\delta E_s}{\delta t})}_{collisions} = \textbf{v}_s \cdot {(\frac{\delta m_s n_s \textbf{v}_s}{\delta t})}_{collisions} + m_{sn} \nu_{sn} n_s [ (3 k_B / m_s) (T_n - T_s) + \lvert \textbf{v}_s - \textbf{v}_n \rvert^2 ]
\end{equation}
Where $m_{sn}$ is the reduced mass of the species with the neutral species, $T$ is temperature, $k_B$ is the Boltzmann constant. The previous equation shows thermal exchange due to collision between the species as well as {\it frictional heating\/} term that is proportional to the difference in speeds between the two. For a conservative scheme it is more approriate to use the total energy equation, but this depends on a case by case basis. The CoMFi code is capable of doing both approaches. For the chromosphere I will be concerned with the thermal evolution.
\subsection{Two-fluid MHD}\label{sec:2fluidmhd}
The ion and electron fluid can be simplified further to be one plasma that tracks the center of momentum between the two. Plasmas are typically quasi-neutral, it has as many positive charges as negative ones. Any imbalance in the charge will create a strong electric field within the plasma and strongly attract outside sources of charges until it is quasi-neutral again. In single hydrogen ion case that means:
\begin{equation}\label{eq:quasineutrality}
n_i = n_e = n
\end{equation}
This can simplify the current density equation as well:
\begin{equation}\label{eq:currentdensity}
\textbf{J} = e ( n_i \textbf{v}_i - n_e \textbf{v}_e) = e n (\textbf{v}_i - \textbf{v}_e)
\end{equation}
Where $e$ is the elementary charge. Subtracting the ion and electron continuity equations gives:
\begin{equation}
\frac{\partial n_i - n_e}{\partial t} + \nabla\cdot(n_i v_i - n_e v_e) = 0
\end{equation}
The charge conservation equation.
\begin{equation}\label{eq:chargeconservation}
\nabla\cdot\textbf{J} = 0
\end{equation}
To simplify the three MHD equations (Equations~\ref{eq:imomentum}-\ref{eq:nmomentum}) I can take the multiple of their masses and add Equation~\ref{eq:imomentum} and~\ref{eq:emomentum}.
\begin{equation}\label{eq:singlemomentum}
\begin{aligned}
& \frac{\partial \rho_i \textbf{v}_i + \rho_e \textbf{v}_e}{\partial t} + \nabla \cdot (\rho_e \textbf{v}_e \textbf{v}_e + \rho_i \textbf{v}_i \textbf{v}_i + \textbf{P}_i + \textbf{P}_e) - \textbf{J} \times \textbf{B} \\
& = - \rho_i \nu_{in}(\textbf{v}_i - \textbf{v}_n) - \rho_e \nu_{en} (\textbf{v}_e - \textbf{v}_n)+ (S m_n \textbf{v}_n - L m_i \textbf{v}_i - L m_e \textbf{v}_e)
\end{aligned}
\end{equation}
The $\rho$ here is the mass density of the fluid. Using the induction equation Maxwell's equations I can simplify $\textbf{J} \times \textbf{B}$ further.
\begin{equation}
\textbf{J} \times \textbf{B} = \frac{1}{\mu_0} (\nabla \times \textbf{B}) \times \textbf{B} = -\nabla \cdot (\frac{B^2}{2\mu_0}\textbf{I} - \textbf{BB})
\end{equation}
This way I can have a magnetic flux and make use of our conservative scheme in Section~\ref{sec:tvd-muscl}. Finally by dividing by $m_i+m_e$ to Equation~\ref{eq:singlemomentum} I can find the center of momentum velocity and simplify the equation one last time:
\begin{equation}
\textbf{V} = \frac{\rho_i \textbf{v}_i + \rho_e \textbf{v}_e}{\rho_i+\rho_e}
\end{equation}
\begin{equation}\label{eq:vi}
\textbf{v}_i = \textbf{V} + \frac{\rho_e}{\rho_i+\rho_e} \frac{1}{n e} \textbf{J} \sim \textbf{V} + \frac{m_e}{m_i} \frac{\textbf{J}}{n e}
\end{equation}
\begin{equation}\label{eq:ve}
\textbf{v}_e = \textbf{V} - \frac{\rho_i}{\rho_i+\rho_e} \frac{1}{n e} \textbf{J} \sim \textbf{V} -\frac{\textbf{J} }{n e}
\end{equation}
\begin{equation}\label{eq:momentumcom}
\begin{aligned}
&\frac{\partial \rho \textbf{V}}{\partial t} + \nabla \cdot (\textbf{K}_{i,e} + \frac{B^2}{2\mu_0}\textbf{I} - \frac{\textbf{BB}}{\mu_0}) \\
&= - (\rho_i \nu_{in} + \rho_e \nu_{en})(\textbf{V} - \textbf{U}) + \frac{m_e}{e}(\nu_{en}-\nu_{in}) \textbf{J} \\
& + [S m_n \textbf{U} - L m_i (\textbf{V} + \frac{m_e}{m_i} \frac{\textbf{J}}{n e})- L m_e (\textbf{V} -\frac{\textbf{J}}{n e})]
\end{aligned}
\end{equation}
The dynamic pressure and thermal pressures have been combined into one kinetic tensor term $\textbf{K}$. $\textbf{U}$ is the neutral velocity.
The neutral momentum equation is much easier since it is not affected by the Lorentz force and the momentum exchange is reversed, so it becomes:
\begin{equation}\label{eq:momentumneutral}
\begin{aligned}
&\frac{\partial \rho_n \textbf{U}}{\partial t} + \nabla \cdot (\textbf{K}_n) \\
&= (\rho_i \nu_{in} + \rho_e \nu_{en})(\textbf{V} - \textbf{U}) - \frac{m_e}{e}(\nu_{en}-\nu_{in}) \textbf{J} \\
& - [S m_n \textbf{U} - L m_i (\textbf{V} + \frac{m_e}{m_i} \frac{\textbf{J}}{n e})- L m_e (\textbf{V} -\frac{\textbf{J}}{n e})]
\end{aligned}
\end{equation}
Finally, following the ideal gas law $P_s = n_s k_B T_s$ and the monoatomic ratio of specific heats $\gamma = 5/3$, the last two equations needed are the temperature equations of the two fluids:
\begin{equation}\label{eq:temperatureion}
\begin{aligned}
&\frac{3}{2} n [\frac{\partial k_B T}{\partial t} + \nabla\cdot(k_B T \textbf{V})] - \frac{1}{2} n k_B T (\nabla\cdot\textbf{V}) + \nabla\cdot\textbf{q} \\
& = n m_{in} \nu_{in} [ 3 k_B (T_n - T) + m_n \lvert \textbf{U} - \textbf{V} \rvert^2 ] + Q
\end{aligned}
\end{equation}
\begin{equation}\label{eq:temperatureneutral}
\begin{aligned}
&\frac{3}{2} n_n [\frac{\partial k_B T_n}{\partial t} + \nabla\cdot(k_B T_n \textbf{U})] - \frac{1}{2} n_n k_B T_n (\nabla\cdot\textbf{U}) + \nabla\cdot\textbf{q} \\
&= n_n m_{ni} \nu_{ni} [ 3 k_B (T - T_n) + m_i \lvert \textbf{V} - \textbf{U} \rvert^2 ] + Q_n
\end{aligned}
\end{equation}
Where $\textbf{q}$ is the heat flux and $Q$ are other heating and cooling terms such as radiative losses.
\subsection{Maxwell's Equations}\label{sec:maxwell}
Since a plasma is a gas the reacts strongly to electro-magnetic fields. Maxwell's equations must be enforced in order to have a plasma consistent with reality. The Maxwell equations will also help us with the time evolution of the fields, as the fields are interconnected. The Maxwell's equations are:
\begin{equation}\label{eq:gausslaw}
\varepsilon_0\nabla\cdot\textbf{E} = n q
\end{equation}
\begin{equation}\label{eq:maggausslaw}
\nabla\cdot\textbf{B} = 0
\end{equation}
\begin{equation}\label{eq:lawofinduction}
\frac{\partial\textbf{B}}{\partial t} = - \nabla\times\textbf{E}
\end{equation}
\begin{equation}\label{eq:ampereslaw}
\mu_0\varepsilon_0\frac{\partial\textbf{E}}{\partial t} + \mu_0\textbf{J} = \nabla\times\textbf{B}
\end{equation}
In a plasma, any evolution of the electric field is very quickly resolved in the timescales I am considering. Ions and electrons would rearrange quickly to cancel out the electric field so it can be assumed as a perfect electrical conductor. This means the evolution of the magnetic field is more useful than the evolution of the electric field in timescales of interest. This also leads to the approximation $\partial\textbf{E}/\partial t \sim 0$:
\begin{equation}\label{eq:ampereslawapprox}
\mu_0\textbf{J} = \nabla\times\textbf{B}
\end{equation}
The plasma is therefore in a static electric field. We will need a definition of the electric field in order to evolve our magnetic fields. This will be discussed in the next Section~\ref{sec:ohmslaw}.
The magnetic field has also never been observed to have monopoles which makes it a solenoidal vector field. This is called Gauss's law of magnetism. The magnetic field will need to keep this shape despite errors in the simulation. The implementation will be discussed in Section~\ref{sec:divergencefree}.
\subsection{Generalized Ohm's Law}\label{sec:ohmslaw}
When talking about the Generalized Ohm's Law (GOL) or the Ohm's Law we typically think about conductivity in metal. Or at least that is how it is taught in college level physics. The Generalized Ohm's Law's purpose is to find the electric field within the plasma. This can be found by subtracting the ion and electron momentum equations~\ref{eq:imomentum}-\ref{eq:emomentum} and multiplying by electron mass.
\begin{equation}
\begin{aligned}
&\frac{m_e}{e}\frac{\partial \textbf{J}}{\partial t} + \nabla \cdot (m_e n [\textbf{v}_i \textbf{v}_i - \textbf{v}_e \textbf{v}_e] +m_e \frac{\textbf{P}_i}{m_i} - \textbf{P}_e) \\
& - n e (-\frac{m_e}{m_i}+1) \textbf{E} - \frac{n e m_e}{m_i} \textbf{v}_i \times \textbf{B} - n e\textbf{v}_e \times \textbf{B} \\
&= -n m_e [ \nu_{ie} (\textbf{v}_i -\textbf{v}_e) + \nu_{in} (\textbf{v}_i -\textbf{v}_n) - \nu_{ei} (\textbf{v}_e -\textbf{v}_i) - \nu_{en} (\textbf{v}_e -\textbf{v}_n)] \\
&+ (\frac{m_e}{m_i} - 1) S m_n \textbf{v}_n - \frac{m_e}{m_i} S m_e \textbf{v}_e - L m_e \textbf{v}_i + S m_n \textbf{v}_n - S m_i \textbf{v}_i - L m_e \textbf{v}_e
\end{aligned}
\end{equation}
Simplifying further by taking the $m_e/m_i \sim 0$ approximation, current density~\ref{eq:currentdensity}, charge conservation~\ref{eq:chargeconservation}, and the velocity definitions~\ref{eq:vi} and~\ref{eq:ve}.
\begin{equation}
\begin{aligned}
&\frac{m_e}{n e^2} \frac{\partial\textbf{J}}{\partial t}+ \frac{m_e}{ne^2} \nabla\cdot[\textbf{V}\textbf{J} + \textbf{J}\textbf{V}] + \frac{-\nabla\cdot\textbf{P}_e + \textbf{J}\times\textbf{B}}{ne}- \textbf{E} - \textbf{V}\times\textbf{B} \\
& = - \frac{m_e}{e}[\nu_{in} (\textbf{V}-\textbf{v}_n) + \nu_{en}(\textbf{V} - \textbf{v}_n)] - \eta\textbf{J}
\end{aligned}
\end{equation}
\begin{equation}\label{eq:gom}
\begin{aligned}
&\textbf{E} = - \textbf{V}\times\textbf{B} + \frac{m_e}{n e^2} \frac{\partial\textbf{J}}{\partial t}+ \frac{m_e}{ne^2} \nabla\cdot[\textbf{V}\textbf{J} + \textbf{J}\textbf{V}] \\
&+ \frac{-\nabla\cdot\textbf{P}_e + \textbf{J}\times\textbf{B}}{ne} \\
& + \frac{m_e}{e}[\nu_{in} (\textbf{V}-\textbf{U}) - \nu_{en}(\textbf{V} - \textbf{U})] + \eta\textbf{J}
\end{aligned}
\end{equation}
Where $\eta = \frac{m_e \nu_e}{e^2 n}$ is the Ohmic resistivity. The relation between the electric field and the resistivity is what we think of when we invoke Ohm's law in college physics. Clearly the equation is a little more complicated in MHD\@. Note that collision with neutrals may change the electric field also. The collisions can cause a drift between the ions and electrons, separating them and causing an electric field.
We can take Equation~\ref{eq:gom} a step further and eliminate the need for an evolving current and instead use the low-frequency approximation (i.e.\ the time scales is much smaller than the plasma frequency $\omega_p = \sqrt{\frac{n_e e^2}{\varepsilon_0 m_e}}$). Removing the convective derivate of the current gives this approximation:
\begin{equation}\label{eq:gomlowfreq}
\begin{aligned}
&\textbf{E} = - \textbf{V}\times\textbf{B} \\
&+ \frac{-\nabla\cdot\textbf{P}_e + \textbf{J}\times\textbf{B}}{ne} \\
& + \frac{m_e}{e}[\nu_{in} (\textbf{V}-\textbf{U}) - \nu_{en}(\textbf{V} - \textbf{U})] + \eta\textbf{J}
\end{aligned}
\end{equation}
And in a two-fluid approach I may define current along with the same assumptions:
\begin{equation}
\textbf{J} = \frac{\nabla\times\textbf{B}}{\mu_0}
\end{equation}
The collisional terms may also be ignored under careful consideration of how small $\frac{\nu}{\omega^2_p}$ may be.
In Section~\ref{sec:chromosphere} I will simplify the above equation further to suit our needs. Typically in simulations you only want to include the terms that matter the most. With careful consideration I can come up with a GOL that is most appropriate for our application.
\subsection{Induction Equation}
To close our set of equations I need a way to evolve the magnetic fields. For this I can use the law of induction (Equation~\ref{eq:lawofinduction}) with the GOL (Equation~\ref{eq:gomlowfreq}).
\begin{equation}
\begin{aligned}
\frac{\partial\textbf{B}}{\partial t} =& \nabla\times(\textbf{V}\times\textbf{B} - \frac{-\nabla\cdot\textbf{P}_e + \textbf{J}\times\textbf{B}}{ne} \\
&- \frac{m_e}{e}[\nu_{in} (\textbf{V}-\textbf{U}) - \nu_{en}(\textbf{V} - \textbf{U})] - \eta\textbf{J})
\end{aligned}
\end{equation}
We may use vector identities to transform the advective terms.
\begin{equation}
\nabla\times(\textbf{V}\times\textbf{B}) = \nabla\cdot(\textbf{BV}-\textbf{VB})
\end{equation}
This also gives the opportunity to have as many terms in conservative forms as I can.
\begin{equation}\label{eq:inductionequation}
\begin{aligned}
& \frac{\partial\textbf{B}}{\partial t} = \\
&\nabla\cdot(\textbf{BV}-\textbf{VB} + \textbf{B}\textbf{V}_{hall}-\textbf{V}_{hall}\textbf{B}) \\
&-k_B (\frac{\nabla n \times \nabla T_e}{ne}) \\
&- \nabla\times(\frac{m_e}{e}[\nu_{in} (\textbf{V}-\textbf{U}) - \nu_{en}(\textbf{V} - \textbf{U})]) \\
& - \frac{1}{\mu_0} \nabla\eta\times\textbf{J} + \eta\nabla^2\textbf{B}
\end{aligned}
\end{equation}
Where
\begin{equation}
\textbf{V}_{hall} = \frac{\textbf{J}}{ne}
\end{equation}
Since it is associated with the Hall term in the induction equation.
In the coming chapters I will be using a simplified form of the GOL---dropping the terms that are less significant.
\section{Implementation}\label{sec:implementation}
Computational fluid dynamics is a well studied field in computer science, numerics and engineering. Many of its principles can be applied to MHD due to the fluid nature of its equations. We will be focusing on only the ones implemented in the code my for this dissertation, the Collisional Multi-Fluid ion (CoMFi) code~\citep{alshidi2019} was made for the chromosphere case~\citep{alshidi2019chromo} which will be explored in more detail in the upcoming chapter (Section~\ref{sec:chromosphere}). The code is an ever-evolving code that uses Graphical Processing Units (GPUs) instead of the common CPUs typically seen for MHD codes. This is to implement MHD that makes use of the frontiers of computer technology. GPUs were made for graphical operations in video games. This means they are specifically designed to be very fast at matrix rotations, translations and other linear algebra. In this chapter I will explore proper general purpose GPU programming techniques for solving differential equations and the schemes used alongside it. CoMFi is written in C++ using ViennaCL~\citep{viennacl} for GPU linear algebra template programming and Armadillo~\citep{arma} for setting up the matrices on the CPU\@.
\subsection{Time Integration}\label{sec:timeintegration}
Time integration is important to the time stepping nature of simulations. We can have both implicit time stepping and explicit time stepping. Explicit time stepping for the Euler equation takes the form:
\begin{equation}\label{eq:explicit}
u^{n+1} = u^n + v\int^{n+1}_n \frac{d}{dx}(u^{n}) dt
\end{equation}
This is the easiest approach to the solutions because you use values in the previous time step to solve for the next. This does not require a solution of a linear system which I will show later. Explicit schemes are limited to time steps that are smaller than the wave period, $\Delta x / v > \Delta t$, and depending on the scheme a multiple smaller but usually within the same order of magnitude. This is because the largest characteristic speed (the speed of information propagation) cannot be faster than the grid spacing and time steps. This will cause loss of information and instabilities as there will be an attempt to skip grids but due to discretization it will fail to resolve.
In implicit time steps
\begin{equation}\label{eq:implicit}
u^{n+1} - v\int^{n+1}_n \frac{d}{dx}(u^{n+1}) dt = u^n
\end{equation}
This introduces a linear equation that must be solved, $Au^{n+1} = u^n$, and the solution is to invert the matrix A, $u^{n+1} = A^{-1} u^n$. This gets more complicated in non-linear systems. In this case I am not limited by that characteristic speed.
There is also a third option, semi-implicit schemes. This integrates some variables implicitly and others explicitly. This is helpful when you do not want to be limited by certain characteristic speeds. For the chromosphere example in Section~\ref{sec:chromosphere} a characteristic I try to overcome is the collision times since it is orders of magnitude larger than the Alf\'ven and sound times in the chromosphere.
\subsection{Stability}\label{sec:stability}
In order for schemes to be stable, errors must not grow over time. We can make sure errors are not growing by employing the Von Neumann analysis~\citep{vonneumann1950}. Let's use a simple explicit forward difference scheme on the wave equation for example.
\begin{equation}
\frac{\partial u}{\partial t} = -v\frac{\partial u}{\partial x}
\end{equation}
\begin{equation}\label{eq:upwind}
u^{n+1}_j = u^n_j - \frac{\Delta t}{\Delta x}v(u^n_{j+1}-u^n_{j})
\end{equation}
The above is the Euler equation for a wave propagating at constant speed $v$ using a forward difference method, also called an upwind scheme. The Von Neumann method takes a Fourier analysis to the error waves generated due to discretization. We say that by using the Taylor series the discretization should have this {\it exact\/} solution.
\begin{equation}
u_{j+1} = u_j + \Delta x {\frac{\partial u}{\partial x}}\rvert_j + \frac{\Delta x^2}{2} {\frac{\partial^2 u}{\partial x^2}}\rvert_j + \frac{\Delta x^3}{3!} {\frac{\partial^3 u}{\partial x^3}}\rvert_j + \cdots
\end{equation}
Where $j$ is the location of the cell solution. Rearranging so that it looks like a forward difference scheme shows its relation to the exact solution of the partial derivative.
\begin{equation}
\epsilon = \frac{u_{j+1} - u_j}{\Delta x} - {\frac{\partial u}{\partial x}}\rvert_j = \frac{\Delta x}{2} {\frac{\partial^2 u}{\partial x^2}}\rvert_j + \frac{\Delta x^2}{3!} {\frac{\partial^3 u}{\partial x^3}}\rvert_j + \cdots = O(\Delta x)
\end{equation}
This means the errors, $\epsilon$, are of first order, proportional to $\Delta x$ so the upwind scheme is a first order scheme in space. To see how the errors evolve in time I employ the Von Neumman analysis. Assuming the computed solution is a linear combination of the real solution and the error.
\begin{equation}
u_{computed} = u_{exact} + \epsilon
\end{equation}
We can subtract the exact solution and do a Fourier analysis of the errors found. Doing this on Equation~\ref{eq:upwind} yields.
\begin{equation}
e^{a(t+\Delta t)+ikx} = e^{at+ikx} - \beta (e^{at + ik(x+\Delta x)}-e^{at + ikx})
\end{equation}
Where $\beta = v(\Delta t / \Delta x)$, $a$ is the component of the errors in time, and $k$ is the series of frequencies of the errors in space. To find the error growth due to time I must find the ratio $e^{at} = u^{n+1}/u^n$.
\begin{equation}
G = e^{a\Delta t} = 1 - \beta (e^{ik\Delta x}- 1)
\end{equation}
$G$ is the growth in error each time step also called the amplification factor. In order to keep the errors bounded I need to ensure that this ratio is less than or equal to 1.
\begin{equation}
\lvert G \rvert \leq 1
\end{equation}
For the upwind scheme example I used:
\begin{equation}
\lvert 1 - \beta (e^{ik\Delta x}- 1) \rvert \leq 1
\end{equation}
This will lead to
\begin{equation}
\beta \leq 1
\end{equation}
Or the stability requirement, also known as the Courant-Friedrich-Lewy condition:
\begin{equation}
v \frac{\Delta t}{\Delta x} \leq 1
\end{equation}
An explicit central difference scheme behaves differently, however.
\begin{equation}\label{eq:central}
u^{n+1}_j = u^n_j - \beta \frac{u^n_{j+1}-u^n_{j-1}}{2}
\end{equation}
Doing the Von Neumann analysis here using a more simplified notation:
\begin{equation}
u^{n+1} e^{ijk} = u^n e^{ijk} - \beta \frac{u^n e^{i(j+1)k} - u^n e^{i(j-1)k}}{2}
\end{equation}
\begin{equation}
G = 1 - \beta \frac{e^{ik} - e^{-ik}}{2} = 1 - i\beta \sin{(k)}
\end{equation}
\begin{equation}
\lvert 1 - i\beta \sin{(k)} \rvert = 1 + \beta^2 \sin^2(k) \nleq 1
\end{equation}
Since the amplification factor is always larger than 1, errors will always grow. This scheme is {\it unconditionally unstable}. Doing this scheme in an implicit fashion can fix this problem.
\begin{equation}\label{eq:implicitcentral}
u^{n+1}_j = u^n_j - \beta \frac{u^{n+1}_{j+1}-u^{n+1}_{j-1}}{2}
\end{equation}
Now doing the Fourier analysis,
\begin{equation}
u^{n+1}_j - \beta \frac{u^{n+1}_{j+1}-u^{n+1}_{j-1}}{2} = u^n_j
\end{equation}
\begin{equation}
u^{n+1}e^{ijk} - \beta \frac{u^{n+1}e^{i(j+1)k}-u^{n+1}e^{i(j-1)k}}{2} = u^n
\end{equation}
\begin{equation}
G (1 - \beta \frac{e^{ik}-e^{-ik}}{2}) = 1
\end{equation}
\begin{equation}
G = \frac{1}{1 - i \beta \sin{(k)}}
\end{equation}
\begin{equation}
\lvert G \rvert = \frac{1}{1+\beta^2 \sin^2{(k)}} \leq 1
\end{equation}
Since the amplification factor is always less than or equal to 1 this implicit central difference scheme is {\it unconditionally stable}.
\sectionsection{Schemes}\label{sec:schemes}
CoMFi uses the conservative MHD equations therefore conservative schemes are of interest. This makes use of the conservative variables unknowns as opposed to the primitive variables ($n v$ as opposed to $v$). This way I can use a finite volume method~\citep{leveque2002} and conserve these quantities to the machine rounding error. Conservative schemes are also known to do well at capturing shocks and the chromosphere is a region where I expect such shocks to exist.
\begin{equation}\label{eq:geneuler}
\frac{\partial \textbf{u}}{\partial t} + \nabla \cdot \textbf{F(u)} = 0
\end{equation}
The above equation is a general Euler equation demonstrating a conservation law problem. The quantity to be conserved is $\textbf{u}$ and is a function the flux $\textbf{F}$. We will be considering the linear case for simplicity however MHD has demonstrably non-linear terms as the flux (e.g. Equation~\ref{eq:imomentum}) but it can easily follow from this linear case. The point is to show the total volume is conserved:
\begin{equation}\label{eq:geneulerint}
\frac{d\textbf{u}}{dt} + \frac{1}{V} \oint \textbf{F} \cdot \textbf{n} dS
\end{equation}
In codes designed to solve differential equations numerically I must decide on the discretization. Since I am using a finite volume method I am discretizing the domain by cells with density quantities in them. The code is discretized in cells existing in Cartesian coordinates (rectangular cells) so I am tasked to find the values of the variables at the cell faces in order to conserve the volume.
We would also like a total-variation-diminishing (TVD) scheme~\citep{harten1997}, this is because spatial derivatives are approximated on a computer. If I take a Taylor series of a derivative from one cell to another and compare with an approximate derivative like $\frac{u(x+\Delta x)-u(x-\Delta x)}{2\Delta x}$ I see that there are many higher order terms missing. Taking the Fourier analysis of these terms show that any high-frequency errors may compound (sometimes referred to as spurious oscillations). This can be fixed by schemes that ensure the total variation $TV$ is diminishing.
\begin{equation}\label{eq:tvd}
\frac{d(TV)}{dt} = \frac{d}{dt} \int \lvert \frac{\partial u}{\partial x} \rvert dx \leq 1
\end{equation}
Therefore, for the purpose of our code, I will use the Total-Variation-Diminishing Monotonic Upwind Scheme for Conservation Laws (TVD-MUSCL).
\subsection{Flux Limiters}\label{sec:fluxlimiters}
To conserve the cell's quantities I must be able to approximate the quantities on the cell edges. At the same time I must preserve monotonicity to avoid the oscillations. This can be achieved through flux limiters. The utility of the flux limiters is to turn the scheme into a first-order upwind scheme in sharp discontinuities and a high-resolution scheme when the solution is smooth.
\begin{equation}\label{eq:fluxlimiter}
u_{j+1/2} = u_j + \frac{1}{2} \phi(r_j) (u_{j+1} - u_j)
\end{equation}
\begin{equation}
r_j = \frac{u_j - u_{j-1}}{u_{j+1} - u_j}
\end{equation}
Subscript $j$ is the discretized cell location with quantity $u$. The ratio of successive gradients $r$ determines how strongly the flux limiter acts to find the extrapolated cell edge variable. The flux limiter $\phi$ includes the cells around edge more readily the smoother the solution is ($r>0$), or sharp it is ($r<0$) in which case the flux limiter is zero ($\phi=0$). These are the properties flux limiters must abide in order to turn the scheme upwind in sharp gradients or high-resolution in smoother gradients. The above equation is a linear reconstruction of a cell edge. Other reconstructions exist but are more diffusive and avoids the shock-capturing goal of the code.
We have some freedom in choosing how to set the flux limiter. Many flux limiters have been made and studied in the past. The simplest flux-limiter is the minmod.
\begin{equation}\label{eq:minmod}
\phi_{minmod}(r) = \max(0, \min(1, r)), \lim_{r \to \infty} \phi(r) = 1
\end{equation}
Implementing these on a computer however is not a trivial task. Many initial conditions require the entirety of the domain be the same number for instance. In that case I get an $r = \frac{0}{0}$ and this causes a computer to return NaN (not a number). Setting to $r=0$ is appropriate but requires extra coding. A work around is to add a small number $\epsilon$ to the denominator known as the machine epsilon to avoid these cases.
The CoMFi code provides several flux limiters. The pre-made flux limiters tend to be symmetric:
\begin{equation}
\frac{\phi(r)}{r} = \phi(\frac{1}{r})
\end{equation}
This is to ensure that it is consistent in negative and positive fluxes.
The provided flux limiters are:
\begin{equation}
\phi_{ospre} (r) = 1.5 \frac{(r^2 + r)}{r^2 + r + 1}
\end{equation}
This is the Ospre~\citep{Waterson2007} limiter, the default limiter in the code.
\begin{equation}
\phi_{van Albada} (r) = \frac{r^2 + r}{r^2 + 1}
\end{equation}
By~\citet{vanalbada1982}.
\begin{equation}
\phi_{van Leer} (r) = \frac{r + \lvert r \rvert}{1 + \lvert r \rvert}
\end{equation}
By~\citet{vanleer1974}
These were chosen because of ViennaCL's limitation of not having element-wise min and max functions. ViennaCL does have the ability to compile custom kernels and examples of min-mod in that case does exist.
\begin{figure}[h!]\label{fig:sweby}
\centering
\includegraphics[width=1.0\linewidth]{images/sweby.png}
\caption{A Sweby diagram of the current limiters in the CoMFi code. The shaded region is the required region for the limiter to be in in order to be second-order TVD\@.}
\end{figure}
Only second-order TVD limiters were chosen because when the scheme is at its high-resolution it is a second-order scheme.
\begin{equation}
r_j = \frac{u_j - u_{j-1}}{u_{j+1} - u_j + \epsilon}
\end{equation}
This machine epsilon should have no effect on the result so long as the variables have been normalized appropriately (see Section~\ref{sec:normalization}). This means the valuable results are within an order of magnitude so the machine epsilon of a 64bit floating point number of $2^{-−52} \sim 2.22 \times 10^{-16}$ would be negligible. If two adjacent cells have the same value, as is common with initial values, then dividing by zero is usefully avoided.
\begin{figure}[ht!]
\centering
\includegraphics[width=0.75\textwidth]{images/spuriousoscillations.png}
\caption{Spurious oscillations that may form in the advection equation due to discretization errors. An explanation of this can be found in Section~\ref{sec:stability}. Imagen taken from [http://farside.ph.utexas.edu/].}\label{fig:spuriousoscillations}
\end{figure}
\subsection{TVD-MUSCL}\label{sec:tvd-muscl}
The TVD-MUSCL scheme~\citep{vanleer1979} reconstructs `left' ($L$) and `right' ($R$) states of the cell edge variables.
\begin{equation}
u^L_{j-1/2} = u_{j-1} + \frac{1}{2} \phi(r_{j-1}) (u_j - u_{j-1})
\end{equation}
\begin{equation}
u^L_{j+1/2} = u_{j} + \frac{1}{2} \phi(r_{j}) (u_j - u_{j-1})
\end{equation}
\begin{equation}
u^R_{j-1/2} = u_{j} + \frac{1}{2} \phi(r_{j}) (u_{j+1} - u_{j})
\end{equation}
\begin{equation}
u^R_{j+1/2} = u_{j+1} + \frac{1}{2} \phi(r_{j+1}) (u_{j+1} - u_{j})
\end{equation}
With the left and right extrapolated variables I may construct a flux.
\begin{equation}
F^*_{j-1/2} = \frac{1}{2} ([F(u^R_{j-1/2})+F(u^L_{j-1/2})] - \lambda_{j-1/2}[u^R_{j-1/2}-u^L_{j-1/2}])
\end{equation}
\begin{equation}
F^*_{j+1/2} = \frac{1}{2} ([F(u^r_{j+1/2})+F(u^l_{j+1/2})] - \lambda_{j+1/2}[u^r_{j+1/2}-u^l_{j+1/2}])
\end{equation}
Here $F u = \lambda u$ are the eigenvalues of the variables. This in physical terms means the largest wave speeds of the system. Typically for the ion plasma it is the fast-mode speed and for the neutrals it is the sound speed. It's important to note in conservative MHD this is only the wave speed ($c_{fast}$) and not the same as the fastest speed of information propagation ($v+c_{fast}$). The diffusive terms proportional to $\lambda$ are meant to avoid the oscillations and if they are larger than they need to be the solution will be more diffusive.
\subsection{Maintaining a Divergence Free Field}\label{sec:divergencefree}
The Gauss's law for magnetic fields (Equation~\ref{eq:maggausslaw}) needs to be taken care of because due to machine rounding error and other errors due to discretization, there will be evolution of the divergence. That is to say, although:
\begin{equation}
\frac{\partial\nabla\cdot\textbf{B}}{\partial t} = -\nabla\cdot\nabla\times\textbf{E} = 0
\end{equation}
The reality is, due to errors:
\begin{equation}
\frac{\partial\nabla\cdot\textbf{B}}{\partial t} = \epsilon_{errors}
\end{equation}
There are many methods to resolving this. A popular method is Yee grids, sometimes referred to as staggered grids. Placing the magnetic fields to the cell edges of the electric fields. By doing this, evolving the magnetic fields reduces errors to machine rounding errors since Stokes' theorem is imposed on the problem.
\begin{equation}\label{eq:stokesyee}
\iint_S\frac{\partial\textbf{B}}{\partial t}\cdot d\textbf{A} = {\oint}_{edges} \textbf{E}\cdot d\textbf{l}
\end{equation}
This is not the method used for CoMFi. Staggering the grid makes using a finite volume method difficult especially when trying to find cell centers from one quantity to the next. Instead I employ the Generalized Lagrange Multiplier method introduced by~\citet{glm}.
\subsection{Generalized Lagrange Multiplier}
The Generalized Lagrange Multiplier (GLM) method adds another unknown to the system of equations to be solved. This has the drawback of using more memory. Its implementation is simple, however, which means adding it to an existing code is easy. The GLM $\Phi$ tries to minimize the monopoles created due to errors in the simulation. It does this by first creating some stress to the induction equation if there is some monopole.
\begin{equation}
\frac{\partial\textbf{B}}{\partial t} = - \nabla\times\textbf{E} + \nabla \Phi
\end{equation}
And filter the monopoles into the GLM using this method of evolution:
\begin{equation}
\mathcal{D}(\Phi) + \nabla\cdot\textbf{B} = 0
\end{equation}
$\mathcal{D}$ is a differential operator and I can choose the GLM to evolve in any way I want. A hyperbolic evolution and/or a parabolic evolution may be used. Due to the non-linear and parabolic nature of our equations I opt to use both:
\begin{equation}
\matchal{D}(\Phi) = \frac{1}{c^2_h}\frac{\partial\Phi}{\partial t} + \frac{1}{c^2_p}\Phi
\end{equation}
Here $c_h$ and $c_p$ are the hyperbolic and parabolic speeds of the divergence errors. That means the divergence errors will propagate at a speed of $c_h$ and dissipate at rate of $c_p$. The new equation that must be solved is:
\begin{equation}\label{eq:glm}
\frac{\partial\Phi}{\partial t} + c^2_h \nabla\cdot\textbf{B} = - \frac{c^2_h}{c^2_p} \Phi
\end{equation}
The hyperbolic speed, $c_h$, can be chosen to be similar the wave speeds in the magnetic field (i.e.\ the fast-mode speed). We have more freedom to chose the ratio of dissipation to propagation, $\alpha = c_h / c^2_p$, also known as the damping parameter. Through testing 0.5 was find to be a good parameter~\citep[p. 5899-5911]{glm2}.
We can separate Equation~\ref{eq:glm} into two parts two solve. We can solve the right hand side exactly, and use the conservative scheme to solve the second term on the left hand side. First solve the left hand side and setting the right hand side equal to zero. Then minimize it with the exact solution:
\begin{equation}
\Phi(t+\Delta t) = \Phi(t) e^{-c_h\alpha\Delta t}
\end{equation}
The efficacy of this method is keeping the normalized divergence errors to lower than the normalized grid-spacing. This is useful so that the monopoles are not evident when drawing the magnetic field lines nor does it have a strong effect on the results.
\subsection{Architecture}\label{sec:architecture}
It is important in scientific computing not to reinvent the wheel. There are many libraries, particularly C++ libraries, that use template programming to make it easier to write linear algebra in code. It is always easier to add an entire vector with one + sign than looping through each element of the two vectors and adding each. For this reason I can avoid low-level programming like Fortran for CPUs or OpenCL and CUDA for GPUs because the Basic Linear Algebra Subroutines (BLAS) have already been written and abstracted by someone else. C++ is a language that is all about abstraction and speed. There is a pervasive myth that if you want to do scientific computing you must use Fortran or CUDA but this is not true and is usually reinforced by scientists' lack of understanding of computer science and/or bad code.
The code uses to template expression libraries in C++. Template expression is how C++ abstracts operators such as $+$, $-$ and $/$ to deal with one variable and the next and call the low level BLAS functions. The libraries used are Armadillo for CPU\@. This is a code typically used for Machine Learning applications so speed and big data is its focus. For GPU programming ViennaCL is used, it's a library used by PETSc for its GPU portion. However, at the time of this writing, PETSc's GPU code is not fully developed so ViennaCL is used directly. Luckily, ViennaCL interfaces with Armadillo well and there exists copy constructors to go from shared memory to GPU memory.
Matrices {\it must\/} be built on the CPU\@. Accessing GPU elements individually is a slow process that is limited by the PCI-e speed and when the machine code (running on CPU) is asked to go back and forth, I get slow code. Best practice is to first build a matrix on the CPU then copy to the GPU\@.
\subsection{Data Structure}\label{sec:datastructure}
When using the semi-implicit method a linear system $Ab^{n+1}=b$ must be solved. We must think of an appropriate ordering of our vector in terms of the where the unknowns must be in the elements of the vector. For GPU programming in order to take advantage of its matrix operations speeds due to its many cores I must also be easily able to change back and forth between matrix and vector form between the implicit and explicit portions of the solution. A good ordering for a two-dimensional domain looks like this:
\begin{equation}
b =
\begin{bmatrix}
u_{0,00} \\
\vdots \\
u_{0,i0} \\
\vdots \\
u_{0,ij} \\
\vdots \\
u_{w,ij} \\
\end{bmatrix}
\end{equation}
The subscripts $i$ and $j$ describe the location of the cell in the $x$ and $y$ axis respectively and $w$ are the scalar unknowns.
\begin{equation}
u_w =
\begin{bmatrix}
B_x \\
B_{\perp} \\
B_z \\
n_i \\
n_n \\
n_i V_x \\
n_i V_{\perp} \\
n_i V_z \\
n_n U_x \\
n_n U_{\perp} \\
n_n U_z \\
T_i \\
T_n \\
\Phi
\end{bmatrix}
\end{equation}
This can be easily resized into a matrix of the form:
\begin{equation}
B =
\begin{bmatrix}
u_{0,00} & \cdots & u_{w,00} \\
\vdots & \ddots & \vdots \\
u_{0,i0} & \cdots & u_{w,i0} \\
\vdots & \ddots & \vdots \\
u_{0,ij} & \cdots & u_{w,ij}
\end{bmatrix}
\end{equation}
This has the benefits of making good use of GPU programming by using the parallelism found in matrix operations. This also means you can share boundary conditions by taking or providing rows for this matrix in chunks. You can do operations on specific unknowns by taking the appropriate column.
\subsection{Normalization}\label{sec:normalization}
The unknowns in the simulations must be normalized. This is typical good practice in numerics when we're dealing with computers due to how computers deal with floating point number. Since computers deal with discrete numbers the floating point number line is discrete and also less regular than the real number line. There are more floating point numbers between -1 and 1 than there are between 10 and 11 for example. For this purpose, it is important to find a way in which the common numbers I will be dealing with be normalized to 1. We can do this by having, usually, the largest numbers found in the simulation domain be the normalizing constants.
\subsection{Constants}\label{sec:normconstants}
The normalization constants were chosen for the chromospheric case I study in Section~\ref{sec:chromosphere}. For a more in-depth discussion on why these were chosen see Section~\ref{sec:simulationdomain}.
\begin{table}[h]\label{tab:normalization}
\centering
\caption[Normalization Constants]{Normalization constants chosen for the chromospheric simulation}
\begin{tabular}[]{l c r}
\toprule
\textbf{Magnetic Field} & $B_0$ & $0.1$ T\\
\textbf{Length} & $L_0$ & $2.1 \times 10^6$ m \\
\textbf{Number Density} & $n_0$ & $1.0\times 10^{20}$ m$^{-3}$ \\
Mass & $m_0 = m_i$ & $1.672621898\times 10^{-−27}$ kg \\
Vacuum Permeability & $\mu_0$ & $1.2566370614\times 10^{-−6}$ Vs/A/m \\
Charge & e_0 & $1.6021766208\times10^{-19}$ C \\
Boltzmann Constant & $k_B$ & $1.38065\times10^{-23}$ J/K\\
Velocity & $V_0=\frac{B_0}{\sqrt{\mu_0 m_i n_0}}$ & $2.18 \times 10^{8}$ m/s\\
Pressure & $p_0= \frac{{B_0}^2}{\mu_0}$ & $8.0 \times 10^3$ Pa \\
Temperature & $T_0 = \frac{p_0}{n_0 k_B} $ & $5.79438\times10^6$ K\\
Current Density & $j_0 = e_0 n_0 V_0$ & $3.493\times10^9$ A/m/m \\
Heat Flow & $q_0 = p_0 V_0$ & $1.744\times10^{12}$ Pa m/s \\
\bottomrule
\end{tabular}
\end{table}
In bold are the free parameters you may choose for the CoMFi code. The constants must be chosen carefully so that the largest numbers of interest are normalized to 1. The reason for choosing the quantities above is discussed in Section~\ref{sec:chromosphere}.
\subsection{Normalized Equations}\label{sec:normequations}
Once I have the normalization constants I may normalize the equations. Replacing each term by its normalized version reduces the equations further. There is less need to include physical constants like $\mu_0$ and $k_B$ as they are implicit in the quantities. Hence, I get normalized MHD equations of the form:
\begin{equation}\label{eq:normcontinuity}
\frac{\partial \bar{n_s}}{\partial \bar{t}} + \nabla \cdot (\bar{n_s} \bar{\textbf{v}_s}) = \bar{S} - \bar{L}
\end{equation}
\begin{equation}\label{eq:normmomentumcom}
\begin{aligned}
&\frac{\partial \bar{n} \bar{\textbf{V}}}{\partial \bar{t}} + \nabla \cdot (\bar{\textbf{K}}_{i,e} + \frac{\bar{B}^2}{2}\textbf{I} - \bar{\textbf{B}}\bar{\textbf{B}}) \\
&= - (\bar{n} \bar{\nu}_{in} + \bar{m_e} \bar{n} \bar{\nu}_{en})(\bar{\textbf{V}} - \bar{\textbf{U}}) + \frac{\bar{m_e}}{\bar{e}}(\bar{\nu}_{en}-\bar{\nu}_{in}) \bar{\textbf{J}} \\
&+ (\bar{S} \bar{m_n} \bar{\textbf{U}} - \bar{L} (\bar{\textbf{V}}+ \frac{\bar{m_e}}{\bar{n}\bar{e}}\bar{\textbf{J}}) - \bar{L} \bar{m_e} (\bar{\textbf{V}} -\frac{\bar{\textbf{J}}}{\bar{n}\bar{e}}) )
\end{aligned}
\end{equation}
\begin{equation}\label{eq:normmomentumneutral}
\begin{aligned}
&\frac{\partial \bar{n}_n \bar{\textbf{U}}}{\partial \bar{t}} + \nabla \cdot (\bar{\textbf{K}}_n) \\
&= + (\bar{n} \bar{\nu}_{in} + \bar{m_e} \bar{n} \bar{\nu}_{en})(\bar{\textbf{V}} - \bar{\textbf{U}}) - \frac{\bar{m_e}}{\bar{e}}(\bar{\nu}_{en}-\bar{\nu}_{in}) \bar{\textbf{J}} \\
&- (\bar{S} \bar{m_n} \bar{\textbf{U}} - \bar{L} (\bar{\textbf{V}}+ \frac{\bar{m_e}}{\bar{n}\bar{e}}\bar{\textbf{J}}) - \bar{L} \bar{m_e} (\bar{\textbf{V}} -\frac{\bar{\textbf{J}}}{\bar{n}\bar{e}}) )
\end{aligned}
\end{equation}
\begin{equation}\label{eq:normtemperatureion}
\begin{aligned}
&[\frac{\partial\bar{T}}{\partial \bar{t}} + \nabla\cdot(\bar{T} \bar{\textbf{V}})] - \frac{1}{3}\bar{T} (\nabla\cdot\bar{\textbf{V}}) + \frac{1}{\bar{n}}\nabla\cdot\bar{\textbf{q}} \\
& = \bar{m}_{in} \bar{\nu}_{in} [2(\bar{T_n} - \bar{T}) + \frac{1}{3}\bar{m_n} \lvert \bar{\textbf{U}} - \bar{\textbf{V}} \rvert^2 ] + \frac{2}{3}\bar{Q}
\end{aligned}
\end{equation}
\begin{equation}\label{eq:normtemperatureneutral}
\begin{aligned}
&[\frac{\partial\bar{T}_n}{\partial \bar{t}} + \nabla\cdot(\bar{T}_n \bar{\textbf{U}})] - \frac{1}{3}\bar{T}_n (\nabla\cdot\bar{\textbf{U}}) + \frac{1}{\bar{n}_n}\nabla\cdot\bar{\textbf{q}}_n \\
& = \bar{m}_{ni} \bar{\nu}_{ni} [2(\bar{T} - \bar{T}_n) + \frac{1}{3}\bar{m_i} \lvert \bar{\textbf{V}} - \bar{\textbf{U}} \rvert^2 ] + \frac{2}{3}\bar{Q}_n
\end{aligned}
\end{equation}
\begin{equation}\label{eq:norminductionequation}
\begin{aligned}
& \frac{\partial\bar{\textbf{B}}}{\partial \bar{t}} = \\
&\nabla\cdot(\bar{\textbf{B}}\bar{\textbf{V}}-\bar{\textbf{V}}\bar{\textbf{B}} + \bar{\textbf{B}}\bar{\textbf{V}}_{hall}-\bar{\textbf{V}}_{hall}\bar{\textbf{B}}) \\
&-\frac{\nabla \bar{n} \times \nabla \bar{T}_e}{\bar{n}\bar{e}} \\
&- \nabla\times(\frac{\bar{m_e}}{\bar{e}}[\bar{\nu}_{in} (\bar{\textbf{V}}-\bar{\textbf{U}}) - \bar{\nu}_{en}(\bar{\textbf{V}} - \bar{\textbf{U}})]) \\
& - \nabla\bar{\eta}\times\bar{\textbf{J}} + \eta\nabla^2\bar{\textbf{B}}
\end{aligned}
\end{equation}
\section{Validation}\label{sec:validation}
The simulation now needs to be validated against well known tests. Our goals are to have a scheme that is shock-capturing, and collissional. A classic test fluid codes undergo is the Sod shock tube test~\citep{Sod1978}. It is inspired by real life shock tubes in which a discontinuity is forced between the left and right halves of the tube. In a real shock tube the diaphragm between the two states is ruptured and the shocks are then observed. They're mostly used to observe material responses to shocks, however, we do have an analytical expectation of how the shock tube evolves through time.
The initial conditions for our left and right states in the CoMFi code are:
\begin{equation}\label{eq:shockinitialconditionsl}
\begin{pmatrix}
n_l \\
P_l \\
V_l \\
\end{pmatrix}
=
\begin{pmatrix}
1.0 \\
1.0 \\
0.0 \\
\end{pmatrix}
\end{equation}
\begin{equation}\label{eq:shockinitialconditionsr}
\begin{pmatrix}
n_r \\
P_r \\
V_r \\
\end{pmatrix}
=
\begin{pmatrix}
0.125 \\
0.1 \\
0.0 \\
\end{pmatrix}
\end{equation}
Figure~\ref{fig:shocktube} shows the tube after time $t = 0.1$ in arbitrary units. In the density graph it can be clearly seen the rarefaction wave, the contact discontinuity and the shock discontinuity. The exact sharpness is difficult to maintain in these codes but what is important is that it has not been too diffusive and the shocks are clear and maintaining their correct values. For the exact, analytical, solution see~\citet{Sod1978}. A resolution of 1001 grid points were used for this simulation. The boundary conditions on the right and left side are set equal to those initial values at all times. The energy equation was changed to the conservative internal energy equation to match Sod's equation set and what is used is the neutral component since it is acting more like a classical fluid and the Lorentz forces are irrelevant.
\begin{figure}[ht!]
\centering
\includegraphics[width=0.75\textwidth]{images/shocktube.eps}
\caption{Neutral fluid shock tube tests. The shocks are being captured appropriately due to the TVD-MUSCL scheme used.}\label{fig:shocktube}
\end{figure}
\citet{Soler2013} devised an initial value problem to test Alfv\'en waves in partially ionized plasmas. In the paper two-fluid plasma dynamics were explored in many ways. Analytical derivations and wave mode derivations were made. The initial value problem posed by~\citet{Soler2013} is based on their fundamental standing mode of an Alfv\'en wave in the fully ionized case of $\omega L / V_A = \pi / 20$. This means in the simulation domain of $z = (-10L,10L)$ an initial value for the velocity perturbation is:
\begin{equation}\label{eq:solerintial}
V_{\perp}(t=0,z) = \cos{(\frac{\pi}{20 L} z)}
\end{equation}
\begin{figure}[ht!]
\centering
\includegraphics[width=1\textwidth]{images/soler.eps}
\caption{The \citet{Soler2013} initial value problem tests. Velocity is taken at $z=0$ of the standing Alf\'ven wave. The solid red is the ion velocity, the dashed blue line is neutral velocity. The top row is where the initial neutral velocity is the same as the ion velocity and the bottom row is where the initial neutral velocity is at zero. The results resemble reasonably well the tests in the \citet{Soler2013} paper.}\label{fig:soler}
\end{figure}
\begin{figure}[ht!]
\centering
\includegraphics[width=1\textwidth]{images/soleretal2013.png}
\caption{Taken from \citet{Soler2013}. Compare with above (Figure~\ref{fig:soler}) for validation.}\label{fig:soleretal2013}
\end{figure}
The left and right boundary conditions in this case are set at $V_{\perp} = 0$ for both ions and neutrals. Constant and arbitrary for all other values. Three different orders of magnitude of the collision rate was used for two different cases. The first with a neutral initial value the same as the ions $V_{\perp} = U_{\perp}$ and the other where $U=0$. The results in Figure~\ref{fig:soler} show the results at $z=0$ and the Alfv\'en wave can be seen clearly damped in the cases. Note how at $\nu_{ni}=1$ the medium is moving in unison but still being damped. It is also important to note the equations used to solve this are fundamentally different than the ones in~\citet{Soler2013}. They solve for the primitive variables while CoMFi solves the conservative form. Still the graphs look similar (Figure~\ref{fig:soleretal2013}) which helps with the case of the validation of the code.
\subsection{Visualization}\label{sec:visualization}
CoMFi comes with its own visualization suite written in Python using Matplotlib~\citep{Hunter2007}. The data is saved in the HDF5 file format~\citep{hdf5} which is compatible with many other visualization software, however the bundled \code{plot-scripts} folder contains the file \code{comfi.py} when imported gives tools to make plots and even animations.
\subsection{Storage}
CoMFi uses the HDF5 file format to store the data. The data hierarchy is shown in Table~\ref{tab:datahierarchy}. Other software like Origin, IDL or Tecplot may be easily used with this format. The data found in each variable is a matrix of the form, $u[x, {nz}-z]$, where ${nz}$ is the number of grid cells in height. This was chosen so the matrix is displayed properly if shown in matrix form. Some software will require the matrix to be flipped when plotted.
\begin{table}[h]\label{tab:datahierarchy}
\centering
\caption[CoMFi.hdf5 data hierarchy]{The HDF5 data hierarchy of the CoMFi code, this may be used in any visualization software with HDF5 support like IDL\@. All data is normalized. The \code{time-step} parent data name is referring to the time step of interest in the data. The \code{constant} name refers to the constant of interest with proper capitalization.}
\begin{tabular}[]{l c r}
\toprule
Time Vector & \code{/t} \\
Normalization Constants & \code{/norm/[constant]} \\
Ion Density & \code{/[time-step]/Np} \\
Neutral Density & \code{/[time-step]/Nn} \\
Ion Momentum (Horizontal) & \code{/[time-step]/NVx} \\
Ion Momentum (Vertical) & \code{/[time-step]/NVz} \\
Ion Momentum (Perpendicular) & \code{/[time-step]/NVp} \\
Neutral Momentum (Horizontal) & \code{/[time-step]/NUx} \\
Neutral Momentum (Vertical) & \code{/[time-step]/NUz} \\
Neutral Momentum (Perpendicular) & \code{/[time-step]/NUp} \\
Ion Temperature & \code{/[time-step]/Tp} \\
Neutral Temperature & \code{/[time-step]/Tn} \\
Magnetic Field (Horizontal) & \code{/[time-step]/Bx} \\
Magnetic Field (Vertical) & \code{/[time-step]/Bz} \\
Magnetic Field (Perpendicular) & \code{/[time-step]/Bp} \\
Electron Temperature (Optional) & \code{/[time-step]/Te} \\
Electron Pressure (Optional) & \code{/[time-step]/Pe} \\