Source code for SMITER_BATCH_API

"""API for running a SMITER case. This is meant to be used in SALOME batch mode
or script mode. This will run the SMITER computation and perform basically the
same as the GUI SMITER_API.ComputeCase, except it is not using PyQt5, to avoid
raising the complexity when writing batch scripts.
"""
import subprocess
try:
    from SMESH_utils import createVTKfromSMESH
    import SMITER_utils
    import salome
except Exception as e:
    print(e)

import os
from glob import glob


def findall(string, char):
    out = []
    i = string.find(char)
    while i != -1:
        out.append(i)
        i = string.find(char, i+1)

    return out


def parseMpiCommand(mpiComm):

    # Find all quotes
    indexes = findall(mpiComm, '\'')
    if not indexes:
        return mpiComm.split()

    out = []
    start = 0
    for i, j in zip(indexes[::2], indexes[1::2]):
        end = i
        out += mpiComm[start:end].split()
        out += [mpiComm[i:j]]
        start = j
    return out


class ComputeProcess(object):
    """Runs SMARDDA executables with subprocess module.
    """
    compPsiRef, compTarg, compShad, compHdsg, compPowc, compMag = range(6)

    def __init__(self):
        self.runDir = ''
        self.smiterDir = ''
        self.smarddaExec = {}
        self.smarddaArgs = {}
        self.runPaths = {}
        self.queue = []

        self.useMPI = False
        self.commandMPI = ''

        self._currentCommand = -1
        self._currentTarget = -1
        self.completionStatus = True

    def outputLog(self, msg=None):
        if msg is None:
            print('\n')
        else:
            print(msg)

    def setMPI(self, bool):
        self.useMPI = bool

    def setMPICommand(self, command):
        self.commandMPI = str(command).replace('%', '$')

    def setRunDir(self, runDir):
        self.runDir = runDir

    def setSmiterDir(self, smiterDir):
        self.smiterDir = smiterDir
        self.setExecPaths()

    def setExecPaths(self):
        execDir = os.path.join(self.smarddaDir, 'exec')
        self.smarddaExec[self.compPsiRef] = os.path.join(execDir, 'geoq')
        self.smarddaExec[self.compTarg] = os.path.join(execDir, 'geoq')
        self.smarddaExec[self.compShad] = os.path.join(execDir, 'geoq')
        self.smarddaExec[self.compHdsg] = os.path.join(execDir, 'hdsgen')
        self.smarddaExec[self.compPowc] = os.path.join(execDir, 'powcal')
        self.smarddaExec[self.compMag] = os.path.join(execDir, 'magtfm')
        self.smarddaExec[self.compCase] = os.path.join(execDir, 'smiter')

    def checkForSMARDDAexecutables(self):
        """This function checks if SMARDDA modules exists (geoq, powcal,
        hdsgen) and warns the user if they do not exist.
        """
        geoq = os.path.join(self.smarddaDir, 'exec', 'geoq')
        hdsgen = os.path.join(self.smarddaDir, 'exec', 'hdsgen')
        powcal = os.path.join(self.smarddaDir, 'exec', 'powcal')
        magtfm = os.path.join(self.smarddaDir, 'exec', 'magtfm')
        smiter = os.path.join(self.smarddaDir, 'exec', 'smiter')

        PASSED = True
        missing = []
        if os.path.isfile(geoq) and os.access(geoq, os.X_OK):
            pass
        else:
            PASSED = False
            missing.append(geoq)

        if os.path.isfile(hdsgen) and os.access(hdsgen, os.X_OK):
            pass
        else:
            PASSED = False
            missing.append(hdsgen)

        if os.path.isfile(powcal) and os.access(powcal, os.X_OK):
            pass
        else:
            PASSED = False
            missing.append(powcal)

        if os.path.isfile(magtfm) and os.access(magtfm, os.X_OK):
            pass
        else:
            PASSED = False
            missing.append(magtfm)

        if os.path.isfile(smiter) and os.access(smiter, os.X_OK):
            pass
        else:
            PASSED = False
            missing.append(smiter)

        if not PASSED:
            self.outputLog.emit('Missing executables:')
            for exe in missing:
                self.outputLog.emit('\t%s' % exe)

            self.outputLog.emit('Check if SMARDDA is compiled.')
            self.outputLog.emit('Or check if the SMARDDA path is correctly set'
                                ' in SMITER preferences!')
            self.outputLog.emit('cd $SMITER_DIR')
            self.outputLog.emit('./exec/build')

        return PASSED

    def setComputeCommands(self, computeCommands):
        self.queue = computeCommands

    def setCurrComm(self, command):
        self._currentCommand = command

    def getCurrComm(self):
        return self._currentCommand

    def setCurrTarg(self, target):
        """Set the current target. Not to be confused with target GEOQ. This
        is simply the name of the current ctl
        """
        self._currentTarget = target

    def getCurrTarg(self):
        return self._currentTarget

    def compute(self):
        if self.queue:
            # Reset completion status
            self.completionStatus = True

            # Run a subprocess
            command, arg = self.queue.pop(0)
            executable = self.smarddaExec[command]

            wholeCommand = ''
            if self.useMPI:
                # Check if $SMITER is inside
                if '$SMITER' in self.commandMPI:
                    wholeCommand = self.commandMPI.replace('$SMITER',
                        f'{executable} {arg}')
                if '$JOBNAME' in self.commandMPI:
                    if wholeCommand:
                        wholeCommand = wholeCommand.replace('$JOBNAME',
                            executable)
                    else:
                        wholeCommand = self.commandMPI.replace('$JOBNAME',
                            executable)
                else:
                    wholeCommand = f'{self.commandMPI} {executable} {arg}'
                if self.shell:
                    executable = self.shell
                    args = ['-c', wholeCommand]
                    wholeCommand = f'{executable} -c "{wholeCommand}"'
                else:
                    split = parseMpiCommand(wholeCommand)
                    executable = split[0]
                    args = split[1:]
            else:
                wholeCommand = f"{executable} {arg}"
                args = [arg]

            split = [executable] + args

            print('Running command %s' % wholeCommand)

            # Both executable and arg are lists!
            proc = subprocess.Popen(split,
                                    cwd=self.runDir, stdout=subprocess.PIPE)

            while 1:
                output = proc.stdout.readline()
                returnCode = proc.poll()
                if output == '' and returnCode is not None:
                    break
                else:
                    self.outputLog(output.strip())

            returnCode = proc.poll()
            path = self.runPaths[command]
            target = arg  # Name of the CTL
            if returnCode:
                self.completionStatus = False
                # Command failed!
                self.outputLog('Command %s failed!' % ' '.join(executable +
                                                               [arg]))
                logFile = path + '/' + target + '.log'
                if os.access(logFile, os.F_OK | os.R_OK):
                    with open(logFile, 'r') as f:
                        self.outputLog(f.read())
                self.queue = []
                self.completionStatus = False
                return

            # Check if command == self.compPsiRef
            if command == self.compPsiRef:
                # Read the *_geoq.out to read the psibdry value, to assign the
                # value to the target and shadow beq_psiref parameter.
                outFile = os.path.join(self.runDir, f'wall/geoq_geoq.out')
                psiRef = None
                if os.path.isfile(outFile) and os.access(outFile, os.R_OK):
                    with open(outFile, 'r') as f:
                        READ_PSIBDRY = False
                        for line in f:
                            # Strip white spaces
                            sline = line.lstrip()
                            if sline.startswith('psibdry'):
                                READ_PSIBDRY = True
                                continue

                            if READ_PSIBDRY:
                                # Read psibdry and finish reading the output file.
                                psiRef = line.strip()
                                break
                else:
                    self.outputLog.emit('Missing output file to read PSIREF from!')

                if psiRef:

                    # It might be dangerous but, usually there is no cause to have
                    # PSIREF in a ctl.
                    targetCtl = [os.path.join(self.runDir, _, 'geoq.ctl') for _
                                 in ['target', 'shadow']]

                    for file in targetCtl:
                        with open(file, 'r') as f:
                            ctl = f.read()

                        ctl = ctl.replace('PSIREF', psiRef)

                        with open(file, 'w') as f:
                            f.write(ctl)
            if command == self.compMag:
                # Link the resulting sp3 file to Powcal directory
                magDir = os.path.join(self.runDir, 'mag')
                powcalDir = os.path.join(self.runDir, 'power')
                shadowDir = os.path.join(self.runDir, 'shadow')
                targetDir = os.path.join(self.runDir, 'target')
                if os.path.exists(self.runPaths[self.compPowc]):
                    sp3File = glob('%s/*.sp3' % magDir)
                    for file in sp3File:
                        if os.name == 'posix':
                            targetLink = os.path.join(powcalDir,
                                                      os.path.basename(file))
                            if os.path.exists(targetLink):
                                os.unlink(targetLink)
                            os.symlink(file, targetLink)

                            targetLink = os.path.join(targetDir,
                                                      os.path.basename(file))
                            if os.path.exists(targetLink):
                                os.unlink(targetLink)
                            os.symlink(file, targetLink)

                            targetLink = os.path.join(shadowDir,
                                                      os.path.basename(file))
                            if os.path.exists(targetLink):
                                os.unlink(targetLink)
                            os.symlink(file, targetLink)
            self.outputLog('test')
            self.compute()

        else:
            # Finished with commands
            passed = 'Passed' if self.completionStatus else 'Failed'
            self.outputLog('Finished batch of commands. Status: %s.' %
                           passed)

[docs]class ComputeCase(object): """The attributes are the same of SMITER_API.ComputeCase """ compPsiRef, compTarg, compShad, compHdsg, compPowc, compMag = range(6) def __init__(self): self.smiterCase = None self.smiterDir = '' self.caseDirectory = '' self.tabIndex = 0 self.commands = [] self.openInParaVieW = False self.savePowcalResults = False self.clean = False # Flag if you wish to rewrite meshes. self.preparationsFlag = False self.batchPrepare = False self.computeLock = False self.computeFieldlineFlag = False self.previousPlotFlinx = '' self.previousOpen_PV = None self.runDir = '' self.computeCommands = [] self.computeProcess = ComputeProcess() self.saveToCase = False def outputLog(self, msg=None): if msg == None: print('\n') else: print(msg)
[docs] def setSmiterDir(self, smiterDir): """Setter for SMITER directory. """ self.smiterDir = smiterDir
[docs] def setCaseDir(self, caseDirectory): """Setter for directories where the cases will be run. """ self.caseDirectory = caseDirectory
def setMPI(self, bool): self.computeProcess.setMPI(bool) def setMPICommand(self, command): self.computeProcess.setMPICommand(command)
[docs] def getSettings(self): """Does nothing since batch mode is run in non-GUI mode and thus no settings can be retrieved from SMITER-GUI preferences """ pass
[docs] def setCase(self, case): """Receives reference to SMITERcase object. Arguments: case (SMITER_ORB__POA.SMITERcase): Reference to CORBA object that holds all the information about the case. """ self.smiterCase = case
[docs] def findAndSetCase(self, caseName): """Function that searches a case with the name ``caseName`` under the SMITER component. Works only when GUI is enabled! Arguments: caseName (str): Name of the case. A Salome object holds the name of the case and the reference to the CORBA object ``SMITER_ORB__POA.SMITERcase``. """ study = salome.myStudy comp = SMITER_utils.findOrCreateComponent() iter = study.NewChildIterator(comp) while iter.More(): sObj = iter.Value() name = sObj.GetName() if name == caseName: self.setCase(sObj.GetObject()) return True iter.Next() return False
[docs] def prepareRunDirectory(self): """Runs the QThread to first prepare the directory for the case. Then it goes through the :attr:`commands` """ # Check if we have a case object # Flag that is put on True at the end of the fuction if everything # prepared correctly. self.preparationsFlag = False # Flag for force writing the meshes again. rewriteMesh = self.clean if self.smiterCase is None: # If for any reason start is being run return # Set the input parameters for each object (geoq, hdsgen, powcal) if not self.smiterCase.setInputParameters(): self.outputLog('SMITERcase object failed to set parameters' ' for input files.') return if self.caseDirectory is None: self.outputLog('No run directory set. Check preferences,' ' if the settings are correctly set.') return # Rename the tab in output viewer in case the case has been renamed. self.renameTab.emit(self.tabIndex, self.smiterCase.getName()) runDirPath = os.path.join(self.caseDirectory, self.smiterCase.getName()) # Check if directory exists ok = os.path.isdir(runDirPath) # Case status tells us if we have already run the case, in which case # we do not necessarily write the VTK files. VTK files are first # created by reading the SMESH objects, which can take some time. if ok: # Check if it is writable if os.access(runDirPath, os.W_OK): # See if there is a .status file self.outputLog(f'Directory {runDirPath} already exists,') self.outputLog('no need to create it.') else: # Directory is not writable. Perhaps a directory of other user? # Cancel everything! self.commands = [] msg = 'Write permission error with directory %s' % runDirPath msg += '. Check if you are the owner of the directory or if' msg += ' the path is valid.' self.outputLog(msg) return else: # No directory for this case yet. self.outputLog('Creating run directory %s' % runDirPath) os.makedirs(runDirPath) # Create the directory structure here, in case there are future 'ideas' # about new directory structure. eqdskDir = os.path.join(runDirPath, 'eqdsk') if not os.path.exists(eqdskDir): self.outputLog('Creating eqdsk directory') os.makedirs(eqdskDir) else: self.outputLog('Eqdsk directory already exists') if self.compMag in self.commands: magDir = os.path.join(runDirPath, 'mag') if not os.path.exists(magDir): self.outputLog('Creating mag directory') os.makedirs(magDir) else: self.outputLog('Mag directory already exists') self._t_cleanOutput(magDir) if self.compPsiRef in self.commands or self.compCase in self.commands: wallDir = os.path.join(runDirPath, 'wall') if not os.path.exists(wallDir): self.outputLog('Creating wall directory') os.makedirs(wallDir) else: self.outputLog('Wall directory already exists') self._t_cleanOutput(wallDir) if self.compTarg in self.commands or self.compCase in self.commands: targetDir = os.path.join(runDirPath, 'target') if not os.path.exists(targetDir): self.outputLog('Creating target directory') os.makedirs(targetDir) else: self.outputLog('Target directory already exists') self._t_cleanOutput(targetDir) if self.compShad in self.commands or self.compCase in self.commands: shadowDir = os.path.join(runDirPath, 'shadow') if not os.path.exists(shadowDir): self.outputLog('Creating shadow directory') os.makedirs(shadowDir) else: self.outputLog('Shadow directory already exists') self._t_cleanOutput(shadowDir) if self.compHdsg in self.commands or self.compCase in self.commands: hdsgenDir = os.path.join(runDirPath, 'hds') if not os.path.exists(hdsgenDir): self.outputLog('Creating hdsgen directory') os.makedirs(hdsgenDir) else: self.outputLog('Hdsgen directory already exists') self._t_cleanOutput(hdsgenDir) if self.compPowc in self.commands or self.compCase in self.commands: powcalDir = os.path.join(runDirPath, 'power') if not os.path.exists(powcalDir): self.outputLog('Creating powcal directory') os.makedirs(powcalDir) else: self.outputLog('Powcal directory already exists') self._t_cleanOutput(powcalDir) # Go to directory os.chdir(runDirPath) self.outputLog('') # 0. step. Check if EQDSK is written eqdsk = self.smiterCase.getEQDSK() eqdskName = eqdsk.getName().rsplit('/', 1)[-1] eqdskPath = os.path.join(eqdskDir, eqdskName) self.outputLog('Writing EQDSK file if necessary.') if os.path.exists(eqdskPath): self.outputLog('EQDSK file already exists.') else: self.outputLog('Writing EQDSK file.') with open(eqdskPath, 'w') as f: f.write(eqdsk.generateText()) # 0b. step. Check if PsiRef has to be computed if self.compPsiRef in self.commands: self.outputLog('') wall = self.smiterCase.getWall() wallName = wall.getName() wallPath = os.path.join(wallDir, f"{wallName}.vtk") if os.path.exists(wallPath) and not rewriteMesh: self.outputLog('Wall mesh %s already exists.' % wallPath) else: self.outputLog('Writing wall mesh to %s' % wallPath) self._t_writeVTK(wallPath, wall) self.outputLog('Writing CTL for wall GEOQ.') self._t_writeCTL(os.path.join(wallDir, 'geoq.ctl'), wall) # 0c. step. Check for Magnetigc ripple field data. If there is no data # skip this step. if self.compMag in self.commands: self.outputLog('') self.outputLog('Checking for magnetic ripple field data.') magtfm = self.smiterCase.getMAGTFM() magName = magtfm.getName() magPath = os.path.join(magDir, magName) if os.path.exists(magPath): self.outputLog('Magnetic ripple field data %s is ' 'already written.' % magName) else: self.outputLog('Writing magnetig ripple field data:' ' %s' % magName) with open('%s.txt' % magPath, 'w') as f: f.write(magtfm.getMAG()) self._t_writeCTL(os.path.join(magDir, 'magtfm.ctl'), magtfm) # 1. step. Check if target GEOQ needs to be run if self.compTarg in self.commands or self.compCase in self.commands: self.outputLog('') self.outputLog('Preparing directory for target GEOQ.') # Now check if the VTK is written in the directory. target = self.smiterCase.getTarget() targetName = target.getName() targetPath = os.path.join(targetDir, f"{targetName}.vtk") if os.path.exists(targetPath) and not rewriteMesh: self.outputLog('Target mesh %s already exists.' % targetPath) else: self.outputLog('Writing target mesh to %s.' % targetPath) self._t_writeVTK(targetPath, target) # Write CTL. This is performed ALWAYS, since the file is small and # is changed the most. self.outputLog('Writing CTL for target GEOQ.') self._t_writeCTL(os.path.join(targetDir, 'geoq.ctl'), target) # 2. step. Check if shadow GEOQ needs to be run if self.compShad in self.commands or self.compCase in self.commands: self.outputLog('') self.outputLog('Preparing directory for shadow GEOQ.') # Now check if the VTK is written in the directory. shadow = self.smiterCase.getShadow() shadowName = shadow.getName() shadowPath = os.path.join(shadowDir, f"{shadowName}.vtk") if os.path.exists(shadowPath) and not rewriteMesh: self.outputLog('Shadow mesh %s already exists.' % shadowPath) else: self.outputLog('Writing shadow mesh to %s' % shadowPath) self._t_writeVTK(shadowPath, shadow) # Write CTL. This is performed ALWAYS, since the file is small and # is changed the most. self.outputLog('Writing CTL for shadow GEOQ.') self._t_writeCTL(os.path.join(shadowDir, 'geoq.ctl'), shadow) # 3. step. Check if HDSGEN needs to be run if self.compHdsg in self.commands or self.compCase in self.commands: self.outputLog('') self.outputLog('Preparing directory for HDSGEN.') hdsgen = self.smiterCase.getHDSGEN() self.outputLog('Writing CTL for HDSGEN.') self._t_writeCTL(os.path.join(hdsgenDir, 'hdsgen.ctl'), hdsgen) # 4. step. Check if POWCAL needs to be run if self.compPowc in self.commands or self.compCase in self.commands: self.outputLog('') powcal = self.smiterCase.getPOWCAL() self.outputLog('Writing CTL for POWCAL.') self._t_writeCTL(os.path.join(powcalDir, 'powcal.ctl'), powcal) # Prepare commands computeCommands = [] if self.compPsiRef in self.commands: computeCommands.append((self.compPsiRef, 'wall/geoq')) if self.compMag in self.commands: computeCommands.append((self.compMag, 'mag/magtfm')) if self.compCase in self.commands: computeCommands.append((self.compCase, 'shadow/geoq target/geoq hds/hdsgen pow/powcal')) else: if self.compTarg in self.commands: computeCommands.append((self.compTarg, 'target/geoq')) if self.compShad in self.commands: computeCommands.append((self.compShad, 'shadow/geoq')) if self.compHdsg in self.commands: computeCommands.append((self.compHdsg, 'hds/hdsgen')) if self.compPowc in self.commands: computeCommands.append((self.compPowc, 'pow/powcal')) # Purge the :attr:`commands` list. self.commands = [] self.runDir = runDirPath self.computeCommands = computeCommands self.preparationsFlag = True return 0
def _t_cleanOutput(self, path): """Function used in the thread. Not to be used by the user, unless you know what they do. This function cleans the ``run`` directory of *.out, *.log, *.gnu, ... Arguments: path (str): Path, in which to clean the output files.. """ # patterns = ["*.out", ".*log", "*.gnu", "*_geo*", "*_hds*", "*_pow*", # "*.sp3", "*_bx.txt"] patterns = ["mag*", "geoq*", "powcal*", "hdsgen*"] files = [] for p in patterns: files += glob(os.path.join(path, p)) for file in files: os.remove(file) def _t_writeVTK(self, path, object): """Function used in the thread. Not to be used by the user, unless you know what they do. This function writes a mesh in VTK format in the specified ``path`` directory. Arguments: path (str): Path where to save the mesh in VTK format. object (SMITER_ORB__POA.GEOQ): Provided geoq object that holds the function :func:`createVTK`, which reads the mesh object it refers to and create a VTK file out of it. """ meshEntry = object.getMeshEntry() sObj = salome.myStudy.FindObjectID(meshEntry) from salome.smesh import smeshBuilder sb = smeshBuilder.New() meshObj = sObj.GetObject() VTK = createVTKfromSMESH(meshObj, sObj.GetName(), writeEdges=False) with open(path, 'w') as f: f.write(VTK) def _t_writeCTL(self, path, object): """Function used in the thread. Not to be used by the user, unless you know what they do. This function writes the CTL file of the provided object in the provided ``path`` directory. Arguments: path (str): Path where to save the CTL file. object : Either SMITER_ORB__POA.GEOQ, SMITER_ORB__POA.HDSGEN or SMITER_ORB__POA.POWCAL object from which we extract the CTL with the call of :func:`createCTL` """ CTL = object.createCTL() with open(path, 'w') as f: f.write(CTL) def setCleanCase(self, bool): self.clean = bool
[docs] def initialCheck(self): """Checks whether the computeLock is set and if there is a CORBA instance of SMITER case. """ if self.computeLock: self.outputLog.emit("Compute lock is set. A case is already " "running!") return False if self.smiterCase is None: self.outputLog.emit("No CORBA instance for SMITER case!") return False if self.smiterCase.getEQDSK() is None: self.outputLog.emit("No EQDSK instance for SMITER case!") return False return True
def computeGEOQ(self): if not self.initialCheck(): return commands = () if self.smiterCase.getWall() is not None: commands += (self.compPsiRef,) if self.smiterCase.getTarget() is not None: commands += (self.compTarg,) else: self.outputLog.emit("No target GEOQ instance in SMITER case!") return if self.smiterCase.getShadow() is not None: commands += (self.compShad,) else: self.outputLog.emit("Not shadow GEOQ instance in SMITER case!") return self.computeLock = True self.batchPrepare = False self.commands = commands self.start()
[docs] def computeHDSGEN(self): """Runs the case ONLY for HDSGEN. Means only the HDSGEN for the case will be run. Requirements: * computeTarget * computeShadow """ if not self.initialCheck(): return commands = () if self.smiterCase.getHDSGEN() is not None: commands = (self.compHdsg,) else: self.outputLog.emit("No HDSGEN instance in SMITER case!") return self.computeLock = True self.batchPrepare = False self.commands = commands self.start()
[docs] def computePOWCAL(self): """Runs the case ONLY for POWCAL. Means only the POWCAL for the case will be run. Requirements: * computeTarget * computeShadow * computeHdsgen """ if not self.initialCheck(): return commands = () if self.smiterCase.getPOWCAL() is not None: commands = (self.compPowc,) else: self.outputLog.emit("No POWCAL instance in SMITER case") return self.computeLock = True self.batchPrepare = False self.commands = commands self.start()
[docs] def computeMAG(self): """Runs the magtfm module of SMARDDA. """ if not self.initialCheck(): return commands = () if self.smiterCase.getMAGTFM() is not None: commands = (self.compMag,) else: self.outputLog.emit("No MAGTFM instance in SMITER case") return self.computeLock = True self.batchPrepare = False self.commands = commands self.start()
[docs] def compute(self): """Computes the whole case, starting with the GEOQ for wall, target and shadow, then HDSGEN and finally POWCAL. """ if not self.initialCheck(): return commands = () if self.smiterCase.getWall() is not None: commands += (self.compPsiRef,) if self.smiterCase.getMAGTFM() is not None: commands = (self.compMag,) if self.smiterCase.getTarget() is None: self.outputLog.emit("No target GEOQ instance in SMITER case") return if self.smiterCase.getShadow() is None: self.outputLog.emit("No shadow GEOQ instance in SMITER case") return if self.smiterCase.getHDSGEN() is None: self.outputLog.emit("No HDSGEN instance in SMITER case") return if self.smiterCase.getPOWCAL() is None: self.outputLog.emit("No POWCAl instance in SMITER case") return commands += (self.compCase,) self.computeLock = True self.batchPrepare = False self.commands = commands self.start()
def start(self): # Prepare the case notOk = self.prepareRunDirectory() if notOk: print('Run dir preparation failed!') return self.computeProcess.completionStatus = True self.computeProcess.setSmiterDir(self.smiterDir) self.computeProcess.setRunDir(self.runDir) self.computeProcess.setComputeCommands(self.computeCommands) self.outputLog('Checking for SMARDDA executables...') ok = self.computeProcess.checkForSMARDDAexecutables() if not ok: self.outputLog('No SMARDDA executables, stopping ' ' run!') self.computeLock = False return self.outputLog('Now starting compute.') self.computeProcess.compute() self.outputLog('Compute finished.') if self.saveToCase: self.outputLog('Saving POWCAL result to case!') # Name for POWCAL VTK result import time powcalName = self.smiterCase.getPOWCAL().getName() caseName = self.smiterCase.getName() name = caseName + '_' + time.strftime('%Y-%m-%d-%H-%M') powcalDir = self.runDir + '/P/' path = powcalDir + '/%s_powx.vtk' % powcalName if not os.access(path, os.F_OK | os.R_OK): self.outputLog('Files %s does not exist!' % path) else: with open(path, 'r') as f: text = f.read() ok = self.smiterCase.saveResult(name, text) if ok: self.outputLog('Saved POWCAL vtk results to case as ' '%s.' % name) else: self.outputLog('Failed to save vtk results to case!') self.outputLog('Maybe there is a result with the ' 'same name already saved.')
def getAvailableCases(): study = salome.myStudy comp = SMITER_utils.findOrCreateComponent() iter = study.NewChildIterator(comp) cases = [] while iter.More(): name = iter.Value().GetName() if name: cases.append(name) iter.Next() return cases