class CfdRunnableFoam(CfdRunnable):
    update_residual_signal = Signal(list, list, list, list)

    def __init__(self, analysis=None, solver=None):
        super(CfdRunnableFoam, self).__init__(analysis, solver)

        self.initResiduals()

        self.residualPlot = None

    def check_prerequisites(self):
        return ""

    def initResiduals(self):
        self.UxResiduals = []
        self.UyResiduals = []
        self.UzResiduals = []
        self.pResiduals = []
        self.rhoResiduals = []
        self.EResiduals = []
        self.kResiduals = []
        self.omegaResiduals = []
        self.niter = 0

    def get_solver_cmd(self, case_dir):
        self.initResiduals()

        self.residualPlot = ResidualPlot()

        # Environment is sourced in run script, so no need to include in run command
        cmd = CfdTools.makeRunCommand('./Allrun', case_dir, source_env=False)
        FreeCAD.Console.PrintMessage("Solver run command: " + ' '.join(cmd) + "\n")
        return cmd

    def getRunEnvironment(self):
        return CfdTools.getRunEnvironment()

    def process_output(self, text):
        loglines = text.split('\n')
        for line in loglines:
            # print line,
            split = line.split()

            # Only store the first residual per timestep
            if line.startswith(u"Time = "):
                self.niter += 1

            # print split
            if "Ux," in split and self.niter-1 > len(self.UxResiduals):
                self.UxResiduals.append(float(split[7].split(',')[0]))
            if "Uy," in split and self.niter-1 > len(self.UyResiduals):
                self.UyResiduals.append(float(split[7].split(',')[0]))
            if "Uz," in split and self.niter-1 > len(self.UzResiduals):
                self.UzResiduals.append(float(split[7].split(',')[0]))
            if "p," in split and self.niter-1 > len(self.pResiduals):
                self.pResiduals.append(float(split[7].split(',')[0]))
            if "p_rgh," in split and self.niter-1 > len(self.pResiduals):
                self.pResiduals.append(float(split[7].split(',')[0]))
            if "h," in split and self.niter-1 > len(self.EResiduals):
                self.EResiduals.append(float(split[7].split(',')[0]))
            # HiSA coupled residuals
            if "Residual:" in split and self.niter-1 > len(self.rhoResiduals):
                self.rhoResiduals.append(float(split[4]))
                self.UxResiduals.append(float(split[5].lstrip('(')))
                self.UyResiduals.append(float(split[6]))
                self.UzResiduals.append(float(split[7].rstrip(')')))
                self.EResiduals.append(float(split[8]))
            if "k," in split and self.niter-1 > len(self.kResiduals):
                self.kResiduals.append(float(split[7].split(',')[0]))
            if "omega," in split and self.niter-1 > len(self.omegaResiduals):
                self.omegaResiduals.append(float(split[7].split(',')[0]))

        if self.niter > 1:
            self.residualPlot.updateResiduals(OrderedDict([
                ('$\\rho$', self.rhoResiduals),
                ('$U_x$', self.UxResiduals),
                ('$U_y$', self.UyResiduals),
                ('$U_z$', self.UzResiduals),
                ('$p$', self.pResiduals),
                ('$E$', self.EResiduals),
                ('$k$', self.kResiduals),
                ('$\\omega$', self.omegaResiduals)]))
Пример #2
0
class CfdRunnableFoam(CfdRunnable):
    update_residual_signal = Signal(list, list, list, list)

    def __init__(self, analysis=None, solver=None):
        super(CfdRunnableFoam, self).__init__(analysis, solver)

        self.writer = CfdCaseWriterFoam.CfdCaseWriterFoam(self.analysis)

        self.UxResiduals = [1]
        self.UyResiduals = [1]
        self.UzResiduals = [1]
        self.pResiduals = [0]
        self.niter = 0

        self.residualPlot = None

        self.print_next_error_lines = 0
        self.print_next_error_file = False

    def check_prerequisites(self):
        return ""

    def get_solver_cmd(self, case_dir):
        self.UxResiduals = [1]
        self.UyResiduals = [1]
        self.UzResiduals = [1]
        self.pResiduals = [1]
        self.niter = 0
        self.print_next_error_lines = 0
        self.print_next_error_file = False

        self.residualPlot = ResidualPlot()

        # Environment is sourced in run script, so no need to include in run command
        cmd = CfdTools.makeRunCommand('./Allrun', case_dir, source_env=False)
        FreeCAD.Console.PrintMessage("Solver run command: " + ' '.join(cmd) +
                                     "\n")
        return cmd

    def getRunEnvironment(self):
        return CfdTools.getRunEnvironment()

    def getParaviewScript(self):
        # Already created when case created - just return script name
        return os.path.join(self.writer.case_folder, "pvScript.py")

    def process_output(self, text):
        loglines = text.split('\n')
        printlines = []
        for line in loglines:
            # print line,
            split = line.split()

            # Only store the first residual per timestep
            if line.startswith(u"Time = "):
                self.niter += 1

            # print split
            if "Ux," in split and self.niter > len(self.UxResiduals):
                self.UxResiduals.append(float(split[7].split(',')[0]))
            if "Uy," in split and self.niter > len(self.UyResiduals):
                self.UyResiduals.append(float(split[7].split(',')[0]))
            if "Uz," in split and self.niter > len(self.UzResiduals):
                self.UzResiduals.append(float(split[7].split(',')[0]))
            if "p," in split and self.niter > len(self.pResiduals):
                self.pResiduals.append(float(split[7].split(',')[0]))

        self.residualPlot.updateResiduals(self.UxResiduals, self.UyResiduals,
                                          self.UzResiduals, self.pResiduals)

    def processErrorOutput(self, err):
        """
        Process standard error text output from solver
        :param err: Standard error output, single or multiple lines
        :return: A message to be printed on console, or None
        """
        ret = ""
        errlines = err.split('\n')
        for errline in errlines:
            if len(errline) > 0:  # Ignore blanks
                if self.print_next_error_lines > 0:
                    ret += errline + "\n"
                    self.print_next_error_lines -= 1
                if self.print_next_error_file and "file:" in errline:
                    ret += errline + "\n"
                    self.print_next_error_file = False
                words = errline.split(' ',
                                      1)  # Split off first field for parallel
                FATAL = "--> FOAM FATAL ERROR"
                FATALIO = "--> FOAM FATAL IO ERROR"
                if errline.startswith(FATAL) or (len(words) > 1 and
                                                 words[1].startswith(FATAL)):
                    self.print_next_error_lines = 1
                    ret += "OpenFOAM fatal error:\n"
                elif errline.startswith(FATALIO) or (
                        len(words) > 1 and words[1].startswith(FATALIO)):
                    self.print_next_error_lines = 1
                    self.print_next_error_file = True
                    ret += "OpenFOAM IO error:\n"
        if len(ret) > 0:
            return ret
        else:
            return None