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

TRI-AMDD / mpet / 8476080312

29 Mar 2024 01:46AM UTC coverage: 55.461% (-7.2%) from 62.648%
8476080312

Pull #126

github

d-cogswell
Adds a benchmark section to docs.
Pull Request #126: v1.0.0

2351 of 4239 relevant lines covered (55.46%)

2.22 hits per line

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

79.43
/mpet/main.py
1
"""The main module that organizes the simulation and manages data IO."""
2
import errno
4✔
3
import glob
4✔
4
import os
4✔
5
import shutil
4✔
6
import subprocess as subp
4✔
7
import sys
4✔
8
import time
4✔
9
from shutil import copyfile
4✔
10

11
import daetools.pyDAE as dae
4✔
12
from daetools.solvers.superlu import pySuperLU
4✔
13

14
import mpet
4✔
15
import mpet.data_reporting as data_reporting
4✔
16
from mpet.config import Config
4✔
17
import mpet.sim as sim
4✔
18
import mpet.utils as utils
4✔
19

20

21
def run_simulation(config, outdir):
4✔
22
    tScale = config["t_ref"]
4✔
23
    # Create Log, Solver, DataReporter and Simulation object
24
    log = dae.daePythonStdOutLog()
4✔
25
    daesolver = dae.daeIDAS()
4✔
26
    simulation = sim.SimMPET(config, tScale)
4✔
27
    datareporter = data_reporting.setup_data_reporters(simulation, config, outdir)
4✔
28

29
    # Use SuperLU direct sparse LA solver
30
    lasolver = pySuperLU.daeCreateSuperLUSolver()
4✔
31
    daesolver.SetLASolver(lasolver)
4✔
32

33
    # Enable reporting of all variables
34
    simulation.m.SetReportingOn(True)
4✔
35

36
    # Turn off reporting of some variables
37
    simulation.m.endCondition.ReportingOn = False
4✔
38

39
    # Turn off reporting of particle and interface ports
40
    for trode in simulation.m.trodes:
4✔
41
        for particle in simulation.m.particles[trode]:
4✔
42
            pModel = particle[0]
4✔
43
            for port in pModel.Ports:
4✔
44
                for var in port.Variables:
4✔
45
                    var.ReportingOn = False
4✔
46
        if config[f"simInterface_{trode}"]:
4✔
47
            for interfaces in simulation.m.interfaces[trode]:
4✔
48
                for iModel in interfaces:
4✔
49
                    for port in iModel.Ports:
4✔
50
                        for var in port.Variables:
4✔
51
                            var.ReportingOn = False
4✔
52

53
    # Turn off reporting of cell ports
54
    for port in simulation.m.Ports:
4✔
55
        for var in port.Variables:
4✔
56
            var.ReportingOn = False
4✔
57

58
    # Set relative tolerances
59
    daesolver.RelativeTolerance = config["relTol"]
4✔
60

61
    # Set the time horizon and the reporting interval
62
    simulation.TimeHorizon = config["tend"]
4✔
63
    # The list of reporting times excludes the first index (zero, which is implied)
64
    simulation.ReportingTimes = config["times"]
4✔
65

66
    # Connect data reporter
67
    simName = simulation.m.Name + time.strftime(
4✔
68
        " [%d.%m.%Y %H:%M:%S]", time.localtime())
69
    if not datareporter.Connect("", simName):
4✔
70
        sys.exit()
×
71

72
    # Initialize the simulation
73
    simulation.Initialize(daesolver, datareporter, log)
4✔
74

75
    # Solve at time=0 (initialization)
76
    # Increase the number of Newton iterations for more robust initialization
77
    dae.daeGetConfig().SetString("daetools.IDAS.MaxNumItersIC","1000")
4✔
78
    dae.daeGetConfig().SetString("daetools.IDAS.MaxNumSteps","100000")
4✔
79
    simulation.SolveInitial()
4✔
80

81
    # Run
82
    try:
4✔
83
        simulation.Run()
4✔
84
    except Exception as e:
×
85
        print(str(e))
×
86
        simulation.ReportData(simulation.CurrentTime)
×
87
        pass
×
88
    except KeyboardInterrupt:
×
89
        print("\nphi_applied at ctrl-C:",
×
90
              simulation.m.phi_applied.GetValue(), "\n")
91
        simulation.ReportData(simulation.CurrentTime)
×
92
    simulation.Finalize()
4✔
93

94

95
def main(paramfile, keepArchive=True, keepFullRun=False):
4✔
96
    timeStart = time.time()
4✔
97
    # Get the parameters dictionary (and the config instance) from the
98
    # parameter file
99
    config = Config(paramfile)
4✔
100

101
    # Directories we'll store output in.
102
    config_file = os.path.basename(paramfile)
4✔
103
    config_base = os.path.splitext(config_file)[0]
4✔
104
    outdir_name = "_".join((time.strftime("%Y%m%d_%H%M%S", time.localtime()), config_base))
4✔
105
    outdir_path = os.path.join(os.getcwd(), "history")
4✔
106
    outdir = os.path.join(outdir_path, outdir_name)
4✔
107
    # Make sure there's a place to store the output
108
    try:
4✔
109
        os.makedirs(outdir)
4✔
110
    except OSError as exception:
×
111
        if exception.errno == errno.EEXIST:
×
112
            print("The output directory, {dirname}, exists. Aborting.".format(dirname=outdir))
×
113
            sys.exit()
×
114
        else:
115
            raise
×
116
    paramFileName = "input_params_system.cfg"
4✔
117
    paramFile = os.path.join(outdir, paramFileName)
4✔
118
    copyfile(paramfile, paramFile)
4✔
119

120
    for trode in config["trodes"]:
4✔
121
        paramFileName = "input_params_{t}.cfg".format(t=trode)
4✔
122
        paramFile = os.path.join(outdir, paramFileName)
4✔
123
        copyfile(config.paramfiles[trode], paramFile)
4✔
124

125
    config.write(outdir)
4✔
126

127
    # Store info about this script
128
    # mpet.py script directory
129
    localDir = os.path.dirname(os.path.abspath(__file__))
4✔
130
    commit_hash = ""
4✔
131
    try:
4✔
132
        # Git option, if it works -- commit info and current diff
133
        branch_name, commit_hash, commit_diff = utils.get_git_info(localDir, shell=False)
4✔
134
    except FileNotFoundError:
×
135
        try:
×
136
            branch_name, commit_hash, commit_diff = utils.get_git_info(localDir, shell=True)
×
137
        except subp.CalledProcessError:
×
138
            pass
×
139
    except subp.CalledProcessError:
×
140
        pass
×
141

142
    fo = open(os.path.join(outdir, 'run_info.txt'), 'w')
4✔
143

144
    # Print mpet version
145
    print("mpet version:", file=fo)
4✔
146
    print(mpet.__version__+"\n", file=fo)
4✔
147

148
    # Print git commit info if it exists
149
    if commit_hash != "":
4✔
150
        # Store commit info to file, as well as how to patch if
151
        # there's a diff
152
        print("branch name:", file=fo)
4✔
153
        print(branch_name, file=fo)
4✔
154
        print("commit hash:", file=fo)
4✔
155
        print(commit_hash, file=fo)
4✔
156
        print("to run, from the root repo directory, copy relevant files there,", file=fo)
4✔
157
        print("edit input_params_system.cfg to point to correct material", file=fo)
4✔
158
        print("params files, and:", file=fo)
4✔
159
        print("$ git checkout [commit hash]", file=fo)
4✔
160
        print("$ patch -p1 < commit.diff:", file=fo)
4✔
161
        print("$ python[3] mpetrun.py input_params_system.cfg", file=fo)
4✔
162
        with open(os.path.join(outdir, 'commit.diff'), 'w') as fo:
4✔
163
            print(commit_diff, file=fo)
4✔
164
    else:
165
        # At least keep a copy of the python files in this directory
166
        # with the output
167
        snapshotDir = os.path.join(outdir, "simSnapshot")
×
168
        os.makedirs(snapshotDir)
×
169
        pyFiles = glob.glob(os.path.join(localDir, "*.py"))
×
170
        for pyFile in pyFiles:
×
171
            shutil.copy(pyFile, snapshotDir)
×
172

173
    fo.close()
4✔
174

175
    # External functions are not supported by the Compute Stack approach.
176
    # Activate the Evaluation Tree approach if noise, CCsegments,
177
    # or CVsegments are used
178
    cfg = dae.daeGetConfig()
4✔
179
    segments = config["profileType"] in ["CCsegments","CVsegments"]
4✔
180
    if (segments and config["tramp"] > 0) \
4✔
181
            and 'daetools.core.equations.evaluationMode' in cfg:
182
        cfg.SetString('daetools.core.equations.evaluationMode', 'evaluationTree_OpenMP')
4✔
183

184
    # Disable printStats
185
    cfg.SetString('daetools.activity.printStats','false')
4✔
186

187
    # Write config file
188
    with open(os.path.join(outdir, "daetools_config_options.txt"), 'w') as fo:
4✔
189
        print(cfg, file=fo)
4✔
190

191
    # Carry out the simulation
192
    run_simulation(config, outdir)
4✔
193

194
    # Final output for user
195
    print("\n\nUsed parameter file ""{fname}""\n\n".format(fname=paramfile))
4✔
196
    timeEnd = time.time()
4✔
197
    tTot = timeEnd - timeStart
4✔
198
    print("Total time:", tTot, "s")
4✔
199
    try:
4✔
200
        with open(os.path.join(outdir, 'run_info.txt'), 'a') as fo:
4✔
201
            print("\nTotal run time:", tTot, "s", file=fo)
4✔
202
    except Exception:
×
203
        pass
×
204

205
    # Copy or move simulation output to current directory. If running multiple jobs,
206
    # make sure to keep all sim_output
207
    tmpDir = os.path.join(os.getcwd(), "sim_output")
4✔
208
    if not keepFullRun:
4✔
209
        shutil.rmtree(tmpDir, ignore_errors=True)
4✔
210
        tmpsubDir = tmpDir
4✔
211
    else:
212
        tmpsubDir = os.path.join(tmpDir, outdir_name)
×
213

214
    if keepArchive:
4✔
215
        shutil.copytree(outdir, tmpsubDir)
×
216
    else:
217
        shutil.move(outdir, tmpsubDir)
4✔
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