<commit_before>#include <tiramisu/expr.h>
#include <tiramisu/core.h>

namespace tiramisu
{

tiramisu::expr& tiramisu::expr::operator=(tiramisu::expr const & e)
{
    this->_operator = e._operator;
    this->op = e.op;
    this->access_vector = e.access_vector;
    this->argument_vector = e.argument_vector;
    this->defined = e.defined;
    this->name = e.name;
    this->dtype = e.dtype;
    this->etype = e.etype;

    // Copy the integer value
    if (e.get_expr_type() == tiramisu::e_val)
    {
        if (e.get_data_type() == tiramisu::p_uint8)
        {
            this->uint8_value = e.get_uint8_value();
        }
        else if (e.get_data_type() == tiramisu::p_int8)
        {
            this->int8_value = e.get_int8_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint16)
        {
            this->uint16_value = e.get_uint16_value();
        }
        else if (e.get_data_type() == tiramisu::p_int16)
        {
            this->int16_value = e.get_int16_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint32)
        {
            this->uint32_value = e.get_uint32_value();
        }
        else if (e.get_data_type() == tiramisu::p_int32)
        {
            this->int32_value = e.get_int32_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint64)
        {
            this->uint64_value = e.get_uint64_value();
        }
        else if (e.get_data_type() == tiramisu::p_int64)
        {
            this->int64_value = e.get_int64_value();
        }
        else if (e.get_data_type() == tiramisu::p_float32)
        {
            this->float32_value = e.get_float32_value();
        }
        else if (e.get_data_type() == tiramisu::p_float64)
        {
            this->float64_value = e.get_float64_value();
        }
    }
    return *this;
}

tiramisu::expr tiramisu::expr::substitute(std::vector<std::pair<var, expr>> substitutions) const
{
    for (auto &substitution: substitutions)
        if (this->is_equal(substitution.first))
            return substitution.second;

    return apply_to_operands([&substitutions](const expr& e){
        return e.substitute(substitutions);
    });
}

tiramisu::expr tiramisu::expr::substitute_access(std::string original, std::string substitute) const {
    expr && result = this->apply_to_operands([&original, &substitute](const expr& e){
        return e.substitute_access(original, substitute);
    });
    if (result.get_op_type() == o_access && result.name == original)
    {
        result.name = substitute;
    }
    return result;
}

tiramisu::var::var(std::string name, bool save)
{
    assert(!name.empty());

    auto declared = var::declared_vars.find(name);

    if (declared != var::declared_vars.end())
    {
        *this = declared->second;
    }
    else
    {
        this->name = name;
        this->etype = tiramisu::e_var;
        this->dtype = global::get_loop_iterator_data_type();
        this->defined = true;
        if (save)
        {
            var::declared_vars.insert(std::make_pair(name, *this));
            DEBUG(3, std::cout << "Saved variable " << this->name << " of type " << str_from_tiramisu_type_primitive(this->dtype));
        }
    }
}

tiramisu::var::var(tiramisu::primitive_t type, std::string name, bool save)
{
    assert(!name.empty());

    auto declared = var::declared_vars.find(name);

    if (declared != var::declared_vars.end())
    {
        assert(declared->second.dtype == type);
        *this = declared->second;
    }
    else
    {
        this->name = name;
        this->etype = tiramisu::e_var;
        this->dtype = type;
        this->defined = true;
        if (save)
        {
            var::declared_vars.insert(std::make_pair(name, *this));
            DEBUG(10, std::cout << "Saved variable " << this->name << " of type " << str_from_tiramisu_type_primitive(this->dtype));
        }
    }
}

tiramisu::expr tiramisu::expr::copy() const
{
    return (*this);
}

expr cast(primitive_t tT, const expr & e) {
    if (e.get_data_type() == tT)
        return e;
    return expr{o_cast, tT, e};
}

expr tiramisu::expr::operator+(tiramisu::expr other) const {
    return tiramisu::expr{o_add, *this, other};
}

expr tiramisu::expr::operator-(tiramisu::expr other) const {
    return tiramisu::expr{o_sub, *this, other};
}

expr tiramisu::expr::operator*(tiramisu::expr other) const {
    return tiramisu::expr{o_mul, *this, other};
}

expr tiramisu::expr::operator/(tiramisu::expr other) const {
    return tiramisu::expr{o_div, *this, other};
}

expr tiramisu::expr::operator%(tiramisu::expr other) const {
    return tiramisu::expr{o_mod, *this, other};
}

expr tiramisu::expr::operator>>(tiramisu::expr other) const {
    return tiramisu::expr{o_right_shift, *this, other};
}

expr tiramisu::expr::operator<<(tiramisu::expr other) const {
    return tiramisu::expr{o_left_shift, *this, other};
}

expr memcpy(const buffer &from, const buffer &to) {
    return expr(o_memcpy, var(p_void_ptr, from.get_name()), var(p_void_ptr, to.get_name()));
}

expr allocate(const buffer &b)
{
    return expr{o_allocate, b.get_name()};
}

expr cublas_gemm(const buffer &A, const buffer &B, buffer &C,
                 expr M, expr N, expr K,
                 expr alpha, expr beta,
                 expr ldA, expr ldB, expr ldC,
                 expr offsetA, expr offsetB, expr offsetC,
                 expr transposeA, expr transposeB)
{
    if (A.get_location() != cuda_ast::memory_location::global ||
        B.get_location() != cuda_ast::memory_location::global ||
        C.get_location() != cuda_ast::memory_location::global) {
        ERROR("Buffers must be on GPU global memory", true);
    }
    std::string fname;
    expr alpha_expr;
    expr beta_expr;
    if (A.get_elements_type() == p_float32 &&
        B.get_elements_type() == p_float32 &&
        C.get_elements_type() == p_float32) {
        fname = "tiramisu_cublas_sgemm";
        alpha_expr = cast(p_float32, alpha);
        beta_expr = cast(p_float32, beta);
    } else if (A.get_elements_type() == p_float64 &&
               B.get_elements_type() == p_float64 &&
               C.get_elements_type() == p_float64) {
        fname = "tiramisu_cublas_dgemm";
        alpha_expr = cast(p_float64, alpha);
        beta_expr = cast(p_float64, beta);
    } else {
        ERROR("All input buffers should be of same type and either p_float32 or p_float64", true);
    }
    return expr(o_call, fname,
            {
                var(p_void_ptr, A.get_name()),
                var(p_void_ptr, B.get_name()),
                var(p_void_ptr, C.get_name()),
                cast(p_uint64, M), cast(p_uint64, N), cast(p_uint64, K),
                alpha_expr, beta_expr,
                cast(p_uint64, ldA), cast(p_uint64, ldB), cast(p_uint64, ldC),
                cast(p_uint64, offsetA), cast(p_uint64, offsetB), cast(p_uint64, offsetC),
                cast(p_boolean, transposeA), cast(p_boolean, transposeB)
            },
            tiramisu::p_uint8);
}

expr cuda_stream_synchronize()
{
    return expr(o_call, "tiramisu_cuda_stream_synchronize", {int32_t(0)}, tiramisu::p_int32);
}

expr mkl_gemm(const buffer &A, const buffer &B, buffer &C,
                 expr M, expr N, expr K,
                 expr alpha, expr beta,
                 expr offsetA, expr offsetB, expr offsetC
                 )
{
    std::string fname;
    expr alpha_expr;
    expr beta_expr;
    if (A.get_elements_type() == p_float32 &&
        B.get_elements_type() == p_float32 &&
        C.get_elements_type() == p_float32) {
        fname = "cblas_sgemm";
        alpha_expr = cast(p_float32, alpha);
        beta_expr = cast(p_float32, beta);
    } else if (A.get_elements_type() == p_float64 &&
               B.get_elements_type() == p_float64 &&
               C.get_elements_type() == p_float64) {
        fname = "cblas_dgemm";
        alpha_expr = cast(p_float64, alpha);
        beta_expr = cast(p_float64, beta);
    } else {
        ERROR("All input buffers should be of same type and either p_float32 or p_float64", true);
    }

    return expr(o_call, fname,
            {CblasRowMajor, CblasNoTrans, CblasNoTrans,
                cast(p_uint64, M), cast(p_uint64, N), cast(p_uint64, K), alpha_expr,  var(p_void_ptr, A.get_name()),
                cast(p_uint64, K),  var(p_void_ptr, B.get_name()),
                cast(p_uint64, N), beta_expr,  var(p_void_ptr, C.get_name()), cast(p_uint64, N)},tiramisu::p_uint8);
}

}
<commit_msg>cblas_gemm call added<commit_after>#include <tiramisu/expr.h>
#include <tiramisu/core.h>
#include "mkl.h"
#include <stdio.h>
#include <stdlib.h>
#define min(x,y) (((x) < (y)) ? (x) : (y))
namespace tiramisu
{

tiramisu::expr& tiramisu::expr::operator=(tiramisu::expr const & e)
{
    this->_operator = e._operator;
    this->op = e.op;
    this->access_vector = e.access_vector;
    this->argument_vector = e.argument_vector;
    this->defined = e.defined;
    this->name = e.name;
    this->dtype = e.dtype;
    this->etype = e.etype;

    // Copy the integer value
    if (e.get_expr_type() == tiramisu::e_val)
    {
        if (e.get_data_type() == tiramisu::p_uint8)
        {
            this->uint8_value = e.get_uint8_value();
        }
        else if (e.get_data_type() == tiramisu::p_int8)
        {
            this->int8_value = e.get_int8_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint16)
        {
            this->uint16_value = e.get_uint16_value();
        }
        else if (e.get_data_type() == tiramisu::p_int16)
        {
            this->int16_value = e.get_int16_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint32)
        {
            this->uint32_value = e.get_uint32_value();
        }
        else if (e.get_data_type() == tiramisu::p_int32)
        {
            this->int32_value = e.get_int32_value();
        }
        else if (e.get_data_type() == tiramisu::p_uint64)
        {
            this->uint64_value = e.get_uint64_value();
        }
        else if (e.get_data_type() == tiramisu::p_int64)
        {
            this->int64_value = e.get_int64_value();
        }
        else if (e.get_data_type() == tiramisu::p_float32)
        {
            this->float32_value = e.get_float32_value();
        }
        else if (e.get_data_type() == tiramisu::p_float64)
        {
            this->float64_value = e.get_float64_value();
        }
    }
    return *this;
}

tiramisu::expr tiramisu::expr::substitute(std::vector<std::pair<var, expr>> substitutions) const
{
    for (auto &substitution: substitutions)
        if (this->is_equal(substitution.first))
            return substitution.second;

    return apply_to_operands([&substitutions](const expr& e){
        return e.substitute(substitutions);
    });
}

tiramisu::expr tiramisu::expr::substitute_access(std::string original, std::string substitute) const {
    expr && result = this->apply_to_operands([&original, &substitute](const expr& e){
        return e.substitute_access(original, substitute);
    });
    if (result.get_op_type() == o_access && result.name == original)
    {
        result.name = substitute;
    }
    return result;
}

tiramisu::var::var(std::string name, bool save)
{
    assert(!name.empty());

    auto declared = var::declared_vars.find(name);

    if (declared != var::declared_vars.end())
    {
        *this = declared->second;
    }
    else
    {
        this->name = name;
        this->etype = tiramisu::e_var;
        this->dtype = global::get_loop_iterator_data_type();
        this->defined = true;
        if (save)
        {
            var::declared_vars.insert(std::make_pair(name, *this));
            DEBUG(3, std::cout << "Saved variable " << this->name << " of type " << str_from_tiramisu_type_primitive(this->dtype));
        }
    }
}

tiramisu::var::var(tiramisu::primitive_t type, std::string name, bool save)
{
    assert(!name.empty());

    auto declared = var::declared_vars.find(name);

    if (declared != var::declared_vars.end())
    {
        assert(declared->second.dtype == type);
        *this = declared->second;
    }
    else
    {
        this->name = name;
        this->etype = tiramisu::e_var;
        this->dtype = type;
        this->defined = true;
        if (save)
        {
            var::declared_vars.insert(std::make_pair(name, *this));
            DEBUG(10, std::cout << "Saved variable " << this->name << " of type " << str_from_tiramisu_type_primitive(this->dtype));
        }
    }
}

tiramisu::expr tiramisu::expr::copy() const
{
    return (*this);
}

std::unordered_map<std::string, var> tiramisu::var::declared_vars;

expr cast(primitive_t tT, const expr & e) {
    if (e.get_data_type() == tT)
        return e;
    return expr{o_cast, tT, e};
}

expr tiramisu::expr::operator+(tiramisu::expr other) const {
    return tiramisu::expr{o_add, *this, other};
}

expr tiramisu::expr::operator-(tiramisu::expr other) const {
    return tiramisu::expr{o_sub, *this, other};
}

expr tiramisu::expr::operator*(tiramisu::expr other) const {
    return tiramisu::expr{o_mul, *this, other};
}

expr tiramisu::expr::operator/(tiramisu::expr other) const {
    return tiramisu::expr{o_div, *this, other};
}

expr tiramisu::expr::operator%(tiramisu::expr other) const {
    return tiramisu::expr{o_mod, *this, other};
}

expr tiramisu::expr::operator>>(tiramisu::expr other) const {
    return tiramisu::expr{o_right_shift, *this, other};
}

expr tiramisu::expr::operator<<(tiramisu::expr other) const {
    return tiramisu::expr{o_left_shift, *this, other};
}

expr memcpy(const buffer &from, const buffer &to) {
    return expr(o_memcpy, var(p_void_ptr, from.get_name()), var(p_void_ptr, to.get_name()));
}

expr allocate(const buffer &b)
{
    return expr{o_allocate, b.get_name()};
}

expr cublas_gemm(const buffer &A, const buffer &B, buffer &C,
                 expr M, expr N, expr K,
                 expr alpha, expr beta,
                 expr ldA, expr ldB, expr ldC,
                 expr offsetA, expr offsetB, expr offsetC,
                 expr transposeA, expr transposeB)
{
    if (A.get_location() != cuda_ast::memory_location::global ||
        B.get_location() != cuda_ast::memory_location::global ||
        C.get_location() != cuda_ast::memory_location::global) {
        ERROR("Buffers must be on GPU global memory", true);
    }
    std::string fname;
    expr alpha_expr;
    expr beta_expr;
    if (A.get_elements_type() == p_float32 &&
        B.get_elements_type() == p_float32 &&
        C.get_elements_type() == p_float32) {
        fname = "tiramisu_cublas_sgemm";
        alpha_expr = cast(p_float32, alpha);
        beta_expr = cast(p_float32, beta);
    } else if (A.get_elements_type() == p_float64 &&
               B.get_elements_type() == p_float64 &&
               C.get_elements_type() == p_float64) {
        fname = "tiramisu_cublas_dgemm";
        alpha_expr = cast(p_float64, alpha);
        beta_expr = cast(p_float64, beta);
    } else {
        ERROR("All input buffers should be of same type and either p_float32 or p_float64", true);
    }
    return expr(o_call, fname,
            {
                var(p_void_ptr, A.get_name()),
                var(p_void_ptr, B.get_name()),
                var(p_void_ptr, C.get_name()),
                cast(p_uint64, M), cast(p_uint64, N), cast(p_uint64, K),
                alpha_expr, beta_expr,
                cast(p_uint64, ldA), cast(p_uint64, ldB), cast(p_uint64, ldC),
                cast(p_uint64, offsetA), cast(p_uint64, offsetB), cast(p_uint64, offsetC),
                cast(p_boolean, transposeA), cast(p_boolean, transposeB)
            },
            tiramisu::p_uint8);
}

expr cuda_stream_synchronize()
{
    return expr(o_call, "tiramisu_cuda_stream_synchronize", {int32_t(0)}, tiramisu::p_int32);
}

extern "C"
int tiramisu_cblas_sgemm(float *A, float *B, float *C,
                          uint64_t M, uint64_t N, uint64_t K,
                          float alpha, float beta,
                          uint64_t ldA, uint64_t ldB, uint64_t ldC,
                          uint64_t offsetA, uint64_t offsetB, uint64_t offsetC,
                          bool transposeA, bool transposeB)
{
    // Default values for tight packing:
    if (ldA == 0) {
        ldA = transposeA ? M : K;
    }
    if (ldB == 0) {
        ldB = transposeB ? K : N;
    }
    if (ldC == 0) {
        ldC = N;
    }

    cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                M, N, K, alpha, A+offsetA, K, B+ offsetB, N, beta, C+ offsetC, N);
    return 0;
}

extern "C"
int tiramisu_cblas_dgemm(double *A, double *B, double *C,
                          uint64_t M, uint64_t N, uint64_t K,
                          double alpha, double beta,
                          uint64_t ldA, uint64_t ldB, uint64_t ldC,
                          uint64_t offsetA, uint64_t offsetB, uint64_t offsetC,
                          bool transposeA, bool transposeB)
{
    // Default values for tight packing:
    if (ldA == 0) {
        ldA = transposeA ? M : K;
    }
    if (ldB == 0) {
        ldB = transposeB ? K : N;
    }
    if (ldC == 0) {
        ldC = N;
    }

    cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                M, N, K, alpha, A+offsetA, K, B+ offsetB, N, beta, C+ offsetC, N);
    return 0;
}

expr cblas_gemm_call(const buffer &A, const buffer &B, buffer &C,
                 expr M, expr N, expr K,
                 expr alpha, expr beta,
                 expr ldA, expr ldB, expr ldC,
                 expr offsetA, expr offsetB, expr offsetC,
                 expr transposeA, expr transposeB)
{
    std::string fname;
    expr alpha_expr;
    expr beta_expr;
    if (A.get_elements_type() == p_float32 &&
        B.get_elements_type() == p_float32 &&
        C.get_elements_type() == p_float32) {
        fname = "tiramisu_cblas_sgemm";
        alpha_expr = cast(p_float32, alpha);
        beta_expr = cast(p_float32, beta);
    } else if (A.get_elements_type() == p_float64 &&
               B.get_elements_type() == p_float64 &&
               C.get_elements_type() == p_float64) {
        fname = "tiramisu_cblas_dgemm";
        alpha_expr = cast(p_float64, alpha);
        beta_expr = cast(p_float64, beta);
    } else {
        ERROR("All input buffers should be of same type and either p_float32 or p_float64", true);
    }
    return expr(o_call, fname,
            {
                var(p_void_ptr, A.get_name()),
                var(p_void_ptr, B.get_name()),
                var(p_void_ptr, C.get_name()),
                cast(p_uint64, M), cast(p_uint64, N), cast(p_uint64, K),
                alpha_expr, beta_expr,
                cast(p_uint64, ldA), cast(p_uint64, ldB), cast(p_uint64, ldC),
                cast(p_uint64, offsetA), cast(p_uint64, offsetB), cast(p_uint64, offsetC),
                cast(p_boolean, transposeA), cast(p_boolean, transposeB)
            },
            tiramisu::p_uint8);
}

}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "helpwindow.h"
#include "utils.h"

#include "ui_mainwindow.h"

#ifdef Q_WS_WIN
    #include <windows.h>
#endif

#include <QApplication>
#include <QDebug>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDir>
#include <QFileInfo>
#include <QHelpEngine>
#include <QMessageBox>
#include <QSettings>
#include <QTemporaryFile>
#include <QUrl>

#define OPENCOR_HOMEPAGE "http://opencor.sourceforge.net/"

#define SETTINGS_INSTITUTION "World"
#define SETTINGS_GENERAL_LOCALE "General_Locale"
#define SETTINGS_GENERAL_GEOMETRY "General_Geometry"
#define SETTINGS_GENERAL_STATE "General_State"
#define SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER "HelpWindow_TextSizeMultiplier"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    // Retrieve the name of the operating system

    osName = getOsName();

    // Retrieve the name of the application

    appName = QFileInfo(qApp->applicationFilePath()).baseName();
    // Note: normally, one would probably use something like:
    //
    //           appName = qApp->applicationName();
    //
    //       but this will return an empty string (probably as a result of our
    //       use of CMake as opposed to QMake and therefore a .pro file), so...

    // Retrieve the version of the application

    QFile versionFile(":version");

    versionFile.open(QIODevice::ReadOnly);

    appVersion = QString(versionFile.readLine()).trimmed();

    if (appVersion.endsWith(".0"))
        // There is no actual patch information, so trim it

        appVersion.truncate(appVersion.length()-2);

    versionFile.close();

    // Set up the GUI

    ui->setupUi(this);

    // Extract the help files

    QTemporaryFile tempDir;

    tempDir.open();    // Note: this is required to get a 'valid' temporary
    tempDir.close();   //       directory name...

    tempDirName = tempDir.fileName().append(".dir");

    QDir().mkdir(tempDirName);

    QString applicationBaseName(QFileInfo(qApp->applicationFilePath()).baseName());

    qchFileName = tempDirName+QDir::separator()+applicationBaseName+".qch";
    qhcFileName = tempDirName+QDir::separator()+applicationBaseName+".qhc";

    saveResourceAs(":qchFile", qchFileName);
    saveResourceAs(":qhcFile", qhcFileName);

    // Set up the help engine

    helpEngine = new QHelpEngine(qhcFileName);

    helpEngine->setupData();

    // Help window

    helpWindow = new HelpWindow(helpEngine, QUrl("qthelp://world.opencor/doc/index.html"));

    connect(helpWindow, SIGNAL(visibilityChanged(bool)), this, SLOT(showHideHelp(bool)));

    // Default user settings

    on_actionResetAll_triggered();

    // Retrieve our default settings

    loadSettings();

    // Set the name of the main window to that of the application

    setWindowTitle(appName);
}

MainWindow::~MainWindow()
{
    // Keep track of our default settings

    saveSettings();

    // Delete some internal objects

    delete helpEngine;
    delete ui;

    // Delete the help files

    QFile(qchFileName).remove();
    QFile(qhcFileName).remove();

    QDir().rmdir(tempDirName);
}

void MainWindow::singleAppMsgRcvd(const QString&)
{
    // We have just received a message from another instance of OpenCOR, so
    // bring ourselves to the foreground
    // Note: one would normally use activateWindow(), but depending on the
    //       operating system it may or not bring OpenCOR to the foreground,
    //       so... instead we do what follows, depending on the operating
    //       system...

#ifdef Q_WS_WIN
    // Retrieve OpenCOR's window Id

    WId mwWinId = winId();

    // Restore OpenCOR, should it be minimized

    if (IsIconic(mwWinId))
        SendMessage(mwWinId, WM_SYSCOMMAND, SC_RESTORE, 0);

    // Bring OpenCOR to the foreground

    DWORD foregroundThreadPId = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
    DWORD mwThreadPId         = GetWindowThreadProcessId(mwWinId, NULL);

    if (foregroundThreadPId != mwThreadPId)
    {
        // OpenCOR's thread process Id is not that of the foreground window, so
        // attach the foreground thread to OpenCOR's, set OpenCOR to the
        // foreground, and detach the foreground thread from OpenCOR's

        AttachThreadInput(foregroundThreadPId, mwThreadPId, true);

        SetForegroundWindow(mwWinId);

        AttachThreadInput(foregroundThreadPId, mwThreadPId, false);
    }
    else
        // OpenCOR's thread process Id is that of the foreground window, so
        // just set OpenCOR to the foreground

        SetForegroundWindow(mwWinId);

    // Note: under Windows, to use activateWindow() will only highlight the
    //       application in the taskbar, since under Windows no application
    //       should be allowed to bring itself to the foreground when another
    //       application is already in the foreground. Fair enough, but it
    //       happens that, here, the user wants OpenCOR to be brought to the
    //       foreground, hence the above code to get the effect we are after...
#else
    // Do what one should normally do and which works fine under Mac OS X

    activateWindow();

    #ifdef Q_WS_X11
        raise();
        // Note: under Linux, to use activateWindow() may or not give the
        //       expected result. The above code is supposed to make sure that
        //       OpenCOR gets brought to the foreground, but that itsn't the
        //       case under Ubuntu at least (it works when you want to open a
        //       second instance of OpenCOR, but not thereafter!)...
    #endif
#endif

    // Now, we must handle the arguments that were passed to us

    // TODO: handle the arguments passed to the 'official' instance of OpenCOR
}

void MainWindow::loadSettings()
{
    QSettings settings(SETTINGS_INSTITUTION, appName);

    // Retrieve the language to be used by OpenCOR, with a default just in case

    setLocale(settings.value(SETTINGS_GENERAL_LOCALE, QLocale::system().name()).toString());

    // Retrieve the geometry of the main window

    restoreGeometry(settings.value(SETTINGS_GENERAL_GEOMETRY).toByteArray());

    // Retrieve the state of the main window

    restoreState(settings.value(SETTINGS_GENERAL_STATE).toByteArray());

    // Retrieve the text size multiplier for the help widget, with a default
    // value just in case

    helpWindow->setHelpWidgetTextSizeMultiplier(settings.value(SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER, helpWindow->helpWidgetTextSizeMultiplier()).toDouble());
}

void MainWindow::saveSettings()
{
    QSettings settings(SETTINGS_INSTITUTION, appName);

    // Keep track of the language to be used by OpenCOR

    settings.setValue(SETTINGS_GENERAL_LOCALE, locale);

    // Keep track of the geometry of the main window

    settings.setValue(SETTINGS_GENERAL_GEOMETRY, saveGeometry());

    // Keep track of the state of the main window

    settings.setValue(SETTINGS_GENERAL_STATE, saveState());

    // Keep track of the text size multiplier for the help widget

    settings.setValue(SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER, helpWindow->helpWidgetTextSizeMultiplier());
}

void MainWindow::setLocale(const QString& newLocale)
{
    if (newLocale != locale)
    {
        locale = newLocale;

        // Specify the language to be used by OpenCOR

//        qApp->removeTranslator(qtTranslator);
//        qtTranslator->load("qt_"+newLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
//        qApp->installTranslator(qtTranslator);

//        qApp->removeTranslator(appTranslator);
//        appTranslator->load(":app_"+newLocale);
//        qApp->installTranslator(appTranslator);
    }

    // Update the checked menu item
    // Note: it has to be done every single time, since selecting a menu item
    //       will automatically toggle its checked status, so...

    ui->actionEnglish->setChecked(newLocale.startsWith("en"));
    ui->actionFrench->setChecked(newLocale.startsWith("fr"));
}

void MainWindow::notYetImplemented(const QString& message)
{
    // Display a warning message about a particular feature having not yet been
    // implemented

    QMessageBox::warning(this, appName, message+tr(" has not yet been implemented..."),
                         QMessageBox::Ok, QMessageBox::Ok);
}

void MainWindow::on_actionExit_triggered()
{
    // Exit OpenCOR

    close();
}

void MainWindow::on_actionEnglish_triggered()
{
    // Select English as the language used by OpenCOR

    setLocale("en");
}

void MainWindow::on_actionFrench_triggered()
{
    // Select French as the language used by OpenCOR

    setLocale("fr");
}

void MainWindow::showHideHelp(const bool& show)
{
    if (show)
        helpWindow->show();
    else
        helpWindow->hide();

    ui->actionHelp->setChecked(show);
}

void MainWindow::on_actionHelp_triggered()
{
    showHideHelp(ui->actionHelp->isChecked());
}

void MainWindow::on_actionHomepage_triggered()
{
    // Look up the OpenCOR home page

    QDesktopServices::openUrl(QUrl(OPENCOR_HOMEPAGE));
}

void MainWindow::on_actionAbout_triggered()
{
    QMessageBox::about(this, appName,
                       QString("")+
                       ""+
                           "
"+appName+" "+appVersion+"
"+
                           "
"+osName+"
"+
                       ""+
                       "
"+
                       ""+appName+" "+tr("is a cross-platform CellML-based modelling environment which can be used to organise, edit, simulate and analyse CellML files.")+"

"+
                       appName+" "+tr("is written in C++, using the Qt framework, and is not currently released under any particular license, but this is going to change in the future."));
}

void MainWindow::on_actionResetAll_triggered()
{
    // Default size and position of both the main and help windows

    const double mainRatio = 3.0/5.0;
    const double helpRatio = 1.0/3.0;
    const double spaceRatio = 1.0/45.0;
    const double horizSpace = spaceRatio*qApp->desktop()->width();
    const double vertSpace  = 2.0*spaceRatio*qApp->desktop()->height();

    addDockWidget(Qt::RightDockWidgetArea, helpWindow);
    // Note: the above is only required so that the help window can then be
    //       docked to the main window, should the user want to do that.
    //       Indeed, to make the help window float is not sufficient, so...

    helpWindow->setFloating(true);

    resize(QSize(mainRatio*qApp->desktop()->width(), mainRatio*qApp->desktop()->height()));
    helpWindow->resize(helpRatio*qApp->desktop()->width(), size().height());

    move(QPoint(horizSpace, vertSpace));
    helpWindow->move(QPoint(qApp->desktop()->width()-helpWindow->size().width()-horizSpace, vertSpace));

    helpWindow->hide();   // By default

    // Default language to be used by OpenCOR

    setLocale(QLocale::system().name());

    // Default text size multiplier for the help widget

    helpWindow->setHelpWidgetTextSizeMultiplier(1.0);
}
<commit_msg>Fixed a small issue, on Linux, which showed a blank window in place of the help window when this one was supposed to be hidden upon starting OpenCOR.<commit_after>#include "mainwindow.h"
#include "helpwindow.h"
#include "utils.h"

#include "ui_mainwindow.h"

#ifdef Q_WS_WIN
    #include <windows.h>
#endif

#include <QApplication>
#include <QDebug>
#include <QDesktopServices>
#include <QDesktopWidget>
#include <QDir>
#include <QFileInfo>
#include <QHelpEngine>
#include <QMessageBox>
#include <QSettings>
#include <QTemporaryFile>
#include <QUrl>

#define OPENCOR_HOMEPAGE "http://opencor.sourceforge.net/"

#define SETTINGS_INSTITUTION "World"
#define SETTINGS_GENERAL_LOCALE "General_Locale"
#define SETTINGS_GENERAL_GEOMETRY "General_Geometry"
#define SETTINGS_GENERAL_STATE "General_State"
#define SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER "HelpWindow_TextSizeMultiplier"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    // Retrieve the name of the operating system

    osName = getOsName();

    // Retrieve the name of the application

    appName = QFileInfo(qApp->applicationFilePath()).baseName();
    // Note: normally, one would probably use something like:
    //
    //           appName = qApp->applicationName();
    //
    //       but this will return an empty string (probably as a result of our
    //       use of CMake as opposed to QMake and therefore a .pro file), so...

    // Retrieve the version of the application

    QFile versionFile(":version");

    versionFile.open(QIODevice::ReadOnly);

    appVersion = QString(versionFile.readLine()).trimmed();

    if (appVersion.endsWith(".0"))
        // There is no actual patch information, so trim it

        appVersion.truncate(appVersion.length()-2);

    versionFile.close();

    // Set up the GUI

    ui->setupUi(this);

    // Extract the help files

    QTemporaryFile tempDir;

    tempDir.open();    // Note: this is required to get a 'valid' temporary
    tempDir.close();   //       directory name...

    tempDirName = tempDir.fileName().append(".dir");

    QDir().mkdir(tempDirName);

    QString applicationBaseName(QFileInfo(qApp->applicationFilePath()).baseName());

    qchFileName = tempDirName+QDir::separator()+applicationBaseName+".qch";
    qhcFileName = tempDirName+QDir::separator()+applicationBaseName+".qhc";

    saveResourceAs(":qchFile", qchFileName);
    saveResourceAs(":qhcFile", qhcFileName);

    // Set up the help engine

    helpEngine = new QHelpEngine(qhcFileName);

    helpEngine->setupData();

    // Help window

    helpWindow = new HelpWindow(helpEngine, QUrl("qthelp://world.opencor/doc/index.html"));

    connect(helpWindow, SIGNAL(visibilityChanged(bool)), this, SLOT(showHideHelp(bool)));

    // Default user settings

    on_actionResetAll_triggered();

    // Retrieve our default settings

    loadSettings();

    // Set the name of the main window to that of the application

    setWindowTitle(appName);
}

MainWindow::~MainWindow()
{
    // Keep track of our default settings

    saveSettings();

    // Delete some internal objects

    delete helpEngine;
    delete ui;

    // Delete the help files

    QFile(qchFileName).remove();
    QFile(qhcFileName).remove();

    QDir().rmdir(tempDirName);
}

void MainWindow::singleAppMsgRcvd(const QString&)
{
    // We have just received a message from another instance of OpenCOR, so
    // bring ourselves to the foreground
    // Note: one would normally use activateWindow(), but depending on the
    //       operating system it may or not bring OpenCOR to the foreground,
    //       so... instead we do what follows, depending on the operating
    //       system...

#ifdef Q_WS_WIN
    // Retrieve OpenCOR's window Id

    WId mwWinId = winId();

    // Restore OpenCOR, should it be minimized

    if (IsIconic(mwWinId))
        SendMessage(mwWinId, WM_SYSCOMMAND, SC_RESTORE, 0);

    // Bring OpenCOR to the foreground

    DWORD foregroundThreadPId = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
    DWORD mwThreadPId         = GetWindowThreadProcessId(mwWinId, NULL);

    if (foregroundThreadPId != mwThreadPId)
    {
        // OpenCOR's thread process Id is not that of the foreground window, so
        // attach the foreground thread to OpenCOR's, set OpenCOR to the
        // foreground, and detach the foreground thread from OpenCOR's

        AttachThreadInput(foregroundThreadPId, mwThreadPId, true);

        SetForegroundWindow(mwWinId);

        AttachThreadInput(foregroundThreadPId, mwThreadPId, false);
    }
    else
        // OpenCOR's thread process Id is that of the foreground window, so
        // just set OpenCOR to the foreground

        SetForegroundWindow(mwWinId);

    // Note: under Windows, to use activateWindow() will only highlight the
    //       application in the taskbar, since under Windows no application
    //       should be allowed to bring itself to the foreground when another
    //       application is already in the foreground. Fair enough, but it
    //       happens that, here, the user wants OpenCOR to be brought to the
    //       foreground, hence the above code to get the effect we are after...
#else
    // Do what one should normally do and which works fine under Mac OS X

    activateWindow();

    #ifdef Q_WS_X11
        raise();
        // Note: under Linux, to use activateWindow() may or not give the
        //       expected result. The above code is supposed to make sure that
        //       OpenCOR gets brought to the foreground, but that itsn't the
        //       case under Ubuntu at least (it works when you want to open a
        //       second instance of OpenCOR, but not thereafter!)...
    #endif
#endif

    // Now, we must handle the arguments that were passed to us

    // TODO: handle the arguments passed to the 'official' instance of OpenCOR
}

void MainWindow::loadSettings()
{
    QSettings settings(SETTINGS_INSTITUTION, appName);

    // Retrieve the language to be used by OpenCOR, with a default just in case

    setLocale(settings.value(SETTINGS_GENERAL_LOCALE, QLocale::system().name()).toString());

    // Retrieve the geometry of the main window

    restoreGeometry(settings.value(SETTINGS_GENERAL_GEOMETRY).toByteArray());

    // Retrieve the state of the main window

    restoreState(settings.value(SETTINGS_GENERAL_STATE).toByteArray());

    // Retrieve the text size multiplier for the help widget, with a default
    // value just in case

    helpWindow->setHelpWidgetTextSizeMultiplier(settings.value(SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER, 1.0).toDouble());

#ifdef Q_WS_X11
    // Really hide the help window, if it is to be hidden upon starting OpenCOR
    // Indeed, on Linux, we still get some kind of a blank window, so...

    if (helpWindow->isHidden())
    {
        helpWindow->show();
        helpWindow->hide();
    }
#endif
}

void MainWindow::saveSettings()
{
    QSettings settings(SETTINGS_INSTITUTION, appName);

    // Keep track of the language to be used by OpenCOR

    settings.setValue(SETTINGS_GENERAL_LOCALE, locale);

    // Keep track of the geometry of the main window

    settings.setValue(SETTINGS_GENERAL_GEOMETRY, saveGeometry());

    // Keep track of the state of the main window

    settings.setValue(SETTINGS_GENERAL_STATE, saveState());

    // Keep track of the text size multiplier for the help widget

    settings.setValue(SETTINGS_HELPWINDOW_TEXTSIZEMULTIPLIER, helpWindow->helpWidgetTextSizeMultiplier());
}

void MainWindow::setLocale(const QString& newLocale)
{
    if (newLocale != locale)
    {
        locale = newLocale;

        // Specify the language to be used by OpenCOR

//        qApp->removeTranslator(qtTranslator);
//        qtTranslator->load("qt_"+newLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
//        qApp->installTranslator(qtTranslator);

//        qApp->removeTranslator(appTranslator);
//        appTranslator->load(":app_"+newLocale);
//        qApp->installTranslator(appTranslator);
    }

    // Update the checked menu item
    // Note: it has to be done every single time, since selecting a menu item
    //       will automatically toggle its checked status, so...

    ui->actionEnglish->setChecked(newLocale.startsWith("en"));
    ui->actionFrench->setChecked(newLocale.startsWith("fr"));
}

void MainWindow::notYetImplemented(const QString& message)
{
    // Display a warning message about a particular feature having not yet been
    // implemented

    QMessageBox::warning(this, appName, message+tr(" has not yet been implemented..."),
                         QMessageBox::Ok, QMessageBox::Ok);
}

void MainWindow::on_actionExit_triggered()
{
    // Exit OpenCOR

    close();
}

void MainWindow::on_actionEnglish_triggered()
{
    // Select English as the language used by OpenCOR

    setLocale("en");
}

void MainWindow::on_actionFrench_triggered()
{
    // Select French as the language used by OpenCOR

    setLocale("fr");
}

void MainWindow::showHideHelp(const bool& show)
{
    if (show)
        helpWindow->show();
    else
        helpWindow->hide();

    ui->actionHelp->setChecked(show);
}

void MainWindow::on_actionHelp_triggered()
{
    showHideHelp(ui->actionHelp->isChecked());
}

void MainWindow::on_actionHomepage_triggered()
{
    // Look up the OpenCOR home page

    QDesktopServices::openUrl(QUrl(OPENCOR_HOMEPAGE));
}

void MainWindow::on_actionAbout_triggered()
{
    QMessageBox::about(this, appName,
                       QString("")+
                       ""+
                           "
"+appName+" "+appVersion+"
"+
                           "
"+osName+"
"+
                       ""+
                       "
"+
                       ""+appName+" "+tr("is a cross-platform CellML-based modelling environment which can be used to organise, edit, simulate and analyse CellML files.")+"

"+
                       appName+" "+tr("is written in C++, using the Qt framework, and is not currently released under any particular license, but this is going to change in the future."));
}

void MainWindow::on_actionResetAll_triggered()
{
    // Default size and position of both the main and help windows

    const double mainRatio = 3.0/5.0;
    const double helpRatio = 1.0/3.0;
    const double spaceRatio = 1.0/45.0;
    const double horizSpace = spaceRatio*qApp->desktop()->width();
    const double vertSpace  = 2.0*spaceRatio*qApp->desktop()->height();

    addDockWidget(Qt::RightDockWidgetArea, helpWindow);
    // Note: the above is only required so that the help window can then be
    //       docked to the main window, should the user want to do that.
    //       Indeed, to make the help window float is not sufficient, so...

    helpWindow->setFloating(true);

    resize(QSize(mainRatio*qApp->desktop()->width(), mainRatio*qApp->desktop()->height()));
    helpWindow->resize(helpRatio*qApp->desktop()->width(), size().height());

    move(QPoint(horizSpace, vertSpace));
    helpWindow->move(QPoint(qApp->desktop()->width()-helpWindow->size().width()-horizSpace, vertSpace));

    helpWindow->hide();   // By default

    // Default language to be used by OpenCOR

    setLocale(QLocale::system().name());

    // Default text size multiplier for the help widget

    helpWindow->setHelpWidgetTextSizeMultiplier(1.0);
}
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2018, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file fd_utils.hxx
 *
 * Helper functions for dealing with posix fds.
 *
 * @author Balazs Racz
 * @date 18 Sep 2018
 */

#ifndef _UTILS_FD_UTILS_HXX_
#define _UTILS_FD_UTILS_HXX_

#include "utils/macros.h"

struct FdUtils
{
    /// Performs a reliable read from the given FD. Crashes if the read fails.
    ///
    /// @param fd the file to read data from
    /// @param buf the location to write data to
    /// @param size how many bytes to read
    ///
    static void repeated_read(int fd, void *buf, size_t size)
    {
        uint8_t *dst = static_cast<uint8_t *>(buf);
        while (size)
        {
            ssize_t ret = ::read(fd, dst, size);
            ERRNOCHECK("read", ret);
            if (ret == 0)
            {
                DIE("Unexpected EOF reading the config file.");
            }
            size -= ret;
            dst += ret;
        }
    }

    /// Performs a reliable write to the given FD. Crashes if the write fails.
    ///
    /// @param fd the file to write data to
    /// @param buf the location of the data to write
    /// @param size how many bytes to write
    ///
    static void repeated_write(int fd, const void *buf, size_t size) const
    {
        const uint8_t *dst = static_cast<const uint8_t *>(buf);
        while (size)
        {
            ssize_t ret = ::write(fd, dst, size);
            ERRNOCHECK("write_config", ret);
            if (ret == 0)
            {
                DIE("Unexpected EOF writing the config file.");
            }
            size -= ret;
            dst += ret;
        }
    }
};

#endif // _UTILS_FD_UTILS_HXX_
<commit_msg>fixes comile error<commit_after>/** \copyright
 * Copyright (c) 2018, Balazs Racz
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file fd_utils.hxx
 *
 * Helper functions for dealing with posix fds.
 *
 * @author Balazs Racz
 * @date 18 Sep 2018
 */

#ifndef _UTILS_FD_UTILS_HXX_
#define _UTILS_FD_UTILS_HXX_

#include "utils/macros.h"

struct FdUtils
{
    /// Performs a reliable read from the given FD. Crashes if the read fails.
    ///
    /// @param fd the file to read data from
    /// @param buf the location to write data to
    /// @param size how many bytes to read
    ///
    static void repeated_read(int fd, void *buf, size_t size)
    {
        uint8_t *dst = static_cast<uint8_t *>(buf);
        while (size)
        {
            ssize_t ret = ::read(fd, dst, size);
            ERRNOCHECK("read", ret);
            if (ret == 0)
            {
                DIE("Unexpected EOF reading the config file.");
            }
            size -= ret;
            dst += ret;
        }
    }

    /// Performs a reliable write to the given FD. Crashes if the write fails.
    ///
    /// @param fd the file to write data to
    /// @param buf the location of the data to write
    /// @param size how many bytes to write
    ///
    static void repeated_write(int fd, const void *buf, size_t size)
    {
        const uint8_t *dst = static_cast<const uint8_t *>(buf);
        while (size)
        {
            ssize_t ret = ::write(fd, dst, size);
            ERRNOCHECK("write_config", ret);
            if (ret == 0)
            {
                DIE("Unexpected EOF writing the config file.");
            }
            size -= ret;
            dst += ret;
        }
    }
};

#endif // _UTILS_FD_UTILS_HXX_
<|endoftext|>


<commit_before>// 01.01.2017 Султан Xottab_DUTY Урамаев
// Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.
#include <iostream>
#include <thread>

#include <GLFW/glfw3.h>

#include "Common/Platform.hpp"
#include "Debug/Log.hpp"
#include "xdCore.hpp"
#include "ConsoleCommand.hpp"
#include "ConsoleCommands.hpp"
#include "xdEngine.hpp"
#include "Renderer/VkDemoRenderer.hpp"

void InitializeConsole()
{
    ConsoleCommands = new XDay::CC_Container;
    Console = new XDay::xdConsole;
    Console->Initialize();
}

void destroyConsole()
{
    ConsoleCommands->Execute(&ConfigSaveCC);
    ConsoleCommands->Destroy();
    delete ConsoleCommands;
    delete Console;
}

void HelpCmdArgs()
{
    Log("\nAvailable parameters:\n"\
        "--p_name - Specifies AppName, default is \"X-Day Engine\" \n"\
        "--p_game - Specifies game module to be attached, default is \"xdGame\";\n"\
        "--p_datapath - Specifies path of application data folder, default is \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Specifies path of resources folder, default is \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Specifies path and name of main config file (path/name.extension), default is \"*DataPath*/main.config\" \n"\
        "--p_nolog - Completely disables engine log. May increase performance\n"\
        "--p_nologflush - Disables log flushing. Useless if -nolog defined\n"\
        "--p_debug - Enables debug mode\n"
        "--p_shrec - Compile shaders even if they already compiled\n"\
        "--p_shpre - Outputs preprocessed shaders to the shader sources dir. Works only in debug mode\n"\
        "--p_texture - Specifies path to texture file to load, default is \"texture.dds\"\n"\
        "--p_model - Specifies path to model file to model, default is \"model.dds\"\n");

    Log("\nДоступные параметры:\n"\
        "--p_name - Задаёт AppName, по умолчанию: \"X-Day Engine\" \n"\
        "--p_game - Задаёт игровую библиотеку для подключения, по умолчанию: \"xdGame\";\n"
        "--p_datapath - Задаёт путь до папки с настройками, по умолчанию: \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Задаёт путь до папки с ресурсами, по умолчанию: \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Задаёт путь и имя главного файла настроек (путь/имя.расширение), по умолчанию: \"*DataPath*/main.config\" \n"\
        "--p_nolog - Полностью выключает лог движка. Может повысить производительность\n"\
        "--p_nologflush - Выключает сброс лога в файл. Не имеет смысла если задан -nolog\n"\
        "--p_debug - Включает режим отладки\n"
        "--p_shrec - Сборка шейдеров даже если они уже собраны\n"\
        "--p_shpre - Сохраняет обработанные шейдеры в папку исходников шейдеров. Работает только в режиме отладки\n"\
        "--p_texture - Задаёт путь до текстуры для загрузки, по умолчанию: \"texture.dds\"\n"\
        "--p_model - Задаёт путь до модели для загрузки, по умолчанию: \"model.dds\"\n", false);
}

void threadedConsole()
{
    while (!glfwWindowShouldClose(Engine.window))
    {
        std::string input;
        std::getline(std::cin, input);
        if (Console && ConsoleCommands && !glfwWindowShouldClose(Engine.window))
            ConsoleCommands->Execute(input);
        else
            break;
    }
}

void Startup()
{
    while (!glfwWindowShouldClose(Engine.window))
    {
        glfwPollEvents();
        VkDemoRender.UpdateUniformBuffer();
        VkDemoRender.DrawFrame();
    }
    VkDemoRender.device.waitIdle();
}

int main(int argc, char* argv[])
{
    // TODO: enable Windows console window hiding once game console drawing in main window is done
#if 0//ndef DEBUG
    FreeConsole();
#endif

    Core.InitializeArguments(argc, argv);
    Core.Initialize();
    InitializeConsole();

    Log(Core.GetGLFWVersionString());
    Log(Core.GetBuildString());
    Log("Core.Params: " + Core.ParamsString);
    Log("Девиз: Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.", false);
    Log("Slogan: It's more interesting to shoot your feet, than catch arrows by your knee. Let's continue.");
    HelpCmdArgs();

    ConsoleCommands->ExecuteConfig(Console->ConfigFile);
    Log(glfwInit() ? "GLFW initialized." : "GLFW not initialized.");

    Engine.Initialize();
    Engine.xdCreateWindow();

    std::thread WatchConsole(threadedConsole);
    WatchConsole.detach();
    VkDemoRender.Initialize();

    Startup();

    WatchConsole.~thread();
    VkDemoRender.Destroy();

    glfwTerminate();
    Log("GLFW terminated.");

    destroyConsole();

    return 0;
}
<commit_msg>Set cmd UTF-8 codepage on app start<commit_after>// 01.01.2017 Султан Xottab_DUTY Урамаев
// Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.
#include <iostream>
#include <thread>

#include <GLFW/glfw3.h>

#include "Common/Platform.hpp"
#include "Debug/Log.hpp"
#include "xdCore.hpp"
#include "ConsoleCommand.hpp"
#include "ConsoleCommands.hpp"
#include "xdEngine.hpp"
#include "Renderer/VkDemoRenderer.hpp"

void InitializeConsole()
{
    ConsoleCommands = new XDay::CC_Container;
    Console = new XDay::xdConsole;
    Console->Initialize();
}

void destroyConsole()
{
    ConsoleCommands->Execute(&ConfigSaveCC);
    ConsoleCommands->Destroy();
    delete ConsoleCommands;
    delete Console;
}

void HelpCmdArgs()
{
    Log("\nAvailable parameters:\n"\
        "--p_name - Specifies AppName, default is \"X-Day Engine\" \n"\
        "--p_game - Specifies game module to be attached, default is \"xdGame\";\n"\
        "--p_datapath - Specifies path of application data folder, default is \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Specifies path of resources folder, default is \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Specifies path and name of main config file (path/name.extension), default is \"*DataPath*/main.config\" \n"\
        "--p_nolog - Completely disables engine log. May increase performance\n"\
        "--p_nologflush - Disables log flushing. Useless if -nolog defined\n"\
        "--p_debug - Enables debug mode\n"
        "--p_shrec - Compile shaders even if they already compiled\n"\
        "--p_shpre - Outputs preprocessed shaders to the shader sources dir. Works only in debug mode\n"\
        "--p_texture - Specifies path to texture file to load, default is \"texture.dds\"\n"\
        "--p_model - Specifies path to model file to model, default is \"model.dds\"\n");

    Log("\nДоступные параметры:\n"\
        "--p_name - Задаёт AppName, по умолчанию: \"X-Day Engine\" \n"\
        "--p_game - Задаёт игровую библиотеку для подключения, по умолчанию: \"xdGame\";\n"
        "--p_datapath - Задаёт путь до папки с настройками, по умолчанию: \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Задаёт путь до папки с ресурсами, по умолчанию: \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Задаёт путь и имя главного файла настроек (путь/имя.расширение), по умолчанию: \"*DataPath*/main.config\" \n"\
        "--p_nolog - Полностью выключает лог движка. Может повысить производительность\n"\
        "--p_nologflush - Выключает сброс лога в файл. Не имеет смысла если задан -nolog\n"\
        "--p_debug - Включает режим отладки\n"
        "--p_shrec - Сборка шейдеров даже если они уже собраны\n"\
        "--p_shpre - Сохраняет обработанные шейдеры в папку исходников шейдеров. Работает только в режиме отладки\n"\
        "--p_texture - Задаёт путь до текстуры для загрузки, по умолчанию: \"texture.dds\"\n"\
        "--p_model - Задаёт путь до модели для загрузки, по умолчанию: \"model.dds\"\n", false);
}

void threadedConsole()
{
    while (!glfwWindowShouldClose(Engine.window))
    {
        std::string input;
        std::getline(std::cin, input);
        if (Console && ConsoleCommands && !glfwWindowShouldClose(Engine.window))
            ConsoleCommands->Execute(input);
        else
            break;
    }
}

void Startup()
{
    while (!glfwWindowShouldClose(Engine.window))
    {
        glfwPollEvents();
        VkDemoRender.UpdateUniformBuffer();
        VkDemoRender.DrawFrame();
    }
    VkDemoRender.device.waitIdle();
}

int main(int argc, char* argv[])
{
    system("chcp 65001");
    // TODO: enable Windows console window hiding once game console drawing in main window is done
#if 0//ndef DEBUG
    FreeConsole();
#endif

    Core.InitializeArguments(argc, argv);
    Core.Initialize();
    InitializeConsole();

    Log(Core.GetGLFWVersionString());
    Log(Core.GetBuildString());
    Log("Core.Params: " + Core.ParamsString);
    Log("Девиз: Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.", false);
    Log("Slogan: It's more interesting to shoot your feet, than catch arrows by your knee. Let's continue.");
    HelpCmdArgs();

    ConsoleCommands->ExecuteConfig(Console->ConfigFile);
    Log(glfwInit() ? "GLFW initialized." : "GLFW not initialized.");

    Engine.Initialize();
    Engine.xdCreateWindow();

    std::thread WatchConsole(threadedConsole);
    WatchConsole.detach();
    VkDemoRender.Initialize();

    Startup();

    WatchConsole.~thread();
    VkDemoRender.Destroy();

    glfwTerminate();
    Log("GLFW terminated.");

    destroyConsole();

    return 0;
}
<|endoftext|>


<commit_before>/**
 *  @file Reactor.cpp
 *
 *  A zero-dimensional reactor
 */

// Copyright 2001  California Institute of Technology

#include "cantera/zeroD/Reactor.h"
//#include "../CVode.h"
#include "cantera/zeroD/FlowDevice.h"
#include "cantera/zeroD/Wall.h"
#include "cantera/kinetics/InterfaceKinetics.h"
#include "cantera/thermo/SurfPhase.h"

using namespace std;

namespace Cantera
{

doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y);

Reactor::Reactor() : ReactorBase(),
    m_kin(0),
    m_temp_atol(1.e-11),
    m_maxstep(0.0),
    m_vdot(0.0),
    m_Q(0.0),
    m_rtol(1.e-9),
    m_chem(true),
    m_energy(true), m_nsens(npos)
{}

// overloaded method of FuncEval. Called by the integrator to
// get the initial conditions.
void Reactor::getInitialConditions(double t0, size_t leny, double* y)
{
    m_init = true;
    if (m_thermo == 0) {
        cout << "Error: reactor is empty." << endl;
        return;
    }
    m_time = t0;
    m_thermo->restoreState(m_state);

    // total mass
    doublereal mass = m_thermo->density() * m_vol;

    // set components y + 2 ... y + K + 1 to the
    // mass M_k of each species
    m_thermo->getMassFractions(y+2);
    scale(y + 2, y + m_nsp + 2, y + 2, mass);

    // set the first component to the total internal
    // energy
    y[0] = m_thermo->intEnergy_mass() * mass;

    // set the second component to the total volume
    y[1] = m_vol;

    // set the remaining components to the surface species
    // coverages on the walls
    size_t loc = m_nsp + 2;
    SurfPhase* surf;
    for (size_t m = 0; m < m_nwalls; m++) {
        surf = m_wall[m]->surface(m_lr[m]);
        if (surf) {
            m_wall[m]->getCoverages(m_lr[m], y + loc);
            //surf->getCoverages(y+loc);
            loc += surf->nSpecies();
        }
    }
}

/*
 *  Must be called before calling method 'advance'
 */
void Reactor::initialize(doublereal t0)
{
    m_thermo->restoreState(m_state);
    m_sdot.resize(m_nsp, 0.0);
    m_nv = m_nsp + 2;
    for (size_t w = 0; w < m_nwalls; w++)
        if (m_wall[w]->surface(m_lr[w])) {
            m_nv += m_wall[w]->surface(m_lr[w])->nSpecies();
        }

    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();

    size_t nt = 0, maxnt = 0;
    for (size_t m = 0; m < m_nwalls; m++) {
        if (m_wall[m]->kinetics(m_lr[m])) {
            nt = m_wall[m]->kinetics(m_lr[m])->nTotalSpecies();
            if (nt > maxnt) {
                maxnt = nt;
            }
            if (m_wall[m]->kinetics(m_lr[m])) {
                if (&m_kin->thermo(0) !=
                        &m_wall[m]->kinetics(m_lr[m])->thermo(0)) {
                    throw CanteraError("Reactor::initialize",
                                       "First phase of all kinetics managers must be"
                                       " the gas.");
                }
            }
        }
    }
    m_work.resize(maxnt);
    m_init = true;
}

size_t Reactor::nSensParams()
{
    if (m_nsens == npos) {
        // determine the number of sensitivity parameters
        size_t m, ns;
        m_nsens = m_pnum.size();
        for (m = 0; m < m_nwalls; m++) {
            ns = m_wall[m]->nSensParams(m_lr[m]);
            m_nsens_wall.push_back(ns);
            m_nsens += ns;
        }
    }
    return m_nsens;
}

void Reactor::updateState(doublereal* y)
{
    ThermoPhase& mix = *m_thermo;  // define for readability

    // The components of y are the total internal energy,
    // the total volume, and the mass of each species.

    // Set the mass fractions and  density of the mixture.

    doublereal u   = y[0];
    m_vol          = y[1];
    doublereal* mss = y + 2;
    doublereal mass = accumulate(y+2, y+2+m_nsp, 0.0);
    m_thermo->setMassFractions(mss);

    m_thermo->setDensity(mass/m_vol);

    doublereal temp = temperature();
    mix.setTemperature(temp);

    if (m_energy) {
        // Decreased the tolerance on delta_T to 1.0E-7 so that T is
        // accurate to 9 sig digits, because this is
        // used in the numerical jacobian routines where relative values
        // of 1.0E-7 are used in the deltas.
        m_thermo->setState_UV(u/mass,m_vol/mass, 1.0e-7);
        temp = mix.temperature(); //mix.setTemperature(temp);
    }
    //m_state[0] = temp;

    size_t loc = m_nsp + 2;
    SurfPhase* surf;
    for (size_t m = 0; m < m_nwalls; m++) {
        surf = m_wall[m]->surface(m_lr[m]);
        if (surf) {
            //                surf->setTemperature(temp);
            //surf->setCoverages(y+loc);
            m_wall[m]->setCoverages(m_lr[m], y+loc);
            loc += surf->nSpecies();
        }
    }

    // save parameters needed by other connected reactors
    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();
    m_thermo->saveState(m_state);
}

/*
 * Called by the integrator to evaluate ydot given y at time 'time'.
 */
void Reactor::evalEqs(doublereal time, doublereal* y,
                      doublereal* ydot, doublereal* params)
{
    size_t i, k, nk;
    m_time = time;
    m_thermo->restoreState(m_state);

    Kinetics* kin;
    size_t m, n, npar, ploc;
    double mult;
    // process sensitivity parameters
    if (params) {

        npar = m_pnum.size();
        for (n = 0; n < npar; n++) {
            //m_mult_save[n] = m_kin->multiplier(m_pnum[n]);
            mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult*params[n]);
            //                m_kin->setMultiplier(m_pnum[n], m_mult_save[n]*params[n]);
        }
        ploc = npar;
        for (m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->setSensitivityParameters(m_lr[m], params + ploc);
                ploc += m_nsens_wall[m];
            }
        }
    }

    //        updateState(y);          // synchronize the reactor state with y

    m_vdot = 0.0;
    m_Q    = 0.0;

    // compute wall terms
    doublereal vdot, rs0, sum, wallarea;
    //        Kinetics* kin;
    SurfPhase* surf;
    size_t lr, ns, loc = m_nsp+2, surfloc;
    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    for (i = 0; i < m_nwalls; i++) {
        lr = 1 - 2*m_lr[i];
        vdot = lr*m_wall[i]->vdot(time);
        m_vdot += vdot;
        m_Q += lr*m_wall[i]->Q(time);
        kin = m_wall[i]->kinetics(m_lr[i]);
        surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            rs0 = 1.0/surf->siteDensity();
            nk = surf->nSpecies();
            sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(DATA_PTR(m_work));
            ns = kin->surfacePhaseIndex();
            surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            wallarea = m_wall[i]->area();
            for (k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
            }
        }
    }

    // volume equation
    ydot[1] = m_vdot;

    /* species equations
     *  Equation is:
     *  \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in}
     *             - \dot m_{out} Y_{k} + A \dot s_k.
     */
    const doublereal* mw = DATA_PTR(m_thermo->molecularWeights());
    if (m_chem) {
        m_kin->getNetProductionRates(ydot+2);   // "omega dot"
    } else {
        fill(ydot + 2, ydot + 2 + m_nsp, 0.0);
    }
    for (n = 0; n < m_nsp; n++) {
        ydot[n+2] *= m_vol;     //           moles/s/m^3 -> moles/s
        ydot[n+2] += m_sdot[n];
        ydot[n+2] *= mw[n];
    }

    /*
     *  Energy equation.
     *  \f[
     *  \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in}
     * - \dot m_{out} h.
     * \f]
     */
    if (m_energy) {
        ydot[0] = - m_thermo->pressure() * m_vdot - m_Q;
    } else {
        ydot[0] = 0.0;
    }

    // add terms for open system
    if (m_open) {

        const doublereal* mf = m_thermo->massFractions();
        doublereal enthalpy = m_thermo->enthalpy_mass();

        // outlets

        doublereal mdot_out;
        for (i = 0; i < m_nOutlets; i++) {
            mdot_out = m_outlet[i]->massFlowRate(time);
            for (size_t n = 0; n < m_nsp; n++) {
                ydot[2+n] -= mdot_out * mf[n];
            }
            if (m_energy) {
                ydot[0] -= mdot_out * enthalpy;
            }
        }

        // inlets

        doublereal mdot_in;
        for (i = 0; i < m_nInlets; i++) {
            mdot_in = m_inlet[i]->massFlowRate(time);
            for (n = 0; n < m_nsp; n++) {
                ydot[2+n] += m_inlet[i]->outletSpeciesMassFlowRate(n);
            }
            if (m_energy) {
                ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass();
            }
        }
    }

    // reset sensitivity parameters
    if (params) {
        npar = m_pnum.size();
        for (n = 0; n < npar; n++) {
            mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult/params[n]);
            //m_kin->setMultiplier(m_pnum[n], m_mult_save[n]);
        }
        ploc = npar;
        for (m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->resetSensitivityParameters(m_lr[m]);
                ploc += m_nsens_wall[m];
            }
        }
    }
}

void Reactor::addSensitivityReaction(size_t rxn)
{
    if (rxn >= m_kin->nReactions())
        throw CanteraError("Reactor::addSensitivityReaction",
                           "Reaction number out of range ("+int2str(rxn)+")");
    m_pnum.push_back(rxn);
    m_pname.push_back(name()+": "+m_kin->reactionString(rxn));
    m_mult_save.push_back(1.0);
}

size_t Reactor::componentIndex(string nm) const
{
    if (nm == "U") {
        return 0;
    }
    if (nm == "V") {
        return 1;
    }
    // check for a gas species name
    size_t k = m_thermo->speciesIndex(nm);
    if (k != npos) {
        return k + 2;
    }

    // check for a wall species
    size_t walloffset = 0, kp = 0;
    thermo_t* th;
    for (size_t m = 0; m < m_nwalls; m++) {
        if (m_wall[m]->kinetics(m_lr[m])) {
            kp = m_wall[m]->kinetics(m_lr[m])->reactionPhaseIndex();
            th = &m_wall[m]->kinetics(m_lr[m])->thermo(kp);
            k = th->speciesIndex(nm);
            if (k != npos) {
                return k + 2 + m_nsp + walloffset;
            } else {
                walloffset += th->nSpecies();
            }
        }
    }
    return npos;
}

}
<commit_msg>Fixed a size_t-related error that caused Reactor walls to behave incorrectly<commit_after>/**
 *  @file Reactor.cpp
 *
 *  A zero-dimensional reactor
 */

// Copyright 2001  California Institute of Technology

#include "cantera/zeroD/Reactor.h"
//#include "../CVode.h"
#include "cantera/zeroD/FlowDevice.h"
#include "cantera/zeroD/Wall.h"
#include "cantera/kinetics/InterfaceKinetics.h"
#include "cantera/thermo/SurfPhase.h"

using namespace std;

namespace Cantera
{

doublereal quadInterp(doublereal x0, doublereal* x, doublereal* y);

Reactor::Reactor() : ReactorBase(),
    m_kin(0),
    m_temp_atol(1.e-11),
    m_maxstep(0.0),
    m_vdot(0.0),
    m_Q(0.0),
    m_rtol(1.e-9),
    m_chem(true),
    m_energy(true), m_nsens(npos)
{}

// overloaded method of FuncEval. Called by the integrator to
// get the initial conditions.
void Reactor::getInitialConditions(double t0, size_t leny, double* y)
{
    m_init = true;
    if (m_thermo == 0) {
        cout << "Error: reactor is empty." << endl;
        return;
    }
    m_time = t0;
    m_thermo->restoreState(m_state);

    // total mass
    doublereal mass = m_thermo->density() * m_vol;

    // set components y + 2 ... y + K + 1 to the
    // mass M_k of each species
    m_thermo->getMassFractions(y+2);
    scale(y + 2, y + m_nsp + 2, y + 2, mass);

    // set the first component to the total internal
    // energy
    y[0] = m_thermo->intEnergy_mass() * mass;

    // set the second component to the total volume
    y[1] = m_vol;

    // set the remaining components to the surface species
    // coverages on the walls
    size_t loc = m_nsp + 2;
    SurfPhase* surf;
    for (size_t m = 0; m < m_nwalls; m++) {
        surf = m_wall[m]->surface(m_lr[m]);
        if (surf) {
            m_wall[m]->getCoverages(m_lr[m], y + loc);
            //surf->getCoverages(y+loc);
            loc += surf->nSpecies();
        }
    }
}

/*
 *  Must be called before calling method 'advance'
 */
void Reactor::initialize(doublereal t0)
{
    m_thermo->restoreState(m_state);
    m_sdot.resize(m_nsp, 0.0);
    m_nv = m_nsp + 2;
    for (size_t w = 0; w < m_nwalls; w++)
        if (m_wall[w]->surface(m_lr[w])) {
            m_nv += m_wall[w]->surface(m_lr[w])->nSpecies();
        }

    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();

    size_t nt = 0, maxnt = 0;
    for (size_t m = 0; m < m_nwalls; m++) {
        if (m_wall[m]->kinetics(m_lr[m])) {
            nt = m_wall[m]->kinetics(m_lr[m])->nTotalSpecies();
            if (nt > maxnt) {
                maxnt = nt;
            }
            if (m_wall[m]->kinetics(m_lr[m])) {
                if (&m_kin->thermo(0) !=
                        &m_wall[m]->kinetics(m_lr[m])->thermo(0)) {
                    throw CanteraError("Reactor::initialize",
                                       "First phase of all kinetics managers must be"
                                       " the gas.");
                }
            }
        }
    }
    m_work.resize(maxnt);
    m_init = true;
}

size_t Reactor::nSensParams()
{
    if (m_nsens == npos) {
        // determine the number of sensitivity parameters
        size_t m, ns;
        m_nsens = m_pnum.size();
        for (m = 0; m < m_nwalls; m++) {
            ns = m_wall[m]->nSensParams(m_lr[m]);
            m_nsens_wall.push_back(ns);
            m_nsens += ns;
        }
    }
    return m_nsens;
}

void Reactor::updateState(doublereal* y)
{
    ThermoPhase& mix = *m_thermo;  // define for readability

    // The components of y are the total internal energy,
    // the total volume, and the mass of each species.

    // Set the mass fractions and  density of the mixture.

    doublereal u   = y[0];
    m_vol          = y[1];
    doublereal* mss = y + 2;
    doublereal mass = accumulate(y+2, y+2+m_nsp, 0.0);
    m_thermo->setMassFractions(mss);

    m_thermo->setDensity(mass/m_vol);

    doublereal temp = temperature();
    mix.setTemperature(temp);

    if (m_energy) {
        // Decreased the tolerance on delta_T to 1.0E-7 so that T is
        // accurate to 9 sig digits, because this is
        // used in the numerical jacobian routines where relative values
        // of 1.0E-7 are used in the deltas.
        m_thermo->setState_UV(u/mass,m_vol/mass, 1.0e-7);
        temp = mix.temperature(); //mix.setTemperature(temp);
    }
    //m_state[0] = temp;

    size_t loc = m_nsp + 2;
    SurfPhase* surf;
    for (size_t m = 0; m < m_nwalls; m++) {
        surf = m_wall[m]->surface(m_lr[m]);
        if (surf) {
            //                surf->setTemperature(temp);
            //surf->setCoverages(y+loc);
            m_wall[m]->setCoverages(m_lr[m], y+loc);
            loc += surf->nSpecies();
        }
    }

    // save parameters needed by other connected reactors
    m_enthalpy = m_thermo->enthalpy_mass();
    m_pressure = m_thermo->pressure();
    m_intEnergy = m_thermo->intEnergy_mass();
    m_thermo->saveState(m_state);
}

/*
 * Called by the integrator to evaluate ydot given y at time 'time'.
 */
void Reactor::evalEqs(doublereal time, doublereal* y,
                      doublereal* ydot, doublereal* params)
{
    m_time = time;
    m_thermo->restoreState(m_state);

    // process sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult*params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->setSensitivityParameters(m_lr[m], params + ploc);
                ploc += m_nsens_wall[m];
            }
        }
    }

    m_vdot = 0.0;
    m_Q    = 0.0;

    // compute wall terms
    size_t loc = m_nsp+2;
    fill(m_sdot.begin(), m_sdot.end(), 0.0);
    for (size_t i = 0; i < m_nwalls; i++) {
        int lr = 1 - 2*m_lr[i];
        double vdot = lr*m_wall[i]->vdot(time);
        m_vdot += vdot;
        m_Q += lr*m_wall[i]->Q(time);
        Kinetics* kin = m_wall[i]->kinetics(m_lr[i]);
        SurfPhase* surf = m_wall[i]->surface(m_lr[i]);
        if (surf && kin) {
            double rs0 = 1.0/surf->siteDensity();
            size_t nk = surf->nSpecies();
            double sum = 0.0;
            surf->setTemperature(m_state[0]);
            m_wall[i]->syncCoverages(m_lr[i]);
            kin->getNetProductionRates(DATA_PTR(m_work));
            size_t ns = kin->surfacePhaseIndex();
            size_t surfloc = kin->kineticsSpeciesIndex(0,ns);
            for (size_t k = 1; k < nk; k++) {
                ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k);
                sum -= ydot[loc + k];
            }
            ydot[loc] = sum;
            loc += nk;

            double wallarea = m_wall[i]->area();
            for (size_t k = 0; k < m_nsp; k++) {
                m_sdot[k] += m_work[k]*wallarea;
            }
        }
    }

    // volume equation
    ydot[1] = m_vdot;

    /* species equations
     *  Equation is:
     *  \dot M_k = \hat W_k \dot\omega_k + \dot m_{in} Y_{k,in}
     *             - \dot m_{out} Y_{k} + A \dot s_k.
     */
    const vector_fp& mw = m_thermo->molecularWeights();
    if (m_chem) {
        m_kin->getNetProductionRates(ydot+2);   // "omega dot"
    } else {
        fill(ydot + 2, ydot + 2 + m_nsp, 0.0);
    }
    for (size_t n = 0; n < m_nsp; n++) {
        ydot[n+2] *= m_vol;     //           moles/s/m^3 -> moles/s
        ydot[n+2] += m_sdot[n];
        ydot[n+2] *= mw[n];
    }

    /*
     *  Energy equation.
     *  \f[
     *  \dot U = -P\dot V + A \dot q + \dot m_{in} h_{in}
     * - \dot m_{out} h.
     * \f]
     */
    if (m_energy) {
        ydot[0] = - m_thermo->pressure() * m_vdot - m_Q;
    } else {
        ydot[0] = 0.0;
    }

    // add terms for open system
    if (m_open) {
        const doublereal* mf = m_thermo->massFractions();
        doublereal enthalpy = m_thermo->enthalpy_mass();

        // outlets
        for (size_t i = 0; i < m_nOutlets; i++) {
            double mdot_out = m_outlet[i]->massFlowRate(time);
            for (size_t n = 0; n < m_nsp; n++) {
                ydot[2+n] -= mdot_out * mf[n];
            }
            if (m_energy) {
                ydot[0] -= mdot_out * enthalpy;
            }
        }

        // inlets
        for (size_t i = 0; i < m_nInlets; i++) {
            double mdot_in = m_inlet[i]->massFlowRate(time);
            for (size_t n = 0; n < m_nsp; n++) {
                ydot[2+n] += m_inlet[i]->outletSpeciesMassFlowRate(n);
            }
            if (m_energy) {
                ydot[0] += mdot_in * m_inlet[i]->enthalpy_mass();
            }
        }
    }

    // reset sensitivity parameters
    if (params) {
        size_t npar = m_pnum.size();
        for (size_t n = 0; n < npar; n++) {
            double mult = m_kin->multiplier(m_pnum[n]);
            m_kin->setMultiplier(m_pnum[n], mult/params[n]);
        }
        size_t ploc = npar;
        for (size_t m = 0; m < m_nwalls; m++) {
            if (m_nsens_wall[m] > 0) {
                m_wall[m]->resetSensitivityParameters(m_lr[m]);
                ploc += m_nsens_wall[m];
            }
        }
    }
}

void Reactor::addSensitivityReaction(size_t rxn)
{
    if (rxn >= m_kin->nReactions())
        throw CanteraError("Reactor::addSensitivityReaction",
                           "Reaction number out of range ("+int2str(rxn)+")");
    m_pnum.push_back(rxn);
    m_pname.push_back(name()+": "+m_kin->reactionString(rxn));
    m_mult_save.push_back(1.0);
}

size_t Reactor::componentIndex(string nm) const
{
    if (nm == "U") {
        return 0;
    }
    if (nm == "V") {
        return 1;
    }
    // check for a gas species name
    size_t k = m_thermo->speciesIndex(nm);
    if (k != npos) {
        return k + 2;
    }

    // check for a wall species
    size_t walloffset = 0, kp = 0;
    thermo_t* th;
    for (size_t m = 0; m < m_nwalls; m++) {
        if (m_wall[m]->kinetics(m_lr[m])) {
            kp = m_wall[m]->kinetics(m_lr[m])->reactionPhaseIndex();
            th = &m_wall[m]->kinetics(m_lr[m])->thermo(kp);
            k = th->speciesIndex(nm);
            if (k != npos) {
                return k + 2 + m_nsp + walloffset;
            } else {
                walloffset += th->nSpecies();
            }
        }
    }
    return npos;
}

}
<|endoftext|>


<commit_before>/*
Takes in two points and finds the slope from the
two points. In otherwords, it retunrs the slope of the interval between two points.

Returns the slope for a line based on the 2 points given.
*/
template <typename t> findSlope(x1, y1, x1, x2){
        t deltaY = y1 - y2;
        t deltaX = x1 - x2;

        return deltaX / deltaY
}
<commit_msg>added types<commit_after>/*
Takes in two points and finds the slope from the
two points. In otherwords, it retunrs the slope of the interval between two points.

Returns the slope for a line based on the 2 points given.
*/
template <typename t> findSlope(t x1, t y1, t x1, t x2){
        t deltaY = y1 - y2;
        t deltaX = x1 - x2;

        return deltaX / deltaY
}
<|endoftext|>


<commit_before>#include "zip.hpp"
#include <iostream>
#include <tuple>
#include <type_traits>
#include <vector>
#include <string>
#include <sstream>
#include <set>

using namespace std;

template<typename Container>
string contents(Container c){
    stringstream s;
    for(auto el : c){
        s << el << ' ';
    }
    auto res = s.str();
    res.pop_back();
    return res;
}

void read_example(){
    std::cout << "Read example:" << std::endl;
    vector<int> vec{1, 2, 3};
    string str("abcd");
    set<string> s {"hello", "world", "this", "is", "cool"};
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
    std::cout << "\ts contains: " << contents(s) << std::endl;
    std::cout << "\tzip contains: ";
    for(auto t : zip(vec, str, s)){
        cout << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t)
            << ") ";
    }
    cout << endl;
}
// Output:
//
// Read example:
//     vec contains: 1 2 3
//     str contains: a b c d
//     s contains: cool hello is this world
//     zip contains: (1,a,cool) (2,b,hello) (3,c,is)

void write_example(){
    std::cout << "Write example:" << std::endl;
    vector<int> vec{1, 2, 3};
    string str("abcd");
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
    for(auto t : zip(vec, str)){
        t = std::make_tuple(0, 'z');
    }
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
}
// Output:
//
// Write example:
//     vec contains: 1 2 3
//     str contains: a b c d
//     vec contains: 0 0 0
//     str contains: z z z d

int main(){
    read_example();
    write_example();
}
<commit_msg>Removed unnecessary #include from zip_examples.cpp<commit_after>#include "zip.hpp"
#include <iostream>
#include <tuple>
#include <vector>
#include <string>
#include <set>
#include <sstream>

using namespace std;

template<typename Container>
string contents(Container c){
    stringstream s;
    for(auto el : c){
        s << el << ' ';
    }
    auto res = s.str();
    res.pop_back();
    return res;
}

void read_example(){
    std::cout << "Read example:" << std::endl;
    vector<int> vec{1, 2, 3};
    string str("abcd");
    set<string> s {"hello", "world", "this", "is", "cool"};
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
    std::cout << "\ts contains: " << contents(s) << std::endl;
    std::cout << "\tzip contains: ";
    for(auto t : zip(vec, str, s)){
        cout << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t)
            << ") ";
    }
    cout << endl;
}
// Output:
//
// Read example:
//     vec contains: 1 2 3
//     str contains: a b c d
//     s contains: cool hello is this world
//     zip contains: (1,a,cool) (2,b,hello) (3,c,is)

void write_example(){
    std::cout << "Write example:" << std::endl;
    vector<int> vec{1, 2, 3};
    string str("abcd");
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
    for(auto t : zip(vec, str)){
        t = std::make_tuple(0, 'z');
    }
    std::cout << "\tvec contains: " << contents(vec) << std::endl;
    std::cout << "\tstr contains: " << contents(str) << std::endl;
}
// Output:
//
// Write example:
//     vec contains: 1 2 3
//     str contains: a b c d
//     vec contains: 0 0 0
//     str contains: z z z d

int main(){
    read_example();
    write_example();
}
<|endoftext|>