<commit_before>#include <iostream>

#include "reader.hpp"
#include "settings.hpp"
#include "forest.hpp"

using namespace std;
using namespace ISUE::RelocForests;

int main(int argc, char *argv[]) {
  if (argc < 2) {
    cout << "Usage: [train||test] ./relocforests <path_to_association_file>";
    return 1;
  }

  // get path
  string data_path(argv[1]);

  Reader *reader = new Reader();
  bool err = reader->Load(data_path);
  if (err) {
    return 1;
  }

  // Get data from reader
  Data *data = reader->GetData();

  // settings for forest
  Settings *settings = new Settings();
  settings->fx = 525.0f;
  settings->fy = 525.0f;
  settings->cx = 319.5f;
  settings->cy = 239.5f;

  Forest<ushort, cv::Vec3b> *forest = nullptr;

  bool train = false;
  if (train) {
    forest = new Forest<ushort, cv::Vec3b>(data, settings);
    forest->Train();
    forest->Serialize("forest.rf");

    cout << "Is forest valid:" << forest->IsValid() << endl;
  }
  else {

    // load forest
    forest = new Forest<ushort, cv::Vec3b>(data, settings, "forest.rf");

    cout << "Is forest valid:" << forest->IsValid() << endl;

    // eval forest at frame
    std::clock_t start;
    double duration;
    start = std::clock();

    Eigen::Affine3d pose = forest->Test(data->GetRGBImage(200), data->GetDepthImage(200));

    duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
    cout << "Train time: " << duration << " Seconds \n";

    // compare pose to known value
    auto known_pose = data->GetPose(200);

    cout << "found pose:" << endl;
    cout << pose.rotation() << endl << endl;
    cout << pose.rotation().eulerAngles(0, 1, 2) * 180 / M_PI << endl;
    cout << pose.translation() << endl;

    cout << "known pose:" << endl;
    cout << known_pose.rotation << endl;
    cout << known_pose.rotation.eulerAngles(0, 1, 2) * 180 / M_PI << endl;
    cout << known_pose.position << endl;

    if ((known_pose.rotation - pose.rotation()).cwiseAbs().maxCoeff() > 1e-13 ||
      (known_pose.position - pose.translation()).cwiseAbs().maxCoeff() > 1e-13)
      cout << "Pose could not be found\n";
    else
      cout << "Pose was found!\n";
  }

  cout << "Done.\n";

  delete forest;
  delete reader;
  delete settings;

  return 0;
}
<commit_msg>Fixes command line interface.<commit_after>#include <iostream>

#include "reader.hpp"
#include "settings.hpp"
#include "forest.hpp"

using namespace std;
using namespace ISUE::RelocForests;

int main(int argc, char *argv[]) {
  if (argc < 2) {
    cout << "Usage: ./relocforests <path_to_association_file> (train|test) <forest_file_name>\n";
    return 1;
  }

  // get path
  string data_path(argv[1]);

  Reader *reader = new Reader();
  bool err = reader->Load(data_path);
  if (err) {
    return 1;
  }

  // train or test time
  string shouldTrain(argv[2]);
  bool train = (shouldTrain == "train");

  // Get data from reader
  Data *data = reader->GetData();

  // settings for forest
  Settings *settings = new Settings(640, 480, 5000, 525.0f, 525.0f, 319.5f, 239.5f);

  Forest<ushort, cv::Vec3b> *forest = nullptr;

  string forest_file_name;
  if (argv[3])
    forest_file_name = string(argv[3]);
  else
    cout << "Train and Test time requires an output file name.\n";

  if (shouldTrain) {
    forest = new Forest<ushort, cv::Vec3b>(data, settings);
    forest->Train();
    forest->Serialize(forest_file_name);

    cout << "Is forest valid:" << forest->IsValid() << endl;
  }
  else {

    // load forest
    forest = new Forest<ushort, cv::Vec3b>(data, settings, "forest.rf");

    cout << "Is forest valid:" << forest->IsValid() << endl;

    // eval forest at frame
    std::clock_t start;
    double duration;
    start = std::clock();

    Eigen::Affine3d pose = forest->Test(data->GetRGBImage(200), data->GetDepthImage(200));

    duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
    cout << "Train time: " << duration << " Seconds \n";

    // compare pose to known value
    auto known_pose = data->GetPose(200);

    cout << "found pose:" << endl;
    cout << pose.rotation() << endl << endl;
    cout << pose.rotation().eulerAngles(0, 1, 2) * 180 / M_PI << endl;
    cout << pose.translation() << endl;

    cout << "known pose:" << endl;
    cout << known_pose.rotation << endl;
    cout << known_pose.rotation.eulerAngles(0, 1, 2) * 180 / M_PI << endl;
    cout << known_pose.position << endl;

  }

  delete forest;
  delete reader;
  delete settings;

  return 0;
}
<|endoftext|>


<commit_before>#include <ctrcommon/app.hpp>
#include <ctrcommon/input.hpp>
#include <ctrcommon/platform.hpp>
#include <ctrcommon/ui.hpp>

#include <stdio.h>

#include <sstream>
#include <iomanip>

#include <sys/dirent.h>

typedef enum {
    INSTALL_CIA,
    DELETE_CIA,
    DELETE_TITLE,
    LAUNCH_TITLE
} Mode;

int main(int argc, char **argv) {
    if(!platformInit()) {
        return 0;
    }

    bool ninjhax = platformIsNinjhax();

    std::vector<std::string> extensions;
    extensions.push_back("cia");

    MediaType destination = SD;
    Mode mode = INSTALL_CIA;
    bool exit = false;
    bool netInstall = false;
    u64 freeSpace = fsGetFreeSpace(destination);
    auto onLoop = [&]() {
        if(ninjhax && inputIsPressed(BUTTON_START)) {
            exit = true;
            return true;
        }

        bool breakLoop = false;

        if(inputIsPressed(BUTTON_L)) {
            if(destination == SD) {
                destination = NAND;
            } else {
                destination = SD;
            }

            freeSpace = fsGetFreeSpace(destination);
            if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
                breakLoop = true;
            }
        }

        if(inputIsPressed(BUTTON_R)) {
            if(mode == INSTALL_CIA) {
                mode = DELETE_CIA;
            } else if(mode == DELETE_CIA) {
                mode = DELETE_TITLE;
                breakLoop = true;
            } else if(mode == DELETE_TITLE) {
                mode = LAUNCH_TITLE;
            } else if(mode == LAUNCH_TITLE) {
                mode = INSTALL_CIA;
                breakLoop = true;
            }
        }

        if(mode == INSTALL_CIA && inputIsPressed(BUTTON_Y)) {
            netInstall = true;
            breakLoop = true;
        }

        std::stringstream stream;
        stream << "FBI v1.3.7" << "\n";
        stream << "Free Space: " << freeSpace << " bytes (" << std::fixed << std::setprecision(2) << freeSpace / 1024.0f / 1024.0f << "MB)" << "\n";
        stream << "Destination: " << (destination == NAND ? "NAND" : "SD") << ", Mode: " << (mode == INSTALL_CIA ? "Install CIA" : mode == DELETE_CIA ? "Delete CIA" : mode == DELETE_TITLE ? "Delete Title" : "Launch Title") << "\n";
        stream << "L - Switch Destination, R - Switch Mode" << "\n";
        if(mode == INSTALL_CIA) {
            stream << "X - Install all CIAs in the current directory" << "\n";
            stream << "Y - Receive an app over the network" << "\n";
        } else if(mode == DELETE_CIA) {
            stream << "X - Delete all CIAs in the current directory" << "\n";
        }

        if(ninjhax) {
            stream << "START - Exit to launcher" << "\n";
        }

        std::string str = stream.str();
        screenDrawString(str, (screenGetWidth() - screenGetStrWidth(str)) / 2, screenGetHeight() - 4 - screenGetStrHeight(str), 255, 255, 255);

        return breakLoop;
    };

    std::string batchInfo = "";

    int prevProgress = -1;
    auto onProgress = [&](u64 pos, u64 totalSize) {
        u32 progress = (u32) ((pos * 100) / totalSize);
        if(prevProgress != (int) progress) {
            prevProgress = (int) progress;

            std::stringstream details;
            details << batchInfo;
            details << "Press B to cancel.";

            uiDisplayProgress(TOP_SCREEN, "Installing", details.str(), true, progress);
        }

        inputPoll();
        return !inputIsPressed(BUTTON_B);
    };

    bool showNetworkPrompts = true;

    while(platformIsRunning()) {
        std::string fileTarget;
        App appTarget;
        if(mode == INSTALL_CIA || mode == DELETE_CIA) {
            if(netInstall && !exit) {
                screenClearBuffers(BOTTOM_SCREEN, 0, 0, 0);

                RemoteFile file = uiAcceptRemoteFile(TOP_SCREEN, [&](std::stringstream& infoStream) {
                    if(inputIsPressed(BUTTON_A)) {
                        showNetworkPrompts = !showNetworkPrompts;
                    }

                    infoStream << "\n";
                    infoStream << "Prompts: " << (showNetworkPrompts ? "Enabled" : "Disabled") << "\n";
                    infoStream << "Press A to toggle prompts." << "\n";
                });

                if(file.fd == NULL) {
                    netInstall = false;
                    continue;
                }

                std::stringstream confirmStream;
                confirmStream << "Install the received application?" << "\n";
                confirmStream << "Size: " << file.fileSize << " bytes (" << std::fixed << std::setprecision(2) << file.fileSize / 1024.0f / 1024.0f << "MB)" << "\n";
                if(!showNetworkPrompts || uiPrompt(TOP_SCREEN, confirmStream.str(), true)) {
                    AppResult ret = appInstall(destination, file.fd, file.fileSize, onProgress);
                    prevProgress = -1;
                    if(showNetworkPrompts || ret != APP_SUCCESS) {
                        std::stringstream resultMsg;
                        resultMsg << "Install ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                    }
                }

                fclose(file.fd);
                continue;
            }

            uiSelectFile(&fileTarget, "/", extensions, [&](const std::string currDirectory, bool inRoot, bool &updateList) {
                if(inputIsPressed(BUTTON_X)) {
                    std::stringstream confirmMsg;
                    if(mode == INSTALL_CIA) {
                        confirmMsg << "Install ";
                    } else {
                        confirmMsg << "Delete ";
                    }

                    confirmMsg << "all CIAs in the current directory?";
                    if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                        bool failed = false;
                        std::vector<FileInfo> contents = fsGetDirectoryContents(currDirectory);
                        u32 currItem = 0;
                        for(std::vector<FileInfo>::iterator it = contents.begin(); it != contents.end(); it++) {
                            std::string path = (*it).path;
                            if(!fsIsDirectory(path) && fsHasExtensions(path, extensions)) {
                                std::string displayFileName = (*it).name;
                                if(displayFileName.length() > 40) {
                                    displayFileName.resize(40);
                                    displayFileName += "...";
                                }

                                if(mode == INSTALL_CIA) {
                                    std::stringstream batchInstallStream;
                                    batchInstallStream << displayFileName << " (" << currItem << ")" << "\n";

                                    batchInfo = batchInstallStream.str();
                                    AppResult ret = appInstallFile(destination, path, onProgress);
                                    prevProgress = -1;
                                    batchInfo = "";
                                    if(ret != APP_SUCCESS) {
                                        Error error = platformGetError();
                                        platformSetError(error);

                                        std::stringstream resultMsg;
                                        resultMsg << "Install failed!" << "\n";
                                        resultMsg << displayFileName << "\n";
                                        resultMsg << appGetResultString(ret) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        if(error.module != MODULE_AM || error.description != DESCRIPTION_ALREADY_EXISTS) {
                                            failed = true;
                                            break;
                                        }
                                    }
                                } else {
                                    std::stringstream deleteStream;
                                    deleteStream << "Deleting CIA..." << "\n";
                                    deleteStream << displayFileName << " (" << currItem << ")" << "\n";

                                    uiDisplayMessage(TOP_SCREEN, deleteStream.str());
                                    if(!fsDelete(path)) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Delete failed!" << "\n";
                                        resultMsg << displayFileName << "\n";
                                        resultMsg << platformGetErrorString(platformGetError()) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    } else {
                                        updateList = true;
                                    }
                                }
                            }

                            currItem++;
                        }

                        if(!failed) {
                            uiPrompt(TOP_SCREEN, "Install succeeded!\n", false);
                        }

                        freeSpace = fsGetFreeSpace(destination);
                    }
                }

                return onLoop();
            }, [&](const std::string path, bool &updateList) {
                std::stringstream confirmMsg;
                if(mode == INSTALL_CIA) {
                    confirmMsg << "Install ";
                } else {
                    confirmMsg << "Delete ";
                }

                confirmMsg << "the selected CIA?";
                if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                    std::stringstream resultMsg;
                    if(mode == INSTALL_CIA) {
                        resultMsg << "Install ";
                    } else {
                        resultMsg << "Delete ";
                    }

                    if(mode == INSTALL_CIA) {
                        AppResult ret = appInstallFile(destination, path, onProgress);
                        prevProgress = -1;
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }
                    } else {
                        uiDisplayMessage(TOP_SCREEN, "Deleting CIA...");
                        if(fsDelete(path)) {
                            updateList = true;
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << platformGetErrorString(platformGetError()) << "\n";
                        }
                    }

                    uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                    freeSpace = fsGetFreeSpace(destination);
                }

                return false;
            });
        } else if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
            uiDisplayMessage(BOTTOM_SCREEN, "Loading title list...");
            uiSelectApp(&appTarget, destination, [&](bool &updateList) {
                return onLoop();
            }, [&](App app, bool &updateList) {
                if(mode == DELETE_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Delete the selected title?", true) && (destination != NAND || uiPrompt(TOP_SCREEN, "You are about to delete a title from the NAND.\nTHIS HAS THE POTENTIAL TO BRICK YOUR 3DS!\nAre you sure you wish to continue?", true))) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Deleting title...");
                        AppResult ret = appDelete(app);

                        std::stringstream resultMsg;
                        resultMsg << "Delete ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                        freeSpace = fsGetFreeSpace(destination);
                    }
                } else if(mode == LAUNCH_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Launch the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Launching title...");
                        AppResult ret = appLaunch(app);

                        if(ret != APP_SUCCESS) {
                            std::stringstream resultMsg;
                            resultMsg << "Launch failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                            uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                        } else {
                            while(true) {
                            }
                        }
                    }
                }

                return false;
            });
        }

        if(exit) {
            break;
        }
    }

    platformCleanup();
    return 0;
}
<commit_msg>Switch from fsDelete to remove.<commit_after>#include <ctrcommon/app.hpp>
#include <ctrcommon/input.hpp>
#include <ctrcommon/platform.hpp>
#include <ctrcommon/ui.hpp>

#include <sys/dirent.h>
#include <sys/errno.h>
#include <stdio.h>
#include <string.h>

#include <sstream>
#include <iomanip>

typedef enum {
    INSTALL_CIA,
    DELETE_CIA,
    DELETE_TITLE,
    LAUNCH_TITLE
} Mode;

int main(int argc, char **argv) {
    if(!platformInit()) {
        return 0;
    }

    bool ninjhax = platformIsNinjhax();

    std::vector<std::string> extensions;
    extensions.push_back("cia");

    MediaType destination = SD;
    Mode mode = INSTALL_CIA;
    bool exit = false;
    bool netInstall = false;
    u64 freeSpace = fsGetFreeSpace(destination);
    auto onLoop = [&]() {
        if(ninjhax && inputIsPressed(BUTTON_START)) {
            exit = true;
            return true;
        }

        bool breakLoop = false;

        if(inputIsPressed(BUTTON_L)) {
            if(destination == SD) {
                destination = NAND;
            } else {
                destination = SD;
            }

            freeSpace = fsGetFreeSpace(destination);
            if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
                breakLoop = true;
            }
        }

        if(inputIsPressed(BUTTON_R)) {
            if(mode == INSTALL_CIA) {
                mode = DELETE_CIA;
            } else if(mode == DELETE_CIA) {
                mode = DELETE_TITLE;
                breakLoop = true;
            } else if(mode == DELETE_TITLE) {
                mode = LAUNCH_TITLE;
            } else if(mode == LAUNCH_TITLE) {
                mode = INSTALL_CIA;
                breakLoop = true;
            }
        }

        if(mode == INSTALL_CIA && inputIsPressed(BUTTON_Y)) {
            netInstall = true;
            breakLoop = true;
        }

        std::stringstream stream;
        stream << "FBI v1.3.8" << "\n";
        stream << "Free Space: " << freeSpace << " bytes (" << std::fixed << std::setprecision(2) << freeSpace / 1024.0f / 1024.0f << "MB)" << "\n";
        stream << "Destination: " << (destination == NAND ? "NAND" : "SD") << ", Mode: " << (mode == INSTALL_CIA ? "Install CIA" : mode == DELETE_CIA ? "Delete CIA" : mode == DELETE_TITLE ? "Delete Title" : "Launch Title") << "\n";
        stream << "L - Switch Destination, R - Switch Mode" << "\n";
        if(mode == INSTALL_CIA) {
            stream << "X - Install all CIAs in the current directory" << "\n";
            stream << "Y - Receive an app over the network" << "\n";
        } else if(mode == DELETE_CIA) {
            stream << "X - Delete all CIAs in the current directory" << "\n";
        }

        if(ninjhax) {
            stream << "START - Exit to launcher" << "\n";
        }

        std::string str = stream.str();
        screenDrawString(str, (screenGetWidth() - screenGetStrWidth(str)) / 2, screenGetHeight() - 4 - screenGetStrHeight(str), 255, 255, 255);

        return breakLoop;
    };

    std::string batchInfo = "";

    int prevProgress = -1;
    auto onProgress = [&](u64 pos, u64 totalSize) {
        u32 progress = (u32) ((pos * 100) / totalSize);
        if(prevProgress != (int) progress) {
            prevProgress = (int) progress;

            std::stringstream details;
            details << batchInfo;
            details << "Press B to cancel.";

            uiDisplayProgress(TOP_SCREEN, "Installing", details.str(), true, progress);
        }

        inputPoll();
        return !inputIsPressed(BUTTON_B);
    };

    bool showNetworkPrompts = true;

    while(platformIsRunning()) {
        std::string fileTarget;
        App appTarget;
        if(mode == INSTALL_CIA || mode == DELETE_CIA) {
            if(netInstall && !exit) {
                screenClearBuffers(BOTTOM_SCREEN, 0, 0, 0);

                RemoteFile file = uiAcceptRemoteFile(TOP_SCREEN, [&](std::stringstream& infoStream) {
                    if(inputIsPressed(BUTTON_A)) {
                        showNetworkPrompts = !showNetworkPrompts;
                    }

                    infoStream << "\n";
                    infoStream << "Prompts: " << (showNetworkPrompts ? "Enabled" : "Disabled") << "\n";
                    infoStream << "Press A to toggle prompts." << "\n";
                });

                if(file.fd == NULL) {
                    netInstall = false;
                    continue;
                }

                std::stringstream confirmStream;
                confirmStream << "Install the received application?" << "\n";
                confirmStream << "Size: " << file.fileSize << " bytes (" << std::fixed << std::setprecision(2) << file.fileSize / 1024.0f / 1024.0f << "MB)" << "\n";
                if(!showNetworkPrompts || uiPrompt(TOP_SCREEN, confirmStream.str(), true)) {
                    AppResult ret = appInstall(destination, file.fd, file.fileSize, onProgress);
                    prevProgress = -1;
                    if(showNetworkPrompts || ret != APP_SUCCESS) {
                        std::stringstream resultMsg;
                        resultMsg << "Install ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                    }
                }

                fclose(file.fd);
                continue;
            }

            uiSelectFile(&fileTarget, "/", extensions, [&](const std::string currDirectory, bool inRoot, bool &updateList) {
                if(inputIsPressed(BUTTON_X)) {
                    std::stringstream confirmMsg;
                    if(mode == INSTALL_CIA) {
                        confirmMsg << "Install ";
                    } else {
                        confirmMsg << "Delete ";
                    }

                    confirmMsg << "all CIAs in the current directory?";
                    if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                        bool failed = false;
                        std::vector<FileInfo> contents = fsGetDirectoryContents(currDirectory);
                        u32 currItem = 0;
                        for(std::vector<FileInfo>::iterator it = contents.begin(); it != contents.end(); it++) {
                            std::string path = (*it).path;
                            if(!fsIsDirectory(path) && fsHasExtensions(path, extensions)) {
                                std::string displayFileName = (*it).name;
                                if(displayFileName.length() > 40) {
                                    displayFileName.resize(40);
                                    displayFileName += "...";
                                }

                                if(mode == INSTALL_CIA) {
                                    std::stringstream batchInstallStream;
                                    batchInstallStream << displayFileName << " (" << currItem << ")" << "\n";

                                    batchInfo = batchInstallStream.str();
                                    AppResult ret = appInstallFile(destination, path, onProgress);
                                    prevProgress = -1;
                                    batchInfo = "";
                                    if(ret != APP_SUCCESS) {
                                        Error error = platformGetError();
                                        platformSetError(error);

                                        std::stringstream resultMsg;
                                        resultMsg << "Install failed!" << "\n";
                                        resultMsg << displayFileName << "\n";
                                        resultMsg << appGetResultString(ret) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        if(error.module != MODULE_AM || error.description != DESCRIPTION_ALREADY_EXISTS) {
                                            failed = true;
                                            break;
                                        }
                                    }
                                } else {
                                    std::stringstream deleteStream;
                                    deleteStream << "Deleting CIA..." << "\n";
                                    deleteStream << displayFileName << " (" << currItem << ")" << "\n";

                                    uiDisplayMessage(TOP_SCREEN, deleteStream.str());
                                    if(remove(path.c_str()) != 0) {
                                        std::stringstream resultMsg;
                                        resultMsg << "Delete failed!" << "\n";
                                        resultMsg << displayFileName << "\n";
                                        resultMsg << strerror(errno) << "\n";
                                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                                        failed = true;
                                        break;
                                    } else {
                                        updateList = true;
                                    }
                                }
                            }

                            currItem++;
                        }

                        if(!failed) {
                            uiPrompt(TOP_SCREEN, "Install succeeded!\n", false);
                        }

                        freeSpace = fsGetFreeSpace(destination);
                    }
                }

                return onLoop();
            }, [&](const std::string path, bool &updateList) {
                std::stringstream confirmMsg;
                if(mode == INSTALL_CIA) {
                    confirmMsg << "Install ";
                } else {
                    confirmMsg << "Delete ";
                }

                confirmMsg << "the selected CIA?";
                if(uiPrompt(TOP_SCREEN, confirmMsg.str(), true)) {
                    std::stringstream resultMsg;
                    if(mode == INSTALL_CIA) {
                        resultMsg << "Install ";
                    } else {
                        resultMsg << "Delete ";
                    }

                    if(mode == INSTALL_CIA) {
                        AppResult ret = appInstallFile(destination, path, onProgress);
                        prevProgress = -1;
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }
                    } else {
                        uiDisplayMessage(TOP_SCREEN, "Deleting CIA...");
                        if(remove(path.c_str()) != 0) {
                            updateList = true;
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << strerror(errno) << "\n";
                        }
                    }

                    uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                    freeSpace = fsGetFreeSpace(destination);
                }

                return false;
            });
        } else if(mode == DELETE_TITLE || mode == LAUNCH_TITLE) {
            uiDisplayMessage(BOTTOM_SCREEN, "Loading title list...");
            uiSelectApp(&appTarget, destination, [&](bool &updateList) {
                return onLoop();
            }, [&](App app, bool &updateList) {
                if(mode == DELETE_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Delete the selected title?", true) && (destination != NAND || uiPrompt(TOP_SCREEN, "You are about to delete a title from the NAND.\nTHIS HAS THE POTENTIAL TO BRICK YOUR 3DS!\nAre you sure you wish to continue?", true))) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Deleting title...");
                        AppResult ret = appDelete(app);

                        std::stringstream resultMsg;
                        resultMsg << "Delete ";
                        if(ret == APP_SUCCESS) {
                            resultMsg << "succeeded!";
                        } else {
                            resultMsg << "failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                        }

                        uiPrompt(TOP_SCREEN, resultMsg.str(), false);

                        freeSpace = fsGetFreeSpace(destination);
                    }
                } else if(mode == LAUNCH_TITLE) {
                    if(uiPrompt(TOP_SCREEN, "Launch the selected title?", true)) {
                        updateList = true;
                        uiDisplayMessage(TOP_SCREEN, "Launching title...");
                        AppResult ret = appLaunch(app);

                        if(ret != APP_SUCCESS) {
                            std::stringstream resultMsg;
                            resultMsg << "Launch failed!" << "\n";
                            resultMsg << appGetResultString(ret) << "\n";
                            uiPrompt(TOP_SCREEN, resultMsg.str(), false);
                        } else {
                            while(true) {
                            }
                        }
                    }
                }

                return false;
            });
        }

        if(exit) {
            break;
        }
    }

    platformCleanup();
    return 0;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "mcc/cfg/cfg.h"

#include "parser.h"
#include "boost/graph/graphviz.hpp"

namespace mcc {
  namespace cfg {

    TEST(Cfg, Cfg) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      std::string expected =
          R"(digraph G {
0;
1;
2;
3;
4;
5;
6;
0->1 ;
0->2 ;
1->3 ;
2->3 ;
3->4 ;
3->5 ;
4->6 ;
5->6 ;
}
)";

      EXPECT_EQ(expected, graph->toDot());
    }

    TEST(Cfg, Idom) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      auto index = tac.getBasicBlockIndex();

      // TODO find reason why shared pointers as well as the results of get() are not equal
      EXPECT_EQ(graph->getIdom(index[0])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[1])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[2])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[3])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[4])->toString(), index[3]->toString());
      EXPECT_EQ(graph->getIdom(index[5])->toString(), index[3]->toString());
      EXPECT_EQ(graph->getIdom(index[6])->toString(), index[3]->toString());

      EXPECT_EQ(graph->getIdom(0), 0);
      EXPECT_EQ(graph->getIdom(1), 0);
      EXPECT_EQ(graph->getIdom(2), 0);
      EXPECT_EQ(graph->getIdom(3), 0);
      EXPECT_EQ(graph->getIdom(4), 3);
      EXPECT_EQ(graph->getIdom(5), 3);
      EXPECT_EQ(graph->getIdom(6), 3);
    }

    /*TEST(Cfg, DomSetVertex) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      auto index = tac.getBasicBlockIndex();

      std::vector<Vertex> set;
      set.push_back(index[0]);
      set.push_back(index[3]);

      auto dom0 = graph->getDomSet(index[0]).begin();
      auto dom1 = graph->getDomSet(index[1]).begin();
      auto dom2 = graph->getDomSet(index[2]).begin();
      auto dom3 = graph->getDomSet(index[3]).begin();
      auto dom4 = graph->getDomSet(index[4]).begin();
      auto dom5 = graph->getDomSet(index[5]).begin();
      auto dom6 = graph->getDomSet(index[6]).begin();

      // TODO find reason why shared pointers as well as the results of get() are not equal
      EXPECT_EQ(dom0->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom1->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom2->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom3->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom4->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom5->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom6->get()->toString(), index[0]->toString());

      EXPECT_EQ((++dom4)->get()->toString(), index[3]->toString());
      EXPECT_EQ((++dom5)->get()->toString(), index[3]->toString());
      EXPECT_EQ((++dom6)->get()->toString(), index[3]->toString());
    }*/

    TEST(Cfg, DomSet) {
      auto tree =
          parser::parse(
              R"(
                      {
                          int x=1;
                          float y = 3.0;

                          if(x > 0) {
                             y = y * 1.5;
                          } else {
                             y = y + 2.0;
                          }

                          int a = 0;

                          if( 1 <= 2) {
                              a = 1;
                          } else {
                              a = 2;
                          }
                        })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      std::vector<VertexDescriptor> set;
      set.push_back(0);
      set.push_back(3);

      auto dom0 = graph->getDomSet(0);
      auto dom1 = graph->getDomSet(1);
      auto dom2 = graph->getDomSet(2);
      auto dom3 = graph->getDomSet(3);
      auto dom4 = graph->getDomSet(4);
      auto dom5 = graph->getDomSet(5);
      auto dom6 = graph->getDomSet(6);

      EXPECT_NE(dom0.find(0), dom0.end());
      EXPECT_NE(dom1.find(0), dom1.end());
      EXPECT_NE(dom2.find(0), dom2.end());
      EXPECT_NE(dom3.find(0), dom3.end());

      for (auto e : set) {
        EXPECT_NE(dom4.find(e), dom4.end());
        EXPECT_NE(dom5.find(e), dom5.end());
        EXPECT_NE(dom6.find(e), dom6.end());
      }
    }
  }
}

<commit_msg>Fixed cfg test segfault<commit_after>#include <gtest/gtest.h>

#include "mcc/cfg/cfg.h"

#include "parser.h"
#include "boost/graph/graphviz.hpp"

namespace mcc {
  namespace cfg {

    TEST(Cfg, Cfg) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      std::string expected =
          R"(digraph G {
0;
1;
2;
3;
4;
5;
6;
0->1 ;
0->2 ;
1->3 ;
2->3 ;
3->4 ;
3->5 ;
4->6 ;
5->6 ;
}
)";

      EXPECT_EQ(expected, graph->toDot());
    }

    TEST(Cfg, Idom) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      auto index = tac.getBasicBlockIndex();

      // TODO find reason why shared pointers as well as the results of get() are not equal
      EXPECT_EQ(graph->getIdom(index[0])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[1])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[2])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[3])->toString(), index[0]->toString());
      EXPECT_EQ(graph->getIdom(index[4])->toString(), index[3]->toString());
      EXPECT_EQ(graph->getIdom(index[5])->toString(), index[3]->toString());
      EXPECT_EQ(graph->getIdom(index[6])->toString(), index[3]->toString());

      EXPECT_EQ(graph->getIdom(0), 0);
      EXPECT_EQ(graph->getIdom(1), 0);
      EXPECT_EQ(graph->getIdom(2), 0);
      EXPECT_EQ(graph->getIdom(3), 0);
      EXPECT_EQ(graph->getIdom(4), 3);
      EXPECT_EQ(graph->getIdom(5), 3);
      EXPECT_EQ(graph->getIdom(6), 3);
    }

    TEST(Cfg, DomSetVertex) {
      auto tree =
          parser::parse(
              R"(
                  {
                      int x=1;
                      float y = 3.0;

                      if(x > 0) {
                         y = y * 1.5;
                      } else {
                         y = y + 2.0;
                      }

                      int a = 0;

                      if( 1 <= 2) {
                          a = 1;
                      } else {
                          a = 2;
                      }
                    })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      auto index = tac.getBasicBlockIndex();

      std::vector<Vertex> set;
      set.push_back(index[0]);
      set.push_back(index[3]);

      auto dom0 = graph->getDomSet(index[0]);
      auto dom1 = graph->getDomSet(index[1]);
      auto dom2 = graph->getDomSet(index[2]);
      auto dom3 = graph->getDomSet(index[3]);
      auto dom4 = graph->getDomSet(index[4]);
      auto dom5 = graph->getDomSet(index[5]);
      auto dom6 = graph->getDomSet(index[6]);

      // TODO find reason why shared pointers as well as the results of get() are not equal
      EXPECT_EQ(dom0.begin()->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom1.begin()->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom2.begin()->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom3.begin()->get()->toString(), index[0]->toString());
      EXPECT_EQ(dom4.begin()->get()->toString(), index[3]->toString());
      EXPECT_EQ(dom5.begin()->get()->toString(), index[3]->toString());
      EXPECT_EQ(dom6.begin()->get()->toString(), index[3]->toString());

      EXPECT_EQ((++dom4.begin())->get()->toString(), index[0]->toString());
      EXPECT_EQ((++dom5.begin())->get()->toString(), index[0]->toString());
      EXPECT_EQ((++dom6.begin())->get()->toString(), index[0]->toString());
    }

    TEST(Cfg, DomSet) {
      auto tree =
          parser::parse(
              R"(
                      {
                          int x=1;
                          float y = 3.0;

                          if(x > 0) {
                             y = y * 1.5;
                          } else {
                             y = y + 2.0;
                          }

                          int a = 0;

                          if( 1 <= 2) {
                              a = 1;
                          } else {
                              a = 2;
                          }
                        })");

      mcc::tac::Tac tac;
      tac.convertAst(tree);
      auto graph = std::make_shared<Cfg>(tac);

      std::vector<VertexDescriptor> set;
      set.push_back(0);
      set.push_back(3);

      auto dom0 = graph->getDomSet(0);
      auto dom1 = graph->getDomSet(1);
      auto dom2 = graph->getDomSet(2);
      auto dom3 = graph->getDomSet(3);
      auto dom4 = graph->getDomSet(4);
      auto dom5 = graph->getDomSet(5);
      auto dom6 = graph->getDomSet(6);

      EXPECT_NE(dom0.find(0), dom0.end());
      EXPECT_NE(dom1.find(0), dom1.end());
      EXPECT_NE(dom2.find(0), dom2.end());
      EXPECT_NE(dom3.find(0), dom3.end());

      for (auto e : set) {
        EXPECT_NE(dom4.find(e), dom4.end());
        EXPECT_NE(dom5.find(e), dom5.end());
        EXPECT_NE(dom6.find(e), dom6.end());
      }
    }
  }
}

<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file CallTip.cxx
 ** Code for displaying call tips.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>

#include "Platform.h"

#include "Scintilla.h"
#include "CallTip.h"

CallTip::CallTip() {
	wCallTip = 0;
	inCallTipMode = false;
	posStartCallTip = 0;
	val = 0;
	xUp = -100;
	xDown = -100;
	lineHeight = 1;
	startHighlight = 0;
	endHighlight = 0;

	colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
	colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
	colourSel.desired = ColourDesired(0, 0, 0x80);
	colourShade.desired = ColourDesired(0, 0, 0);
	colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
}

CallTip::~CallTip() {
	font.Release();
	wCallTip.Destroy();
	delete []val;
	val = 0;
}

const int widthArrow = 14;

void CallTip::RefreshColourPalette(Palette &pal, bool want) {
	pal.WantFind(colourBG, want);
	pal.WantFind(colourUnSel, want);
	pal.WantFind(colourSel, want);
	pal.WantFind(colourShade, want);
	pal.WantFind(colourLight, want);
}

static bool IsArrowCharacter(char ch) {
	return (ch == 0) || (ch == '\001') || (ch == '\002');
}

void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
	int posStart, int posEnd, int ytext, PRectangle rcClient,
	bool highlight, bool draw) {
	s += posStart;
	int len = posEnd - posStart;
	int maxEnd = 0;
	int ends[10];
	for (int i=0;i<len;i++) {
		if (IsArrowCharacter(s[i])) {
			if (i > 0)
				ends[maxEnd++] = i;
			ends[maxEnd++] = i+1;
		}
	}
	ends[maxEnd++] = len;
	int startSeg = 0;
	int xEnd;
	for (int seg = 0; seg<maxEnd; seg++) {
		int endSeg = ends[seg];
		if (endSeg > startSeg) {
			if (IsArrowCharacter(s[startSeg])) {
				xEnd = x + widthArrow;
				offsetMain = xEnd;
				if (draw) {
					const int halfWidth = widthArrow / 2 - 3;
					const int centreX = x + widthArrow / 2 - 1;
					const int centreY = (rcClient.top + rcClient.bottom) / 2;
					rcClient.left = x;
					rcClient.right = xEnd;
					surface->FillRectangle(rcClient, colourBG.allocated);
					PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
					surface->FillRectangle(rcClientInner, colourUnSel.allocated);

					if (s[startSeg] == '\001') {
						// Up arrow
						Point pts[] = {
    						Point(centreX - halfWidth, centreY + halfWidth / 2),
    						Point(centreX + halfWidth, centreY + halfWidth / 2),
    						Point(centreX, centreY - halfWidth + halfWidth / 2),
						};
						surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
                 						colourBG.allocated, colourBG.allocated);
					} else {
						// Down arrow
						Point pts[] = {
    						Point(centreX - halfWidth, centreY - halfWidth / 2),
    						Point(centreX + halfWidth, centreY - halfWidth / 2),
    						Point(centreX, centreY + halfWidth - halfWidth / 2),
						};
						surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
                 						colourBG.allocated, colourBG.allocated);
					}
				} else {
					if (s[startSeg] == '\001') {
						xUp = x+1;
					} else {
						xDown = x+1;
					}
				}
			} else {
				xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
				if (draw) {
					rcClient.left = x;
					rcClient.right = xEnd;
					surface->DrawTextNoClip(rcClient, font, ytext,
										s+startSeg, endSeg - startSeg,
										highlight ? colourSel.allocated : colourUnSel.allocated,
										colourBG.allocated);
				}
			}
			x = xEnd;
			startSeg = endSeg;
		}
	}
}

int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
	PRectangle rcClientPos = wCallTip.GetClientPosition();
	PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
	                        rcClientPos.bottom - rcClientPos.top);
	PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);

	// To make a nice small call tip window, it is only sized to fit most normal characters without accents
	int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);

	// For each line...
	// Draw the definition in three parts: before highlight, highlighted, after highlight
	int ytext = rcClient.top + ascent + 1;
	rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
	char *chunkVal = val;
	bool moreChunks = true;
	int maxWidth = 0;
	while (moreChunks) {
		char *chunkEnd = strchr(chunkVal, '\n');
		if (chunkEnd == NULL) {
			chunkEnd = chunkVal + strlen(chunkVal);
			moreChunks = false;
		}
		int chunkOffset = chunkVal - val;
		int chunkLength = chunkEnd - chunkVal;
		int chunkEndOffset = chunkOffset + chunkLength;
		int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
		thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
		thisStartHighlight -= chunkOffset;
		int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
		thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
		thisEndHighlight -= chunkOffset;
		rcClient.top = ytext - ascent - 1;

		int x = 5;

		DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
			ytext, rcClient, false, draw);
		DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
			ytext, rcClient, true, draw);
		DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
			ytext, rcClient, false, draw);

		chunkVal = chunkEnd + 1;
		ytext += lineHeight;
		rcClient.bottom += lineHeight;
		maxWidth = Platform::Maximum(maxWidth, x);
	}
	return maxWidth;
}

void CallTip::PaintCT(Surface *surfaceWindow) {
	if (!val)
		return;
	PRectangle rcClientPos = wCallTip.GetClientPosition();
	PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
	                        rcClientPos.bottom - rcClientPos.top);
	PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);

	surfaceWindow->FillRectangle(rcClient, colourBG.allocated);

	offsetMain = 5;
	PaintContents(surfaceWindow, true);

	// Draw a raised border around the edges of the window
	surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
	surfaceWindow->PenColour(colourShade.allocated);
	surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
	surfaceWindow->LineTo(rcClientSize.right - 1, 0);
	surfaceWindow->PenColour(colourLight.allocated);
	surfaceWindow->LineTo(0, 0);
	surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
}

void CallTip::MouseClick(Point pt) {
	clickPlace = 0;
	if (pt.y < lineHeight) {
		if ((pt.x > xUp) && (pt.x < xUp + widthArrow - 2)) {
			clickPlace = 1;
		} else if ((pt.x > xDown) && (pt.x < xDown + widthArrow - 2)) {
			clickPlace = 2;
		}
	}
}

PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
                                 const char *faceName, int size,
                                 int codePage_, int characterSet, Window &wParent) {
	clickPlace = 0;
	if (val)
		delete []val;
	val = new char[strlen(defn) + 1];
	if (!val)
		return PRectangle();
	strcpy(val, defn);
	codePage = codePage_;
	Surface *surfaceMeasure = Surface::Allocate();
	if (!surfaceMeasure)
		return PRectangle();
	surfaceMeasure->Init(wParent.GetID());
	surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
	surfaceMeasure->SetDBCSMode(codePage);
	startHighlight = 0;
	endHighlight = 0;
	inCallTipMode = true;
	posStartCallTip = pos;
	int deviceHeight = surfaceMeasure->DeviceHeightFont(size);
	font.Create(faceName, characterSet, deviceHeight, false, false);
	// Look for multiple lines in the text
	// Only support \n here - simply means container must avoid \r!
	int numLines = 1;
	const char *newline;
	const char *look = val;
	xUp = -100;
	xDown = -100;
	offsetMain = 5;
	int width = PaintContents(surfaceMeasure, false) + 5;
	while ((newline = strchr(look, '\n')) != NULL) {
		look = newline + 1;
		numLines++;
	}
	lineHeight = surfaceMeasure->Height(font);
	// Extra line for border and an empty line at top and bottom
	int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
	delete surfaceMeasure;
	return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
}

void CallTip::CallTipCancel() {
	inCallTipMode = false;
	if (wCallTip.Created()) {
		wCallTip.Destroy();
	}
}

void CallTip::SetHighlight(int start, int end) {
	// Avoid flashing by checking something has really changed
	if ((start != startHighlight) || (end != endHighlight)) {
		startHighlight = start;
		endHighlight = end;
		if (wCallTip.Created()) {
			wCallTip.InvalidateAll();
		}
	}
}
<commit_msg>Fixed up and down button handling so they work when not on first line of calltip.<commit_after>// Scintilla source code edit control
/** @file CallTip.cxx
 ** Code for displaying call tips.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>

#include "Platform.h"

#include "Scintilla.h"
#include "CallTip.h"

CallTip::CallTip() {
	wCallTip = 0;
	inCallTipMode = false;
	posStartCallTip = 0;
	val = 0;
	rectUp = PRectangle(0,0,0,0);
	rectDown = PRectangle(0,0,0,0);
	lineHeight = 1;
	startHighlight = 0;
	endHighlight = 0;

	colourBG.desired = ColourDesired(0xff, 0xff, 0xff);
	colourUnSel.desired = ColourDesired(0x80, 0x80, 0x80);
	colourSel.desired = ColourDesired(0, 0, 0x80);
	colourShade.desired = ColourDesired(0, 0, 0);
	colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
}

CallTip::~CallTip() {
	font.Release();
	wCallTip.Destroy();
	delete []val;
	val = 0;
}

const int widthArrow = 14;

void CallTip::RefreshColourPalette(Palette &pal, bool want) {
	pal.WantFind(colourBG, want);
	pal.WantFind(colourUnSel, want);
	pal.WantFind(colourSel, want);
	pal.WantFind(colourShade, want);
	pal.WantFind(colourLight, want);
}

static bool IsArrowCharacter(char ch) {
	return (ch == 0) || (ch == '\001') || (ch == '\002');
}

void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
	int posStart, int posEnd, int ytext, PRectangle rcClient,
	bool highlight, bool draw) {
	s += posStart;
	int len = posEnd - posStart;
	int maxEnd = 0;
	int ends[10];
	for (int i=0;i<len;i++) {
		if (IsArrowCharacter(s[i])) {
			if (i > 0)
				ends[maxEnd++] = i;
			ends[maxEnd++] = i+1;
		}
	}
	ends[maxEnd++] = len;
	int startSeg = 0;
	int xEnd;
	for (int seg = 0; seg<maxEnd; seg++) {
		int endSeg = ends[seg];
		if (endSeg > startSeg) {
			if (IsArrowCharacter(s[startSeg])) {
				xEnd = x + widthArrow;
				offsetMain = xEnd;
				rcClient.left = x;
				rcClient.right = xEnd;
				if (draw) {
					const int halfWidth = widthArrow / 2 - 3;
					const int centreX = x + widthArrow / 2 - 1;
					const int centreY = (rcClient.top + rcClient.bottom) / 2;
					surface->FillRectangle(rcClient, colourBG.allocated);
					PRectangle rcClientInner(rcClient.left+1, rcClient.top+1, rcClient.right-2, rcClient.bottom-1);
					surface->FillRectangle(rcClientInner, colourUnSel.allocated);

					if (s[startSeg] == '\001') {
						// Up arrow
						Point pts[] = {
    						Point(centreX - halfWidth, centreY + halfWidth / 2),
    						Point(centreX + halfWidth, centreY + halfWidth / 2),
    						Point(centreX, centreY - halfWidth + halfWidth / 2),
						};
						surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
                 						colourBG.allocated, colourBG.allocated);
					} else {
						// Down arrow
						Point pts[] = {
    						Point(centreX - halfWidth, centreY - halfWidth / 2),
    						Point(centreX + halfWidth, centreY - halfWidth / 2),
    						Point(centreX, centreY + halfWidth - halfWidth / 2),
						};
						surface->Polygon(pts, sizeof(pts) / sizeof(pts[0]),
                 						colourBG.allocated, colourBG.allocated);
					}
				} else {
					if (s[startSeg] == '\001') {
						rectUp = rcClient;
					} else {
						rectDown = rcClient;
					}
				}
			} else {
				xEnd = x + surface->WidthText(font, s+startSeg, endSeg - startSeg);
				if (draw) {
					rcClient.left = x;
					rcClient.right = xEnd;
					surface->DrawTextNoClip(rcClient, font, ytext,
										s+startSeg, endSeg - startSeg,
										highlight ? colourSel.allocated : colourUnSel.allocated,
										colourBG.allocated);
				}
			}
			x = xEnd;
			startSeg = endSeg;
		}
	}
}

int CallTip::PaintContents(Surface *surfaceWindow, bool draw) {
	PRectangle rcClientPos = wCallTip.GetClientPosition();
	PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
	                        rcClientPos.bottom - rcClientPos.top);
	PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);

	// To make a nice small call tip window, it is only sized to fit most normal characters without accents
	int ascent = surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font);

	// For each line...
	// Draw the definition in three parts: before highlight, highlighted, after highlight
	int ytext = rcClient.top + ascent + 1;
	rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1;
	char *chunkVal = val;
	bool moreChunks = true;
	int maxWidth = 0;
	while (moreChunks) {
		char *chunkEnd = strchr(chunkVal, '\n');
		if (chunkEnd == NULL) {
			chunkEnd = chunkVal + strlen(chunkVal);
			moreChunks = false;
		}
		int chunkOffset = chunkVal - val;
		int chunkLength = chunkEnd - chunkVal;
		int chunkEndOffset = chunkOffset + chunkLength;
		int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset);
		thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset);
		thisStartHighlight -= chunkOffset;
		int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset);
		thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset);
		thisEndHighlight -= chunkOffset;
		rcClient.top = ytext - ascent - 1;

		int x = 5;

		DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight,
			ytext, rcClient, false, draw);
		DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight,
			ytext, rcClient, true, draw);
		DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength,
			ytext, rcClient, false, draw);

		chunkVal = chunkEnd + 1;
		ytext += lineHeight;
		rcClient.bottom += lineHeight;
		maxWidth = Platform::Maximum(maxWidth, x);
	}
	return maxWidth;
}

void CallTip::PaintCT(Surface *surfaceWindow) {
	if (!val)
		return;
	PRectangle rcClientPos = wCallTip.GetClientPosition();
	PRectangle rcClientSize(0, 0, rcClientPos.right - rcClientPos.left,
	                        rcClientPos.bottom - rcClientPos.top);
	PRectangle rcClient(1, 1, rcClientSize.right - 1, rcClientSize.bottom - 1);

	surfaceWindow->FillRectangle(rcClient, colourBG.allocated);

	offsetMain = 5;
	PaintContents(surfaceWindow, true);

	// Draw a raised border around the edges of the window
	surfaceWindow->MoveTo(0, rcClientSize.bottom - 1);
	surfaceWindow->PenColour(colourShade.allocated);
	surfaceWindow->LineTo(rcClientSize.right - 1, rcClientSize.bottom - 1);
	surfaceWindow->LineTo(rcClientSize.right - 1, 0);
	surfaceWindow->PenColour(colourLight.allocated);
	surfaceWindow->LineTo(0, 0);
	surfaceWindow->LineTo(0, rcClientSize.bottom - 1);
}

void CallTip::MouseClick(Point pt) {
	clickPlace = 0;
	if (rectUp.Contains(pt))
		clickPlace = 1;
	if (rectDown.Contains(pt))
		clickPlace = 2;
}

PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn,
                                 const char *faceName, int size,
                                 int codePage_, int characterSet, Window &wParent) {
	clickPlace = 0;
	if (val)
		delete []val;
	val = new char[strlen(defn) + 1];
	if (!val)
		return PRectangle();
	strcpy(val, defn);
	codePage = codePage_;
	Surface *surfaceMeasure = Surface::Allocate();
	if (!surfaceMeasure)
		return PRectangle();
	surfaceMeasure->Init(wParent.GetID());
	surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage);
	surfaceMeasure->SetDBCSMode(codePage);
	startHighlight = 0;
	endHighlight = 0;
	inCallTipMode = true;
	posStartCallTip = pos;
	int deviceHeight = surfaceMeasure->DeviceHeightFont(size);
	font.Create(faceName, characterSet, deviceHeight, false, false);
	// Look for multiple lines in the text
	// Only support \n here - simply means container must avoid \r!
	int numLines = 1;
	const char *newline;
	const char *look = val;
	rectUp = PRectangle(0,0,0,0);
	rectDown = PRectangle(0,0,0,0);
	offsetMain = 5;
	int width = PaintContents(surfaceMeasure, false) + 5;
	while ((newline = strchr(look, '\n')) != NULL) {
		look = newline + 1;
		numLines++;
	}
	lineHeight = surfaceMeasure->Height(font);
	// Extra line for border and an empty line at top and bottom
	int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
	delete surfaceMeasure;
	return PRectangle(pt.x - offsetMain, pt.y + 1, pt.x + width - offsetMain, pt.y + 1 + height);
}

void CallTip::CallTipCancel() {
	inCallTipMode = false;
	if (wCallTip.Created()) {
		wCallTip.Destroy();
	}
}

void CallTip::SetHighlight(int start, int end) {
	// Avoid flashing by checking something has really changed
	if ((start != startHighlight) || (end != endHighlight)) {
		startHighlight = start;
		endHighlight = end;
		if (wCallTip.Created()) {
			wCallTip.InvalidateAll();
		}
	}
}
<|endoftext|>


<commit_before>#include "../include/Cluster.hpp"

using namespace std;

Cluster::Cluster(Options options)
{

int symmetric, format, offset;
bool reduceZeroRows, transpose, printCooOrDense;

#if 0
    std::string path2matrix = options.path2data+"/testMat"+to_string(0)+".txt";
    Matrix A;

    symmetric = 0;  // 0-not, 1-lower tr., 2-upper tr.
    format = 1;     // 0-coo, 1-csr, 2-dense
    offset = 0;

    printCooOrDense = true;
    A.readCooFromFile(path2matrix,symmetric,format,offset);
    A.printToFile("modif",0,printCooOrDense);
    A.CSR2COO();
    A.printToFile("modif2",0,printCooOrDense);
    printCooOrDense = true;
    A.printToFile("modif3",0,printCooOrDense);

    return

#endif
    const int nS = options.n_subdomOnCluster;

    K.resize(nS);
    K_reg.resize(nS);
    Lumped.resize(nS);
    R.resize(nS);
    rhs.resize(nS);
    Bc.resize(nS);
    Bf.resize(nS);
    Bc_dense.resize(nS);
    Fc.resize(nS);
    Gc.resize(nS);

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*                         READING DATA (TXT)                              */
/*                 matrices in coo format are one-based                    */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

    for (int i = 0 ; i < nS ; i++){
        /* K - stiffness matrix */
        string path2matrix = options.path2data+"/K"+to_string(i)+".txt";
        symmetric = 2; format = 1; offset = 1;
        K[i].readCooFromFile(path2matrix,symmetric,format,offset);

        /* R - kernel matrix */
        path2matrix = options.path2data+"/R1"+to_string(i)+".txt";
        symmetric = 0; format = 2; offset = 1;
        R[i].readCooFromFile(path2matrix,symmetric,format,offset);

        /* rhs - right-hand-side vector */
        path2matrix = options.path2data+"/f"+to_string(i)+".txt";
        rhs[i].readCooFromFile(path2matrix,K[i].n_row);
//
        /* Bf - constraints matrix */
        path2matrix = options.path2data+"/B1"+to_string(i)+".txt";
        symmetric = 0; format = 1; offset = 1;
        Bf[i].readCooFromFile(path2matrix,symmetric,format,offset);
//
        /* Bc - constraints matrix */
        path2matrix = options.path2data+"/B0"+to_string(i)+".txt";
        symmetric = 0; format = 1; offset = 1;
        Bc[i].readCooFromFile(path2matrix,symmetric,format,offset);

//
        /* Bc_dense - constraints matrix */
        Bc_dense[i] = Bc[i];
        reduceZeroRows = true;
        transpose = true;
        Bc_dense[i].CSRorCOO2DNS(reduceZeroRows,transpose);

  }

    for (int i_sub = 0; i_sub < nS; i_sub++){
        Matrix Y;
        Y.zero_dense(K[i_sub].n_row_cmprs , R[i_sub].n_col);
        K[i_sub].mult(R[i_sub],Y,true);

        double normK = K[i_sub].norm2();
        double normR = R[i_sub].norm2();
        double normKR = Y.norm2();

        printf("|K| = %.6e, ", normK);
        printf("|R| = %.6e, ", normR);
        printf("|KR|/(|K|*|R|) = %.6e \n", normKR / (normK*normR));
    }

    printCooOrDense = true;
    for (int i = 0; i < nS ; i++ ){
        K_reg[i] = K[i];
        K_reg[i].factorization();

        Matrix BcK_dense;
        BcK_dense = Matrix::CreateCopyFrom(Bc_dense[i]);
        BcK_dense.setZero();

        K[i].mult(Bc_dense[i],BcK_dense,true);
        BcK_dense.printToFile("BcK_dense",i,printCooOrDense);
        Lumped[i].zero_dense(Bc[i].n_row_cmprs,  Bc[i].n_row_cmprs);
        Bc[i].mult(BcK_dense,Lumped[i],true);
        Lumped[i].printToFile("Lumped",i,printCooOrDense);

        Matrix BcKplus_dense;
        BcKplus_dense = Matrix::CreateCopyFrom(Bc_dense[i]);
        BcKplus_dense.setZero();

        K_reg[i].solve(Bc_dense[i],BcKplus_dense);
        BcKplus_dense.printToFile("BcKplus",i,printCooOrDense);
        Fc[i].zero_dense(Bc[i].n_row_cmprs,  Bc[i].n_row_cmprs);
        Bc[i].mult(BcKplus_dense,Fc[i],true);
        Fc[i].printToFile("Fc",i,printCooOrDense);
        Fc[i].l2g_i_coo = Bc[i].l2g_i_coo;

        /* Gc - constraints matrix */
        int n_rowGc = Bc[i].n_row_cmprs;
        int n_colGc = R[i].n_col;
        Gc[i].zero_dense(n_rowGc, n_colGc );
        Bc[i].mult(R[i],Gc[i],true);

        K[i].printToFile("K",i,printCooOrDense);
        K_reg[i].printToFile("K_reg",i,printCooOrDense);
        R[i].printToFile("R",i,printCooOrDense);
        Bc[i].printToFile("Bc",i,printCooOrDense);
        Bc_dense[i].printToFile("Bc_dense",i,printCooOrDense);
        Bf[i].printToFile("Bf",i,printCooOrDense);
        Gc[i].printToFile("Gc",i,printCooOrDense);
        Gc[i].l2g_i_coo = Bc[i].l2g_i_coo;

    }

//    Matrix::testPardiso();

    /* Fc_clust  */
    createFc_clust();
    Fc_clust.printToFile("Fc_clust",0,printCooOrDense);

    createGc_clust();
    Gc_clust.printToFile("Gc_clust",0,printCooOrDense);

    for (int i = 0 ; i < nS; i++){
       K_reg[i].FinalizeSolve(i);
    }
}

void Cluster::createFc_clust(){

    Matrix & A_clust = Fc_clust;
    vector <Matrix> & A_i = Fc;
    A_clust.symmetric = 2;
    bool remapCols = true;
    create_clust_object(A_clust, A_i, remapCols);

}

void Cluster::createGc_clust(){

    Matrix & A_clust = Gc_clust;
    vector <Matrix> & A_i = Gc;
    A_clust.symmetric = 0;
    bool remapCols = false;
    create_clust_object(A_clust, A_i, remapCols);

}

void Cluster::create_clust_object(Matrix &A_clust, vector <Matrix> & A_i, bool remapCols){

    const int nS = A_i.size();
    int init_nnz = 0;
    for (int i = 0; i < nS; i++){
        init_nnz += A_i[i].nnz;
    }

    A_clust.format = 0;

    vector < int_int_dbl > tmpVec;
    tmpVec.resize(init_nnz);

    A_clust.n_col = 0;

/* Sorting [I, J, V]  --------------------------------------------------------*/
    int cnt = 0;
    int _i, _j;
    for (int d = 0; d < nS ; d++){
        A_i[d].DNS2COO();
        for (int i = 0; i < A_i[d].i_coo_cmpr.size();i++){
            _i = A_i[d].l2g_i_coo[ A_i[d].i_coo_cmpr[i] ];
            _j = A_i[d].j_col[i];
            if (remapCols){
                _j = A_i[d].l2g_i_coo[ _j ];
            }
            else{
                _j += A_clust.n_col;
            }
            if (A_clust.symmetric == 0 ||
                    (A_clust.symmetric == 1 && _j <= _i) ||
                    (A_clust.symmetric == 2 && _i <= _j)    ){
                tmpVec[cnt].I = _i;
                tmpVec[cnt].J = _j;
                tmpVec[cnt].V = A_i[d].val[i];
                cnt++;
            }
        }
        A_clust.n_col += A_i[d].n_col;
    }
    A_clust.nnz = cnt;
    tmpVec.resize(A_clust.nnz);

/* sort according to index I -------------------------------------------------*/
    sort(tmpVec.begin(),tmpVec.end(),Matrix::cmp_int_int_I);
/* partial sorting according to index J (per sets with same I)----------------*/
    int startInd = 0, endInd = 1;
    int tmpVecIprev = tmpVec[0].I;
    for (int i = 1 ; i < tmpVec.size(); i ++){
        if (tmpVec[i].I == tmpVecIprev){
            endInd++;
        }
        if (tmpVec[i].I != tmpVecIprev || (tmpVec[i].I == tmpVecIprev &&
                 i == tmpVec.size() - 1))
        {
            sort(tmpVec.begin() + startInd,
                              tmpVec.begin() + (endInd  ),Matrix::cmp_int_int_J);
            startInd = i;
            endInd = i + 1;
        }
        tmpVecIprev = tmpVec[i].I;
    }

/* Cumulating duplicated A[I,J] elements--------------------------------------*/
    int prevInd_I = -1;
    int prevInd_J = -1;
    int counter = 0;
    int cnt_j = -1;
    A_clust.l2g_i_coo.resize(tmpVec.size());

    A_clust.i_coo_cmpr.resize(A_clust.nnz);
    A_clust.j_col.resize(A_clust.nnz);
    A_clust.val.resize(A_clust.nnz);

    for (int i = 0 ; i < tmpVec.size(); i++){

        if (prevInd_I != tmpVec[i].I){
            A_clust.l2g_i_coo[counter] = tmpVec[i].I;
            counter++;
        }
        if (prevInd_I == tmpVec[i].I && prevInd_J == tmpVec[i].J){
            A_clust.val[cnt_j] += tmpVec[i].V;
            A_clust.nnz--;
        }
        else {
            cnt_j++;
            A_clust.i_coo_cmpr[cnt_j] = counter - 1;
            A_clust.j_col[cnt_j] = tmpVec[i].J;
            A_clust.val[cnt_j] = tmpVec[i].V;
        }
        prevInd_I = tmpVec[i].I;
        prevInd_J = tmpVec[i].J;
    }

    A_clust.l2g_i_coo.resize(counter );
    A_clust.l2g_i_coo.shrink_to_fit();

    A_clust.i_coo_cmpr.resize(A_clust.nnz);
    A_clust.i_coo_cmpr.shrink_to_fit();

    A_clust.j_col.resize(A_clust.nnz);
    A_clust.j_col.shrink_to_fit();

    A_clust.val.resize(A_clust.nnz);
    A_clust.val.shrink_to_fit();

    A_clust.n_row_cmprs = counter;
    A_clust.n_row = counter;

    if (A_clust.symmetric > 0){
        A_clust.n_col = A_clust.n_row_cmprs;
    }

    A_clust.COO2CSR();

    tmpVec.clear();
    tmpVec.shrink_to_fit();
}
<commit_msg>src/Cluster.cpp: refactoring<commit_after>#include "../include/Cluster.hpp"

using namespace std;

Cluster::Cluster(Options options)
{

int symmetric, format, offset;
bool reduceZeroRows, transpose, printCooOrDense;

#if 0
    std::string path2matrix = options.path2data+"/testMat"+to_string(0)+".txt";
    Matrix A;

    symmetric = 0;  // 0-not, 1-lower tr., 2-upper tr.
    format = 1;     // 0-coo, 1-csr, 2-dense
    offset = 0;

    printCooOrDense = true;
    A.readCooFromFile(path2matrix,symmetric,format,offset);
    A.printToFile("modif",folder,0,printCooOrDense);
    A.CSR2COO();
    A.printToFile("modif2",folder,0,printCooOrDense);
    printCooOrDense = true;
    A.printToFile("modif3",folder,0,printCooOrDense);

    return

#endif
    const int nS = options.n_subdomOnCluster;
    string folder = options.path2data;

    K.resize(nS);
    K_reg.resize(nS);
    Lumped.resize(nS);
    R.resize(nS);
    rhs.resize(nS);
    Bc.resize(nS);
    Bf.resize(nS);
    Bc_dense.resize(nS);
    Fc.resize(nS);
    Gc.resize(nS);

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*                         READING DATA (TXT)                              */
/*                 matrices in coo format are one-based                    */
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

    for (int i = 0 ; i < nS ; i++){
        /* K - stiffness matrix */
        string path2matrix = options.path2data+"/K"+to_string(i)+".txt";
        symmetric = 2; format = 1; offset = 1;
        K[i].readCooFromFile(path2matrix,symmetric,format,offset);

        /* R - kernel matrix */
        path2matrix = options.path2data+"/R1"+to_string(i)+".txt";
        symmetric = 0; format = 2; offset = 1;
        R[i].readCooFromFile(path2matrix,symmetric,format,offset);

        /* rhs - right-hand-side vector */
        path2matrix = options.path2data+"/f"+to_string(i)+".txt";
        rhs[i].readCooFromFile(path2matrix,K[i].n_row);
//
        /* Bf - constraints matrix */
        path2matrix = options.path2data+"/B1"+to_string(i)+".txt";
        symmetric = 0; format = 1; offset = 1;
        Bf[i].readCooFromFile(path2matrix,symmetric,format,offset);
//
        /* Bc - constraints matrix */
        path2matrix = options.path2data+"/B0"+to_string(i)+".txt";
        symmetric = 0; format = 1; offset = 1;
        Bc[i].readCooFromFile(path2matrix,symmetric,format,offset);

//
        /* Bc_dense - constraints matrix */
        Bc_dense[i] = Bc[i];
        reduceZeroRows = true;
        transpose = true;
        Bc_dense[i].CSRorCOO2DNS(reduceZeroRows,transpose);

  }

#if 0
    for (int i_sub = 0; i_sub < nS; i_sub++){
        Matrix Y;
        Y.zero_dense(K[i_sub].n_row_cmprs , R[i_sub].n_col);
        K[i_sub].mult(R[i_sub],Y,true);

        double normK = K[i_sub].norm2();
        double normR = R[i_sub].norm2();
        double normKR = Y.norm2();

        printf("|K| = %.6e, ", normK);
        printf("|R| = %.6e, ", normR);
        printf("|KR|/(|K|*|R|) = %.6e \n", normKR / (normK*normR));
    }
#endif
    printCooOrDense = true;
    for (int i = 0; i < nS ; i++ ){

        vector <int > nullPivots;
        R[i].getNullPivots(nullPivots);
//        for (int i = 0 ; i < nullPivots.size(); i++){
//            cout << nullPivots[i] << endl;
//        }

        K_reg[i] = K[i];
        K_reg[i].factorization(nullPivots);

        Matrix BcK_dense;
        //BcK_dense = Matrix::CreateCopyFrom(Bc_dense[i]);
        BcK_dense = Bc_dense[i];
        BcK_dense.setZero();

        K[i].mult(Bc_dense[i],BcK_dense,true);
        BcK_dense.printToFile("BcK_dense",folder,i,printCooOrDense);
        Lumped[i].zero_dense(Bc[i].n_row_cmprs,  Bc[i].n_row_cmprs);
        Bc[i].mult(BcK_dense,Lumped[i],true);
        Lumped[i].printToFile("Lumped",folder,i,printCooOrDense);

        Matrix BcKplus_dense;
//        BcKplus_dense = Matrix::CreateCopyFrom(Bc_dense[i]);
        BcKplus_dense = Bc_dense[i];
        BcKplus_dense.setZero();

        K_reg[i].solve(Bc_dense[i],BcKplus_dense);
        BcKplus_dense.printToFile("BcKplus",folder,i,printCooOrDense);
        Fc[i].zero_dense(Bc[i].n_row_cmprs,  Bc[i].n_row_cmprs);
        Bc[i].mult(BcKplus_dense,Fc[i],true);
        Fc[i].printToFile("Fc",folder,i,printCooOrDense);
        Fc[i].l2g_i_coo = Bc[i].l2g_i_coo;

        /* Gc - constraints matrix */
        int n_rowGc = Bc[i].n_row_cmprs;
        int n_colGc = R[i].n_col;
        Gc[i].zero_dense(n_rowGc, n_colGc );
        Bc[i].mult(R[i],Gc[i],true);

        /* print */
        /* K, R, etc.*/
        cout << "   ... printing matrices start  ...";
        K[i].printToFile("K",folder,i,printCooOrDense);
        K_reg[i].printToFile("K_reg",folder,i,printCooOrDense);
        R[i].printToFile("R",folder,i,printCooOrDense);
        Bc[i].printToFile("Bc",folder,i,printCooOrDense);
        Bc_dense[i].printToFile("Bc_dense",folder,i,printCooOrDense);
        Bf[i].printToFile("Bf",folder,i,printCooOrDense);
        Gc[i].printToFile("Gc",folder,i,printCooOrDense);
        Gc[i].l2g_i_coo = Bc[i].l2g_i_coo;
        cout << "  " << i <<"/" << nS <<"  ...\n";
    }

//    Matrix::testPardiso();

    /* Fc_clust  */
    create_Fc_clust();
    Fc_clust.printToFile("Fc_clust",folder,0,printCooOrDense);

    create_Gc_clust();
    Gc_clust.printToFile("Gc_clust",folder,0,printCooOrDense);

    for (int i = 0 ; i < nS; i++){
       K_reg[i].FinalizeSolve(i);
    }
}

void Cluster::create_Fc_clust(){

    Matrix & A_clust = Fc_clust;
    vector <Matrix> & A_i = Fc;
    A_clust.symmetric = 2;
    bool remapCols = true;
    create_clust_object(A_clust, A_i, remapCols);
}

void Cluster::create_Gc_clust(){

    Matrix & A_clust = Gc_clust;
    vector <Matrix> & A_i = Gc;
    A_clust.symmetric = 0;
    bool remapCols = false;
    create_clust_object(A_clust, A_i, remapCols);
}

void Cluster::create_clust_object(Matrix &A_clust, vector <Matrix> & A_i, bool remapCols){

    const int nS = A_i.size();
    int init_nnz = 0;
    for (int i = 0; i < nS; i++){
        init_nnz += A_i[i].nnz;
    }

    A_clust.format = 0;

    vector < int_int_dbl > tmpVec;
    tmpVec.resize(init_nnz);

    A_clust.n_col = 0;

/* Sorting [I, J, V]  --------------------------------------------------------*/
    int cnt = 0;
    int _i, _j;
    for (int d = 0; d < nS ; d++){
        A_i[d].DNS2COO();
        for (int i = 0; i < A_i[d].i_coo_cmpr.size();i++){
            _i = A_i[d].l2g_i_coo[ A_i[d].i_coo_cmpr[i] ];
            _j = A_i[d].j_col[i];
            if (remapCols){
                _j = A_i[d].l2g_i_coo[ _j ];
            }
            else{
                _j += A_clust.n_col;
            }
            if (A_clust.symmetric == 0 ||
                    (A_clust.symmetric == 1 && _j <= _i) ||
                    (A_clust.symmetric == 2 && _i <= _j)    ){
                tmpVec[cnt].I = _i;
                tmpVec[cnt].J = _j;
                tmpVec[cnt].V = A_i[d].val[i];
                cnt++;
            }
        }
        A_clust.n_col += A_i[d].n_col;
    }
    A_clust.nnz = cnt;
    tmpVec.resize(A_clust.nnz);

/* sort according to index I -------------------------------------------------*/
    sort(tmpVec.begin(),tmpVec.end(),Matrix::cmp_int_int_I);
/* partial sorting according to index J (per sets with same I)----------------*/
    int startInd = 0, endInd = 1;
    int tmpVecIprev = tmpVec[0].I;
    for (int i = 1 ; i < tmpVec.size(); i ++){
        if (tmpVec[i].I == tmpVecIprev){
            endInd++;
        }
        if (tmpVec[i].I != tmpVecIprev || (tmpVec[i].I == tmpVecIprev &&
                 i == tmpVec.size() - 1))
        {
            sort(tmpVec.begin() + startInd,
                              tmpVec.begin() + (endInd  ),Matrix::cmp_int_int_J);
            startInd = i;
            endInd = i + 1;
        }
        tmpVecIprev = tmpVec[i].I;
    }

/* Cumulating duplicated A[I,J] elements--------------------------------------*/
    int prevInd_I = -1;
    int prevInd_J = -1;
    int counter = 0;
    int cnt_j = -1;
    A_clust.l2g_i_coo.resize(tmpVec.size());

    A_clust.i_coo_cmpr.resize(A_clust.nnz);
    A_clust.j_col.resize(A_clust.nnz);
    A_clust.val.resize(A_clust.nnz);

    for (int i = 0 ; i < tmpVec.size(); i++){

        if (prevInd_I != tmpVec[i].I){
            A_clust.l2g_i_coo[counter] = tmpVec[i].I;
            counter++;
        }
        if (prevInd_I == tmpVec[i].I && prevInd_J == tmpVec[i].J){
            A_clust.val[cnt_j] += tmpVec[i].V;
            A_clust.nnz--;
        }
        else {
            cnt_j++;
            A_clust.i_coo_cmpr[cnt_j] = counter - 1;
            A_clust.j_col[cnt_j] = tmpVec[i].J;
            A_clust.val[cnt_j] = tmpVec[i].V;
        }
        prevInd_I = tmpVec[i].I;
        prevInd_J = tmpVec[i].J;
    }

    A_clust.l2g_i_coo.resize(counter );
    A_clust.l2g_i_coo.shrink_to_fit();

    A_clust.i_coo_cmpr.resize(A_clust.nnz);
    A_clust.i_coo_cmpr.shrink_to_fit();

    A_clust.j_col.resize(A_clust.nnz);
    A_clust.j_col.shrink_to_fit();

    A_clust.val.resize(A_clust.nnz);
    A_clust.val.shrink_to_fit();

    A_clust.n_row_cmprs = counter;
    A_clust.n_row = counter;

    if (A_clust.symmetric > 0){
        A_clust.n_col = A_clust.n_row_cmprs;
    }

    A_clust.COO2CSR();

    tmpVec.clear();
    tmpVec.shrink_to_fit();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cassert>

#include "CubeCmd.h"
#include "HdfWriter.h"
#include "TextWriter.h"
#include "VtkWriter.h"
#include "StringUtils.h"

using namespace std;
using namespace cigma;

// ---------------------------------------------------------------------------

cigma::CubeCmd::CubeCmd()
{
    name = "cube";

    L = M = N = 0;
    mesh = 0;
    writer = 0;
}

cigma::CubeCmd::~CubeCmd()
{
}

// ---------------------------------------------------------------------------

void cigma::CubeCmd::setupOptions(AnyOption *opt)
{
    //cout << "Calling cigma::CubeCmd::setupOptions()" << endl;
    assert(opt != 0);

    /* setup usage */
    opt->addUsage("Usage:");
    opt->addUsage("  cigma cube [options]");
    opt->addUsage("    -x               Number of elements along x-dimension");
    opt->addUsage("    -y               Number of elements along y-dimension");
    opt->addUsage("    -z               Number of elements along z-dimension");
    opt->addUsage("    --hex8           Create hexahedral partition (default)");
    opt->addUsage("    --tet4           Create tetrahedral partition");
    opt->addUsage("    --output         Target output file");
    opt->addUsage("    --coords-path    Target path for coordinates (.h5 only)");
    opt->addUsage("    --connect-path   Target path for connectivity (.h5 only)");

    /* setup flags and options */

    opt->setFlag("help", 'h');
    opt->setFlag("verbose", 'v');

    opt->setFlag("hex8");
    opt->setFlag("tet4");

    opt->setOption('x');
    opt->setOption('y');
    opt->setOption('z');

    opt->setOption("output", 'o');
    opt->setOption("coords-path");
    opt->setOption("connect-path");

}

void cigma::CubeCmd::configure(AnyOption *opt)
{
    //std::cout << "Calling cigma::CubeCmd::configure()" << std::endl;
    assert(opt != 0);

    if (!opt->hasOptions())
    {
        //std::cerr << "No options?" << std::endl;
        opt->printUsage();
        exit(1);
    }

    char *in;
    string inputstr;

    // read verbose flag
    verbose = opt->getFlag("verbose");

    // read L
    in = opt->getValue('x');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -x" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, L);

    // read M
    in = opt->getValue('y');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -y" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, M);

    // read N
    in = opt->getValue('z');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -z" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, N);

    // read output file
    in = opt->getValue("output");
    if (in == 0)
    {
        cerr << "cube: Please specify the option --output" << endl;
        exit(1);
    }
    output_filename = in;

    // determine the extension and instantiate appropriate writer object
    string root, ext;
    path_splitext(output_filename, root, ext);
    writer = NewWriter(ext.c_str());
    if (writer == 0)
    {
        cerr << "cube: File with bad extension (" << ext << ")" << endl;
        exit(1);
    }

    // read target path for coordinates array
    in = opt->getValue("coords-path");
    if (in == 0)
    {
        if (writer->getType() == Writer::HDF_WRITER)
        {
            coords_path = "/coordinates";
        }
    }
    else
    {
        coords_path = in;
    }
    if ((coords_path != "") && (writer->getType() != Writer::HDF_WRITER))
    {
        cerr << "cube: Can only use --coords-path "
             << "when writing to an HDF5 (.h5) file" << endl;
        exit(1);

    }

    // read target path for connectivity array
    in = opt->getValue("connect-path");
    if (in == 0)
    {
        if (writer->getType() == Writer::HDF_WRITER)
        {
            connect_path = "/connectivity";
        }
    }
    else
    {
        connect_path = in;
    }
    if ((connect_path != "") && (writer->getType() != Writer::HDF_WRITER))
    {
        cerr << "cube: Can only use --connect-path "
             << "when writing to an HDF5 (.h5) file" << endl;
        exit(1);
    }

    // read tet/hex flags
    bool hexFlag = opt->getFlag("hex8");
    bool tetFlag = opt->getFlag("tet4");
    if (hexFlag && tetFlag)
    {
        std::cerr << "cube: Please specify only one of the flags "
                  << "--hex8 or --tet8" << std::endl;
        exit(1);
    }
    if (!tetFlag)
    {
        hexFlag = true;
    }
    assert(hexFlag != tetFlag);

    // initialize mesh object
    mesh = new cigma::CubeMeshPart();
    mesh->calc_coordinates(L,M,N);
    if (hexFlag) { mesh->calc_hex8_connectivity(); }
    if (tetFlag) { mesh->calc_tet4_connectivity(); }
}

int cigma::CubeCmd::run()
{
    //std::cout << "Calling cigma::CubeCmd::run()" << std::endl;
    assert(mesh != 0);
    assert(writer != 0);

    if (verbose)
    {
        std::cout << "L, M, N = (" << L << ", " << M << ", " << N << ")" << std::endl;
        std::cout << "mesh->nno = " << mesh->nno << std::endl;
        std::cout << "mesh->nel = " << mesh->nel << std::endl;
        std::cout << "mesh->ndofs = " << mesh->ndofs << std::endl;
    }

    if (verbose)
    {
        int e = 0;
        double pts[2][3] = {{0.5, 0.5, 0.5},
                            {1.0, 1.0, 1.0}};

        cout << "cube test: Looking for centroid..." << endl;
        bool found = mesh->find_cell(pts[0], &e);

        if (!found)
        {
            cerr << "cube test error: Could not find cell "
                 << "containing centroid (0.5,0.5,0.5)" << endl;
            exit(1);
        }
        else
        {
            cout << "cube test: Found centroid in cell " << e << endl;
        }
    }

    int ierr;

    cout << "Creating file " << output_filename << endl;

    if (writer->getType() == Writer::HDF_WRITER)
    {
        HdfWriter *hdfWriter = static_cast<HdfWriter*>(writer);
        ierr = hdfWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not open (or create) the HDF5 file " << output_filename << endl;
            exit(1);
        }

        ierr = hdfWriter->write_coordinates(coords_path.c_str(), mesh->coords, mesh->nno, mesh->nsd);
        if (ierr < 0)
        {
            cerr << "Error: Could not write dataset " << coords_path << endl;
            exit(1);
        }

        ierr = hdfWriter->write_connectivity(connect_path.c_str(), mesh->connect, mesh->nel, mesh->ndofs);
        if (ierr < 0)
        {
            cerr << "Error: Could not write dataset " << connect_path << endl;
            exit(1);
        }

        hdfWriter->close();
    }
    else if (writer->getType() == Writer::TEXT_WRITER)
    {
        TextWriter *textWriter = static_cast<TextWriter*>(writer);
        ierr = textWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not create output text file " << output_filename << endl;
            exit(1);
        }

        textWriter->write_coordinates(mesh->coords, mesh->nno, mesh->nsd);
        textWriter->write_connectivity(mesh->connect, mesh->nel, mesh->ndofs);
        textWriter->close();
    }
    else if (writer->getType() == Writer::VTK_WRITER)
    {
        VtkWriter *vtkWriter = static_cast<VtkWriter*>(writer);
        ierr = vtkWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not create output VTK file " << output_filename << endl;
            exit(1);
        }

        vtkWriter->write_header();
        vtkWriter->write_points(mesh->coords, mesh->nno, mesh->nsd);
        vtkWriter->write_cells(mesh->connect, mesh->nel, mesh->ndofs);
        vtkWriter->write_cell_types(mesh->nsd, mesh->nel, mesh->ndofs);
        vtkWriter->close();
    }
    else
    {
        /* this should be unreachable */
        cerr << "Fatal Error: Unsupported extension in output filename?" << endl;
        return 1;
    }

    if (writer != 0)
    {
        delete writer;
    }

    return 0;
}

// ---------------------------------------------------------------------------

<commit_msg>Updated usage of TextWriter in CubeCmd<commit_after>#include <iostream>
#include <string>
#include <cassert>

#include "CubeCmd.h"
#include "HdfWriter.h"
#include "TextWriter.h"
#include "VtkWriter.h"
#include "StringUtils.h"

using namespace std;
using namespace cigma;

// ---------------------------------------------------------------------------

cigma::CubeCmd::CubeCmd()
{
    name = "cube";

    L = M = N = 0;
    mesh = 0;
    writer = 0;
}

cigma::CubeCmd::~CubeCmd()
{
}

// ---------------------------------------------------------------------------

void cigma::CubeCmd::setupOptions(AnyOption *opt)
{
    //cout << "Calling cigma::CubeCmd::setupOptions()" << endl;
    assert(opt != 0);

    /* setup usage */
    opt->addUsage("Usage:");
    opt->addUsage("  cigma cube [options]");
    opt->addUsage("    -x               Number of elements along x-dimension");
    opt->addUsage("    -y               Number of elements along y-dimension");
    opt->addUsage("    -z               Number of elements along z-dimension");
    opt->addUsage("    --hex8           Create hexahedral partition (default)");
    opt->addUsage("    --tet4           Create tetrahedral partition");
    opt->addUsage("    --output         Target output file");
    opt->addUsage("    --coords-path    Target path for coordinates (.h5 only)");
    opt->addUsage("    --connect-path   Target path for connectivity (.h5 only)");

    /* setup flags and options */

    opt->setFlag("help", 'h');
    opt->setFlag("verbose", 'v');

    opt->setFlag("hex8");
    opt->setFlag("tet4");

    opt->setOption('x');
    opt->setOption('y');
    opt->setOption('z');

    opt->setOption("output", 'o');
    opt->setOption("coords-path");
    opt->setOption("connect-path");

}

void cigma::CubeCmd::configure(AnyOption *opt)
{
    //std::cout << "Calling cigma::CubeCmd::configure()" << std::endl;
    assert(opt != 0);

    if (!opt->hasOptions())
    {
        //std::cerr << "No options?" << std::endl;
        opt->printUsage();
        exit(1);
    }

    char *in;
    string inputstr;

    // read verbose flag
    verbose = opt->getFlag("verbose");

    // read L
    in = opt->getValue('x');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -x" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, L);

    // read M
    in = opt->getValue('y');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -y" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, M);

    // read N
    in = opt->getValue('z');
    if (in == 0)
    {
        cerr << "cube: Please specify the option -z" << endl;
        exit(1);
    }
    inputstr = in;
    string_to_int(inputstr, N);

    // read output file
    in = opt->getValue("output");
    if (in == 0)
    {
        cerr << "cube: Please specify the option --output" << endl;
        exit(1);
    }
    output_filename = in;

    // determine the extension and instantiate appropriate writer object
    string root, ext;
    path_splitext(output_filename, root, ext);
    writer = NewWriter(ext.c_str());
    if (writer == 0)
    {
        cerr << "cube: File with bad extension (" << ext << ")" << endl;
        exit(1);
    }

    // read target path for coordinates array
    in = opt->getValue("coords-path");
    if (in == 0)
    {
        if (writer->getType() == Writer::HDF_WRITER)
        {
            coords_path = "/coordinates";
        }
    }
    else
    {
        coords_path = in;
    }
    if ((coords_path != "") && (writer->getType() != Writer::HDF_WRITER))
    {
        cerr << "cube: Can only use --coords-path "
             << "when writing to an HDF5 (.h5) file" << endl;
        exit(1);

    }

    // read target path for connectivity array
    in = opt->getValue("connect-path");
    if (in == 0)
    {
        if (writer->getType() == Writer::HDF_WRITER)
        {
            connect_path = "/connectivity";
        }
    }
    else
    {
        connect_path = in;
    }
    if ((connect_path != "") && (writer->getType() != Writer::HDF_WRITER))
    {
        cerr << "cube: Can only use --connect-path "
             << "when writing to an HDF5 (.h5) file" << endl;
        exit(1);
    }

    // read tet/hex flags
    bool hexFlag = opt->getFlag("hex8");
    bool tetFlag = opt->getFlag("tet4");
    if (hexFlag && tetFlag)
    {
        std::cerr << "cube: Please specify only one of the flags "
                  << "--hex8 or --tet8" << std::endl;
        exit(1);
    }
    if (!tetFlag)
    {
        hexFlag = true;
    }
    assert(hexFlag != tetFlag);

    // initialize mesh object
    mesh = new cigma::CubeMeshPart();
    mesh->calc_coordinates(L,M,N);
    if (hexFlag) { mesh->calc_hex8_connectivity(); }
    if (tetFlag) { mesh->calc_tet4_connectivity(); }
}

int cigma::CubeCmd::run()
{
    //std::cout << "Calling cigma::CubeCmd::run()" << std::endl;
    assert(mesh != 0);
    assert(writer != 0);

    if (verbose)
    {
        std::cout << "L, M, N = (" << L << ", " << M << ", " << N << ")" << std::endl;
        std::cout << "mesh->nno = " << mesh->nno << std::endl;
        std::cout << "mesh->nel = " << mesh->nel << std::endl;
        std::cout << "mesh->ndofs = " << mesh->ndofs << std::endl;
    }

    if (verbose)
    {
        int e = 0;
        double pts[2][3] = {{0.5, 0.5, 0.5},
                            {1.0, 1.0, 1.0}};

        cout << "cube test: Looking for centroid..." << endl;
        bool found = mesh->find_cell(pts[0], &e);

        if (!found)
        {
            cerr << "cube test error: Could not find cell "
                 << "containing centroid (0.5,0.5,0.5)" << endl;
            exit(1);
        }
        else
        {
            cout << "cube test: Found centroid in cell " << e << endl;
        }
    }

    int ierr;

    cout << "Creating file " << output_filename << endl;

    if (writer->getType() == Writer::HDF_WRITER)
    {
        HdfWriter *hdfWriter = static_cast<HdfWriter*>(writer);
        ierr = hdfWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not open (or create) the HDF5 file " << output_filename << endl;
            exit(1);
        }

        ierr = hdfWriter->write_coordinates(coords_path.c_str(), mesh->coords, mesh->nno, mesh->nsd);
        if (ierr < 0)
        {
            cerr << "Error: Could not write dataset " << coords_path << endl;
            exit(1);
        }

        ierr = hdfWriter->write_connectivity(connect_path.c_str(), mesh->connect, mesh->nel, mesh->ndofs);
        if (ierr < 0)
        {
            cerr << "Error: Could not write dataset " << connect_path << endl;
            exit(1);
        }

        hdfWriter->close();
    }
    else if (writer->getType() == Writer::TEXT_WRITER)
    {
        TextWriter *textWriter = static_cast<TextWriter*>(writer);
        ierr = textWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not create output text file " << output_filename << endl;
            exit(1);
        }

        textWriter->write_coordinates(coords_path.c_str(), mesh->coords, mesh->nno, mesh->nsd);
        textWriter->write_connectivity(connect_path.c_str(), mesh->connect, mesh->nel, mesh->ndofs);
        textWriter->close();
    }
    else if (writer->getType() == Writer::VTK_WRITER)
    {
        VtkWriter *vtkWriter = static_cast<VtkWriter*>(writer);
        ierr = vtkWriter->open(output_filename.c_str());
        if (ierr < 0)
        {
            cerr << "Error: Could not create output VTK file " << output_filename << endl;
            exit(1);
        }

        //vtkWriter->write_header();
        vtkWriter->write_points(mesh->coords, mesh->nno, mesh->nsd);
        vtkWriter->write_cells(mesh->connect, mesh->nel, mesh->ndofs);
        vtkWriter->write_cell_types(mesh->nsd, mesh->nel, mesh->ndofs);
        vtkWriter->close();
    }
    else
    {
        /* this should be unreachable */
        cerr << "Fatal Error: Unsupported extension in output filename?" << endl;
        return 1;
    }

    if (writer != 0)
    {
        delete writer;
    }

    return 0;
}

// ---------------------------------------------------------------------------

<|endoftext|>