PySDM_examples.Lowe_et_al_2019.aerosol

  1from chempy import Substance
  2from pystrict import strict
  3
  4from PySDM.initialisation import spectra
  5from PySDM.initialisation.aerosol_composition import DryAerosolMixture
  6from PySDM.physics import si
  7
  8
  9@strict
 10class AerosolMarine(DryAerosolMixture):
 11    def __init__(
 12        self, water_molar_volume: float, Forg: float = 0.2, Acc_N2: float = 134
 13    ):
 14        Aitken = {
 15            "palmitic": Forg,
 16            "(NH4)2SO4": (1 - Forg),
 17            "NaCl": 0,
 18        }
 19        Accumulation = {
 20            "palmitic": Forg,
 21            "(NH4)2SO4": 0,
 22            "NaCl": (1 - Forg),
 23        }
 24
 25        super().__init__(
 26            ionic_dissociation_phi={
 27                "palmitic": 1,
 28                "(NH4)2SO4": 3,
 29                "NaCl": 2,
 30            },
 31            is_soluble={
 32                "palmitic": False,
 33                "(NH4)2SO4": True,
 34                "NaCl": True,
 35            },
 36            densities={
 37                "palmitic": 0.852 * si.g / si.cm**3,
 38                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
 39                "NaCl": 2.16 * si.g / si.cm**3,
 40            },
 41            compounds=("palmitic", "(NH4)2SO4", "NaCl"),
 42            molar_masses={
 43                "palmitic": 256.4 * si.g / si.mole,
 44                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
 45                * si.gram
 46                / si.mole,
 47                "NaCl": Substance.from_formula("NaCl").mass * si.gram / si.mole,
 48            },
 49        )
 50        self.modes = (
 51            {
 52                "f_org": 1 - self.f_soluble_volume(Aitken),
 53                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
 54                "nu_org": self.nu_org(Aitken),
 55                "spectrum": spectra.Lognormal(
 56                    norm_factor=226 / si.cm**3, m_mode=19.6 * si.nm, s_geom=1.71
 57                ),
 58            },
 59            {
 60                "f_org": 1 - self.f_soluble_volume(Accumulation),
 61                "kappa": self.kappa(
 62                    Accumulation, water_molar_volume=water_molar_volume
 63                ),
 64                "nu_org": self.nu_org(Accumulation),
 65                "spectrum": spectra.Lognormal(
 66                    norm_factor=Acc_N2 / si.cm**3, m_mode=69.5 * si.nm, s_geom=1.7
 67                ),
 68            },
 69        )
 70
 71    color = "dodgerblue"
 72
 73
 74@strict
 75class AerosolBoreal(DryAerosolMixture):
 76    def __init__(
 77        self, water_molar_volume: float, Forg: float = 0.668, Acc_N2: float = 540
 78    ):
 79        # note: SOA1 or SOA2 unclear from the paper
 80        Aitken = {
 81            "SOA1": Forg,
 82            "SOA2": 0,
 83            "(NH4)2SO4": (1 - Forg) / 2,
 84            "NH4NO3": (1 - Forg) / 2,
 85        }
 86        Accumulation = {
 87            "SOA1": 0,
 88            "SOA2": Forg,
 89            "(NH4)2SO4": (1 - Forg) / 2,
 90            "NH4NO3": (1 - Forg) / 2,
 91        }
 92
 93        super().__init__(
 94            ionic_dissociation_phi={
 95                "SOA1": 1,
 96                "SOA2": 1,
 97                "(NH4)2SO4": 3,
 98                "NH4NO3": 2,
 99            },
100            molar_masses={
101                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
102                * si.gram
103                / si.mole,
104                "NH4NO3": Substance.from_formula("NH4NO3").mass * si.gram / si.mole,
105                "SOA1": 190 * si.g / si.mole,
106                "SOA2": 368.4 * si.g / si.mole,
107            },
108            densities={
109                "SOA1": 1.24 * si.g / si.cm**3,
110                "SOA2": 1.2 * si.g / si.cm**3,
111                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
112                "NH4NO3": 1.72 * si.g / si.cm**3,
113            },
114            compounds=("SOA1", "SOA2", "(NH4)2SO4", "NH4NO3"),
115            is_soluble={
116                "SOA1": False,
117                "SOA2": False,
118                "(NH4)2SO4": True,
119                "NH4NO3": True,
120            },
121        )
122        self.modes = (
123            {
124                "f_org": 1 - self.f_soluble_volume(Aitken),
125                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
126                "nu_org": self.nu_org(Aitken),
127                "spectrum": spectra.Lognormal(
128                    norm_factor=1110 / si.cm**3, m_mode=22.7 * si.nm, s_geom=1.75
129                ),
130            },
131            {
132                "f_org": 1 - self.f_soluble_volume(Accumulation),
133                "kappa": self.kappa(
134                    Accumulation, water_molar_volume=water_molar_volume
135                ),
136                "nu_org": self.nu_org(Accumulation),
137                "spectrum": spectra.Lognormal(
138                    norm_factor=Acc_N2 / si.cm**3,
139                    m_mode=82.2 * si.nm,
140                    s_geom=1.62,
141                ),
142            },
143        )
144
145    color = "yellowgreen"
146
147
148@strict
149class AerosolNascent(DryAerosolMixture):
150    def __init__(
151        self, water_molar_volume: float, Acc_Forg: float = 0.3, Acc_N2: float = 30
152    ):
153        Ultrafine = {
154            "SOA1": 0.52,
155            "SOA2": 0,
156            "(NH4)2SO4": 0.48,
157        }
158        Accumulation = {
159            "SOA1": 0,
160            "SOA2": Acc_Forg,
161            "(NH4)2SO4": (1 - Acc_Forg),
162        }
163        super().__init__(
164            ionic_dissociation_phi={
165                "SOA1": 1,
166                "SOA2": 1,
167                "(NH4)2SO4": 3,
168            },
169            molar_masses={
170                "SOA1": 190 * si.g / si.mole,
171                "SOA2": 368.4 * si.g / si.mole,
172                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
173                * si.gram
174                / si.mole,
175            },
176            densities={
177                "SOA1": 1.24 * si.g / si.cm**3,
178                "SOA2": 1.2 * si.g / si.cm**3,
179                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
180            },
181            compounds=("SOA1", "SOA2", "(NH4)2SO4"),
182            is_soluble={
183                "SOA1": False,
184                "SOA2": False,
185                "(NH4)2SO4": True,
186            },
187        )
188        self.modes = (
189            {
190                "f_org": 1 - self.f_soluble_volume(Ultrafine),
191                "kappa": self.kappa(Ultrafine, water_molar_volume=water_molar_volume),
192                "nu_org": self.nu_org(Ultrafine),
193                "spectrum": spectra.Lognormal(
194                    norm_factor=2000 / si.cm**3, m_mode=11.5 * si.nm, s_geom=1.71
195                ),
196            },
197            {
198                "f_org": 1 - self.f_soluble_volume(Accumulation),
199                "kappa": self.kappa(
200                    Accumulation, water_molar_volume=water_molar_volume
201                ),
202                "nu_org": self.nu_org(Accumulation),
203                "spectrum": spectra.Lognormal(
204                    norm_factor=Acc_N2 / si.cm**3, m_mode=100 * si.nm, s_geom=1.70
205                ),
206            },
207        )
208
209    color = "orangered"
10@strict
11class AerosolMarine(DryAerosolMixture):
12    def __init__(
13        self, water_molar_volume: float, Forg: float = 0.2, Acc_N2: float = 134
14    ):
15        Aitken = {
16            "palmitic": Forg,
17            "(NH4)2SO4": (1 - Forg),
18            "NaCl": 0,
19        }
20        Accumulation = {
21            "palmitic": Forg,
22            "(NH4)2SO4": 0,
23            "NaCl": (1 - Forg),
24        }
25
26        super().__init__(
27            ionic_dissociation_phi={
28                "palmitic": 1,
29                "(NH4)2SO4": 3,
30                "NaCl": 2,
31            },
32            is_soluble={
33                "palmitic": False,
34                "(NH4)2SO4": True,
35                "NaCl": True,
36            },
37            densities={
38                "palmitic": 0.852 * si.g / si.cm**3,
39                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
40                "NaCl": 2.16 * si.g / si.cm**3,
41            },
42            compounds=("palmitic", "(NH4)2SO4", "NaCl"),
43            molar_masses={
44                "palmitic": 256.4 * si.g / si.mole,
45                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
46                * si.gram
47                / si.mole,
48                "NaCl": Substance.from_formula("NaCl").mass * si.gram / si.mole,
49            },
50        )
51        self.modes = (
52            {
53                "f_org": 1 - self.f_soluble_volume(Aitken),
54                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
55                "nu_org": self.nu_org(Aitken),
56                "spectrum": spectra.Lognormal(
57                    norm_factor=226 / si.cm**3, m_mode=19.6 * si.nm, s_geom=1.71
58                ),
59            },
60            {
61                "f_org": 1 - self.f_soluble_volume(Accumulation),
62                "kappa": self.kappa(
63                    Accumulation, water_molar_volume=water_molar_volume
64                ),
65                "nu_org": self.nu_org(Accumulation),
66                "spectrum": spectra.Lognormal(
67                    norm_factor=Acc_N2 / si.cm**3, m_mode=69.5 * si.nm, s_geom=1.7
68                ),
69            },
70        )
71
72    color = "dodgerblue"
AerosolMarine(water_molar_volume: float, Forg: float = 0.2, Acc_N2: float = 134)
12    def __init__(
13        self, water_molar_volume: float, Forg: float = 0.2, Acc_N2: float = 134
14    ):
15        Aitken = {
16            "palmitic": Forg,
17            "(NH4)2SO4": (1 - Forg),
18            "NaCl": 0,
19        }
20        Accumulation = {
21            "palmitic": Forg,
22            "(NH4)2SO4": 0,
23            "NaCl": (1 - Forg),
24        }
25
26        super().__init__(
27            ionic_dissociation_phi={
28                "palmitic": 1,
29                "(NH4)2SO4": 3,
30                "NaCl": 2,
31            },
32            is_soluble={
33                "palmitic": False,
34                "(NH4)2SO4": True,
35                "NaCl": True,
36            },
37            densities={
38                "palmitic": 0.852 * si.g / si.cm**3,
39                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
40                "NaCl": 2.16 * si.g / si.cm**3,
41            },
42            compounds=("palmitic", "(NH4)2SO4", "NaCl"),
43            molar_masses={
44                "palmitic": 256.4 * si.g / si.mole,
45                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
46                * si.gram
47                / si.mole,
48                "NaCl": Substance.from_formula("NaCl").mass * si.gram / si.mole,
49            },
50        )
51        self.modes = (
52            {
53                "f_org": 1 - self.f_soluble_volume(Aitken),
54                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
55                "nu_org": self.nu_org(Aitken),
56                "spectrum": spectra.Lognormal(
57                    norm_factor=226 / si.cm**3, m_mode=19.6 * si.nm, s_geom=1.71
58                ),
59            },
60            {
61                "f_org": 1 - self.f_soluble_volume(Accumulation),
62                "kappa": self.kappa(
63                    Accumulation, water_molar_volume=water_molar_volume
64                ),
65                "nu_org": self.nu_org(Accumulation),
66                "spectrum": spectra.Lognormal(
67                    norm_factor=Acc_N2 / si.cm**3, m_mode=69.5 * si.nm, s_geom=1.7
68                ),
69            },
70        )
modes
39    @property
40    def modes(self):
41        return self._modes
color = 'dodgerblue'
 75@strict
 76class AerosolBoreal(DryAerosolMixture):
 77    def __init__(
 78        self, water_molar_volume: float, Forg: float = 0.668, Acc_N2: float = 540
 79    ):
 80        # note: SOA1 or SOA2 unclear from the paper
 81        Aitken = {
 82            "SOA1": Forg,
 83            "SOA2": 0,
 84            "(NH4)2SO4": (1 - Forg) / 2,
 85            "NH4NO3": (1 - Forg) / 2,
 86        }
 87        Accumulation = {
 88            "SOA1": 0,
 89            "SOA2": Forg,
 90            "(NH4)2SO4": (1 - Forg) / 2,
 91            "NH4NO3": (1 - Forg) / 2,
 92        }
 93
 94        super().__init__(
 95            ionic_dissociation_phi={
 96                "SOA1": 1,
 97                "SOA2": 1,
 98                "(NH4)2SO4": 3,
 99                "NH4NO3": 2,
100            },
101            molar_masses={
102                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
103                * si.gram
104                / si.mole,
105                "NH4NO3": Substance.from_formula("NH4NO3").mass * si.gram / si.mole,
106                "SOA1": 190 * si.g / si.mole,
107                "SOA2": 368.4 * si.g / si.mole,
108            },
109            densities={
110                "SOA1": 1.24 * si.g / si.cm**3,
111                "SOA2": 1.2 * si.g / si.cm**3,
112                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
113                "NH4NO3": 1.72 * si.g / si.cm**3,
114            },
115            compounds=("SOA1", "SOA2", "(NH4)2SO4", "NH4NO3"),
116            is_soluble={
117                "SOA1": False,
118                "SOA2": False,
119                "(NH4)2SO4": True,
120                "NH4NO3": True,
121            },
122        )
123        self.modes = (
124            {
125                "f_org": 1 - self.f_soluble_volume(Aitken),
126                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
127                "nu_org": self.nu_org(Aitken),
128                "spectrum": spectra.Lognormal(
129                    norm_factor=1110 / si.cm**3, m_mode=22.7 * si.nm, s_geom=1.75
130                ),
131            },
132            {
133                "f_org": 1 - self.f_soluble_volume(Accumulation),
134                "kappa": self.kappa(
135                    Accumulation, water_molar_volume=water_molar_volume
136                ),
137                "nu_org": self.nu_org(Accumulation),
138                "spectrum": spectra.Lognormal(
139                    norm_factor=Acc_N2 / si.cm**3,
140                    m_mode=82.2 * si.nm,
141                    s_geom=1.62,
142                ),
143            },
144        )
145
146    color = "yellowgreen"
AerosolBoreal(water_molar_volume: float, Forg: float = 0.668, Acc_N2: float = 540)
 77    def __init__(
 78        self, water_molar_volume: float, Forg: float = 0.668, Acc_N2: float = 540
 79    ):
 80        # note: SOA1 or SOA2 unclear from the paper
 81        Aitken = {
 82            "SOA1": Forg,
 83            "SOA2": 0,
 84            "(NH4)2SO4": (1 - Forg) / 2,
 85            "NH4NO3": (1 - Forg) / 2,
 86        }
 87        Accumulation = {
 88            "SOA1": 0,
 89            "SOA2": Forg,
 90            "(NH4)2SO4": (1 - Forg) / 2,
 91            "NH4NO3": (1 - Forg) / 2,
 92        }
 93
 94        super().__init__(
 95            ionic_dissociation_phi={
 96                "SOA1": 1,
 97                "SOA2": 1,
 98                "(NH4)2SO4": 3,
 99                "NH4NO3": 2,
100            },
101            molar_masses={
102                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
103                * si.gram
104                / si.mole,
105                "NH4NO3": Substance.from_formula("NH4NO3").mass * si.gram / si.mole,
106                "SOA1": 190 * si.g / si.mole,
107                "SOA2": 368.4 * si.g / si.mole,
108            },
109            densities={
110                "SOA1": 1.24 * si.g / si.cm**3,
111                "SOA2": 1.2 * si.g / si.cm**3,
112                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
113                "NH4NO3": 1.72 * si.g / si.cm**3,
114            },
115            compounds=("SOA1", "SOA2", "(NH4)2SO4", "NH4NO3"),
116            is_soluble={
117                "SOA1": False,
118                "SOA2": False,
119                "(NH4)2SO4": True,
120                "NH4NO3": True,
121            },
122        )
123        self.modes = (
124            {
125                "f_org": 1 - self.f_soluble_volume(Aitken),
126                "kappa": self.kappa(Aitken, water_molar_volume=water_molar_volume),
127                "nu_org": self.nu_org(Aitken),
128                "spectrum": spectra.Lognormal(
129                    norm_factor=1110 / si.cm**3, m_mode=22.7 * si.nm, s_geom=1.75
130                ),
131            },
132            {
133                "f_org": 1 - self.f_soluble_volume(Accumulation),
134                "kappa": self.kappa(
135                    Accumulation, water_molar_volume=water_molar_volume
136                ),
137                "nu_org": self.nu_org(Accumulation),
138                "spectrum": spectra.Lognormal(
139                    norm_factor=Acc_N2 / si.cm**3,
140                    m_mode=82.2 * si.nm,
141                    s_geom=1.62,
142                ),
143            },
144        )
modes
39    @property
40    def modes(self):
41        return self._modes
color = 'yellowgreen'
149@strict
150class AerosolNascent(DryAerosolMixture):
151    def __init__(
152        self, water_molar_volume: float, Acc_Forg: float = 0.3, Acc_N2: float = 30
153    ):
154        Ultrafine = {
155            "SOA1": 0.52,
156            "SOA2": 0,
157            "(NH4)2SO4": 0.48,
158        }
159        Accumulation = {
160            "SOA1": 0,
161            "SOA2": Acc_Forg,
162            "(NH4)2SO4": (1 - Acc_Forg),
163        }
164        super().__init__(
165            ionic_dissociation_phi={
166                "SOA1": 1,
167                "SOA2": 1,
168                "(NH4)2SO4": 3,
169            },
170            molar_masses={
171                "SOA1": 190 * si.g / si.mole,
172                "SOA2": 368.4 * si.g / si.mole,
173                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
174                * si.gram
175                / si.mole,
176            },
177            densities={
178                "SOA1": 1.24 * si.g / si.cm**3,
179                "SOA2": 1.2 * si.g / si.cm**3,
180                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
181            },
182            compounds=("SOA1", "SOA2", "(NH4)2SO4"),
183            is_soluble={
184                "SOA1": False,
185                "SOA2": False,
186                "(NH4)2SO4": True,
187            },
188        )
189        self.modes = (
190            {
191                "f_org": 1 - self.f_soluble_volume(Ultrafine),
192                "kappa": self.kappa(Ultrafine, water_molar_volume=water_molar_volume),
193                "nu_org": self.nu_org(Ultrafine),
194                "spectrum": spectra.Lognormal(
195                    norm_factor=2000 / si.cm**3, m_mode=11.5 * si.nm, s_geom=1.71
196                ),
197            },
198            {
199                "f_org": 1 - self.f_soluble_volume(Accumulation),
200                "kappa": self.kappa(
201                    Accumulation, water_molar_volume=water_molar_volume
202                ),
203                "nu_org": self.nu_org(Accumulation),
204                "spectrum": spectra.Lognormal(
205                    norm_factor=Acc_N2 / si.cm**3, m_mode=100 * si.nm, s_geom=1.70
206                ),
207            },
208        )
209
210    color = "orangered"
AerosolNascent(water_molar_volume: float, Acc_Forg: float = 0.3, Acc_N2: float = 30)
151    def __init__(
152        self, water_molar_volume: float, Acc_Forg: float = 0.3, Acc_N2: float = 30
153    ):
154        Ultrafine = {
155            "SOA1": 0.52,
156            "SOA2": 0,
157            "(NH4)2SO4": 0.48,
158        }
159        Accumulation = {
160            "SOA1": 0,
161            "SOA2": Acc_Forg,
162            "(NH4)2SO4": (1 - Acc_Forg),
163        }
164        super().__init__(
165            ionic_dissociation_phi={
166                "SOA1": 1,
167                "SOA2": 1,
168                "(NH4)2SO4": 3,
169            },
170            molar_masses={
171                "SOA1": 190 * si.g / si.mole,
172                "SOA2": 368.4 * si.g / si.mole,
173                "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass
174                * si.gram
175                / si.mole,
176            },
177            densities={
178                "SOA1": 1.24 * si.g / si.cm**3,
179                "SOA2": 1.2 * si.g / si.cm**3,
180                "(NH4)2SO4": 1.77 * si.g / si.cm**3,
181            },
182            compounds=("SOA1", "SOA2", "(NH4)2SO4"),
183            is_soluble={
184                "SOA1": False,
185                "SOA2": False,
186                "(NH4)2SO4": True,
187            },
188        )
189        self.modes = (
190            {
191                "f_org": 1 - self.f_soluble_volume(Ultrafine),
192                "kappa": self.kappa(Ultrafine, water_molar_volume=water_molar_volume),
193                "nu_org": self.nu_org(Ultrafine),
194                "spectrum": spectra.Lognormal(
195                    norm_factor=2000 / si.cm**3, m_mode=11.5 * si.nm, s_geom=1.71
196                ),
197            },
198            {
199                "f_org": 1 - self.f_soluble_volume(Accumulation),
200                "kappa": self.kappa(
201                    Accumulation, water_molar_volume=water_molar_volume
202                ),
203                "nu_org": self.nu_org(Accumulation),
204                "spectrum": spectra.Lognormal(
205                    norm_factor=Acc_N2 / si.cm**3, m_mode=100 * si.nm, s_geom=1.70
206                ),
207            },
208        )
modes
39    @property
40    def modes(self):
41        return self._modes
color = 'orangered'