<commit_before>#pragma once

#include <functional>
#include <mutex>
#include <utility>

#include "../replicated.hpp"

#include <derecho/mutils-serialization/SerializationSupport.hpp>

namespace derecho {

template <typename T>
Replicated<T>::Replicated(subgroup_type_id_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                          uint32_t subgroup_index, uint32_t shard_num,
                          rpc::RPCManager& group_rpc_manager, Factory<T> client_object_factory,
                          _Group* group)
        : persistent_registry_ptr(std::make_unique<persistent::PersistentRegistry>(
                  this, std::type_index(typeid(T)), subgroup_index, shard_num)),
          user_object_ptr(std::make_unique<std::unique_ptr<T>>(
                  client_object_factory(persistent_registry_ptr.get()))),
          node_id(nid),
          subgroup_id(subgroup_id),
          subgroup_index(subgroup_index),
          shard_num(shard_num),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invocable_class(user_object_ptr.get(),
                                                                     type_id, subgroup_id,
                                                                     T::register_functions())),
          group(group) {
    if constexpr(std::is_base_of_v<GroupReference, T>) {
        (**user_object_ptr).set_group_pointers(group, subgroup_index);
    }
}

template <typename T>
Replicated<T>::Replicated(subgroup_type_id_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                          uint32_t subgroup_index, uint32_t shard_num,
                          rpc::RPCManager& group_rpc_manager, _Group* group)
        : persistent_registry_ptr(std::make_unique<persistent::PersistentRegistry>(
                  this, std::type_index(typeid(T)), subgroup_index, shard_num)),
          user_object_ptr(std::make_unique<std::unique_ptr<T>>(nullptr)),
          node_id(nid),
          subgroup_id(subgroup_id),
          subgroup_index(subgroup_index),
          shard_num(shard_num),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invocable_class(user_object_ptr.get(),
                                                                     type_id, subgroup_id,
                                                                     T::register_functions())),
          group(group) {}

template <typename T>
Replicated<T>::Replicated(Replicated&& rhs) : persistent_registry_ptr(std::move(rhs.persistent_registry_ptr)),
                                              user_object_ptr(std::move(rhs.user_object_ptr)),
                                              node_id(rhs.node_id),
                                              subgroup_id(rhs.subgroup_id),
                                              subgroup_index(rhs.subgroup_index),
                                              shard_num(rhs.shard_num),
                                              group_rpc_manager(rhs.group_rpc_manager),
                                              wrapped_this(std::move(rhs.wrapped_this)),
                                              group(rhs.group) {
    persistent_registry_ptr->updateTemporalFrontierProvider(this);
}

template <typename T>
Replicated<T>::~Replicated() {
    // hack to check if the object was merely moved
    if(wrapped_this) {
        group_rpc_manager.destroy_remote_invocable_class(subgroup_id);
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto Replicated<T>::p2p_send(node_id_t dest_node, Args&&... args) {
    if(is_valid()) {
        assert(dest_node != node_id);
        if(group_rpc_manager.view_manager.get_current_view().get().rank_of(dest_node) == -1) {
            throw invalid_node_exception("Cannot send a p2p request to node "
                    + std::to_string(dest_node) + ": it is not a member of the Group.");
        }
        auto return_pair = wrapped_this->template send<tag>(
                [this, &dest_node](size_t size) -> char* {
                    const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
                    if(size <= max_payload_size) {
                        return (char*)group_rpc_manager.get_sendbuffer_ptr(dest_node,
                                                                           sst::REQUEST_TYPE::P2P_REQUEST);
                    } else {
                        return nullptr;
                    }
                },
                std::forward<Args>(args)...);
        group_rpc_manager.finish_p2p_send(dest_node, subgroup_id, return_pair.pending);
        return std::move(return_pair.results);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto Replicated<T>::ordered_send(Args&&... args) {
    if(is_valid()) {
        size_t payload_size_for_multicast_send = wrapped_this->template get_size_for_ordered_send<tag>(std::forward<Args>(args)...);

        using Ret = typename std::remove_pointer<decltype(wrapped_this->template getReturnType<tag>(
                std::forward<Args>(args)...))>::type;
        rpc::QueryResults<Ret>* results_ptr;
        rpc::PendingResults<Ret>* pending_ptr;
        auto serializer = [&](char* buffer) {
            //By the time this lambda runs, the current thread will be holding a read lock on view_mutex
            const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
            auto send_return_struct = wrapped_this->template send<tag>(
                    [&buffer, &max_payload_size](size_t size) -> char* {
                        if(size <= max_payload_size) {
                            return buffer;
                        } else {
                            return nullptr;
                        }
                    },
                    std::forward<Args>(args)...);
            results_ptr = new rpc::QueryResults<Ret>(std::move(send_return_struct.results));
            pending_ptr = &send_return_struct.pending;
        };

        std::shared_lock<std::shared_timed_mutex> view_read_lock(group_rpc_manager.view_manager.view_mutex);
        group_rpc_manager.view_manager.view_change_cv.wait(view_read_lock, [&]() {
            return group_rpc_manager.view_manager.curr_view
                    ->multicast_group->send(subgroup_id, payload_size_for_multicast_send, serializer, true);
        });
        group_rpc_manager.finish_rpc_send(subgroup_id, *pending_ptr);
        return std::move(*results_ptr);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
void Replicated<T>::send(unsigned long long int payload_size,
                         const std::function<void(char* buf)>& msg_generator) {
    group_rpc_manager.view_manager.send(subgroup_id, payload_size, msg_generator);
}

template <typename T>
std::size_t Replicated<T>::object_size() const {
    return mutils::bytes_size(**user_object_ptr);
}

template <typename T>
void Replicated<T>::send_object(tcp::socket& receiver_socket) const {
    auto bind_socket_write = [&receiver_socket](const char* bytes, std::size_t size) {
        receiver_socket.write(bytes, size);
    };
    mutils::post_object(bind_socket_write, object_size());
    send_object_raw(receiver_socket);
}

template <typename T>
void Replicated<T>::send_object_raw(tcp::socket& receiver_socket) const {
    auto bind_socket_write = [&receiver_socket](const char* bytes, std::size_t size) {
        receiver_socket.write(bytes, size);
    };
    mutils::post_object(bind_socket_write, **user_object_ptr);
}

template <typename T>
std::size_t Replicated<T>::receive_object(char* buffer) {
    // *user_object_ptr = std::move(mutils::from_bytes<T>(&group_rpc_manager.dsm, buffer));
    mutils::RemoteDeserialization_v rdv{group_rpc_manager.rdv};
    rdv.insert(rdv.begin(), persistent_registry_ptr.get());
    mutils::DeserializationManager dsm{rdv};
    *user_object_ptr = std::move(mutils::from_bytes<T>(&dsm, buffer));
    if constexpr(std::is_base_of_v<GroupReference, T>) {
        (**user_object_ptr).set_group_pointers(group, subgroup_index);
    }
    return mutils::bytes_size(**user_object_ptr);
}

template <typename T>
void Replicated<T>::persist(const persistent::version_t version) noexcept(false) {
    persistent::version_t persisted_ver;

    // persist variables
    do {
        persisted_ver = persistent_registry_ptr->persist();
        if(persisted_ver == -1) {
            // for replicated<T> without Persistent fields,
            // tell the persistent thread that we are done.
            persisted_ver = version;
        }
    } while(persisted_ver < version);
};

template <typename T>
const persistent::version_t Replicated<T>::get_minimum_latest_persisted_version() noexcept(false) {
    return persistent_registry_ptr->getMinimumLatestPersistedVersion();
}

template <typename T>
const uint64_t Replicated<T>::compute_global_stability_frontier() {
    return group_rpc_manager.view_manager.compute_global_stability_frontier(subgroup_id);
}

template <typename T>
ExternalCaller<T>::ExternalCaller(uint32_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                                  rpc::RPCManager& group_rpc_manager)
        : node_id(nid),
          subgroup_id(subgroup_id),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invoker<T>(type_id, subgroup_id,
                                                                T::register_functions())) {}

//This is literally copied and pasted from Replicated<T>. I wish I could let them share code with inheritance,
//but I'm afraid that will introduce unnecessary overheads.
template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto ExternalCaller<T>::p2p_send(node_id_t dest_node, Args&&... args) {
    if(is_valid()) {
        assert(dest_node != node_id);
        if(group_rpc_manager.view_manager.get_current_view().get().rank_of(dest_node) == -1) {
            throw invalid_node_exception("Cannot send a p2p request to node "
                    + std::to_string(dest_node) + ": it is not a member of the Group.");
        }
        auto return_pair = wrapped_this->template send<tag>(
                [this, &dest_node](size_t size) -> char* {
                    const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
                    if(size <= max_payload_size) {
                        return (char*)group_rpc_manager.get_sendbuffer_ptr(dest_node,
                                                                           sst::REQUEST_TYPE::P2P_REQUEST);
                    } else {
                        return nullptr;
                    }
                },
                std::forward<Args>(args)...);
        group_rpc_manager.finish_p2p_send(dest_node, subgroup_id, return_pair.pending);
        return std::move(return_pair.results);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto ShardIterator<T>::p2p_send(Args&&... args) {
    // shard_reps should have at least one member
    auto send_result = EC.template p2p_send<tag>(shard_reps.at(0), std::forward<Args>(args)...);
    std::vector<decltype(send_result)> send_result_vec;
    send_result_vec.emplace_back(std::move(send_result));
    for(uint i = 1; i < shard_reps.size(); ++i) {
        send_result_vec.emplace_back(EC.template p2p_send<tag>(shard_reps[i], std::forward<Args>(args)...));
    }
    return send_result_vec;
}

}  // namespace derecho
<commit_msg>throw exception if serialized data exceeds the maximum message size.<commit_after>#pragma once

#include <functional>
#include <mutex>
#include <utility>

#include "../replicated.hpp"

#include <derecho/mutils-serialization/SerializationSupport.hpp>

namespace derecho {

template <typename T>
Replicated<T>::Replicated(subgroup_type_id_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                          uint32_t subgroup_index, uint32_t shard_num,
                          rpc::RPCManager& group_rpc_manager, Factory<T> client_object_factory,
                          _Group* group)
        : persistent_registry_ptr(std::make_unique<persistent::PersistentRegistry>(
                  this, std::type_index(typeid(T)), subgroup_index, shard_num)),
          user_object_ptr(std::make_unique<std::unique_ptr<T>>(
                  client_object_factory(persistent_registry_ptr.get()))),
          node_id(nid),
          subgroup_id(subgroup_id),
          subgroup_index(subgroup_index),
          shard_num(shard_num),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invocable_class(user_object_ptr.get(),
                                                                     type_id, subgroup_id,
                                                                     T::register_functions())),
          group(group) {
    if constexpr(std::is_base_of_v<GroupReference, T>) {
        (**user_object_ptr).set_group_pointers(group, subgroup_index);
    }
}

template <typename T>
Replicated<T>::Replicated(subgroup_type_id_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                          uint32_t subgroup_index, uint32_t shard_num,
                          rpc::RPCManager& group_rpc_manager, _Group* group)
        : persistent_registry_ptr(std::make_unique<persistent::PersistentRegistry>(
                  this, std::type_index(typeid(T)), subgroup_index, shard_num)),
          user_object_ptr(std::make_unique<std::unique_ptr<T>>(nullptr)),
          node_id(nid),
          subgroup_id(subgroup_id),
          subgroup_index(subgroup_index),
          shard_num(shard_num),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invocable_class(user_object_ptr.get(),
                                                                     type_id, subgroup_id,
                                                                     T::register_functions())),
          group(group) {}

template <typename T>
Replicated<T>::Replicated(Replicated&& rhs) : persistent_registry_ptr(std::move(rhs.persistent_registry_ptr)),
                                              user_object_ptr(std::move(rhs.user_object_ptr)),
                                              node_id(rhs.node_id),
                                              subgroup_id(rhs.subgroup_id),
                                              subgroup_index(rhs.subgroup_index),
                                              shard_num(rhs.shard_num),
                                              group_rpc_manager(rhs.group_rpc_manager),
                                              wrapped_this(std::move(rhs.wrapped_this)),
                                              group(rhs.group) {
    persistent_registry_ptr->updateTemporalFrontierProvider(this);
}

template <typename T>
Replicated<T>::~Replicated() {
    // hack to check if the object was merely moved
    if(wrapped_this) {
        group_rpc_manager.destroy_remote_invocable_class(subgroup_id);
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto Replicated<T>::p2p_send(node_id_t dest_node, Args&&... args) {
    if(is_valid()) {
        assert(dest_node != node_id);
        if(group_rpc_manager.view_manager.get_current_view().get().rank_of(dest_node) == -1) {
            throw invalid_node_exception("Cannot send a p2p request to node "
                    + std::to_string(dest_node) + ": it is not a member of the Group.");
        }
        auto return_pair = wrapped_this->template send<tag>(
                [this, &dest_node](size_t size) -> char* {
                    const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
                    if(size <= max_payload_size) {
                        return (char*)group_rpc_manager.get_sendbuffer_ptr(dest_node,
                                                                           sst::REQUEST_TYPE::P2P_REQUEST);
                    } else {
                        throw derecho_exception("The size of serialized args exceeds the maximum message size.");
                    }
                },
                std::forward<Args>(args)...);
        group_rpc_manager.finish_p2p_send(dest_node, subgroup_id, return_pair.pending);
        return std::move(return_pair.results);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto Replicated<T>::ordered_send(Args&&... args) {
    if(is_valid()) {
        size_t payload_size_for_multicast_send = wrapped_this->template get_size_for_ordered_send<tag>(std::forward<Args>(args)...);

        using Ret = typename std::remove_pointer<decltype(wrapped_this->template getReturnType<tag>(
                std::forward<Args>(args)...))>::type;
        rpc::QueryResults<Ret>* results_ptr;
        rpc::PendingResults<Ret>* pending_ptr;
        auto serializer = [&](char* buffer) {
            //By the time this lambda runs, the current thread will be holding a read lock on view_mutex
            const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
            auto send_return_struct = wrapped_this->template send<tag>(
                    [&buffer, &max_payload_size](size_t size) -> char* {
                        if(size <= max_payload_size) {
                            return buffer;
                        } else {
                            throw derecho_exception("The size of serialized args exceeds the maximum message size.");
                        }
                    },
                    std::forward<Args>(args)...);
            results_ptr = new rpc::QueryResults<Ret>(std::move(send_return_struct.results));
            pending_ptr = &send_return_struct.pending;
        };

        std::shared_lock<std::shared_timed_mutex> view_read_lock(group_rpc_manager.view_manager.view_mutex);
        group_rpc_manager.view_manager.view_change_cv.wait(view_read_lock, [&]() {
            return group_rpc_manager.view_manager.curr_view
                    ->multicast_group->send(subgroup_id, payload_size_for_multicast_send, serializer, true);
        });
        group_rpc_manager.finish_rpc_send(subgroup_id, *pending_ptr);
        return std::move(*results_ptr);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
void Replicated<T>::send(unsigned long long int payload_size,
                         const std::function<void(char* buf)>& msg_generator) {
    group_rpc_manager.view_manager.send(subgroup_id, payload_size, msg_generator);
}

template <typename T>
std::size_t Replicated<T>::object_size() const {
    return mutils::bytes_size(**user_object_ptr);
}

template <typename T>
void Replicated<T>::send_object(tcp::socket& receiver_socket) const {
    auto bind_socket_write = [&receiver_socket](const char* bytes, std::size_t size) {
        receiver_socket.write(bytes, size);
    };
    mutils::post_object(bind_socket_write, object_size());
    send_object_raw(receiver_socket);
}

template <typename T>
void Replicated<T>::send_object_raw(tcp::socket& receiver_socket) const {
    auto bind_socket_write = [&receiver_socket](const char* bytes, std::size_t size) {
        receiver_socket.write(bytes, size);
    };
    mutils::post_object(bind_socket_write, **user_object_ptr);
}

template <typename T>
std::size_t Replicated<T>::receive_object(char* buffer) {
    // *user_object_ptr = std::move(mutils::from_bytes<T>(&group_rpc_manager.dsm, buffer));
    mutils::RemoteDeserialization_v rdv{group_rpc_manager.rdv};
    rdv.insert(rdv.begin(), persistent_registry_ptr.get());
    mutils::DeserializationManager dsm{rdv};
    *user_object_ptr = std::move(mutils::from_bytes<T>(&dsm, buffer));
    if constexpr(std::is_base_of_v<GroupReference, T>) {
        (**user_object_ptr).set_group_pointers(group, subgroup_index);
    }
    return mutils::bytes_size(**user_object_ptr);
}

template <typename T>
void Replicated<T>::persist(const persistent::version_t version) noexcept(false) {
    persistent::version_t persisted_ver;

    // persist variables
    do {
        persisted_ver = persistent_registry_ptr->persist();
        if(persisted_ver == -1) {
            // for replicated<T> without Persistent fields,
            // tell the persistent thread that we are done.
            persisted_ver = version;
        }
    } while(persisted_ver < version);
};

template <typename T>
const persistent::version_t Replicated<T>::get_minimum_latest_persisted_version() noexcept(false) {
    return persistent_registry_ptr->getMinimumLatestPersistedVersion();
}

template <typename T>
const uint64_t Replicated<T>::compute_global_stability_frontier() {
    return group_rpc_manager.view_manager.compute_global_stability_frontier(subgroup_id);
}

template <typename T>
ExternalCaller<T>::ExternalCaller(uint32_t type_id, node_id_t nid, subgroup_id_t subgroup_id,
                                  rpc::RPCManager& group_rpc_manager)
        : node_id(nid),
          subgroup_id(subgroup_id),
          group_rpc_manager(group_rpc_manager),
          wrapped_this(group_rpc_manager.make_remote_invoker<T>(type_id, subgroup_id,
                                                                T::register_functions())) {}

//This is literally copied and pasted from Replicated<T>. I wish I could let them share code with inheritance,
//but I'm afraid that will introduce unnecessary overheads.
template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto ExternalCaller<T>::p2p_send(node_id_t dest_node, Args&&... args) {
    if(is_valid()) {
        assert(dest_node != node_id);
        if(group_rpc_manager.view_manager.get_current_view().get().rank_of(dest_node) == -1) {
            throw invalid_node_exception("Cannot send a p2p request to node "
                    + std::to_string(dest_node) + ": it is not a member of the Group.");
        }
        auto return_pair = wrapped_this->template send<tag>(
                [this, &dest_node](size_t size) -> char* {
                    const std::size_t max_payload_size = group_rpc_manager.view_manager.get_max_payload_sizes().at(subgroup_id);
                    if(size <= max_payload_size) {
                        return (char*)group_rpc_manager.get_sendbuffer_ptr(dest_node,
                                                                           sst::REQUEST_TYPE::P2P_REQUEST);
                    } else {
                        throw derecho_exception("The size of serialized args exceeds the maximum message size.");
                    }
                },
                std::forward<Args>(args)...);
        group_rpc_manager.finish_p2p_send(dest_node, subgroup_id, return_pair.pending);
        return std::move(return_pair.results);
    } else {
        throw empty_reference_exception{"Attempted to use an empty Replicated<T>"};
    }
}

template <typename T>
template <rpc::FunctionTag tag, typename... Args>
auto ShardIterator<T>::p2p_send(Args&&... args) {
    // shard_reps should have at least one member
    auto send_result = EC.template p2p_send<tag>(shard_reps.at(0), std::forward<Args>(args)...);
    std::vector<decltype(send_result)> send_result_vec;
    send_result_vec.emplace_back(std::move(send_result));
    for(uint i = 1; i < shard_reps.size(); ++i) {
        send_result_vec.emplace_back(EC.template p2p_send<tag>(shard_reps[i], std::forward<Args>(args)...));
    }
    return send_result_vec;
}

}  // namespace derecho
<|endoftext|>


<commit_before>/**
 * These codes are licensed under the Unlicense.
 * http://unlicense.org
 */

#ifndef FURFURYLIC_GUARD_D53E08F9_CF1C_4762_BF77_1A6FB68C6A96
#define FURFURYLIC_GUARD_D53E08F9_CF1C_4762_BF77_1A6FB68C6A96

#include <ios>
#include <cstddef>
#include <streambuf>
#include <string>
#include <vector>

#include "csv_error.hpp"
#include "key_chars.hpp"

namespace furfurylic {
namespace commata {

class record_extraction_error :
    public csv_error
{
public:
    explicit record_extraction_error(std::string what_arg) :
        csv_error(std::move(what_arg))
    {}
};

template <class FieldNamePred, class FieldValuePred,
    class Ch, class Tr = std::char_traits<Ch>>
class record_extractor
{
    enum class record_mode
    {
        unknown,
        include,
        exclude
    };

    static const std::size_t npos = static_cast<std::size_t>(-1);

    std::basic_streambuf<Ch, Tr>* out_;
    FieldNamePred field_name_pred_;
    FieldValuePred field_value_pred_;
    bool includes_header_;

    std::size_t record_num_to_include_;
    bool header_yet_;
    std::size_t field_index_;
    std::size_t target_field_index_;
    record_mode record_mode_;

    const Ch* record_begin_;
    std::basic_string<Ch, Tr> field_buffer_;
    std::vector<Ch> record_buffer_;

public:
    record_extractor(
        std::basic_streambuf<Ch, Tr>& out,
        FieldNamePred field_name_pred, FieldValuePred field_value_pred,
        bool includes_header,
        std::size_t max_record_num) :
        out_(&out),
        field_name_pred_(std::move(field_name_pred)),
        field_value_pred_(std::move(field_value_pred)),
        includes_header_(includes_header), record_num_to_include_(max_record_num),
        header_yet_(true), field_index_(0), target_field_index_(npos)
    {}

    record_extractor(record_extractor&&) = default;
    record_extractor& operator=(record_extractor&&) = default;

    void start_buffer(const Ch* buffer_begin)
    {
        record_begin_ = buffer_begin;
    }

    void end_buffer(const Ch* buffer_end)
    {
        if (record_mode_ != record_mode::exclude) {
            record_buffer_.insert(record_buffer_.cend(), record_begin_, buffer_end);
        }
    }

    void start_record(const Ch* row_begin)
    {
        record_begin_ = row_begin;
        if (header_yet_) {
            record_mode_ = includes_header_ ?
                record_mode::include : record_mode::exclude;
        } else {
            record_mode_ = record_mode::unknown;
        }
        field_index_ = 0;
        record_buffer_.clear();
    }

    bool update(const Ch* first, const Ch* last)
    {
        if (header_yet_) {
            if (target_field_index_ == npos) {
                field_buffer_.append(first, last);
            }
        } else if (field_index_ == target_field_index_) {
            field_buffer_.append(first, last);
        }
        return true;
    }

    bool finalize(const Ch* first, const Ch* last)
    {
        if (header_yet_) {
            if ((target_field_index_ == npos)
             && with_field_buffer_appended(first, last, field_name_pred_)) {
                target_field_index_ = field_index_;
            }
        } else if (field_index_ == target_field_index_) {
            if (with_field_buffer_appended(first, last, field_value_pred_)) {
                record_mode_ = record_mode::include;
            } else {
                record_mode_ = record_mode::exclude;
                record_buffer_.clear();
            }
        }
        ++field_index_;
        return true;
    }

    bool end_record(const Ch* end)
    {
        if (header_yet_ && (target_field_index_ == npos)) {
            throw record_extraction_error("No matching field found");
        }
        if (record_mode_ == record_mode::include) {
            (*out_).sputn(record_buffer_.data(), record_buffer_.size());
            (*out_).sputn(record_begin_, end - record_begin_);
            (*out_).sputc(detail::key_chars<Ch>::LF);
            if ((record_num_to_include_ < std::numeric_limits<std::size_t>::max())
             && !header_yet_) {
                if (record_num_to_include_ == 1) {
                    return false;
                }
                --record_num_to_include_;
            }
            record_mode_ = record_mode::exclude;
        }
        header_yet_ = false;
        return true;
    }

private:
    template <class F>
    auto with_field_buffer_appended(const Ch* first, const Ch* last, F& f)
      -> decltype(f(nullptr, nullptr))
    {
        if (field_buffer_.empty()) {
            return f(first, last);
        } else {
            field_buffer_.append(first, last);
            const auto r = f(
                field_buffer_.data(), field_buffer_.data() + field_buffer_.size());
            field_buffer_.clear();
            return r;
        }
    }
};

namespace detail {

template <class Ch, class Tr>
class string_eq
{
    std::basic_string<Ch, Tr> s_;

public:
    explicit string_eq(std::basic_string<Ch, Tr>&& s) :
        s_(std::move(s))
    {}

    bool operator()(const Ch* begin, const Ch* end) const
    {
        const auto rlen = static_cast<decltype(s_.size())>(end - begin);
        return (s_.size() == rlen) && (Tr::compare(s_.data(), begin, rlen) == 0);
    }
};

template <class Ch, class Tr, class T>
auto forward_as_string_pred(T&& t)
  -> typename std::enable_if<
        std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        string_eq<Ch, Tr>>::type
{
    return string_eq<Ch, Tr>(std::forward<T>(t));
}

template <class Ch, class Tr, class T>
auto forward_as_string_pred(T&& t)
  -> typename std::enable_if<
        !std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        T&&>::type
{
    return std::forward<T>(t);
}

template <class Ch, class Tr, class T>
using string_pred =
    typename std::conditional<
        std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        string_eq<Ch, Tr>,
        typename std::remove_reference<T>::type>::type;

template <class FieldNamePredF, class FieldValuePredF, class Ch, class Tr>
using record_extractor_from =
    record_extractor<
        string_pred<Ch, Tr, FieldNamePredF>,
        string_pred<Ch, Tr, FieldValuePredF>,
        Ch, Tr>;

} // end namespace detail

template <class FieldNamePredF, class FieldValuePredF, class Ch, class Tr>
detail::record_extractor_from<FieldNamePredF, FieldValuePredF, Ch, Tr>
make_record_extractor(
    std::basic_streambuf<Ch, Tr>& out,
    FieldNamePredF&& field_name_pred,
    FieldValuePredF&& field_value_pred,
    bool includes_header = true,
    std::size_t max_record_num = static_cast<std::size_t>(-1))
{
    return detail::record_extractor_from<FieldNamePredF, FieldValuePredF, Ch, Tr>(
        out,
        detail::forward_as_string_pred<Ch, Tr>(
            std::forward<FieldNamePredF>(field_name_pred)),
        detail::forward_as_string_pred<Ch, Tr>(
            std::forward<FieldValuePredF>(field_value_pred)),
        includes_header, max_record_num);
}

}}

#endif
<commit_msg>Refactor record_extractor.hpp<commit_after>/**
 * These codes are licensed under the Unlicense.
 * http://unlicense.org
 */

#ifndef FURFURYLIC_GUARD_D53E08F9_CF1C_4762_BF77_1A6FB68C6A96
#define FURFURYLIC_GUARD_D53E08F9_CF1C_4762_BF77_1A6FB68C6A96

#include <ios>
#include <cstddef>
#include <cstdint>
#include <streambuf>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "csv_error.hpp"
#include "key_chars.hpp"

namespace furfurylic {
namespace commata {

class record_extraction_error :
    public csv_error
{
public:
    explicit record_extraction_error(std::string what_arg) :
        csv_error(std::move(what_arg))
    {}
};

template <class FieldNamePred, class FieldValuePred,
    class Ch, class Tr = std::char_traits<Ch>>
class record_extractor
{
    enum class record_mode : std::int_fast8_t
    {
        unknown,
        include,
        exclude
    };

    static const std::size_t npos = static_cast<std::size_t>(-1);

    FieldNamePred field_name_pred_;
    FieldValuePred field_value_pred_;

    record_mode header_mode_;
    record_mode record_mode_;

    std::size_t record_num_to_include_;
    std::size_t target_field_index_;

    std::size_t field_index_;
    const Ch* record_begin_;
    std::basic_streambuf<Ch, Tr>* out_;
    std::vector<Ch> field_buffer_;
    std::vector<Ch> record_buffer_;

public:
    record_extractor(
        std::basic_streambuf<Ch, Tr>& out,
        FieldNamePred field_name_pred, FieldValuePred field_value_pred,
        bool includes_header, std::size_t max_record_num) :
        field_name_pred_(std::move(field_name_pred)),
        field_value_pred_(std::move(field_value_pred)),
        header_mode_(includes_header ?
            record_mode::include : record_mode::exclude),
        record_num_to_include_(max_record_num), target_field_index_(npos),
        field_index_(0), out_(&out)
    {}

    record_extractor(record_extractor&&) = default;
    record_extractor& operator=(record_extractor&&) = default;

    void start_buffer(const Ch* buffer_begin)
    {
        record_begin_ = buffer_begin;
    }

    void end_buffer(const Ch* buffer_end)
    {
        if (record_mode_ != record_mode::exclude) {
            record_buffer_.insert(record_buffer_.cend(), record_begin_, buffer_end);
        }
    }

    void start_record(const Ch* record_begin)
    {
        record_begin_ = record_begin;
        record_mode_ = header_yet() ? header_mode_ : record_mode::unknown;
        field_index_ = 0;
        record_buffer_.clear();
    }

    bool update(const Ch* first, const Ch* last)
    {
        if ((header_yet() && (target_field_index_ == npos))
         || (field_index_ == target_field_index_)) {
            field_buffer_.insert(field_buffer_.cend(), first, last);
        }
        return true;
    }

    bool finalize(const Ch* first, const Ch* last)
    {
        if (header_yet()) {
            if ((target_field_index_ == npos)
             && with_field_buffer_appended(first, last, field_name_pred_)) {
                target_field_index_ = field_index_;
            }
        } else if (field_index_ == target_field_index_) {
            if (with_field_buffer_appended(first, last, field_value_pred_)) {
                record_mode_ = record_mode::include;
            } else {
                record_mode_ = record_mode::exclude;
                record_buffer_.clear();
            }
        }
        ++field_index_;
        return true;
    }

    bool end_record(const Ch* record_end)
    {
        if (header_yet() && (target_field_index_ == npos)) {
            throw record_extraction_error("No matching field found");
        }
        if (record_mode_ == record_mode::include) {
            if (!record_buffer_.empty()) {
                out_->sputn(record_buffer_.data(), record_buffer_.size());
            }
            out_->sputn(record_begin_, record_end - record_begin_);
            out_->sputc(detail::key_chars<Ch>::LF);
            if (!header_yet()
             && (record_num_to_include_ < static_cast<std::size_t>(-1))) {
                if (record_num_to_include_ == 1) {
                    return false;
                }
                --record_num_to_include_;
            }
            record_mode_ = record_mode::exclude; // to prevent end_buffer
                                                 // from doing anything
        }
        header_mode_ = record_mode::unknown;
        return true;
    }

private:
    bool header_yet() const
    {
        return header_mode_ != record_mode::unknown;
    }

    template <class F>
    auto with_field_buffer_appended(const Ch* first, const Ch* last, F& f)
      -> decltype(f(nullptr, nullptr))
    {
        if (field_buffer_.empty()) {
            return f(first, last);
        } else {
            field_buffer_.insert(field_buffer_.cend(), first, last);
            const auto r = f(
                field_buffer_.data(),
                field_buffer_.data() + field_buffer_.size());
            field_buffer_.clear();
            return r;
        }
    }
};

namespace detail {

template <class Ch, class Tr>
class string_eq
{
    std::basic_string<Ch, Tr> s_;

public:
    explicit string_eq(std::basic_string<Ch, Tr>&& s) :
        s_(std::move(s))
    {}

    bool operator()(const Ch* begin, const Ch* end) const
    {
        const auto rlen = static_cast<decltype(s_.size())>(end - begin);
        return (s_.size() == rlen)
            && (Tr::compare(s_.data(), begin, rlen) == 0);
    }
};

template <class Ch, class Tr, class T>
auto forward_as_string_pred(T&& t)
  -> typename std::enable_if<
        std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        string_eq<Ch, Tr>>::type
{
    return string_eq<Ch, Tr>(std::forward<T>(t));
}

template <class Ch, class Tr, class T>
auto forward_as_string_pred(T&& t)
  -> typename std::enable_if<
        !std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        T&&>::type
{
    return std::forward<T>(t);
}

template <class Ch, class Tr, class T>
using string_pred =
    typename std::conditional<
        std::is_constructible<std::basic_string<Ch, Tr>, T&&>::value,
        string_eq<Ch, Tr>,
        typename std::remove_reference<T>::type>::type;

template <class FieldNamePredF, class FieldValuePredF, class Ch, class Tr>
using record_extractor_from =
    record_extractor<
        string_pred<Ch, Tr, FieldNamePredF>,
        string_pred<Ch, Tr, FieldValuePredF>,
        Ch, Tr>;

} // end namespace detail

template <class FieldNamePredF, class FieldValuePredF, class Ch, class Tr>
detail::record_extractor_from<FieldNamePredF, FieldValuePredF, Ch, Tr>
make_record_extractor(
    std::basic_streambuf<Ch, Tr>& out,
    FieldNamePredF&& field_name_pred,
    FieldValuePredF&& field_value_pred,
    bool includes_header = true,
    std::size_t max_record_num = static_cast<std::size_t>(-1))
{
    return detail::record_extractor_from<
            FieldNamePredF, FieldValuePredF, Ch, Tr>(
        out,
        detail::forward_as_string_pred<Ch, Tr>(
            std::forward<FieldNamePredF>(field_name_pred)),
        detail::forward_as_string_pred<Ch, Tr>(
            std::forward<FieldValuePredF>(field_value_pred)),
        includes_header, max_record_num);
}

}}

#endif
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH
# define HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH

# include <sstream>
# include <hpp/model/device.hh>
# include <hpp/model/joint.hh>
# include <hpp/model/joint-configuration.hh>
# include <hpp/core/configuration-shooter.hh>

namespace hpp {
  namespace core {
    /// \addtogroup configuration_sampling
    /// \{

    /// Uniformly sample with bounds of degrees of freedom.
    class HPP_CORE_DLLAPI BasicConfigurationShooter :
      public ConfigurationShooter
    {
    public:
      static BasicConfigurationShooterPtr_t create (const DevicePtr_t& robot)
      {
	BasicConfigurationShooter* ptr = new BasicConfigurationShooter (robot);
	BasicConfigurationShooterPtr_t shPtr (ptr);
	ptr->init (shPtr);
	return shPtr;
      }
      virtual ConfigurationPtr_t shoot () const
      {
	JointVector_t jv = robot_->getJointVector ();
	ConfigurationPtr_t config (new Configuration_t (robot_->configSize ()));
	for (JointVector_t::const_iterator itJoint = jv.begin ();
	     itJoint != jv.end (); itJoint++) {
	  std::size_t rank = (*itJoint)->rankInConfiguration ();
	  (*itJoint)->configuration ()->uniformlySample (rank, *config);
	}
	// Shoot extra configuration variables
	size_type extraDim = robot_->extraConfigSpace ().dimension ();
	size_type offset = robot_->configSize () - extraDim;
	for (size_type i=0; i<extraDim; ++i) {
	  value_type lower = robot_->extraConfigSpace ().lower (i);
	  value_type upper = robot_->extraConfigSpace ().upper (i);
	  value_type range = upper - lower;
	  if ((range < 0) ||
	      (range == std::numeric_limits<double>::infinity())) {
	    std::ostringstream oss
	      ("Cannot uniformy sample extra config variable ");
	    oss << i << ". min = " << ", max = " << upper << std::endl;
	    throw std::runtime_error (oss.str ());
	  }
	  (*config) [offset + i] = lower + (upper - lower) * rand ()/RAND_MAX;
	}
	return config;
      }
    protected:
      /// Uniformly sample configuration space
      ///
      /// Note that translation joints have to be bounded.
      BasicConfigurationShooter (const DevicePtr_t& robot) : robot_ (robot)
      {
      }
      void init (const BasicConfigurationShooterPtr_t& self)
      {
	ConfigurationShooter::init (self);
	weak_ = self;
      }

    private:
      const DevicePtr_t& robot_;
      BasicConfigurationShooterWkPtr_t weak_;
    }; // class BasicConfigurationShooter
    /// \}
  } //   namespace core
} // namespace hpp

#endif // HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH
<commit_msg>Fix error message in BasicConfigurationShooter.<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux
//
// This file is part of hpp-core
// hpp-core is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH
# define HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH

# include <sstream>
# include <hpp/model/device.hh>
# include <hpp/model/joint.hh>
# include <hpp/model/joint-configuration.hh>
# include <hpp/core/configuration-shooter.hh>

namespace hpp {
  namespace core {
    /// \addtogroup configuration_sampling
    /// \{

    /// Uniformly sample with bounds of degrees of freedom.
    class HPP_CORE_DLLAPI BasicConfigurationShooter :
      public ConfigurationShooter
    {
    public:
      static BasicConfigurationShooterPtr_t create (const DevicePtr_t& robot)
      {
	BasicConfigurationShooter* ptr = new BasicConfigurationShooter (robot);
	BasicConfigurationShooterPtr_t shPtr (ptr);
	ptr->init (shPtr);
	return shPtr;
      }
      virtual ConfigurationPtr_t shoot () const
      {
	JointVector_t jv = robot_->getJointVector ();
	ConfigurationPtr_t config (new Configuration_t (robot_->configSize ()));
	for (JointVector_t::const_iterator itJoint = jv.begin ();
	     itJoint != jv.end (); itJoint++) {
	  std::size_t rank = (*itJoint)->rankInConfiguration ();
	  (*itJoint)->configuration ()->uniformlySample (rank, *config);
	}
	// Shoot extra configuration variables
	size_type extraDim = robot_->extraConfigSpace ().dimension ();
	size_type offset = robot_->configSize () - extraDim;
	for (size_type i=0; i<extraDim; ++i) {
	  value_type lower = robot_->extraConfigSpace ().lower (i);
	  value_type upper = robot_->extraConfigSpace ().upper (i);
	  value_type range = upper - lower;
	  if ((range < 0) ||
	      (range == std::numeric_limits<double>::infinity())) {
	    std::ostringstream oss
	      ("Cannot uniformy sample extra config variable ");
	    oss << i << ". min = " <<lower<< ", max = " << upper << std::endl;
	    throw std::runtime_error (oss.str ());
	  }
	  (*config) [offset + i] = lower + (upper - lower) * rand ()/RAND_MAX;
	}
	return config;
      }
    protected:
      /// Uniformly sample configuration space
      ///
      /// Note that translation joints have to be bounded.
      BasicConfigurationShooter (const DevicePtr_t& robot) : robot_ (robot)
      {
      }
      void init (const BasicConfigurationShooterPtr_t& self)
      {
	ConfigurationShooter::init (self);
	weak_ = self;
      }

    private:
      const DevicePtr_t& robot_;
      BasicConfigurationShooterWkPtr_t weak_;
    }; // class BasicConfigurationShooter
    /// \}
  } //   namespace core
} // namespace hpp

#endif // HPP_CORE_BASIC_CONFIGURATION_SHOOTER_HH
<|endoftext|>


<commit_before>//----------------------------  solver.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  solver.cc  ---------------------------

#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include "testmatrix.h"
#include <base/logstream.h>
#include <lac/sparse_matrix.h>
#include <lac/vector.h>
#include <lac/vector_memory.h>
#include <lac/solver_control.h>
#include <lac/solver_cg.h>
#include <lac/solver_gmres.h>
#include <lac/solver_bicgstab.h>
#include <lac/solver_richardson.h>
#include <lac/solver_qmrs.h>
#include <lac/precondition.h>

template<class SOLVER, class MATRIX, class VECTOR, class PRECONDITION>
void
check_method( SOLVER& solver, const MATRIX& A,
	     VECTOR& u, VECTOR& f, const PRECONDITION& P)
{
  u = 0.;
  f = 1.;
  try
    {
      solver.solve(A,u,f,P);
    }
  catch (std::exception& e)
    {
      deallog << e.what() << std::endl;
    }
}

int main()
{
  std::ofstream logfile("solver.output");
//  logfile.setf(std::ios::fixed);
  logfile.precision(4);
  deallog.attach(logfile);
  deallog.depth_console(0);

  GrowingVectorMemory<> mem;
  SolverControl control(100, 1.e-3);
  SolverControl verbose_control(100, 1.e-3, true);
  SolverCG<> cg(control, mem);
  SolverGMRES<> gmres(control, mem, 8);
  SolverBicgstab<> bicgstab(control, mem);
  SolverRichardson<> rich(control, mem);
  SolverQMRS<> qmrs(control, mem);

  for (unsigned int size=4; size <= 30; size *= 3)
    {
      unsigned int dim = (size-1)*(size-1);

      deallog << "Size " << size << " Unknowns " << dim << std::endl;

				       // Make matrix
      FDMatrix testproblem(size, size);
      SparsityPattern structure(dim, dim, 5);
      testproblem.five_point_structure(structure);
      structure.compress();
      SparseMatrix<double>  A(structure);
      testproblem.five_point(A);

      PreconditionIdentity prec_no;
      PreconditionSOR<> prec_sor;
      prec_sor.initialize(A, 1.2);
      PreconditionSSOR<> prec_ssor;
      prec_ssor.initialize(A, 1.2);

      Vector<double>  f(dim);
      Vector<double>  u(dim);
      Vector<double> res(dim);

      f = 1.;
      u = 1.;

      A.residual(res,u,f);
      A.SOR(res);
      res.add(1.,u);
      A.SOR_step(u,f);
      res.add(-1.,u);

      deallog << "SOR-diff:" << res*res << std::endl;

      try
	{
	  deallog.push("no-fail");

	  control.set_max_steps(10);
	  check_method(cg,A,u,f,prec_no);
	  check_method(bicgstab,A,u,f,prec_no);
	  check_method(gmres,A,u,f,prec_no);
	  check_method(qmrs,A,u,f,prec_no);
	  control.set_max_steps(100);

	  deallog.pop();

	  deallog.push("no");

	  check_method(cg,A,u,f,prec_no);
	  check_method(bicgstab,A,u,f,prec_no);
	  check_method(gmres,A,u,f,prec_no);
	  check_method(qmrs,A,u,f,prec_no);

	  deallog.pop();

	  deallog.push("ssor");

	  check_method(rich,A,u,f,prec_ssor);
	  check_method(cg,A,u,f,prec_ssor);
	  check_method(bicgstab,A,u,f,prec_ssor);
	  check_method(gmres,A,u,f,prec_ssor);
	  check_method(qmrs,A,u,f,prec_ssor);

	  deallog.pop();

	  deallog.push("sor");

	  check_method(rich,A,u,f,prec_sor);
	  check_method(cg,A,u,f,prec_sor);
	  check_method(bicgstab,A,u,f,prec_sor);
	  check_method(gmres,A,u,f,prec_sor);

	  deallog.pop();
	}
      catch (std::exception& e)
	{
	  std::cerr << e.what() << std::endl;
	}
    };
}

<commit_msg>add test for PreconditionPSOR<commit_after>//----------------------------  solver.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  solver.cc  ---------------------------

#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include "testmatrix.h"
#include <base/logstream.h>
#include <lac/sparse_matrix.h>
#include <lac/vector.h>
#include <lac/vector_memory.h>
#include <lac/solver_control.h>
#include <lac/solver_cg.h>
#include <lac/solver_gmres.h>
#include <lac/solver_bicgstab.h>
#include <lac/solver_richardson.h>
#include <lac/solver_qmrs.h>
#include <lac/precondition.h>

template<class SOLVER, class MATRIX, class VECTOR, class PRECONDITION>
void
check_method( SOLVER& solver, const MATRIX& A,
	     VECTOR& u, VECTOR& f, const PRECONDITION& P)
{
  u = 0.;
  f = 1.;
  try
    {
      solver.solve(A,u,f,P);
    }
  catch (std::exception& e)
    {
      deallog << e.what() << std::endl;
    }
}

int main()
{
  std::ofstream logfile("solver.output");
//  logfile.setf(std::ios::fixed);
  logfile.precision(4);
  deallog.attach(logfile);
  deallog.depth_console(0);

  GrowingVectorMemory<> mem;
  SolverControl control(100, 1.e-3);
  SolverControl verbose_control(100, 1.e-3, true);
  SolverCG<> cg(control, mem);
  SolverGMRES<> gmres(control, mem, 8);
  SolverBicgstab<> bicgstab(control, mem);
  SolverRichardson<> rich(control, mem);
  SolverQMRS<> qmrs(control, mem);

  for (unsigned int size=4; size <= 30; size *= 3)
    {
      unsigned int dim = (size-1)*(size-1);

      deallog << "Size " << size << " Unknowns " << dim << std::endl;

				       // Make matrix
      FDMatrix testproblem(size, size);
      SparsityPattern structure(dim, dim, 5);
      testproblem.five_point_structure(structure);
      structure.compress();
      SparseMatrix<double>  A(structure);
      testproblem.five_point(A);

      PreconditionIdentity prec_no;
      PreconditionSOR<> prec_sor;
      prec_sor.initialize(A, 1.2);
      PreconditionSSOR<> prec_ssor;
      prec_ssor.initialize(A, 1.2);

      std::vector<unsigned int> permutation(dim);
      for (unsigned int i=0;i<dim;++i)
	permutation(i) = dim-i-1;

      PreconditionPSOR<> prec_psor;
      prec_psor.initialize(A, permutation, 1.2);

      Vector<double>  f(dim);
      Vector<double>  u(dim);
      Vector<double> res(dim);

      f = 1.;
      u = 1.;

      A.residual(res,u,f);
      A.SOR(res);
      res.add(1.,u);
      A.SOR_step(u,f);
      res.add(-1.,u);

      deallog << "SOR-diff:" << res*res << std::endl;

      try
	{
	  deallog.push("no-fail");

	  control.set_max_steps(10);
	  check_method(cg,A,u,f,prec_no);
	  check_method(bicgstab,A,u,f,prec_no);
	  check_method(gmres,A,u,f,prec_no);
	  check_method(qmrs,A,u,f,prec_no);
	  control.set_max_steps(100);

	  deallog.pop();

	  deallog.push("no");

	  check_method(cg,A,u,f,prec_no);
	  check_method(bicgstab,A,u,f,prec_no);
	  check_method(gmres,A,u,f,prec_no);
	  check_method(qmrs,A,u,f,prec_no);

	  deallog.pop();

	  deallog.push("ssor");

	  check_method(rich,A,u,f,prec_ssor);
	  check_method(cg,A,u,f,prec_ssor);
	  check_method(bicgstab,A,u,f,prec_ssor);
	  check_method(gmres,A,u,f,prec_ssor);
	  check_method(qmrs,A,u,f,prec_ssor);

	  deallog.pop();

	  deallog.push("sor");

	  check_method(rich,A,u,f,prec_sor);
	  check_method(cg,A,u,f,prec_sor);
	  check_method(bicgstab,A,u,f,prec_sor);
	  check_method(gmres,A,u,f,prec_sor);

	  deallog.push("psor");

	  check_method(rich,A,u,f,prec_psor);
	  check_method(cg,A,u,f,prec_psor);
	  check_method(bicgstab,A,u,f,prec_psor);
	  check_method(gmres,A,u,f,prec_psor);

	  deallog.pop();
	}
      catch (std::exception& e)
	{
	  std::cerr << e.what() << std::endl;
	}
    };
}

<|endoftext|>


<commit_before>#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkStructuredGridReader.h"
#include "vtkStructuredGridOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkStructuredGridGeometryFilter.h"
#include "vtkLineSource.h"
#include "vtkStreamLine.h"
#include "vtkCamera.h"

#include "SaveImage.h"

void main( int argc, char *argv[] )
{
  float range[2];
  float maxVelocity, maxTime;

  vtkRenderer *aren = vtkRenderer::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
    renWin->AddRenderer(aren);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);
//
// Read data
//
  vtkStructuredGridReader *reader = vtkStructuredGridReader::New();
    //reader->DebugOn();
    reader->SetFileName("../../../vtkdata/kitchen.vtk");
    reader->Update(); //force a read to occur
    reader->GetOutput()->GetLength();

  if ( reader->GetOutput()->GetPointData()->GetScalars() )
    {
    reader->GetOutput()->GetPointData()->GetScalars()->GetRange(range);
    }
  if ( reader->GetOutput()->GetPointData()->GetVectors() )
    {
    maxVelocity = reader->GetOutput()->GetPointData()->GetVectors()->GetMaxNorm();
    maxTime = 35.0*reader->GetOutput()->GetLength()/maxVelocity ;
    }
//
// Outline around data
//
  vtkStructuredGridOutlineFilter *outlineF = vtkStructuredGridOutlineFilter::New();
    outlineF->SetInput(reader->GetOutput());
  vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
    outlineMapper->SetInput(outlineF->GetOutput());
  vtkActor *outline = vtkActor::New();
    outline->SetMapper(outlineMapper);
    outline->GetProperty()->SetColor(1,1,1);
//
// Set up shaded surfaces (i.e., supporting geometry)
//
  vtkStructuredGridGeometryFilter *doorGeom = vtkStructuredGridGeometryFilter::New();
    doorGeom->SetInput(reader->GetOutput());
    doorGeom->SetExtent(27,27,14,18,0,11);
  vtkPolyDataMapper *mapDoor = vtkPolyDataMapper::New();
    mapDoor->SetInput(doorGeom->GetOutput());
    mapDoor->ScalarVisibilityOff();
  vtkActor *door = vtkActor::New();
    door->SetMapper(mapDoor);
    door->GetProperty()->SetColor(.59,.427,.3);

  vtkStructuredGridGeometryFilter *window1Geom = vtkStructuredGridGeometryFilter::New();
    window1Geom->SetInput(reader->GetOutput());
    window1Geom->SetExtent(0,0,9,18,6,12);
  vtkPolyDataMapper *mapWindow1 = vtkPolyDataMapper::New();
    mapWindow1->SetInput(window1Geom->GetOutput());
    mapWindow1->ScalarVisibilityOff();
  vtkActor *window1 = vtkActor::New();
    window1->SetMapper(mapWindow1);
    window1->GetProperty()->SetColor(.3,.3,.5);

  vtkStructuredGridGeometryFilter *window2Geom = vtkStructuredGridGeometryFilter::New();
    window2Geom->SetInput(reader->GetOutput());
    window2Geom->SetExtent(5,12,23,23,6,12);
  vtkPolyDataMapper *mapWindow2 = vtkPolyDataMapper::New();
    mapWindow2->SetInput(window2Geom->GetOutput());
    mapWindow2->ScalarVisibilityOff();
  vtkActor *window2 = vtkActor::New();
    window2->SetMapper(mapWindow2);
    window2->GetProperty()->SetColor(.3,.3,.5);

  vtkStructuredGridGeometryFilter *klower1Geom = vtkStructuredGridGeometryFilter::New();
    klower1Geom->SetInput(reader->GetOutput());
    klower1Geom->SetExtent(17,17,0,11,0,6);
  vtkPolyDataMapper *mapKlower1 = vtkPolyDataMapper::New();
    mapKlower1->SetInput(klower1Geom->GetOutput());
    mapKlower1->ScalarVisibilityOff();
  vtkActor *klower1 = vtkActor::New();
    klower1->SetMapper(mapKlower1);
    klower1->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower2Geom = vtkStructuredGridGeometryFilter::New();
    klower2Geom->SetInput(reader->GetOutput());
    klower2Geom->SetExtent(19,19,0,11,0,6);
  vtkPolyDataMapper *mapKlower2 = vtkPolyDataMapper::New();
    mapKlower2->SetInput(klower2Geom->GetOutput());
    mapKlower2->ScalarVisibilityOff();
  vtkActor *klower2 = vtkActor::New();
    klower2->SetMapper(mapKlower2);
    klower2->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower3Geom = vtkStructuredGridGeometryFilter::New();
    klower3Geom->SetInput(reader->GetOutput());
    klower3Geom->SetExtent(17,19,0,0,0,6);
  vtkPolyDataMapper *mapKlower3 = vtkPolyDataMapper::New();
    mapKlower3->SetInput(klower3Geom->GetOutput());
    mapKlower3->ScalarVisibilityOff();
  vtkActor *klower3 = vtkActor::New();
    klower3->SetMapper(mapKlower3);
    klower3->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower4Geom = vtkStructuredGridGeometryFilter::New();
    klower4Geom->SetInput(reader->GetOutput());
    klower4Geom->SetExtent(17,19,11,11,0,6);
  vtkPolyDataMapper *mapKlower4 = vtkPolyDataMapper::New();
    mapKlower4->SetInput(klower4Geom->GetOutput());
    mapKlower4->ScalarVisibilityOff();
  vtkActor *klower4 = vtkActor::New();
    klower4->SetMapper(mapKlower4);
    klower4->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower5Geom = vtkStructuredGridGeometryFilter::New();
    klower5Geom->SetInput(reader->GetOutput());
    klower5Geom->SetExtent(17,19,0,11,0,0);
  vtkPolyDataMapper *mapKlower5 = vtkPolyDataMapper::New();
    mapKlower5->SetInput(klower5Geom->GetOutput());
    mapKlower5->ScalarVisibilityOff();
  vtkActor *klower5 = vtkActor::New();
    klower5->SetMapper(mapKlower5);
    klower5->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower6Geom = vtkStructuredGridGeometryFilter::New();
    klower6Geom->SetInput(reader->GetOutput());
    klower6Geom->SetExtent(17,19,0,7,6,6);
  vtkPolyDataMapper *mapKlower6 = vtkPolyDataMapper::New();
    mapKlower6->SetInput(klower6Geom->GetOutput());
    mapKlower6->ScalarVisibilityOff();
  vtkActor *klower6 = vtkActor::New();
    klower6->SetMapper(mapKlower6);
    klower6->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower7Geom = vtkStructuredGridGeometryFilter::New();
    klower7Geom->SetInput(reader->GetOutput());
    klower7Geom->SetExtent(17,19,9,11,6,6);
  vtkPolyDataMapper *mapKlower7 = vtkPolyDataMapper::New();
    mapKlower7->SetInput(klower7Geom->GetOutput());
    mapKlower7->ScalarVisibilityOff();
  vtkActor *klower7 = vtkActor::New();
    klower7->SetMapper(mapKlower7);
    klower7->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood1Geom = vtkStructuredGridGeometryFilter::New();
    hood1Geom->SetInput(reader->GetOutput());
    hood1Geom->SetExtent(17,17,0,11,11,16);
  vtkPolyDataMapper *mapHood1 = vtkPolyDataMapper::New();
    mapHood1->SetInput(hood1Geom->GetOutput());
    mapHood1->ScalarVisibilityOff();
  vtkActor *hood1 = vtkActor::New();
    hood1->SetMapper(mapHood1);
    hood1->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood2Geom = vtkStructuredGridGeometryFilter::New();
    hood2Geom->SetInput(reader->GetOutput());
    hood2Geom->SetExtent(19,19,0,11,11,16);
  vtkPolyDataMapper *mapHood2 = vtkPolyDataMapper::New();
    mapHood2->SetInput(hood2Geom->GetOutput());
    mapHood2->ScalarVisibilityOff();
  vtkActor *hood2 = vtkActor::New();
    hood2->SetMapper(mapHood2);
    hood2->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood3Geom = vtkStructuredGridGeometryFilter::New();
    hood3Geom->SetInput(reader->GetOutput());
    hood3Geom->SetExtent(17,19,0,0,11,16);
  vtkPolyDataMapper *mapHood3 = vtkPolyDataMapper::New();
    mapHood3->SetInput(hood3Geom->GetOutput());
    mapHood3->ScalarVisibilityOff();
  vtkActor *hood3 = vtkActor::New();
    hood3->SetMapper(mapHood3);
    hood3->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood4Geom = vtkStructuredGridGeometryFilter::New();
    hood4Geom->SetInput(reader->GetOutput());
    hood4Geom->SetExtent(17,19,11,11,11,16);
  vtkPolyDataMapper *mapHood4 = vtkPolyDataMapper::New();
    mapHood4->SetInput(hood4Geom->GetOutput());
    mapHood4->ScalarVisibilityOff();
  vtkActor *hood4 = vtkActor::New();
    hood4->SetMapper(mapHood4);
    hood4->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood6Geom = vtkStructuredGridGeometryFilter::New();
    hood6Geom->SetInput(reader->GetOutput());
    hood6Geom->SetExtent(17,19,0,11,16,16);
  vtkPolyDataMapper *mapHood6 = vtkPolyDataMapper::New();
    mapHood6->SetInput(hood6Geom->GetOutput());
    mapHood6->ScalarVisibilityOff();
  vtkActor *hood6 = vtkActor::New();
    hood6->SetMapper(mapHood6);
    hood6->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *cookingPlateGeom = vtkStructuredGridGeometryFilter::New();
    cookingPlateGeom->SetInput(reader->GetOutput());
    cookingPlateGeom->SetExtent(17,19,7,9,6,6);
  vtkPolyDataMapper *mapCookingPlate = vtkPolyDataMapper::New();
    mapCookingPlate->SetInput(cookingPlateGeom->GetOutput());
    mapCookingPlate->ScalarVisibilityOff();
  vtkActor *cookingPlate = vtkActor::New();
    cookingPlate->SetMapper(mapCookingPlate);
    cookingPlate->GetProperty()->SetColor(.9,.1,.1);

  vtkStructuredGridGeometryFilter *filterGeom = vtkStructuredGridGeometryFilter::New();
    filterGeom->SetInput(reader->GetOutput());
    filterGeom->SetExtent(17,19,7,9,11,11);
  vtkPolyDataMapper *mapFilter = vtkPolyDataMapper::New();
    mapFilter->SetInput(filterGeom->GetOutput());
    mapFilter->ScalarVisibilityOff();
  vtkActor *filter = vtkActor::New();
    filter->SetMapper(mapFilter);
    filter->GetProperty()->SetColor(.8,.6,.6);
//
// regular streamlines
//
  vtkLineSource *line = vtkLineSource::New();
    line->SetResolution(39);
    line->SetPoint1(0.08, 2.50, 0.71);
    line->SetPoint2(0.08, 4.50, 0.71);
  vtkPolyDataMapper *rakeMapper = vtkPolyDataMapper::New();
    rakeMapper->SetInput(line->GetOutput());
  vtkActor *rake = vtkActor::New();
    rake->SetMapper(rakeMapper);

  vtkStreamLine *streamers = vtkStreamLine::New();
    //streamers->DebugOn();
    streamers->SetInput(reader->GetOutput());
    streamers->SetSource(line->GetOutput());
    streamers->SetMaximumPropagationTime(maxTime);
    streamers->SetStepLength(maxTime/500.0);
    streamers->SetIntegrationStepLength(0.2);
    streamers->Update();
    //streamers->DebugOff();
  vtkPolyDataMapper *streamersMapper = vtkPolyDataMapper::New();
    streamersMapper->SetInput(streamers->GetOutput());
    streamersMapper->SetScalarRange(range);
//    streamersMapper->ScalarVisibilityOff();
  vtkActor *lines = vtkActor::New();
    lines->SetMapper(streamersMapper);
    lines->GetProperty()->SetColor(0,0,0);

  aren->AddActor(outline);
  aren->AddActor(door);
  aren->AddActor(window1);
  aren->AddActor(window2);
  aren->AddActor(klower1);
  aren->AddActor(klower2);
  aren->AddActor(klower3);
  aren->AddActor(klower4);
  aren->AddActor(klower5);
  aren->AddActor(klower6);
  aren->AddActor(klower7);
  aren->AddActor(hood1);
  aren->AddActor(hood2);
  aren->AddActor(hood3);
  aren->AddActor(hood4);
  aren->AddActor(hood6);
  aren->AddActor(cookingPlate);
  aren->AddActor(filter);
  aren->AddActor(lines);
  aren->AddActor(rake);

  aren->SetBackground(0.1, 0.2, 0.4);

  vtkCamera *aCamera = vtkCamera::New();
    aCamera->SetViewUp(0,1,0);
  aren->SetActiveCamera(aCamera);
  aren->ResetCamera();
  aCamera->Elevation(90.0);

  renWin->SetSize(300,300);
  renWin->Render();

  SAVEIMAGE( renWin );

  // interact with data
  iren->Start();

  // Clean up
  aren->Delete();
  renWin->Delete();
  iren->Delete();
  reader->Delete();
  outlineF->Delete();
  outlineMapper->Delete();
  outline->Delete();
  doorGeom->Delete();
  mapDoor->Delete();
  door->Delete();
  window1Geom->Delete();
  mapWindow1->Delete();
  window1->Delete();
  window2Geom->Delete();
  mapWindow2->Delete();
  window2->Delete();
  klower1Geom->Delete();
  mapKlower1->Delete();
  klower1->Delete();
  klower2Geom->Delete();
  mapKlower2->Delete();
  klower2->Delete();
  klower3Geom->Delete();
  mapKlower3->Delete();
  klower3->Delete();
  klower4Geom->Delete();
  mapKlower4->Delete();
  klower4->Delete();
  klower5Geom->Delete();
  mapKlower5->Delete();
  klower5->Delete();
  klower6Geom->Delete();
  mapKlower6->Delete();
  klower6->Delete();
  klower7Geom->Delete();
  mapKlower7->Delete();
  klower7->Delete();
  hood1Geom->Delete();
  mapHood1->Delete();
  hood1->Delete();
  hood2Geom->Delete();
  mapHood2->Delete();
  hood2->Delete();
  hood3Geom->Delete();
  mapHood3->Delete();
  hood3->Delete();
  hood4Geom->Delete();
  mapHood4->Delete();
  hood4->Delete();
  hood6Geom->Delete();
  mapHood6->Delete();
  hood6->Delete();
  cookingPlateGeom->Delete();
  mapCookingPlate->Delete();
  cookingPlate->Delete();
  filterGeom->Delete();
  mapFilter->Delete();
  filter->Delete();
  line->Delete();
  rakeMapper->Delete();
  rake->Delete();
  streamers->Delete();
  streamersMapper->Delete();
  lines->Delete();
  aCamera->Delete();
}
<commit_msg>ENH: Removed Elevation 90. Replaced with SetPosition/FocalPoint/ViewUp. Was causing sigularity problems on Reality Engine.<commit_after>#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkStructuredGridReader.h"
#include "vtkStructuredGridOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkStructuredGridGeometryFilter.h"
#include "vtkLineSource.h"
#include "vtkStreamLine.h"
#include "vtkCamera.h"

#include "SaveImage.h"

void main( int argc, char *argv[] )
{
  float range[2];
  float maxVelocity, maxTime;

  vtkRenderer *aren = vtkRenderer::New();
  vtkRenderWindow *renWin = vtkRenderWindow::New();
    renWin->AddRenderer(aren);

  vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);
//
// Read data
//
  vtkStructuredGridReader *reader = vtkStructuredGridReader::New();
    //reader->DebugOn();
    reader->SetFileName("../../../vtkdata/kitchen.vtk");
    reader->Update(); //force a read to occur
    reader->GetOutput()->GetLength();

  if ( reader->GetOutput()->GetPointData()->GetScalars() )
    {
    reader->GetOutput()->GetPointData()->GetScalars()->GetRange(range);
    }
  if ( reader->GetOutput()->GetPointData()->GetVectors() )
    {
    maxVelocity = reader->GetOutput()->GetPointData()->GetVectors()->GetMaxNorm();
    maxTime = 35.0*reader->GetOutput()->GetLength()/maxVelocity ;
    }
//
// Outline around data
//
  vtkStructuredGridOutlineFilter *outlineF = vtkStructuredGridOutlineFilter::New();
    outlineF->SetInput(reader->GetOutput());
  vtkPolyDataMapper *outlineMapper = vtkPolyDataMapper::New();
    outlineMapper->SetInput(outlineF->GetOutput());
  vtkActor *outline = vtkActor::New();
    outline->SetMapper(outlineMapper);
    outline->GetProperty()->SetColor(1,1,1);
//
// Set up shaded surfaces (i.e., supporting geometry)
//
  vtkStructuredGridGeometryFilter *doorGeom = vtkStructuredGridGeometryFilter::New();
    doorGeom->SetInput(reader->GetOutput());
    doorGeom->SetExtent(27,27,14,18,0,11);
  vtkPolyDataMapper *mapDoor = vtkPolyDataMapper::New();
    mapDoor->SetInput(doorGeom->GetOutput());
    mapDoor->ScalarVisibilityOff();
  vtkActor *door = vtkActor::New();
    door->SetMapper(mapDoor);
    door->GetProperty()->SetColor(.59,.427,.3);

  vtkStructuredGridGeometryFilter *window1Geom = vtkStructuredGridGeometryFilter::New();
    window1Geom->SetInput(reader->GetOutput());
    window1Geom->SetExtent(0,0,9,18,6,12);
  vtkPolyDataMapper *mapWindow1 = vtkPolyDataMapper::New();
    mapWindow1->SetInput(window1Geom->GetOutput());
    mapWindow1->ScalarVisibilityOff();
  vtkActor *window1 = vtkActor::New();
    window1->SetMapper(mapWindow1);
    window1->GetProperty()->SetColor(.3,.3,.5);

  vtkStructuredGridGeometryFilter *window2Geom = vtkStructuredGridGeometryFilter::New();
    window2Geom->SetInput(reader->GetOutput());
    window2Geom->SetExtent(5,12,23,23,6,12);
  vtkPolyDataMapper *mapWindow2 = vtkPolyDataMapper::New();
    mapWindow2->SetInput(window2Geom->GetOutput());
    mapWindow2->ScalarVisibilityOff();
  vtkActor *window2 = vtkActor::New();
    window2->SetMapper(mapWindow2);
    window2->GetProperty()->SetColor(.3,.3,.5);

  vtkStructuredGridGeometryFilter *klower1Geom = vtkStructuredGridGeometryFilter::New();
    klower1Geom->SetInput(reader->GetOutput());
    klower1Geom->SetExtent(17,17,0,11,0,6);
  vtkPolyDataMapper *mapKlower1 = vtkPolyDataMapper::New();
    mapKlower1->SetInput(klower1Geom->GetOutput());
    mapKlower1->ScalarVisibilityOff();
  vtkActor *klower1 = vtkActor::New();
    klower1->SetMapper(mapKlower1);
    klower1->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower2Geom = vtkStructuredGridGeometryFilter::New();
    klower2Geom->SetInput(reader->GetOutput());
    klower2Geom->SetExtent(19,19,0,11,0,6);
  vtkPolyDataMapper *mapKlower2 = vtkPolyDataMapper::New();
    mapKlower2->SetInput(klower2Geom->GetOutput());
    mapKlower2->ScalarVisibilityOff();
  vtkActor *klower2 = vtkActor::New();
    klower2->SetMapper(mapKlower2);
    klower2->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower3Geom = vtkStructuredGridGeometryFilter::New();
    klower3Geom->SetInput(reader->GetOutput());
    klower3Geom->SetExtent(17,19,0,0,0,6);
  vtkPolyDataMapper *mapKlower3 = vtkPolyDataMapper::New();
    mapKlower3->SetInput(klower3Geom->GetOutput());
    mapKlower3->ScalarVisibilityOff();
  vtkActor *klower3 = vtkActor::New();
    klower3->SetMapper(mapKlower3);
    klower3->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower4Geom = vtkStructuredGridGeometryFilter::New();
    klower4Geom->SetInput(reader->GetOutput());
    klower4Geom->SetExtent(17,19,11,11,0,6);
  vtkPolyDataMapper *mapKlower4 = vtkPolyDataMapper::New();
    mapKlower4->SetInput(klower4Geom->GetOutput());
    mapKlower4->ScalarVisibilityOff();
  vtkActor *klower4 = vtkActor::New();
    klower4->SetMapper(mapKlower4);
    klower4->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower5Geom = vtkStructuredGridGeometryFilter::New();
    klower5Geom->SetInput(reader->GetOutput());
    klower5Geom->SetExtent(17,19,0,11,0,0);
  vtkPolyDataMapper *mapKlower5 = vtkPolyDataMapper::New();
    mapKlower5->SetInput(klower5Geom->GetOutput());
    mapKlower5->ScalarVisibilityOff();
  vtkActor *klower5 = vtkActor::New();
    klower5->SetMapper(mapKlower5);
    klower5->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower6Geom = vtkStructuredGridGeometryFilter::New();
    klower6Geom->SetInput(reader->GetOutput());
    klower6Geom->SetExtent(17,19,0,7,6,6);
  vtkPolyDataMapper *mapKlower6 = vtkPolyDataMapper::New();
    mapKlower6->SetInput(klower6Geom->GetOutput());
    mapKlower6->ScalarVisibilityOff();
  vtkActor *klower6 = vtkActor::New();
    klower6->SetMapper(mapKlower6);
    klower6->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *klower7Geom = vtkStructuredGridGeometryFilter::New();
    klower7Geom->SetInput(reader->GetOutput());
    klower7Geom->SetExtent(17,19,9,11,6,6);
  vtkPolyDataMapper *mapKlower7 = vtkPolyDataMapper::New();
    mapKlower7->SetInput(klower7Geom->GetOutput());
    mapKlower7->ScalarVisibilityOff();
  vtkActor *klower7 = vtkActor::New();
    klower7->SetMapper(mapKlower7);
    klower7->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood1Geom = vtkStructuredGridGeometryFilter::New();
    hood1Geom->SetInput(reader->GetOutput());
    hood1Geom->SetExtent(17,17,0,11,11,16);
  vtkPolyDataMapper *mapHood1 = vtkPolyDataMapper::New();
    mapHood1->SetInput(hood1Geom->GetOutput());
    mapHood1->ScalarVisibilityOff();
  vtkActor *hood1 = vtkActor::New();
    hood1->SetMapper(mapHood1);
    hood1->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood2Geom = vtkStructuredGridGeometryFilter::New();
    hood2Geom->SetInput(reader->GetOutput());
    hood2Geom->SetExtent(19,19,0,11,11,16);
  vtkPolyDataMapper *mapHood2 = vtkPolyDataMapper::New();
    mapHood2->SetInput(hood2Geom->GetOutput());
    mapHood2->ScalarVisibilityOff();
  vtkActor *hood2 = vtkActor::New();
    hood2->SetMapper(mapHood2);
    hood2->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood3Geom = vtkStructuredGridGeometryFilter::New();
    hood3Geom->SetInput(reader->GetOutput());
    hood3Geom->SetExtent(17,19,0,0,11,16);
  vtkPolyDataMapper *mapHood3 = vtkPolyDataMapper::New();
    mapHood3->SetInput(hood3Geom->GetOutput());
    mapHood3->ScalarVisibilityOff();
  vtkActor *hood3 = vtkActor::New();
    hood3->SetMapper(mapHood3);
    hood3->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood4Geom = vtkStructuredGridGeometryFilter::New();
    hood4Geom->SetInput(reader->GetOutput());
    hood4Geom->SetExtent(17,19,11,11,11,16);
  vtkPolyDataMapper *mapHood4 = vtkPolyDataMapper::New();
    mapHood4->SetInput(hood4Geom->GetOutput());
    mapHood4->ScalarVisibilityOff();
  vtkActor *hood4 = vtkActor::New();
    hood4->SetMapper(mapHood4);
    hood4->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *hood6Geom = vtkStructuredGridGeometryFilter::New();
    hood6Geom->SetInput(reader->GetOutput());
    hood6Geom->SetExtent(17,19,0,11,16,16);
  vtkPolyDataMapper *mapHood6 = vtkPolyDataMapper::New();
    mapHood6->SetInput(hood6Geom->GetOutput());
    mapHood6->ScalarVisibilityOff();
  vtkActor *hood6 = vtkActor::New();
    hood6->SetMapper(mapHood6);
    hood6->GetProperty()->SetColor(.8,.8,.6);

  vtkStructuredGridGeometryFilter *cookingPlateGeom = vtkStructuredGridGeometryFilter::New();
    cookingPlateGeom->SetInput(reader->GetOutput());
    cookingPlateGeom->SetExtent(17,19,7,9,6,6);
  vtkPolyDataMapper *mapCookingPlate = vtkPolyDataMapper::New();
    mapCookingPlate->SetInput(cookingPlateGeom->GetOutput());
    mapCookingPlate->ScalarVisibilityOff();
  vtkActor *cookingPlate = vtkActor::New();
    cookingPlate->SetMapper(mapCookingPlate);
    cookingPlate->GetProperty()->SetColor(.9,.1,.1);

  vtkStructuredGridGeometryFilter *filterGeom = vtkStructuredGridGeometryFilter::New();
    filterGeom->SetInput(reader->GetOutput());
    filterGeom->SetExtent(17,19,7,9,11,11);
  vtkPolyDataMapper *mapFilter = vtkPolyDataMapper::New();
    mapFilter->SetInput(filterGeom->GetOutput());
    mapFilter->ScalarVisibilityOff();
  vtkActor *filter = vtkActor::New();
    filter->SetMapper(mapFilter);
    filter->GetProperty()->SetColor(.8,.6,.6);
//
// regular streamlines
//
  vtkLineSource *line = vtkLineSource::New();
    line->SetResolution(39);
    line->SetPoint1(0.08, 2.50, 0.71);
    line->SetPoint2(0.08, 4.50, 0.71);
  vtkPolyDataMapper *rakeMapper = vtkPolyDataMapper::New();
    rakeMapper->SetInput(line->GetOutput());
  vtkActor *rake = vtkActor::New();
    rake->SetMapper(rakeMapper);

  vtkStreamLine *streamers = vtkStreamLine::New();
    //streamers->DebugOn();
    streamers->SetInput(reader->GetOutput());
    streamers->SetSource(line->GetOutput());
    streamers->SetMaximumPropagationTime(maxTime);
    streamers->SetStepLength(maxTime/500.0);
    streamers->SetIntegrationStepLength(0.2);
    streamers->Update();
    //streamers->DebugOff();
  vtkPolyDataMapper *streamersMapper = vtkPolyDataMapper::New();
    streamersMapper->SetInput(streamers->GetOutput());
    streamersMapper->SetScalarRange(range);
//    streamersMapper->ScalarVisibilityOff();
  vtkActor *lines = vtkActor::New();
    lines->SetMapper(streamersMapper);
    lines->GetProperty()->SetColor(0,0,0);

  aren->AddActor(outline);
  aren->AddActor(door);
  aren->AddActor(window1);
  aren->AddActor(window2);
  aren->AddActor(klower1);
  aren->AddActor(klower2);
  aren->AddActor(klower3);
  aren->AddActor(klower4);
  aren->AddActor(klower5);
  aren->AddActor(klower6);
  aren->AddActor(klower7);
  aren->AddActor(hood1);
  aren->AddActor(hood2);
  aren->AddActor(hood3);
  aren->AddActor(hood4);
  aren->AddActor(hood6);
  aren->AddActor(cookingPlate);
  aren->AddActor(filter);
  aren->AddActor(lines);
  aren->AddActor(rake);

  aren->SetBackground(0.1, 0.2, 0.4);

  vtkCamera *aCamera = vtkCamera::New();
  aren->SetActiveCamera(aCamera);
  aren->ResetCamera();

  aCamera->SetFocalPoint(3.505, 2.505, 1.255);
  aCamera->SetPosition(3.505, 24.6196, 1.255);
  aCamera->SetViewUp(0,0,1);

  renWin->SetSize(300,300);
  renWin->Render();

  SAVEIMAGE( renWin );

  // interact with data
  iren->Start();

  // Clean up
  aren->Delete();
  renWin->Delete();
  iren->Delete();
  reader->Delete();
  outlineF->Delete();
  outlineMapper->Delete();
  outline->Delete();
  doorGeom->Delete();
  mapDoor->Delete();
  door->Delete();
  window1Geom->Delete();
  mapWindow1->Delete();
  window1->Delete();
  window2Geom->Delete();
  mapWindow2->Delete();
  window2->Delete();
  klower1Geom->Delete();
  mapKlower1->Delete();
  klower1->Delete();
  klower2Geom->Delete();
  mapKlower2->Delete();
  klower2->Delete();
  klower3Geom->Delete();
  mapKlower3->Delete();
  klower3->Delete();
  klower4Geom->Delete();
  mapKlower4->Delete();
  klower4->Delete();
  klower5Geom->Delete();
  mapKlower5->Delete();
  klower5->Delete();
  klower6Geom->Delete();
  mapKlower6->Delete();
  klower6->Delete();
  klower7Geom->Delete();
  mapKlower7->Delete();
  klower7->Delete();
  hood1Geom->Delete();
  mapHood1->Delete();
  hood1->Delete();
  hood2Geom->Delete();
  mapHood2->Delete();
  hood2->Delete();
  hood3Geom->Delete();
  mapHood3->Delete();
  hood3->Delete();
  hood4Geom->Delete();
  mapHood4->Delete();
  hood4->Delete();
  hood6Geom->Delete();
  mapHood6->Delete();
  hood6->Delete();
  cookingPlateGeom->Delete();
  mapCookingPlate->Delete();
  cookingPlate->Delete();
  filterGeom->Delete();
  mapFilter->Delete();
  filter->Delete();
  line->Delete();
  rakeMapper->Delete();
  rake->Delete();
  streamers->Delete();
  streamersMapper->Delete();
  lines->Delete();
  aCamera->Delete();
}
<|endoftext|>