Statistiques
| Révision :

root / ase / md / logger.py @ 19

Historique | Voir | Annoter | Télécharger (3,17 ko)

1 1 tkerber
"""Logging for molecular dynamics."""
2 1 tkerber
3 1 tkerber
import weakref
4 1 tkerber
import sys
5 1 tkerber
import ase.units as units
6 1 tkerber
# ase.parallel imported in __init__
7 1 tkerber
8 1 tkerber
class MDLogger:
9 1 tkerber
    """Class for logging molecular dynamics simulations.
10 1 tkerber

11 1 tkerber
    Parameters:
12 1 tkerber
    dyn:           The dynamics.  Only a weak reference is kept.
13 1 tkerber

14 1 tkerber
    atoms:         The atoms.
15 1 tkerber

16 1 tkerber
    logfile:       File name or open file, "-" meaning standart output.
17 1 tkerber

18 1 tkerber
    stress=False:  Include stress in log.
19 1 tkerber

20 1 tkerber
    peratom=False: Write energies per atom.
21 1 tkerber

22 1 tkerber
    mode="a":      How the file is opened if logfile is a filename.
23 1 tkerber
    """
24 1 tkerber
    def __init__(self, dyn, atoms, logfile, header=True, stress=False,
25 1 tkerber
                 peratom=False, mode="a"):
26 1 tkerber
        import ase.parallel
27 1 tkerber
        if ase.parallel.rank > 0:
28 1 tkerber
            logfile="/dev/null"  # Only log on master
29 1 tkerber
        if hasattr(dyn, "get_time"):
30 1 tkerber
            self.dyn = weakref.proxy(dyn)
31 1 tkerber
        else:
32 1 tkerber
            self.dyn = None
33 1 tkerber
        self.atoms = atoms
34 1 tkerber
        self.natoms = atoms.get_number_of_atoms()
35 1 tkerber
        if logfile == "-":
36 1 tkerber
            self.logfile = sys.stdout
37 1 tkerber
            self.ownlogfile = False
38 1 tkerber
        elif hasattr(logfile, "write"):
39 1 tkerber
            self.logfile = logfile
40 1 tkerber
            self.ownlogfile = False
41 1 tkerber
        else:
42 1 tkerber
            self.logfile = open(logfile, mode)
43 1 tkerber
            self.ownlogfile = True
44 1 tkerber
        self.stress = stress
45 1 tkerber
        self.peratom = peratom
46 1 tkerber
        if self.dyn is not None:
47 1 tkerber
            self.hdr = "%-8s " % ("Time[ps]",)
48 1 tkerber
            self.fmt = "%-8.2f "
49 1 tkerber
        else:
50 1 tkerber
            self.hdr = ""
51 1 tkerber
            self.fmt = ""
52 1 tkerber
        if self.peratom:
53 1 tkerber
            self.hdr += "%12s %12s %12s  %6s" % ("Etot/N[eV]", "Epot/N[eV]",
54 1 tkerber
                                                 "Ekin/N[eV]", "T[K]")
55 1 tkerber
            self.fmt += "%12.4f %12.4f %12.4f  %6.1f"
56 1 tkerber
        else:
57 1 tkerber
            self.hdr += "%12s %12s %12s  %6s" % ("Etot[eV]", "Epot[eV]",
58 1 tkerber
                                                 "Ekin[eV]", "T[K]")
59 1 tkerber
            # Choose a sensible number of decimals
60 1 tkerber
            if self.natoms <= 10:
61 1 tkerber
                digits = 4
62 1 tkerber
            elif self.natoms <= 100:
63 1 tkerber
                digits = 3
64 1 tkerber
            elif self.natoms <= 1000:
65 1 tkerber
                digits = 2
66 1 tkerber
            else:
67 1 tkerber
                digits = 1
68 1 tkerber
            self.fmt += 3*("%%12.%df " % (digits,)) + " %6.1f"
69 1 tkerber
        if self.stress:
70 1 tkerber
            self.hdr += "---------------- stress [GPa] -----------------"
71 1 tkerber
            self.fmt += 6*" %10.3f"
72 1 tkerber
        self.fmt += "\n"
73 1 tkerber
        if header:
74 1 tkerber
            self.logfile.write(self.hdr+"\n")
75 1 tkerber
76 1 tkerber
    def __del__(self):
77 1 tkerber
        self.close()
78 1 tkerber
79 1 tkerber
    def close(self):
80 1 tkerber
        if self.ownlogfile:
81 1 tkerber
            self.logfile.close()
82 1 tkerber
83 1 tkerber
    def __call__(self):
84 1 tkerber
        epot = self.atoms.get_potential_energy()
85 1 tkerber
        ekin = self.atoms.get_kinetic_energy()
86 1 tkerber
        temp = ekin / (1.5 * units.kB * self.natoms)
87 1 tkerber
        if self.peratom:
88 1 tkerber
            epot /= self.natoms
89 1 tkerber
            ekin /= self.natoms
90 1 tkerber
        if self.dyn is not None:
91 1 tkerber
            t = self.dyn.get_time() / (1000*units.fs)
92 1 tkerber
            dat = (t,)
93 1 tkerber
        else:
94 1 tkerber
            dat = ()
95 1 tkerber
        dat += (epot+ekin, epot, ekin, temp)
96 1 tkerber
        if self.stress:
97 1 tkerber
            dat += tuple(self.atoms.get_stress() / units.GPa)
98 1 tkerber
        self.logfile.write(self.fmt % dat)
99 1 tkerber
        self.logfile.flush()