mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #1359 from akva2/import_utils_from_core
Import some utils from opm-core
This commit is contained in:
commit
4c8f1c2ce4
@ -47,6 +47,8 @@ list (APPEND MAIN_SOURCE_FILES
|
|||||||
opm/autodiff/VFPProdProperties.cpp
|
opm/autodiff/VFPProdProperties.cpp
|
||||||
opm/autodiff/VFPInjProperties.cpp
|
opm/autodiff/VFPInjProperties.cpp
|
||||||
opm/autodiff/MissingFeatures.cpp
|
opm/autodiff/MissingFeatures.cpp
|
||||||
|
opm/core/utility/Event.cpp
|
||||||
|
opm/core/utility/NullStream.cpp
|
||||||
opm/polymer/PolymerState.cpp
|
opm/polymer/PolymerState.cpp
|
||||||
opm/polymer/PolymerBlackoilState.cpp
|
opm/polymer/PolymerBlackoilState.cpp
|
||||||
opm/polymer/CompressibleTpfaPolymer.cpp
|
opm/polymer/CompressibleTpfaPolymer.cpp
|
||||||
@ -95,6 +97,7 @@ list (APPEND TEST_SOURCE_FILES
|
|||||||
tests/test_wellswitchlogger.cpp
|
tests/test_wellswitchlogger.cpp
|
||||||
tests/test_timer.cpp
|
tests/test_timer.cpp
|
||||||
tests/test_invert.cpp
|
tests/test_invert.cpp
|
||||||
|
tests/test_event.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list (APPEND TEST_DATA_FILES
|
list (APPEND TEST_DATA_FILES
|
||||||
@ -221,6 +224,11 @@ list (APPEND PUBLIC_HEADER_FILES
|
|||||||
opm/autodiff/BlackoilWellModel_impl.hpp
|
opm/autodiff/BlackoilWellModel_impl.hpp
|
||||||
opm/autodiff/MissingFeatures.hpp
|
opm/autodiff/MissingFeatures.hpp
|
||||||
opm/autodiff/ThreadHandle.hpp
|
opm/autodiff/ThreadHandle.hpp
|
||||||
|
opm/core/utility/DataMap.hpp
|
||||||
|
opm/core/utility/Event.hpp
|
||||||
|
opm/core/utility/Event_impl.hpp
|
||||||
|
opm/core/utility/NullStream.hpp
|
||||||
|
opm/core/utility/share_obj.hpp
|
||||||
opm/polymer/CompressibleTpfaPolymer.hpp
|
opm/polymer/CompressibleTpfaPolymer.hpp
|
||||||
opm/polymer/GravityColumnSolverPolymer.hpp
|
opm/polymer/GravityColumnSolverPolymer.hpp
|
||||||
opm/polymer/GravityColumnSolverPolymer_impl.hpp
|
opm/polymer/GravityColumnSolverPolymer_impl.hpp
|
||||||
|
33
opm/core/utility/DataMap.hpp
Normal file
33
opm/core/utility/DataMap.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2012 SINTEF ICT, Applied Mathematics.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM 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 Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_DATAMAP_HEADER_INCLUDED
|
||||||
|
#define OPM_DATAMAP_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
/// Intended to map strings (giving the output field names) to data.
|
||||||
|
typedef std::map<std::string, const std::vector<double>*> DataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
opm/core/utility/Event.cpp
Normal file
22
opm/core/utility/Event.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <opm/core/utility/Event.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Opm;
|
||||||
|
|
||||||
|
Event&
|
||||||
|
EventSource::add (const std::function<void ()>& handler) {
|
||||||
|
// add handler to the back of the queue
|
||||||
|
handlers_.push_back (handler);
|
||||||
|
|
||||||
|
// return ourselves so we can be used in a call chain
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EventSource::signal () {
|
||||||
|
// loop through the list of handlers, and invoke every one of them
|
||||||
|
// (range-based for loops are not available until GCC 4.6)
|
||||||
|
for (auto it = handlers_.begin(); it != handlers_.end(); ++it) {
|
||||||
|
(*it) ();
|
||||||
|
}
|
||||||
|
}
|
98
opm/core/utility/Event.hpp
Normal file
98
opm/core/utility/Event.hpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#ifndef OPM_EVENT_HEADER_INCLUDED
|
||||||
|
#define OPM_EVENT_HEADER_INCLUDED
|
||||||
|
|
||||||
|
// Copyright (C) 2013 Uni Research AS
|
||||||
|
// This file is licensed under the GNU General Public License v3.0
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
/// Interface to register interest in receiving notifications when a
|
||||||
|
/// certain event, such as the completion of a timestep, has happened.
|
||||||
|
struct Event {
|
||||||
|
/// Register a callback to receive notifications from this event.
|
||||||
|
///
|
||||||
|
/// \param[in] handler
|
||||||
|
/// Function object that will be invoked when the event happens.
|
||||||
|
///
|
||||||
|
/// \return
|
||||||
|
/// The event object itself, so that multiple additions can be chained.
|
||||||
|
///
|
||||||
|
/// \note
|
||||||
|
/// The event may happen several times, and the handler will receive
|
||||||
|
/// a notification every time.
|
||||||
|
///
|
||||||
|
/// \note
|
||||||
|
/// If a handler is added more than once, it will also be called
|
||||||
|
/// more than once.
|
||||||
|
virtual Event& add (const std::function <void ()>& handler) = 0;
|
||||||
|
|
||||||
|
/// Convenience routine to add a member function of a class as
|
||||||
|
/// an event handler.
|
||||||
|
///
|
||||||
|
/// This allows us to have all the necessary information the handler
|
||||||
|
/// needs put into an object, and then register this with the event.
|
||||||
|
template <typename T, void (T::*member)()> Event& add (T& t);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Generator of event notifications.
|
||||||
|
///
|
||||||
|
/// As more than one event is possible from an object, it is expected
|
||||||
|
/// that event servers implements this functionality by aggregation and
|
||||||
|
/// provide accessors to let clients reach the various events.
|
||||||
|
///
|
||||||
|
/// You should not provide the full EventSource interface to clients,
|
||||||
|
/// as this will allow them to signal the event themselves; rather, return
|
||||||
|
/// the registration-only parent interface.
|
||||||
|
///
|
||||||
|
/// \example
|
||||||
|
/// You can add an event to your code like this:
|
||||||
|
///
|
||||||
|
/// \code{.cpp}
|
||||||
|
/// struct Foo {
|
||||||
|
/// // accessor of the event that other can register at
|
||||||
|
/// Event& completed () { return completed_; }
|
||||||
|
///
|
||||||
|
/// // something that ultimately triggers the event
|
||||||
|
/// void action () { /* ... */ completed_.signal(); }
|
||||||
|
///
|
||||||
|
/// private:
|
||||||
|
/// EventSource completed_;
|
||||||
|
/// };
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// It could then be accessed by the client like this:
|
||||||
|
///
|
||||||
|
/// \code{.cpp}
|
||||||
|
/// struct Bar {
|
||||||
|
/// void callMe() { /* ... */ }
|
||||||
|
/// };
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// \code{.cpp}
|
||||||
|
/// Foo foo;
|
||||||
|
/// Bar bar;
|
||||||
|
///
|
||||||
|
/// // setup the connection between the two
|
||||||
|
/// foo.completed().add<Bar, &Bar::callMe>(bar);
|
||||||
|
///
|
||||||
|
/// // set events in motion
|
||||||
|
/// foo.action();
|
||||||
|
/// \endcode
|
||||||
|
class EventSource : public Event {
|
||||||
|
public:
|
||||||
|
virtual Event& add (const std::function <void ()>& handler);
|
||||||
|
virtual void signal ();
|
||||||
|
protected:
|
||||||
|
/// List of actual handlers that will be called
|
||||||
|
std::list <std::function <void ()> > handlers_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// inline definitions
|
||||||
|
#include "Event_impl.hpp"
|
||||||
|
|
||||||
|
} /* namespace Opm */
|
||||||
|
|
||||||
|
#endif /* OPM_EVENT_HEADER_INCLUDED */
|
13
opm/core/utility/Event_impl.hpp
Normal file
13
opm/core/utility/Event_impl.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (C) 2013 Uni Research AS
|
||||||
|
// This file is licensed under the GNU General Public License v3.0
|
||||||
|
|
||||||
|
#ifndef OPM_EVENT_HEADER_INCLUDED
|
||||||
|
#error Do NOT include this file directly!
|
||||||
|
#endif /* OPM_EVENT_HEADER_INCLUDED */
|
||||||
|
|
||||||
|
template <typename T, void (T::*member)()> inline Event&
|
||||||
|
Event::add (T& t) {
|
||||||
|
// wrap the member function in a std::function and add that
|
||||||
|
// notice the use of ref() to avoid invoking the copy constructor
|
||||||
|
return this->add (std::bind (member, std::ref(t)));
|
||||||
|
}
|
20
opm/core/utility/NullStream.cpp
Normal file
20
opm/core/utility/NullStream.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (C) 2013 Uni Research AS
|
||||||
|
// This file is licensed under the GNU General Public License v3.0
|
||||||
|
|
||||||
|
#include <opm/core/utility/NullStream.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
#include <streambuf>
|
||||||
|
|
||||||
|
// buffer that ignores everything
|
||||||
|
// see <http://forums.codeguru.com/showthread.php?460071-ostream-bit-bucket>
|
||||||
|
struct NullBuf : public std::streambuf {};
|
||||||
|
static NullBuf null_buf_impl;
|
||||||
|
|
||||||
|
// link the stream up to the black hole buffer
|
||||||
|
struct NullStream : public std::ostream {
|
||||||
|
NullStream () : std::ostream (&null_buf_impl) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// create a singleton and point the reference to it
|
||||||
|
static NullStream null_stream_impl;
|
||||||
|
std::ostream& Opm::null_stream = null_stream_impl;
|
30
opm/core/utility/NullStream.hpp
Normal file
30
opm/core/utility/NullStream.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef OPM_NULLSTREAM_HEADER_INCLUDED
|
||||||
|
#define OPM_NULLSTREAM_HEADER_INCLUDED
|
||||||
|
|
||||||
|
// Copyright (C) 2013 Uni Research AS
|
||||||
|
// This file is licensed under the GNU General Public License v3.0
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output stream that ignores everything written to it.
|
||||||
|
*
|
||||||
|
* Use this stream if you want to disable output without having a
|
||||||
|
* lot of conditionals in your code.
|
||||||
|
*
|
||||||
|
* Since the null stream has no state, there is no point in
|
||||||
|
* instantiating your own; simply use this reference instead.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* @code{.cpp}
|
||||||
|
* std::ostream& outp = (quiet ? Opm::null_stream : std::cerr);
|
||||||
|
* outp << "Hello, World!" << std::endl;
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
extern std::ostream& null_stream;
|
||||||
|
|
||||||
|
} /* namespace Opm */
|
||||||
|
|
||||||
|
#endif /* OPM_NULLSTREAM_HEADER_INCLUDED */
|
49
opm/core/utility/share_obj.hpp
Normal file
49
opm/core/utility/share_obj.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2013 Uni Research AS
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM 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 Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_SHARE_OBJ_HPP
|
||||||
|
#define OPM_SHARE_OBJ_HPP
|
||||||
|
|
||||||
|
#include <memory> // shared_ptr
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
/// Custom deleter that does nothing
|
||||||
|
inline void no_delete (void const *) { }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Share pointer of a local object.
|
||||||
|
*
|
||||||
|
* Use this wrapper when an interface needs a shared_ptr, but you
|
||||||
|
* want to pass an object that has local storage (and you know
|
||||||
|
* that the shared_ptr client doesn't need it outside of the scope).
|
||||||
|
*
|
||||||
|
* \example
|
||||||
|
* \code{.cpp}
|
||||||
|
* Foo obj;
|
||||||
|
* std::shared_ptr <Foo> ptr = share_obj (obj);
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
template <typename T> std::shared_ptr <T> share_obj (T& t) {
|
||||||
|
return std::shared_ptr <T> (&t, no_delete);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
#endif /* OPM_SHARE_OBJ_HPP */
|
78
tests/test_event.cpp
Normal file
78
tests/test_event.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* Copyright 2013 Uni Research AS
|
||||||
|
* This file is licensed under GPL3, see http://www.opm-project.org/
|
||||||
|
*/
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/* --- Boost.Test boilerplate --- */
|
||||||
|
#if HAVE_DYNAMIC_BOOST_TEST
|
||||||
|
#define BOOST_TEST_DYN_LINK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NVERBOSE // Suppress own messages when throw()ing
|
||||||
|
|
||||||
|
#define BOOST_TEST_MODULE EventTest
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
/* --- our own headers --- */
|
||||||
|
#include <opm/core/utility/Event.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Opm;
|
||||||
|
|
||||||
|
// idiomatic implementation of generator and receiver
|
||||||
|
struct EventGenerator {
|
||||||
|
EventSource eventSource_;
|
||||||
|
Event& event () { return eventSource_; }
|
||||||
|
void action () { eventSource_.signal (); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EventReceiver {
|
||||||
|
int numOfCalls;
|
||||||
|
EventReceiver () : numOfCalls (0) { }
|
||||||
|
void handler () { ++numOfCalls; }
|
||||||
|
private:
|
||||||
|
// make sure bind() doesn't implement copy constructor
|
||||||
|
EventReceiver (EventReceiver&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// declare a generator, a receiver and connect them
|
||||||
|
struct EventFixture {
|
||||||
|
EventGenerator gen;
|
||||||
|
EventReceiver recv;
|
||||||
|
void register_handler () {
|
||||||
|
gen.event().add<EventReceiver,&EventReceiver::handler>(recv);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventFixture () {
|
||||||
|
register_handler();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_FIXTURE_TEST_SUITE(EventTest, EventFixture)
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(none)
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE_EQUAL (recv.numOfCalls, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(once)
|
||||||
|
{
|
||||||
|
gen.action();
|
||||||
|
BOOST_REQUIRE_EQUAL (recv.numOfCalls, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(twice)
|
||||||
|
{
|
||||||
|
gen.action();
|
||||||
|
gen.action();
|
||||||
|
BOOST_REQUIRE_EQUAL (recv.numOfCalls, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(reg_twice)
|
||||||
|
{
|
||||||
|
register_handler();
|
||||||
|
gen.action();
|
||||||
|
BOOST_REQUIRE_EQUAL (recv.numOfCalls, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue
Block a user