• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zincware / MDSuite / 3999396905

pending completion
3999396905

push

github-actions

GitHub
[merge before other PRs] ruff updates (#580)

960 of 1311 branches covered (73.23%)

Branch coverage included in aggregate %.

15 of 15 new or added lines in 11 files covered. (100.0%)

4034 of 4930 relevant lines covered (81.83%)

3.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

11.43
/mdsuite/calculators/nernst_einstein_ionic_conductivity.py
1
"""
2
MDSuite: A Zincwarecode package.
3

4
License
5
-------
6
This program and the accompanying materials are made available under the terms
7
of the Eclipse Public License v2.0 which accompanies this distribution, and is
8
available at https://www.eclipse.org/legal/epl-v20.html
9

10
SPDX-License-Identifier: EPL-2.0
11

12
Copyright Contributors to the Zincwarecode Project.
13

14
Contact Information
15
-------------------
16
email: zincwarecode@gmail.com
17
github: https://github.com/zincware
18
web: https://zincwarecode.com/
19

20
Citation
21
--------
22
If you use this module please cite us with:
23

24
Summary
25
-------
26
"""
27
import logging
4✔
28
import operator
4✔
29

30
from mdsuite.calculators.calculator import Calculator, call
4✔
31
from mdsuite.utils.units import boltzmann_constant, elementary_charge
4✔
32

33
log = logging.getLogger(__name__)
4✔
34

35

36
class NernstEinsteinIonicConductivity(Calculator):
4✔
37
    """
38
    Class for the calculation of the Nernst-Einstein ionic conductivity.
39

40
    See Also
41
    --------
42
    mdsuite.calculators.calculator.Calculator class
43

44
    Examples
45
    --------
46
    experiment.run_computation.NernstEinsteinIonicConductivity()
47

48
    """
49

50
    def __init__(self, **kwargs):
4✔
51
        """
52
        Standard constructor.
53

54
        Parameters
55
        ----------
56
        experiment : Experiment
57
                Experiment class from which to read
58
        """
59
        super().__init__(**kwargs)
×
60
        self.post_generation = True
×
61

62
        # Properties
63
        self._truth_table = None
×
64

65
        self.database_group = "Ionic_Conductivity"
×
66
        self.analysis_name = "Nernst_Einstein_Ionic_Conductivity"
×
67

68
    @call
4✔
69
    def __call__(
4✔
70
        self,
71
        corrected: bool = False,
72
        plot: bool = False,
73
        data_range: int = 1,
74
        export: bool = False,
75
        species: list = None,
76
        save: bool = True,
77
    ):
78
        """
79
        Standard constructor.
80

81
        Parameters
82
        ----------
83
        corrected : bool
84
                If true, correct the output with the distinct diffusion
85
                coefficient.
86
        export : bool
87
                If true, generate a csv file after the analysis.
88
        plot : bool
89
                if true, plot the output.
90
        species : list
91
                List of species on which to operate.
92
        data_range : int
93
                Data range to use in the analysis.
94
        save : bool
95
                if true, save the output.
96
        """
97
        self.update_user_args(plot=plot, save=False, data_range=data_range, export=export)
×
98
        self.corrected = corrected
×
99
        self.data = self._load_data()  # tensor_values to be read in
×
100

101
        if species is None:
×
102
            self.species = list(self.experiment.species)
×
103
        else:
104
            self.species = species
×
105

106
    def _load_data(self):
4✔
107
        """
108
        Load tensor_values from a yaml file.
109

110
        Returns
111
        -------
112
        tensor_values: dict
113
                A dictionary of tensor_values stored in the yaml file
114
        """
115
        test = self.experiment.export_property_data(
×
116
            {"property": "Diffusion_Coefficients"}
117
        )
118
        return test
×
119

120
    @property
4✔
121
    def truth_table(self):
3✔
122
        """
123
        Builds a truth table to communicate which tensor_values is available to the
124
        analysis.
125

126
        Returns
127
        -------
128
        truth_table : list
129
                A truth table communication which tensor_values is available for the
130
                analysis.
131
        """
132
        if self._truth_table is None:
×
133
            log.warning(
×
134
                "No support for different data ranges! This method always picks the"
135
                " first entry in the database!"
136
            )
137
            case_1 = self.experiment.export_property_data(
×
138
                {
139
                    "property": "Diffusion_Coefficients",
140
                    "analysis": "Green_Kubo_Self_Diffusion_Coefficients",
141
                }
142
            )
143
            case_2 = self.experiment.export_property_data(
×
144
                {
145
                    "property": "Diffusion_Coefficients",
146
                    "analysis": "Green_Kubo_Distinct_Diffusion_Coefficients",
147
                }
148
            )
149
            case_3 = self.experiment.export_property_data(
×
150
                {
151
                    "property": "Diffusion_Coefficients",
152
                    "analysis": "Einstein_Self_Diffusion_Coefficients",
153
                }
154
            )
155
            case_4 = self.experiment.export_property_data(
×
156
                {
157
                    "property": "Diffusion_Coefficients",
158
                    "analysis": "Einstein_Distinct_Diffusion_Coefficients",
159
                }
160
            )
161
            truth_table = [
×
162
                list(map(operator.not_, [not case_1, not case_2])),
163
                list(map(operator.not_, [not case_3, not case_4])),
164
            ]
165
            self._truth_table = truth_table
×
166
        return self._truth_table
×
167

168
    def _nernst_einstein(self, diffusion_information: list):
4✔
169
        """
170
        Calculate the Nernst-Einstein ionic conductivity.
171

172
        Parameters
173
        ----------
174
        diffusion_information : list
175
                A list of dictionaries loaded from the SQL properties database.
176

177
        Returns
178
        -------
179
        Nernst-Einstein Ionic conductivity of the experiment in units of S/cm
180
        """
181
        # evaluate the prefactor
182
        numerator = self.experiment.number_of_atoms * (elementary_charge**2)
×
183
        denominator = (
×
184
            boltzmann_constant
185
            * self.experiment.temperature
186
            * (self.experiment.volume * self.experiment.units.volume)
187
        )
188
        prefactor = numerator / denominator
×
189

190
        conductivity = 0.0
×
191
        uncertainty = 0.0
×
192
        for item in diffusion_information:
×
193
            log.debug(f"Analysing: {item}")
×
194
            diffusion_coefficient = item.data_dict[0].x
×
195
            diffusion_uncertainty = item.data_dict[0].uncertainty
×
196
            species = item.subjects[0].subject
×
197
            charge_term = self.experiment.species[species].charge[0] ** 2
×
198
            mass_fraction_term = (
×
199
                self.experiment.species[species].n_particles
200
                / self.experiment.number_of_atoms
201
            )
202
            conductivity += diffusion_coefficient * charge_term * mass_fraction_term
×
203
            uncertainty += diffusion_uncertainty * charge_term * mass_fraction_term
×
204
            data_range = item.data_range
×
205

206
        return [prefactor * conductivity, prefactor * uncertainty, data_range]
×
207

208
    def _corrected_nernst_einstein(
4✔
209
        self, self_diffusion_information: list, distinct_diffusion_information: list
210
    ):
211
        """
212
        Calculate the corrected Nernst-Einstein ionic conductivity.
213

214
        Parameters
215
        ----------
216
        self_diffusion_information : dict
217
                dictionary containing information about self diffusion
218
        distinct_diffusion_information : dict
219
                dictionary containing information about distinct diffusion
220

221
        Returns
222
        -------
223
        Corrected Nernst-Einstein ionic conductivity in units of S/cm
224
        """
225
        # evaluate the prefactor
226
        numerator = self.experiment.number_of_atoms * (elementary_charge**2)
×
227
        denominator = (
×
228
            boltzmann_constant
229
            * self.experiment.temperature
230
            * (self.experiment.volume * self.experiment.units.volume)
231
        )
232
        prefactor = numerator / denominator
×
233

234
        conductivity = 0.0
×
235
        uncertainty = 0.0
×
236
        for item in self_diffusion_information:
×
237
            diffusion_coefficient = item["data"]
×
238
            diffusion_uncertainty = item["uncertainty"]
×
239
            species = item["Subject"]
×
240
            charge_term = self.experiment.species[species].charge[0] ** 2
×
241
            mass_fraction_term = (
×
242
                self.experiment.species[species].n_particles
243
                / self.experiment.number_of_atoms
244
            )
245
            conductivity += diffusion_coefficient * charge_term * mass_fraction_term
×
246
            uncertainty += diffusion_uncertainty * charge_term * mass_fraction_term
×
247
            data_range = item["data_range"]
×
248
        for item in distinct_diffusion_information:
×
249
            diffusion_coefficient = item["data"]
×
250
            diffusion_uncertainty = item["uncertainty"]
×
251
            constituents = item["Subject"].split("_")
×
252
            charge_term = (
×
253
                self.experiment.species[constituents[0]].charge[0]
254
                * self.experiment.species[constituents[1]].charge[0]
255
            )
256
            mass_fraction_term = (
×
257
                self.experiment.species[constituents[0]].n_particles
258
                / self.experiment.number_of_atoms
259
            ) * (
260
                self.experiment.species[constituents[1]].n_particles
261
                / self.experiment.number_of_atoms
262
            )
263
            conductivity += diffusion_coefficient * charge_term * mass_fraction_term
×
264
            uncertainty += diffusion_uncertainty * charge_term * mass_fraction_term
×
265

266
        return [prefactor * conductivity, prefactor * uncertainty, data_range]
×
267

268
    def _run_nernst_einstein(self):
4✔
269
        """
270
        Process truth table and run all possible nernst-einstein calculations.
271

272
        Returns
273
        -------
274

275
        """
276
        ne_table = [self.truth_table[0][0], self.truth_table[1][0]]
×
277
        if ne_table[0]:
×
278
            input_data = [
×
279
                self.experiment.export_property_data(
280
                    {
281
                        "property": "Diffusion_Coefficients",
282
                        "analysis": "Green_Kubo_Self_Diffusion_Coefficients",
283
                        "subjects": [species[0] for species in self.species],
284
                    }
285
                )
286
            ]
287
            data = self._nernst_einstein(input_data)
×
288
            properties = {
×
289
                "Property": self.database_group,
290
                "Analysis": "Green_Kubo_Nernst_Einstein_Ionic_Conductivity",
291
                "Subject": ["System"],
292
                "data_range": data[2],
293
                "data": [{"x": data[0], "uncertainty": data[1]}],
294
            }
295
            self._update_properties_file(properties)
×
296

297
        if ne_table[1]:
×
298
            input_data = [
×
299
                self.experiment.export_property_data(
300
                    {
301
                        "property": "Diffusion_Coefficients",
302
                        "analysis": "Einstein_Self_Diffusion_Coefficients",
303
                        "subjects": [species[0] for species in self.species],
304
                    }
305
                )
306
            ]
307
            data = self._nernst_einstein(input_data)
×
308

309
            properties = {
×
310
                "Property": self.database_group,
311
                "Analysis": "Einstein_Nernst_Einstein_Ionic_Conductivity",
312
                "Subject": ["System"],
313
                "data_range": data[2],
314
                "data": [{"x": data[0], "uncertainty": data[1]}],
315
            }
316
            self._update_properties_file(properties)
×
317

318
        if not any(ne_table):
×
319
            ValueError(
×
320
                "There is no values to analyse, please run a diffusion calculation to"
321
                " proceed"
322
            )
323

324
    def _run_corrected_nernst_einstein(self):
4✔
325
        """
326
        Process truth table and run all possible nernst-einstein calculations.
327

328
        Returns
329
        -------
330
        Updates the experiment database_path
331
        """
332
        cne_table = [self.truth_table[0][1], self.truth_table[1][1]]
×
333

334
        if cne_table[0]:
×
335
            input_self = [
×
336
                self.experiment.export_property_data(
337
                    {
338
                        "property": "Diffusion_Coefficients",
339
                        "analysis": "Green_Kubo_Self_Diffusion_Coefficients",
340
                        "subjects": [species],
341
                    }
342
                )[0]
343
                for species in self.species
344
            ]
345
            input_distinct = [
×
346
                self.experiment.export_property_data(
347
                    {
348
                        "property": "Diffusion_Coefficients",
349
                        "analysis": "Green_Kubo_Distinct_Diffusion_Coefficients",
350
                        "subjects": [species],
351
                    }
352
                )[0]
353
                for species in self.species
354
            ]
355
            data = self._corrected_nernst_einstein(input_self, input_distinct)
×
356

357
            properties = {
×
358
                "Property": self.database_group,
359
                "Analysis": "Green_Kubo_Corrected_Nernst_Einstein_Ionic_Conductivity",
360
                "Subject": ["System"],
361
                "data_range": data[2],
362
                "data": [{"x": data[0], "uncertainty": data[1]}],
363
            }
364
            self._update_properties_file(properties)
×
365

366
        if cne_table[1]:
×
367
            input_self = [
×
368
                self.experiment.export_property_data(
369
                    {
370
                        "property": "Diffusion_Coefficients",
371
                        "analysis": "Einstein_Self_Diffusion_Coefficients",
372
                        "subjects": [species],
373
                    }
374
                )[0]
375
                for species in self.species
376
            ]
377
            input_distinct = [
×
378
                self.experiment.export_property_data(
379
                    {
380
                        "property": "Diffusion_Coefficients",
381
                        "analysis": "Einstein_Distinct_Diffusion_Coefficients",
382
                        "subjects": [species],
383
                    }
384
                )[0]
385
                for species in self.species
386
            ]
387
            data = self._corrected_nernst_einstein(input_self, input_distinct)
×
388

389
            properties = {
×
390
                "Property": self.database_group,
391
                "Analysis": "Einstein_Corrected_Nernst_Einstein_Ionic_Conductivity",
392
                "Subject": ["System"],
393
                "data_range": data[2],
394
                "data": [{"x": data[0], "uncertainty": data[1]}],
395
            }
396
            self._update_properties_file(properties)
×
397

398
    def run_post_generation_analysis(self):
4✔
399
        """Run the analysis."""
400
        self._run_nernst_einstein()
×
401
        if self.corrected:
×
402
            self._run_corrected_nernst_einstein()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc