コード例 #1
0
ファイル: System.cpp プロジェクト: haibiao/pybinding
void populate_system(System& system, Foundation const& foundation,
                     HamiltonianIndices const& hamiltonian_indices) {
    auto const size = hamiltonian_indices.size();
    system.positions.resize(size);
    system.sublattices.resize(size);
    system.hoppings.resize(size, size);

    auto const& lattice = foundation.get_lattice();
    auto const reserve_nonzeros = (lattice.max_hoppings() * size) / 2;
    auto matrix_view = compressed_inserter(system.hoppings, reserve_nonzeros);

    for (auto const& site : foundation) {
        auto const index = hamiltonian_indices[site];
        if (index < 0)
            continue; // invalid site

        system.positions[index] = site.get_position();
        system.sublattices[index] = lattice[site.get_sublattice()].alias;

        matrix_view.start_row(index);
        site.for_each_neighbour([&](Site neighbor, Hopping hopping) {
            auto const neighbor_index = hamiltonian_indices[neighbor];
            if (neighbor_index < 0)
                return; // invalid

            if (!hopping.is_conjugate) // only make half the matrix, other half is the conjugate
                matrix_view.insert(neighbor_index, hopping.id);
        });
    }
    matrix_view.compress();
}
コード例 #2
0
ファイル: System.cpp プロジェクト: haibiao/pybinding
void populate_boundaries(System& system, Foundation const& foundation,
                         HamiltonianIndices const& hamiltonian_indices,
                         TranslationalSymmetry const& symmetry) {
    // a boundary is added first to prevent copying of Eigen::SparseMatrix
    // --> revise when Eigen types become movable

    auto const size = hamiltonian_indices.size();
    auto const& lattice = foundation.get_lattice();

    system.boundaries.emplace_back();
    for (const auto& translation : symmetry.translations(foundation)) {
        auto& boundary = system.boundaries.back();

        boundary.shift = translation.shift_lenght;
        boundary.hoppings.resize(size, size);

        // the reservation number is intentionally overestimated
        auto const reserve_nonzeros = [&]{
            auto nz = static_cast<int>(lattice.sublattices.size() * lattice.max_hoppings() / 2);
            for (auto i = 0; i < translation.boundary_slice.ndims(); ++i) {
                if (translation.boundary_slice[i].end < 0)
                    nz *= foundation.get_size()[i];
            }
            return nz;
        }();
        auto boundary_matrix_view = compressed_inserter(boundary.hoppings, reserve_nonzeros);

        for (auto const& site : foundation[translation.boundary_slice]) {
            if (!site.is_valid())
                continue;

            boundary_matrix_view.start_row(hamiltonian_indices[site]);

            auto const shifted_site = site.shifted(translation.shift_index);
            // the site is shifted to the opposite edge of the translation unit
            shifted_site.for_each_neighbour([&](Site neighbor, Hopping hopping) {
                auto const neighbor_index = hamiltonian_indices[neighbor];
                if (neighbor_index < 0)
                    return; // invalid

                boundary_matrix_view.insert(neighbor_index, hopping.id);
            });
        }
        boundary_matrix_view.compress();

        if (boundary.hoppings.nonZeros() > 0)
            system.boundaries.emplace_back();
    }
    system.boundaries.pop_back();
}
コード例 #3
0
ファイル: SaveLoad.cpp プロジェクト: Hacklin/freeorion
void SaveGame(const std::string& filename, const ServerSaveGameData& server_save_game_data,
              const std::vector<PlayerSaveGameData>& player_save_game_data, const Universe& universe,
              const EmpireManager& empire_manager, const SpeciesManager& species_manager,
              const CombatLogManager& combat_log_manager, const GalaxySetupData& galaxy_setup_data,
              bool multiplayer)
{
    ScopedTimer timer("SaveGame: " + filename, true);

    bool use_binary = GetOptionsDB().Get<bool>("binary-serialization");
    DebugLogger() << "SaveGame(" << (use_binary ? "binary" : "zlib-xml") << ") filename: " << filename;
    GetUniverse().EncodingEmpire() = ALL_EMPIRES;

    DebugLogger() << "Compiling save empire and preview data";
    std::map<int, SaveGameEmpireData> empire_save_game_data = CompileSaveGameEmpireData(empire_manager);
    SaveGamePreviewData save_preview_data;
    CompileSaveGamePreviewData(server_save_game_data, player_save_game_data, empire_save_game_data, save_preview_data);


    // reinterpret save game data as header data for uncompressed header
    std::vector<PlayerSaveHeaderData> player_save_header_data;
    for (std::vector<PlayerSaveGameData>::const_iterator it = player_save_game_data.begin();
            it != player_save_game_data.end(); ++it)
    {
        player_save_header_data.push_back(*it);
    }


    try {
        fs::path path = FilenameToPath(filename);
        // A relative path should be relative to the save directory.
        if (path.is_relative()) {
            path = GetSaveDir()/path;
            DebugLogger() << "Made save path relative to save dir. Is now: " << path;
        }

        if (multiplayer) {
            // Make sure the path points into our save directory
            if (!IsInside(path, GetSaveDir())) {
                path = GetSaveDir() / path.filename();
            }
        }

        // set up output archive / stream for saving
        fs::ofstream ofs(path, std::ios_base::binary);
        if (!ofs)
            throw std::runtime_error(UNABLE_TO_OPEN_FILE);

        if (use_binary) {
            DebugLogger() << "Creating binary oarchive";
            freeorion_bin_oarchive boa(ofs);
            boa << BOOST_SERIALIZATION_NVP(save_preview_data);
            boa << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            boa << BOOST_SERIALIZATION_NVP(server_save_game_data);
            boa << BOOST_SERIALIZATION_NVP(player_save_header_data);
            boa << BOOST_SERIALIZATION_NVP(empire_save_game_data);

            boa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            boa << BOOST_SERIALIZATION_NVP(empire_manager);
            boa << BOOST_SERIALIZATION_NVP(species_manager);
            boa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(boa, universe);
            DebugLogger() << "Done serializing";

        } else {
            // Two-tier serialization:
            // main archive is uncompressed serialized header data first
            // then contains a string for compressed second archive
            // that contains the main gamestate info


            // allocate buffers for serialized gamestate
            DebugLogger() << "Allocating buffers for XML serialization...";
            std::string serial_str, compressed_str;
            try {
                serial_str.reserve(    std::pow(2.0, 29.0));
                compressed_str.reserve(std::pow(2.0, 26.0));
            } catch (...) {
                DebugLogger() << "Unable to preallocate full serialization buffers. Attempting serialization with dynamic buffer allocation.";
            }

            // wrap buffer string in iostream::stream to receive serialized data
            typedef boost::iostreams::back_insert_device<std::string> InsertDevice;
            InsertDevice serial_inserter(serial_str);
            boost::iostreams::stream<InsertDevice> s_sink(serial_inserter);

            // create archive with (preallocated) buffer...
            freeorion_xml_oarchive xoa(s_sink);
            // serialize main gamestate info
            xoa << BOOST_SERIALIZATION_NVP(player_save_game_data);
            xoa << BOOST_SERIALIZATION_NVP(empire_manager);
            xoa << BOOST_SERIALIZATION_NVP(species_manager);
            xoa << BOOST_SERIALIZATION_NVP(combat_log_manager);
            Serialize(xoa, universe);
            s_sink.flush();

            // wrap gamestate string in iostream::stream to extract serialized data
            typedef boost::iostreams::basic_array_source<char> SourceDevice;
            SourceDevice source(serial_str.data(), serial_str.size());
            boost::iostreams::stream<SourceDevice> s_source(source);

            // wrap compresed buffer string in iostream::streams to receive compressed string
            InsertDevice compressed_inserter(compressed_str);
            boost::iostreams::stream<InsertDevice> c_sink(compressed_inserter);

            // compression-filter gamestate into compressed string
            boost::iostreams::filtering_ostreambuf o;
            o.push(boost::iostreams::zlib_compressor());
            o.push(c_sink);
            boost::iostreams::copy(s_source, o);
            c_sink.flush();

            // write to save file: uncompressed header serialized data, with compressed main archive string at end...
            freeorion_xml_oarchive xoa2(ofs);
            // serialize uncompressed save header info
            xoa2 << BOOST_SERIALIZATION_NVP(save_preview_data);
            xoa2 << BOOST_SERIALIZATION_NVP(galaxy_setup_data);
            xoa2 << BOOST_SERIALIZATION_NVP(server_save_game_data);
            xoa2 << BOOST_SERIALIZATION_NVP(player_save_header_data);
            xoa2 << BOOST_SERIALIZATION_NVP(empire_save_game_data);
            // append compressed gamestate info
            xoa2 << BOOST_SERIALIZATION_NVP(compressed_str);
        }

    } catch (const std::exception& e) {
        ErrorLogger() << UserString("UNABLE_TO_WRITE_SAVE_FILE") << " SaveGame exception: " << ": " << e.what();
        throw e;
    }
    DebugLogger() << "SaveGame : Successfully wrote save file";
}
コード例 #4
0
ファイル: System.cpp プロジェクト: haibiao/pybinding
System::Port::Port(Foundation const& foundation,
                   HamiltonianIndices const& hamiltonian_indices,
                   Lead const& lead) {
    auto const& lattice = foundation.get_lattice();
    shift = static_cast<float>(-lead.sign) * lattice.vectors[lead.axis];

    auto const junction = LeadJunction(foundation, lead);
    auto const slice = foundation[junction.slice_index];

    indices = [&]{
        auto indices = std::vector<int>();
        indices.reserve(junction.is_valid.count());

        for (auto const& site : slice) {
            if (junction.is_valid[site.get_slice_idx()]) {
                indices.push_back(hamiltonian_indices[site]);
            }
        }
        return indices;
    }();

    inner_hoppings = [&]{
        auto const size = static_cast<int>(indices.size());
        auto matrix = SparseMatrixX<hop_id>(size, size);
        auto matrix_view = compressed_inserter(matrix, size * lattice.max_hoppings());

        for (auto const& site : slice) {
            if (!junction.is_valid[site.get_slice_idx()]) {
                continue;
            }

            matrix_view.start_row();
            site.for_each_neighbour([&](Site neighbor, Hopping hopping) {
                auto const index = lead_index(hamiltonian_indices[neighbor]);
                if (index >= 0) {
                    matrix_view.insert(index, hopping.id);
                }
            });
        }
        matrix_view.compress();

        return matrix;
    }();

    outer_hoppings = [&]{
        auto const size = static_cast<int>(indices.size());
        auto matrix = SparseMatrixX<hop_id>(size, size);
        auto matrix_view = compressed_inserter(matrix, size * lattice.max_hoppings());

        for (auto const& site : slice) {
            if (!junction.is_valid[site.get_slice_idx()]) {
                continue;
            }

            auto const shifted_site = [&]{
                Index3D shift_index = Index3D::Zero();
                shift_index[lead.axis] = lead.sign;
                return site.shifted(shift_index);
            }();

            matrix_view.start_row();
            shifted_site.for_each_neighbour([&](Site neighbor, Hopping hopping) {
                auto const index = lead_index(hamiltonian_indices[neighbor]);
                if (index >= 0) {
                    matrix_view.insert(index, hopping.id);
                }
            });
        }
        matrix_view.compress();

        return matrix;
    }();
}