Jean Fromentin il y a 2 ans
Parent
commit
676c14df2f
72 fichiers modifiés avec 2548 ajouts et 208 suppressions
  1. 19 9
      Makefile
  2. BIN
      RichardsFastSlow
  3. BIN
      inputs/test.input
  4. BIN
      inputs/test2.input
  5. 177 0
      moc/input.cpp
  6. 143 0
      moc/input_geometry.cpp
  7. 119 0
      moc/input_view.cpp
  8. 136 0
      moc/mainwindow.cpp
  9. 118 0
      moc/view_solution.cpp
  10. BIN
      obj/geometry.o
  11. BIN
      obj/initial_state.o
  12. BIN
      obj/kernel.o
  13. BIN
      obj/math/algo.o
  14. BIN
      obj/math/poly3.o
  15. BIN
      obj/math/spline.o
  16. BIN
      obj/physics.o
  17. BIN
      obj/qt/input.o
  18. BIN
      obj/qt/input_geometry.o
  19. BIN
      obj/qt/input_geometry_curves.o
  20. BIN
      obj/qt/input_physics.o
  21. BIN
      obj/qt/input_time.o
  22. BIN
      obj/qt/mainwindow.o
  23. BIN
      obj/qt/view_solution.o
  24. BIN
      obj/qt/view_solution_geometry.o
  25. BIN
      obj/source.o
  26. BIN
      obj/time.o
  27. 86 0
      src/geometry.cpp
  28. 20 2
      src/geometry.hpp
  29. 1 0
      src/initial_state.cpp
  30. 10 0
      src/initial_state.hpp
  31. 2 0
      src/kernel.cpp
  32. 30 0
      src/kernel.hpp
  33. 9 32
      src/main.cpp
  34. 16 0
      src/math/algo.cpp
  35. 17 0
      src/math/algo.hpp
  36. 31 0
      src/math/point.hpp
  37. 18 0
      src/math/poly3.cpp
  38. 31 0
      src/math/poly3.hpp
  39. 80 0
      src/math/spline.cpp
  40. 35 0
      src/math/spline.hpp
  41. 81 68
      src/physics.cpp
  42. 31 33
      src/physics.hpp
  43. 1 0
      src/qt/.#input.hpp
  44. 136 5
      src/qt/input.cpp
  45. 36 3
      src/qt/input.hpp
  46. 89 2
      src/qt/input_geometry.cpp
  47. 45 1
      src/qt/input_geometry.hpp
  48. 163 0
      src/qt/input_geometry_curves.cpp
  49. 61 0
      src/qt/input_geometry_curves.hpp
  50. 7 0
      src/qt/input_initial_state.cpp
  51. 18 0
      src/qt/input_initial_state.hpp
  52. 99 20
      src/qt/input_physics.cpp
  53. 6 13
      src/qt/input_physics.hpp
  54. 7 0
      src/qt/input_sources.cpp
  55. 18 0
      src/qt/input_sources.hpp
  56. 34 3
      src/qt/input_time.cpp
  57. 13 4
      src/qt/input_time.hpp
  58. 39 0
      src/qt/input_view.cpp
  59. 27 0
      src/qt/input_view.hpp
  60. 73 2
      src/qt/mainwindow.cpp
  61. 23 2
      src/qt/mainwindow.hpp
  62. 11 0
      src/qt/spline.hpp
  63. 74 0
      src/qt/view.cpp
  64. 35 2
      src/qt/view.hpp
  65. 44 0
      src/qt/view_solution.cpp
  66. 33 0
      src/qt/view_solution.hpp
  67. 194 0
      src/qt/view_solution_geometry.cpp
  68. 27 0
      src/qt/view_solution_geometry.hpp
  69. 1 0
      src/source.cpp
  70. 8 0
      src/source.hpp
  71. 7 0
      src/time.cpp
  72. 9 7
      src/time.hpp

+ 19 - 9
Makefile

@@ -1,26 +1,36 @@
-QT_FLAG		=`pkg-config --cflags --libs Qt5Widgets`
-QT_LIB		=`pkg-config --libs Qt5Widgets`
+QT_FLAGS	=-fPIC `pkg-config --cflags --libs Qt5OpenGL`
+QT_LIB		=`pkg-config --libs Qt5OpenGL` -lGL -lGLU
 QT_MOC		= moc
 GPP		= g++
-FLAGS 		= -fPIC $(QT_FLAG)
+FLAGS 		= -g -O3 -Isrc
 
-QT_FILES	= mainwindow input input_physics input_time input_geometry
-QT_MOC_FILES	= input_physics
-EXE		= RichardsFastSlow
+QT_FILES	= mainwindow input input_physics input_time input_geometry input_geometry_curves view_solution view_solution_geometry input_initial_state input_sources input_view view
+QT_MOC_FILES	= mainwindow input_physics input  view_solution input_view input_geometry
+MATH_FILES	= poly3 algo spline
+SRC_FILES	= physics time geometry kernel initial_state source
 
 QT_OBJS		= $(addprefix obj/qt/,$(addsuffix .o,$(QT_FILES)))
 QT_MOCS		= $(addprefix moc/,$(addsuffix .cpp,$(QT_MOC_FILES)))
+MATH_OBJS	= $(addprefix obj/math/,$(addsuffix .o,$(MATH_FILES)))
+SRC_OBJS	= $(addprefix obj/,$(addsuffix .o,$(SRC_FILES)))
+EXE		= RichardsFastSlow
 
 all : $(EXE)
 
-$(EXE) : src/main.cpp $(QT_MOCS) $(QT_OBJS)
-	$(GPP) $(FLAGS) $^ $(QT_LIB) -o $@
+$(EXE) : src/main.cpp $(MATH_OBJS) $(SRC_OBJS) $(QT_MOCS) $(QT_OBJS)
+	$(GPP) $(FLAGS) $(QT_FLAGS) $^ $(QT_LIB) -o $@
 
 obj/qt/%.o : src/qt/%.cpp src/qt/%.hpp
+	$(GPP) $(FLAGS) $(QT_FLAGS) -c $< -o $@
+
+obj/math/%.o : src/math/%.cpp src/math/%.hpp
+	$(GPP) $(FLAGS) -c $< -o $@
+
+obj/%.o : src/%.cpp src/%.hpp
 	$(GPP) $(FLAGS) -c $< -o $@
 
 moc/%.cpp : src/qt/%.hpp
 	$(QT_MOC) $< -o $@
 
 clean:
-	-$(RM) $(EXE) moc/* obj/*.o obj/qt/*.o src/*~ src/qt/*~
+	-$(RM) $(EXE) moc/* obj/*.o obj/math/*.o obj/qt/*.o src/*~ src/qt/*~ src/math/*~

BIN
RichardsFastSlow


BIN
inputs/test.input


BIN
inputs/test2.input


+ 177 - 0
moc/input.cpp

@@ -0,0 +1,177 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'input.hpp'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include <memory>
+#include "../src/qt/input.hpp"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'input.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.15.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+struct qt_meta_stringdata_QtInput_t {
+    QByteArrayData data[10];
+    char stringdata0[84];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    qptrdiff(offsetof(qt_meta_stringdata_QtInput_t, stringdata0) + ofs \
+        - idx * sizeof(QByteArrayData)) \
+    )
+static const qt_meta_stringdata_QtInput_t qt_meta_stringdata_QtInput = {
+    {
+QT_MOC_LITERAL(0, 0, 7), // "QtInput"
+QT_MOC_LITERAL(1, 8, 10), // "run_signal"
+QT_MOC_LITERAL(2, 19, 0), // ""
+QT_MOC_LITERAL(3, 20, 11), // "exit_signal"
+QT_MOC_LITERAL(4, 32, 3), // "run"
+QT_MOC_LITERAL(5, 36, 4), // "save"
+QT_MOC_LITERAL(6, 41, 6), // "cancel"
+QT_MOC_LITERAL(7, 48, 14), // "changeTabIndex"
+QT_MOC_LITERAL(8, 63, 5), // "index"
+QT_MOC_LITERAL(9, 69, 14) // "updateGeometry"
+
+    },
+    "QtInput\0run_signal\0\0exit_signal\0run\0"
+    "save\0cancel\0changeTabIndex\0index\0"
+    "updateGeometry"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QtInput[] = {
+
+ // content:
+       8,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       7,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       2,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    0,   49,    2, 0x06 /* Public */,
+       3,    0,   50,    2, 0x06 /* Public */,
+
+ // slots: name, argc, parameters, tag, flags
+       4,    0,   51,    2, 0x08 /* Private */,
+       5,    0,   52,    2, 0x08 /* Private */,
+       6,    0,   53,    2, 0x08 /* Private */,
+       7,    1,   54,    2, 0x08 /* Private */,
+       9,    0,   57,    2, 0x08 /* Private */,
+
+ // signals: parameters
+    QMetaType::Void,
+    QMetaType::Void,
+
+ // slots: parameters
+    QMetaType::Void,
+    QMetaType::Void,
+    QMetaType::Void,
+    QMetaType::Void, QMetaType::Int,    8,
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void QtInput::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        auto *_t = static_cast<QtInput *>(_o);
+        (void)_t;
+        switch (_id) {
+        case 0: _t->run_signal(); break;
+        case 1: _t->exit_signal(); break;
+        case 2: _t->run(); break;
+        case 3: _t->save(); break;
+        case 4: _t->cancel(); break;
+        case 5: _t->changeTabIndex((*reinterpret_cast< int(*)>(_a[1]))); break;
+        case 6: _t->updateGeometry(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        {
+            using _t = void (QtInput::*)();
+            if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&QtInput::run_signal)) {
+                *result = 0;
+                return;
+            }
+        }
+        {
+            using _t = void (QtInput::*)();
+            if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&QtInput::exit_signal)) {
+                *result = 1;
+                return;
+            }
+        }
+    }
+}
+
+QT_INIT_METAOBJECT const QMetaObject QtInput::staticMetaObject = { {
+    QMetaObject::SuperData::link<QWidget::staticMetaObject>(),
+    qt_meta_stringdata_QtInput.data,
+    qt_meta_data_QtInput,
+    qt_static_metacall,
+    nullptr,
+    nullptr
+} };
+
+
+const QMetaObject *QtInput::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QtInput::qt_metacast(const char *_clname)
+{
+    if (!_clname) return nullptr;
+    if (!strcmp(_clname, qt_meta_stringdata_QtInput.stringdata0))
+        return static_cast<void*>(this);
+    return QWidget::qt_metacast(_clname);
+}
+
+int QtInput::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 7)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 7;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 7)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 7;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void QtInput::run_signal()
+{
+    QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
+}
+
+// SIGNAL 1
+void QtInput::exit_signal()
+{
+    QMetaObject::activate(this, &staticMetaObject, 1, nullptr);
+}
+QT_WARNING_POP
+QT_END_MOC_NAMESPACE

+ 143 - 0
moc/input_geometry.cpp

@@ -0,0 +1,143 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'input_geometry.hpp'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include <memory>
+#include "../src/qt/input_geometry.hpp"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'input_geometry.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.15.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+struct qt_meta_stringdata_QtInputGeometry_t {
+    QByteArrayData data[4];
+    char stringdata0[53];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    qptrdiff(offsetof(qt_meta_stringdata_QtInputGeometry_t, stringdata0) + ofs \
+        - idx * sizeof(QByteArrayData)) \
+    )
+static const qt_meta_stringdata_QtInputGeometry_t qt_meta_stringdata_QtInputGeometry = {
+    {
+QT_MOC_LITERAL(0, 0, 15), // "QtInputGeometry"
+QT_MOC_LITERAL(1, 16, 15), // "geometryChanged"
+QT_MOC_LITERAL(2, 32, 0), // ""
+QT_MOC_LITERAL(3, 33, 19) // "emitGeometryChanged"
+
+    },
+    "QtInputGeometry\0geometryChanged\0\0"
+    "emitGeometryChanged"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QtInputGeometry[] = {
+
+ // content:
+       8,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       2,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       1,       // signalCount
+
+ // signals: name, argc, parameters, tag, flags
+       1,    0,   24,    2, 0x06 /* Public */,
+
+ // slots: name, argc, parameters, tag, flags
+       3,    0,   25,    2, 0x0a /* Public */,
+
+ // signals: parameters
+    QMetaType::Void,
+
+ // slots: parameters
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void QtInputGeometry::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        auto *_t = static_cast<QtInputGeometry *>(_o);
+        (void)_t;
+        switch (_id) {
+        case 0: _t->geometryChanged(); break;
+        case 1: _t->emitGeometryChanged(); break;
+        default: ;
+        }
+    } else if (_c == QMetaObject::IndexOfMethod) {
+        int *result = reinterpret_cast<int *>(_a[0]);
+        {
+            using _t = void (QtInputGeometry::*)();
+            if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&QtInputGeometry::geometryChanged)) {
+                *result = 0;
+                return;
+            }
+        }
+    }
+    (void)_a;
+}
+
+QT_INIT_METAOBJECT const QMetaObject QtInputGeometry::staticMetaObject = { {
+    QMetaObject::SuperData::link<QWidget::staticMetaObject>(),
+    qt_meta_stringdata_QtInputGeometry.data,
+    qt_meta_data_QtInputGeometry,
+    qt_static_metacall,
+    nullptr,
+    nullptr
+} };
+
+
+const QMetaObject *QtInputGeometry::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QtInputGeometry::qt_metacast(const char *_clname)
+{
+    if (!_clname) return nullptr;
+    if (!strcmp(_clname, qt_meta_stringdata_QtInputGeometry.stringdata0))
+        return static_cast<void*>(this);
+    return QWidget::qt_metacast(_clname);
+}
+
+int QtInputGeometry::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 2)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 2;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 2)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 2;
+    }
+    return _id;
+}
+
+// SIGNAL 0
+void QtInputGeometry::geometryChanged()
+{
+    QMetaObject::activate(this, &staticMetaObject, 0, nullptr);
+}
+QT_WARNING_POP
+QT_END_MOC_NAMESPACE

+ 119 - 0
moc/input_view.cpp

@@ -0,0 +1,119 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'input_view.hpp'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include <memory>
+#include "../src/qt/input_view.hpp"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'input_view.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.15.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+struct qt_meta_stringdata_QtInputView_t {
+    QByteArrayData data[3];
+    char stringdata0[28];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    qptrdiff(offsetof(qt_meta_stringdata_QtInputView_t, stringdata0) + ofs \
+        - idx * sizeof(QByteArrayData)) \
+    )
+static const qt_meta_stringdata_QtInputView_t qt_meta_stringdata_QtInputView = {
+    {
+QT_MOC_LITERAL(0, 0, 11), // "QtInputView"
+QT_MOC_LITERAL(1, 12, 14), // "updateGeometry"
+QT_MOC_LITERAL(2, 27, 0) // ""
+
+    },
+    "QtInputView\0updateGeometry\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QtInputView[] = {
+
+ // content:
+       8,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       1,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+ // slots: name, argc, parameters, tag, flags
+       1,    0,   19,    2, 0x0a /* Public */,
+
+ // slots: parameters
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void QtInputView::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        auto *_t = static_cast<QtInputView *>(_o);
+        (void)_t;
+        switch (_id) {
+        case 0: _t->updateGeometry(); break;
+        default: ;
+        }
+    }
+    (void)_a;
+}
+
+QT_INIT_METAOBJECT const QMetaObject QtInputView::staticMetaObject = { {
+    QMetaObject::SuperData::link<QtView::staticMetaObject>(),
+    qt_meta_stringdata_QtInputView.data,
+    qt_meta_data_QtInputView,
+    qt_static_metacall,
+    nullptr,
+    nullptr
+} };
+
+
+const QMetaObject *QtInputView::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QtInputView::qt_metacast(const char *_clname)
+{
+    if (!_clname) return nullptr;
+    if (!strcmp(_clname, qt_meta_stringdata_QtInputView.stringdata0))
+        return static_cast<void*>(this);
+    return QtView::qt_metacast(_clname);
+}
+
+int QtInputView::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QtView::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 1)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 1;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 1)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 1;
+    }
+    return _id;
+}
+QT_WARNING_POP
+QT_END_MOC_NAMESPACE

+ 136 - 0
moc/mainwindow.cpp

@@ -0,0 +1,136 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'mainwindow.hpp'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include <memory>
+#include "../src/qt/mainwindow.hpp"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'mainwindow.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.15.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+struct qt_meta_stringdata_QtMainWindow_t {
+    QByteArrayData data[7];
+    char stringdata0[61];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    qptrdiff(offsetof(qt_meta_stringdata_QtMainWindow_t, stringdata0) + ofs \
+        - idx * sizeof(QByteArrayData)) \
+    )
+static const qt_meta_stringdata_QtMainWindow_t qt_meta_stringdata_QtMainWindow = {
+    {
+QT_MOC_LITERAL(0, 0, 12), // "QtMainWindow"
+QT_MOC_LITERAL(1, 13, 9), // "new_input"
+QT_MOC_LITERAL(2, 23, 0), // ""
+QT_MOC_LITERAL(3, 24, 10), // "load_input"
+QT_MOC_LITERAL(4, 35, 4), // "exit"
+QT_MOC_LITERAL(5, 40, 9), // "run_input"
+QT_MOC_LITERAL(6, 50, 10) // "exit_input"
+
+    },
+    "QtMainWindow\0new_input\0\0load_input\0"
+    "exit\0run_input\0exit_input"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QtMainWindow[] = {
+
+ // content:
+       8,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       5,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+ // slots: name, argc, parameters, tag, flags
+       1,    0,   39,    2, 0x08 /* Private */,
+       3,    0,   40,    2, 0x08 /* Private */,
+       4,    0,   41,    2, 0x08 /* Private */,
+       5,    0,   42,    2, 0x08 /* Private */,
+       6,    0,   43,    2, 0x08 /* Private */,
+
+ // slots: parameters
+    QMetaType::Void,
+    QMetaType::Void,
+    QMetaType::Void,
+    QMetaType::Void,
+    QMetaType::Void,
+
+       0        // eod
+};
+
+void QtMainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        auto *_t = static_cast<QtMainWindow *>(_o);
+        (void)_t;
+        switch (_id) {
+        case 0: _t->new_input(); break;
+        case 1: _t->load_input(); break;
+        case 2: _t->exit(); break;
+        case 3: _t->run_input(); break;
+        case 4: _t->exit_input(); break;
+        default: ;
+        }
+    }
+    (void)_a;
+}
+
+QT_INIT_METAOBJECT const QMetaObject QtMainWindow::staticMetaObject = { {
+    QMetaObject::SuperData::link<QMainWindow::staticMetaObject>(),
+    qt_meta_stringdata_QtMainWindow.data,
+    qt_meta_data_QtMainWindow,
+    qt_static_metacall,
+    nullptr,
+    nullptr
+} };
+
+
+const QMetaObject *QtMainWindow::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QtMainWindow::qt_metacast(const char *_clname)
+{
+    if (!_clname) return nullptr;
+    if (!strcmp(_clname, qt_meta_stringdata_QtMainWindow.stringdata0))
+        return static_cast<void*>(this);
+    return QMainWindow::qt_metacast(_clname);
+}
+
+int QtMainWindow::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QMainWindow::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 5)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 5;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 5)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 5;
+    }
+    return _id;
+}
+QT_WARNING_POP
+QT_END_MOC_NAMESPACE

+ 118 - 0
moc/view_solution.cpp

@@ -0,0 +1,118 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'view_solution.hpp'
+**
+** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.2)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include <memory>
+#include "../src/qt/view_solution.hpp"
+#include <QtCore/qbytearray.h>
+#include <QtCore/qmetatype.h>
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'view_solution.hpp' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 67
+#error "This file was generated using the moc from 5.15.2. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+struct qt_meta_stringdata_QtViewSolution_t {
+    QByteArrayData data[3];
+    char stringdata0[28];
+};
+#define QT_MOC_LITERAL(idx, ofs, len) \
+    Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
+    qptrdiff(offsetof(qt_meta_stringdata_QtViewSolution_t, stringdata0) + ofs \
+        - idx * sizeof(QByteArrayData)) \
+    )
+static const qt_meta_stringdata_QtViewSolution_t qt_meta_stringdata_QtViewSolution = {
+    {
+QT_MOC_LITERAL(0, 0, 14), // "QtViewSolution"
+QT_MOC_LITERAL(1, 15, 11), // "time_change"
+QT_MOC_LITERAL(2, 27, 0) // ""
+
+    },
+    "QtViewSolution\0time_change\0"
+};
+#undef QT_MOC_LITERAL
+
+static const uint qt_meta_data_QtViewSolution[] = {
+
+ // content:
+       8,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       1,   14, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+       0,    0, // constructors
+       0,       // flags
+       0,       // signalCount
+
+ // slots: name, argc, parameters, tag, flags
+       1,    1,   19,    2, 0x08 /* Private */,
+
+ // slots: parameters
+    QMetaType::Void, QMetaType::Int,    2,
+
+       0        // eod
+};
+
+void QtViewSolution::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        auto *_t = static_cast<QtViewSolution *>(_o);
+        (void)_t;
+        switch (_id) {
+        case 0: _t->time_change((*reinterpret_cast< int(*)>(_a[1]))); break;
+        default: ;
+        }
+    }
+}
+
+QT_INIT_METAOBJECT const QMetaObject QtViewSolution::staticMetaObject = { {
+    QMetaObject::SuperData::link<QWidget::staticMetaObject>(),
+    qt_meta_stringdata_QtViewSolution.data,
+    qt_meta_data_QtViewSolution,
+    qt_static_metacall,
+    nullptr,
+    nullptr
+} };
+
+
+const QMetaObject *QtViewSolution::metaObject() const
+{
+    return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
+}
+
+void *QtViewSolution::qt_metacast(const char *_clname)
+{
+    if (!_clname) return nullptr;
+    if (!strcmp(_clname, qt_meta_stringdata_QtViewSolution.stringdata0))
+        return static_cast<void*>(this);
+    return QWidget::qt_metacast(_clname);
+}
+
+int QtViewSolution::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QWidget::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    if (_c == QMetaObject::InvokeMetaMethod) {
+        if (_id < 1)
+            qt_static_metacall(this, _c, _id, _a);
+        _id -= 1;
+    } else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
+        if (_id < 1)
+            *reinterpret_cast<int*>(_a[0]) = -1;
+        _id -= 1;
+    }
+    return _id;
+}
+QT_WARNING_POP
+QT_END_MOC_NAMESPACE

BIN
obj/geometry.o


BIN
obj/initial_state.o


BIN
obj/kernel.o


BIN
obj/math/algo.o


BIN
obj/math/poly3.o


BIN
obj/math/spline.o


BIN
obj/physics.o


BIN
obj/qt/input.o


BIN
obj/qt/input_geometry.o


BIN
obj/qt/input_geometry_curves.o


BIN
obj/qt/input_physics.o


BIN
obj/qt/input_time.o


BIN
obj/qt/mainwindow.o


BIN
obj/qt/view_solution.o


BIN
obj/qt/view_solution_geometry.o


BIN
obj/source.o


BIN
obj/time.o


+ 86 - 0
src/geometry.cpp

@@ -2,6 +2,20 @@
 
 double inf = numeric_limits<double>::infinity();
 
+Geometry::Geometry(){
+  lX=0;
+  nX=0;
+  dX=0;
+  hsoil=nullptr;
+  dhsoil=nullptr;
+  hbot=nullptr;
+  dhbot=nullptr;
+  nZ=nullptr;
+  dZ=nullptr;
+  Z=nullptr;
+}
+
+// Obsolete, we must add hsat
 Geometry::Geometry(double _lX,size_t _nX,size_t _nZ,Func _hsoil,Func _dhsoil,Func _hbot,Func _dhbot){
   lX=_lX;
   nX=_nX;
@@ -22,6 +36,35 @@ Geometry::Geometry(double _lX,size_t _nX,size_t _nZ,Func _hsoil,Func _dhsoil,Fun
     dhbot[k]=_dhbot(x);
   }
   double dZ_avg=(hs_max-hb_min)/_nZ;
+  initZ(dZ_avg);
+}
+
+
+/*Geometry::Geometry(double _lX,size_t _nX,double depth,size_t _nZ,Spline& Ssoil,Spline& Sbot){
+  lX=_lX;
+  nX=_nX;
+  dX=lX/nX;
+  hsoil=new double[nX];
+  dhsoil=new double[nX];
+  hbot=new double[nX];
+  dhbot=new double[nX];
+  double hs_max=-inf,hb_min=inf;
+  double v;
+  for(size_t k=0;k<nX;++k){
+    double x=k*dX/lX;
+    v=hsoil[k]=1-Ssoil(x);
+    hs_max=max(v,hs_max);
+    dhsoil[k]=-Ssoil.derivate(x);
+    v=hbot[k]=1-Sbot(x);
+    hb_min=min(v,hb_min);
+    dhbot[k]=-Sbot.derivate(x);
+  }
+  double dZ_avg=(hs_max-hb_min)/_nZ;
+  initZ(dZ_avg);
+  }*/
+
+void
+Geometry::initZ(double dZ_avg){
   nZ=new size_t[nX];
   dZ=new double[nX];
   Z=new double*[nX];
@@ -37,3 +80,46 @@ Geometry::Geometry(double _lX,size_t _nX,size_t _nZ,Func _hsoil,Func _dhsoil,Fun
     }
   }
 }
+
+void
+Geometry::initDefault(){
+  lX=20;
+  nX=100;
+  dX=lX/(nX-1);
+  hsoil=new double[nX];
+  dhsoil=new double[nX];
+  hbot=new double[nX];
+  dhbot=new double[nX];
+  for(size_t i=0;i<nX;++i){
+    hsoil[i]=0.7;
+    hbot[i]=0.3;
+    dhsoil[i]=0;
+    dhbot[i]=0;
+  }
+  depth=0.7-0.3;
+  nZ_max=100;
+  initZ(depth/nZ_max);
+}
+
+void
+Geometry::update(double _lX,size_t _nX,double _depth,size_t _nZ_max){
+  lX=_lX;
+  depth=_depth;
+  if(_nX!=nX or _nZ_max!=nZ_max){
+    delete[] hsoil;
+    delete[] dhsoil;
+    delete[] hbot;
+    delete[] dhbot;
+    delete[] nZ;
+    delete[] dZ;
+    for(size_t i=0;i<nX;++i) delete[] Z[i];
+    delete[] Z;
+    nX=_nX;
+    nZ_max=_nZ_max;
+    hsoil=new double[nX];
+    dhsoil=new double[nX];
+    hbot=new double[nX];
+    dhbot=new double[nX];
+    initZ(depth/nZ_max);
+  }
+}

+ 20 - 2
src/geometry.hpp

@@ -4,6 +4,8 @@
 #include <iostream>
 #include <limits>
 
+#include "math/spline.hpp"
+
 using namespace std;
 
 using Func = double (*)(double);
@@ -13,9 +15,15 @@ extern double inf;
 //! The Geometry class contains all geometric parameters of the domain.
 class Geometry{
 public:
+  //!
+  Geometry();
+  
   //! Geometry constructor
-  Geometry(double lX,size_t nX,size_t nZ,Func hsoil,Func dhsoil,Func hbot,Func dhbot);
-	   
+  Geometry(double _lX,size_t _nX,size_t _nZ,Func _hsoil,Func _dhsoil,Func _hbot,Func _dhbot);
+
+
+  void initDefault();
+  
   //! Horizontal length of the domain
   double lX;
 
@@ -25,6 +33,11 @@ public:
   //! Horizontal step
   double dX;
 
+  size_t nZ_max;
+
+  double depth;
+
+  
   //! Level of the soil depending on X, e.g, hsoil[k]=level of the soil at X=k*dX.
   //! Vector of size nX.
   double* hsoil;
@@ -39,6 +52,7 @@ public:
   //! Derivative of the bottom depending on X, vector of size nX.
   double* dhbot;
 
+  
   //! Number of vertical step at a given X, vector of size nX.
   size_t* nZ;
   
@@ -47,6 +61,10 @@ public:
 
   //! Vertical considered positions at a given X, vector of vectors of size nX. For each k, Z[k] is a vector of size nZ[k]
   double** Z;
+
   
+  void initZ(double dZ_avg);
+
+  void update(double _lX,size_t _nX,double _depth,size_t _nZ_max);
 };
 #endif

+ 1 - 0
src/initial_state.cpp

@@ -0,0 +1 @@
+#include "initial_state.hpp"

+ 10 - 0
src/initial_state.hpp

@@ -0,0 +1,10 @@
+#ifndef INITIAL_STATE_HPP
+#define INITIAL_STATE_HPP
+
+class InitialState{
+private:
+public:
+  
+};
+
+#endif

+ 2 - 0
src/kernel.cpp

@@ -0,0 +1,2 @@
+#include "kernel.hpp"
+

+ 30 - 0
src/kernel.hpp

@@ -0,0 +1,30 @@
+#ifndef KERNEL_HPP
+#define KERNEL_HPP
+
+#include "physics.hpp"
+#include "geometry.hpp"
+#include "time.hpp"
+
+
+class Kernel{
+public:
+  Geometry& geometry;
+  size_t step;
+  double*** P;
+  
+  size_t nZ(size_t ix);
+  double Z(size_t ix,size_t iz);
+  void next();
+};
+
+inline size_t
+Kernel::nZ(size_t ix){
+  return geometry.nZ[ix];
+}
+
+inline double
+Kernel::Z(size_t ix,size_t iz){
+  return geometry.Z[ix][iz];
+}
+
+#endif

+ 9 - 32
src/main.cpp

@@ -24,38 +24,15 @@ double dhbot(double x){
 
 int main(int argc,char** argv){
   QApplication app(argc,argv);
-  QtMainWindow window;
-  window.resize(1280,1024);
-  window.show();
+  QtMainWindow* window;
+  if(argc==2){
+    window=new QtMainWindow(argv[1]);
+  }
+  else{
+    window=new QtMainWindow;
+  }
+  window->resize(1280,1024);
+  window->show();
   return app.exec();
-  /*
-  Physics physics(BrooksCorey);
-  //Physical parameters 
-
-  physics.g=9.81;
-  physics.rho=1000;
-  physics.phi=0.3;
-  physics.k0=3e-5;
-  physics.nivrivsat=0.01;
   
-  //BrooksCorey model data
-  physics.model_datas[0]=-2000;
-  physics.model_datas[1]=0;
-  physics.model_datas[2]=3;
-  physics.model_datas[3]=11;
-
-  //BrooksCorey test
-  double v,dv;
-  double P=-4000;
-  cout<<physics.s(P)<<endl;
-  cout<<physics.ds(P)<<endl;
-  cout<<physics.kr(P)<<endl;
-  cout<<physics.dkr(P)<<endl;
-  physics.s_ds(P,v,dv);
-  cout<<v<<' '<<dv<<endl;
-  physics.kr_dkr(P,v,dv);
-  cout<<v<<' '<<dv<<endl;
-
-  //Geometry test
-  Geometry geometry(10,200,200,&hsoil,&dhsoil,&hbot,&dhbot);*/
 }

+ 16 - 0
src/math/algo.cpp

@@ -0,0 +1,16 @@
+#include "algo.hpp"
+
+void Thomas(size_t n,double* a,double* b,double* c,double* d,double* x){
+  double last=c[0]=c[0]/b[0];
+  for(size_t i=1;i<n-1;++i){
+    last=c[i]=c[i]/(b[i]-a[i-1]*last);
+  }
+  last=d[0]=d[0]/b[0];
+  for(size_t i=1;i<n;++i){
+    last=d[i]=(d[i]-a[i-1]*last)/(b[i]-a[i-1]*c[i-1]);
+  }
+  last=x[n-1]=d[n-1];
+  for(int i=n-1;i>0;--i){
+    last=x[i-1]=d[i-1]-c[i-1]*last;
+  }
+}

+ 17 - 0
src/math/algo.hpp

@@ -0,0 +1,17 @@
+#ifndef ALGO_HPP
+#define ALGO_HPP
+
+#include <iostream>
+
+/*! Thomas algorithm to solve AX=B where A is a tridiagonal matrix
+  \param n size of the matrix A
+  \param a (n-1) sub-diagonal coefficients of matrix A
+  \param b n diagonal coefficients of matrix A
+  \param c (n-1) sup-diagonal coefficients of matrix A (modified)
+  \param d n coefficients of vector B (modified)
+  \param x n coefficients vector to store the result (modified)
+*/
+
+void Thomas(size_t n,double* a,double* b,double* c,double* d,double* x);
+
+#endif

+ 31 - 0
src/math/point.hpp

@@ -0,0 +1,31 @@
+#ifndef POINT_HPP
+#define POINT_HPP
+
+#include <iostream>
+
+using namespace std;
+
+class Point{
+public:
+  double x;
+  double y;
+  Point();
+  Point(double x,double y);
+};
+
+ostream& operator<<(ostream& os,const Point& P);
+
+inline
+Point::Point():x(0),y(0){
+}
+
+inline
+Point::Point(double _x,double _y):x(_x),y(_y){
+}
+
+inline ostream&
+operator<<(ostream& os,const Point& P){
+  return os<<'('<<P.x<<','<<P.y<<')';
+}
+
+#endif

+ 18 - 0
src/math/poly3.cpp

@@ -0,0 +1,18 @@
+#include "poly3.hpp"
+
+double
+Poly3::operator()(double x) const{
+  double res=a;
+  res=res*x+b;
+  res=res*x+c;
+  res=res*x+d;
+  return res;
+}
+
+double
+Poly3::derivate(double x) const{
+  double res=a;
+  res=res*x+b;
+  res=res*x+c;
+  return res;
+}

+ 31 - 0
src/math/poly3.hpp

@@ -0,0 +1,31 @@
+#ifndef POLY3_HPP
+#define POLY3_HPP
+
+#include <iostream>
+
+using namespace std;
+
+class Poly3{
+public:
+  double a,b,c,d;
+  Poly3();
+  Poly3(double a,double b,double c,double d);
+  double operator()(double x) const;
+  double derivate(double x) const;
+};
+
+ostream& operator<<(ostream& os,const Poly3& P);
+
+inline
+Poly3::Poly3(){
+}
+
+inline
+Poly3::Poly3(double _a,double _b,double _c,double _d):a(_a),b(_b),c(_c),d(_d){
+}
+
+inline
+ostream& operator<<(ostream& os,const Poly3& P){
+  return os<<'['<<P.a<<','<<P.b<<','<<P.c<<','<<P.d<<']';
+}
+#endif

+ 80 - 0
src/math/spline.cpp

@@ -0,0 +1,80 @@
+#include "spline.hpp"
+
+void
+Spline::setPoints(Point* _points,size_t _n){
+  P=_points;
+  n=_n;
+  q=new Poly3[n-1];
+}
+
+void Spline::compute(){
+  double* Asub=new double[n-1];
+  double* Adiag=new double[n];
+  double* Asup=new double[n-1];
+  double* B=new double[n];
+  double* m=new double[n];
+  double* h=new double[n-1];
+
+  //Compute h
+  for(size_t i=0;i<n-1;++i){
+    h[i]=P[i+1].x-P[i].x;
+  }
+
+  //Compute B
+  B[0]=0;
+  for(size_t i=1;i<n-1;++i){
+    B[i]=6*((P[i+1].y-P[i].y)/h[i]-(P[i].y-P[i-1].y)/h[i-1]);
+  }
+  B[n-1]=0;
+
+  //Compute A
+  Adiag[0]=1;
+  Asup[0]=0;
+  for(size_t i=1;i<n-1;++i){
+    Asub[i-1]=h[i-1];
+    Adiag[i]=2*(h[i-1]+h[i]);
+    Asup[i]=h[i];
+  }
+  Asub[n-2]=0;
+  Adiag[n-1]=1;
+
+  //Compute m
+  Thomas(n,Asub,Adiag,Asup,B,m);
+
+  //Compute ploynimials q
+  for(size_t i=0;i<n-1;++i){
+    q[i].d=P[i].y;
+    q[i].b=m[i]/2;
+    q[i].a=(m[i+1]-m[i])/(6*h[i]);
+    q[i].c=(P[i+1].y-P[i].y)/h[i]-h[i]*(m[i+1]-m[i])/6-(h[i]*m[i])/2;
+    
+  }
+  
+  delete[] Asub;
+  delete[] Adiag;
+  delete[] Asup;
+  delete[] B;
+  delete[] m;
+  delete[] h;
+}
+
+size_t
+Spline::findIndex(double x) const{
+//Find minimal i s.t. P[i].x>x
+  size_t i=0;
+  while(i<n-1 and P[i].x<=x) ++i;
+  // Here i=n-1 or P[i].x>x
+  return i-1;
+}
+
+double
+Spline::operator()(double x) const{
+  size_t i=findIndex(x);
+  return q[i](x-P[i].x);	     
+}
+
+double
+Spline::derivate(double x) const{
+  size_t i=findIndex(x);
+  return q[i].derivate(x-P[i].x);
+}

+ 35 - 0
src/math/spline.hpp

@@ -0,0 +1,35 @@
+#ifndef SPLINE_HPP
+#define SPLINE_HPP
+
+#include <iostream>
+#include "math/point.hpp"
+#include "math/poly3.hpp"
+#include "math/algo.hpp"
+
+using namespace std;
+
+
+class Spline{
+private:
+  Poly3* q;
+  Point* P;
+  size_t n;
+  size_t findIndex(double x) const;
+public:
+  Spline();
+  ~Spline();
+  void setPoints(Point* points,size_t n);
+  void compute();
+  double operator()(double x) const;
+  double derivate(double x) const;
+};
+
+inline Spline::Spline(){
+}
+
+inline Spline::~Spline(){
+  delete[] q;
+}
+
+
+#endif

+ 81 - 68
src/physics.cpp

@@ -1,81 +1,94 @@
 #include "physics.hpp"
-
-double Physics::model_datas[6];
-
-//-------------
-// Constructor
-//-------------
-
-Physics::Physics(PhysicModel model){
-  switch(model){
-  case BrooksCorey:
-    s=&s_BC;
-    ds=&ds_BC;
-    s_ds=&s_ds_BC;
-    kr=&kr_BC;
-    dkr=&dkr_BC;
-    kr_dkr=&kr_dkr_BC;
-    break;
-  default:
-    assert(false);
-  };
-
-}
 //------------------------
 // Brooks and Corey model
 //------------------------
 
-#define Psat model_datas[0]
-#define sres model_datas[1]
-#define lambda model_datas[2]
-#define alpha model_datas[3]
-
-double
-Physics::s_BC(double P){
-  if(P>=Psat) return 1;
-  return sres+(1-sres)*pow(Psat/P,lambda);
-}
-
-double
-Physics::ds_BC(double P){
-  if(P>=Psat) return 0;
-  return ((sres-1)*lambda*pow(Psat/P,lambda))/P;
-}
+namespace Physics{
+  double g=9.81;
+  double rho=1000;
+  double phi=0.3;
+  double k0=3e-5;
+  double nivrivsat=0.01;
+  double (*s)(double)=&s_BC;
+  double (*ds)(double)=&ds_BC;
+  void (*s_ds)(double,double&,double&)=&s_ds_BC;
+  double (*kr)(double)=&kr_BC;
+  double (*dkr)(double)=&dkr_BC;
+  void (*kr_dkr)(double,double&,double&)=&kr_dkr_BC;
+  double model_data[6]={-2000,0,3,11,0,0};
+  
+#define Psat model_data[0]
+#define sres model_data[1]
+#define lambda model_data[2]
+#define alpha model_data[3]
 
-void
-Physics::s_ds_BC(double P,double& v,double& dv){
-  if(P>=Psat){
-    v=1;
-    dv=0;
+  void setModel(Model model){
+    switch(model){
+    case BrooksCorey:
+      s=&s_BC;
+      ds=&ds_BC;
+      s_ds=&s_ds_BC;
+      kr=&kr_BC;
+      dkr=&dkr_BC;
+      kr_dkr=&kr_dkr_BC;
+      Psat=-2000;
+      sres=0;
+      lambda=3;
+      alpha=11;
+      break;
+    default:
+      assert(false);
+    };
   }
-  else{
-    double t=(1-sres)*pow(Psat/P,lambda);
-    v=sres+t;
-    dv=-(lambda*t)/P;
+  
+  
+  double
+  s_BC(double P){
+    if(P>=Psat) return 1;
+    return sres+(1-sres)*pow(Psat/P,lambda);
+  }
+  
+  double
+  ds_BC(double P){
+    if(P>=Psat) return 0;
+    return ((sres-1)*lambda*pow(Psat/P,lambda))/P;
+  }
+  
+  void
+  s_ds_BC(double P,double& v,double& dv){
+    if(P>=Psat){
+      v=1;
+      dv=0;
+    }
+    else{
+      double t=(1-sres)*pow(Psat/P,lambda);
+      v=sres+t;
+      dv=-(lambda*t)/P;
+    }
+  }
+  
+  double
+  kr_BC(double P){
+    if(P>=Psat) return 1;
+    return pow(Psat/P,alpha);
   }
-}
-
-double
-Physics::kr_BC(double P){
-  if(P>=Psat) return 1;
-  return pow(Psat/P,alpha);
-}
-
-double
-Physics::dkr_BC(double P){
-  if(P>=Psat) return 0;
-  return -alpha*pow(Psat/P,alpha)/P;
-}
 
-void
-Physics::kr_dkr_BC(double P,double& v,double& dv){
-  if(P>=Psat){
-    v=1;
-    dv=0;
+  double
+  dkr_BC(double P){
+    if(P>=Psat) return 0;
+    return -alpha*pow(Psat/P,alpha)/P;
   }
-  else{
-    double t=pow(Psat/P,alpha);
-    v=t;
+
+  void
+  kr_dkr_BC(double P,double& v,double& dv){
+    if(P>=Psat){
+      v=1;
+      dv=0;
+    }
+    else{
+      double t=pow(Psat/P,alpha);
+      v=t;
     dv=-(alpha*t)/P;
+    }
   }
 }

+ 31 - 33
src/physics.hpp

@@ -4,72 +4,70 @@
 #include <cmath>
 #include <cassert>
 
-enum PhysicModel{BrooksCorey};
+//! The Physics namespace contains all physical parameters characterising the soil.
+namespace Physics{
 
-//! The Physics class contains all physical parameters characterising the soil.
-class Physics{
-public:
-  //! Physics constructor
-  Physics(PhysicModel model);
+  enum Model{BrooksCorey};
+  
+  //! Set physics model
+  void setModel(Model model);
   
   //! Gravity acceleration (m.s^-2)
-  double g;
+  extern double g;
   //! Fluid density (g.l^(-1))
-  double rho;
+  extern double rho;
   
   //! Porosity of the soil
-  double phi;
+  extern double phi;
   //! Conductivity of the saturated soil
-  double k0;
+  extern double k0;
 
   //! Characterise the water pressure at the bottom of the overland water
-  double nivrivsat;
+  extern double nivrivsat;
 
- 
-  //! Return the saturation in function of the pressure
-  double (*s)(double);
+   //! Return the saturation in function of the pressure
+  extern double (*s)(double);
   //! Return the derivtive of the saturation in function of the pressure
-  double (*ds)(double);
+  extern double (*ds)(double);
   //! Set the saturation and its derivative in function of the pressure
-  void (*s_ds)(double,double&,double&);
+  extern void (*s_ds)(double,double&,double&);
   
   //! Return the relative conductivity in function of the pressure
-  double (*kr)(double);
+  extern double(*kr)(double);
   //! Return the derivtive of the relative conductivity in function of the pressure
-  double (*dkr)(double);
+  extern double (*dkr)(double);
   //! Set the relative conductivity and its derivative in function of the pressure
-  void (*kr_dkr)(double,double&,double&);
+  extern void (*kr_dkr)(double,double&,double&);
   
 
   //---------------------
   // Models descriptions 
   //---------------------
-
+  
   //! Datas used to define the model
-  static double model_datas[6];
+  extern double model_data[6];
 
   //------------------------
   // Brooks and Corey model
   //------------------------
   
-  //model_datas[0] -> psat : minimal pressure such that s(psat)=1
-  //model_datas[1] -> sres : residual pressure
-  //model_datas[2] -> lambda 
-  //model_datas[3] -> alpha
+  //model_data[0] -> psat : minimal pressure such that s(psat)=1
+  //model_data[1] -> sres : residual pressure
+  //model_data[2] -> lambda 
+  //model_data[3] -> alpha
   
   //! Brooks and Corey saturation map
-  static double s_BC(double P);
+  double s_BC(double P);
   //! Brooks and Corey derivative of the saturation map
-  static double ds_BC(double P);
+  double ds_BC(double P);
   //! Brooks and Corey saturation and its derivative setter
-  static void (s_ds_BC)(double P,double& v,double& dv);
+  void (s_ds_BC)(double P,double& v,double& dv);
 
   //! Brooks and Corey relative conductivity map
-  static double kr_BC(double P);
+  double kr_BC(double P);
   //! Brooks and Corey derivative of the relative conductivity map
-  static double dkr_BC(double P);
+  double dkr_BC(double P);
   //! Brooks and Corey relative conductivity and its derivative setter
-  static void (kr_dkr_BC)(double P,double& v,double& dv);
-
-};
+  void (kr_dkr_BC)(double P,double& v,double& dv);
+}
 #endif

+ 1 - 0
src/qt/.#input.hpp

@@ -0,0 +1 @@
+fromentin@atuan.36324:1624433263

+ 136 - 5
src/qt/input.cpp

@@ -1,30 +1,161 @@
 #include "input.hpp"
 
 QtInput::QtInput():QWidget(){
+  geometry=new Geometry;
+  geometry->initDefault();
+  
   main_layout=new QVBoxLayout;
-  button_layout=new QHBoxLayout();
+  button_layout=new QHBoxLayout;
   tab_widget=new QTabWidget;
-  button_widget=new QWidget();
-  button_ok=new QPushButton("Ok");
+  button_widget=new QWidget;
+  button_save=new QPushButton("Save");
   button_cancel=new QPushButton("Cancel");
+  button_run=new QPushButton("Run");
 
+  input_view=new QtInputView;
   input_physics=new QtInputPhysics;
   input_time=new QtInputTime;
-  input_geometry=new QtInputGeometry;
+  input_geometry=new QtInputGeometry(geometry);
+  input_initial_state=new QtInputInitialState;
+  input_sources=new QtInputSources;
 
+  input_view->setGeometry(geometry);
+  input_view->updateGeometry();
+  
   //Tab
   tab_widget->addTab(input_physics,"Physics");
   tab_widget->addTab(input_time,"Time");
   tab_widget->addTab(input_geometry,"Geometry");
+  tab_widget->addTab(input_initial_state,"Initial state");
+  tab_widget->addTab(input_sources,"Sources");
   
   //Buttons
-  button_layout->addWidget(button_ok);
+  button_layout->addWidget(button_run);
+  button_layout->addWidget(button_save);
   button_layout->addWidget(button_cancel);
   button_widget->setLayout(button_layout);
 
   //Main
   main_layout->addWidget(tab_widget);
+  main_layout->addWidget(input_view,2);
   main_layout->addWidget(button_widget);
   setLayout(main_layout);
 
+  //Conectors
+  connect(button_save,&QPushButton::clicked,this,&QtInput::save);
+  connect(button_cancel,&QPushButton::clicked,this,&QtInput::cancel);
+  connect(button_run,&QPushButton::clicked,this,&QtInput::run);
+  connect(input_geometry,&QtInputGeometry::geometryChanged,this,&QtInput::updateGeometry);
+  connect(tab_widget,&QTabWidget::currentChanged,this,&QtInput::changeTabIndex);
+
+  previous_index=-1;
+
+}
+
+QtInput::QtInput(QString filename):QtInput(){
+  load(filename.toStdString());
+}
+
+QtInput::~QtInput(){
+}
+
+bool
+QtInput::validate(){
+  QWidget* widget=input_physics->validate();
+  if(widget!=nullptr){
+    QMessageBox msgBox;
+    msgBox.setText("Incorrect physics entry");
+    msgBox.exec();
+    tab_widget->setCurrentWidget(input_physics);
+    widget->setFocus();
+    return false;
+  }
+  widget=input_time->validate();
+  if(widget!=nullptr){
+    QMessageBox msgBox;
+    msgBox.setText("Incorrect time entry");
+    msgBox.exec();
+    tab_widget->setCurrentWidget(input_time);
+    widget->setFocus();
+    return false;
+  }
+  widget=input_geometry->validate();
+  if(widget!=nullptr){
+    QMessageBox msgBox;
+    msgBox.setText("Incorrect geometry entry");
+    msgBox.exec();
+    tab_widget->setCurrentWidget(input_geometry);
+    widget->setFocus();
+    return false;
+  }
+  return true;  
+}
+
+void
+QtInput::save(){
+  if(validate()){
+    QString filename=QFileDialog::getSaveFileName(this,"Save input","inputs/","QT input file (*.input)");
+    if(not filename.isEmpty()){
+      if(filename.indexOf(".input")==-1){
+	filename.append(".input");
+      }
+      save_input(filename.toStdString());
+    }
+  }
+}
+
+void
+QtInput::run(){
+  if(validate()){
+    emit run_signal();
+  }
+}
+
+void
+QtInput::save_input(string filename){
+  fstream file;
+  file.open(filename.c_str(),fstream::out|fstream::trunc|fstream::binary);
+  input_physics->save(file);
+  input_time->save(file);
+  input_geometry->save(file);
+  file.close();
+}
+
+void
+QtInput::cancel(){
+  emit exit_signal();
+}
+
+void
+QtInput::load(string filename){
+  fstream file;
+  file.open(filename.c_str(),fstream::in|fstream::binary);
+  input_physics->load(file);
+  input_time->load(file);
+  input_geometry->load(file);
+  file.close();
+}
+
+void
+QtInput::changeTabIndex(int index){
+  if(previous_index==2){
+    updateGeometry();
+  }
+  previous_index=index;
+  
+}
+
+void
+QtInput::updateGeometry(){
+  QWidget* widget=input_geometry->validate();
+  if(widget!=nullptr){
+    QMessageBox msgBox;
+    msgBox.setText("Incorrect geometry entry");
+    msgBox.exec();
+    tab_widget->setCurrentWidget(input_geometry);
+    widget->setFocus();
+  }
+  else{
+    input_view->updateGeometry();
+  }
 }

+ 36 - 3
src/qt/input.hpp

@@ -5,25 +5,58 @@
 #include <QHBoxLayout>
 #include <QVBoxLayout>
 #include <QPushButton>
+#include <QMessageBox>
+#include <QFileDialog>
+#include <fstream>
+
 #include "input_physics.hpp"
 #include "input_time.hpp"
 #include "input_geometry.hpp"
+#include "input_initial_state.hpp"
+#include "input_sources.hpp"
+#include "input_view.hpp"
+#include "geometry.hpp"
+
+using namespace std;
 
 class QtInput:public QWidget{
+  Q_OBJECT
 private:
+  int previous_index;
+  Geometry* geometry;
+  
   QVBoxLayout* main_layout;
   QHBoxLayout* button_layout;
   QTabWidget* tab_widget;
   QWidget* button_widget;
-  QPushButton* button_ok;
+  QPushButton* button_save;
+  QPushButton* button_run;
   QPushButton* button_cancel;
   QtInputPhysics* input_physics;
   QtInputTime* input_time;
   QtInputGeometry* input_geometry;
-
+  QtInputInitialState* input_initial_state;
+  QtInputSources* input_sources;
+  QtInputView* input_view;
+ 
+  bool validate();
+  void load(string filename);
 public:
   QtInput();
-  
+  QtInput(QString filename);
+  ~QtInput();
+  void save_input(string filename);
+
+signals:
+  void run_signal();
+  void exit_signal();
+private slots:
+  void run();
+  void save();
+  void cancel();
+  void changeTabIndex(int index);
+  void updateGeometry();
 };
 
+
 #endif

+ 89 - 2
src/qt/input_geometry.cpp

@@ -1,7 +1,94 @@
 #include "input_geometry.hpp"
 
-QtInputGeometry::QtInputGeometry():QWidget(){
+QtInputGeometry::QtInputGeometry(Geometry* _geometry):QWidget(){
+  geometry=_geometry;
+  
+  main_layout=new QVBoxLayout;
+  lX_label=new QLabel("Horizontal lenght of the domain (l<sub>X</sub>)");
+  nX_label=new QLabel("Number of horizontal steps (n<sub>X</sub>)");
+  nZ_label=new QLabel("Number of vertical steps (n<sub>Z</sub>)");
+  depth_label=new QLabel("Maximal height between h<sub>soil</sub> and h<sub>bot</sub> (depth)");
+  lX_input=new QLineEdit(QString::number(geometry->lX));
+  nX_input=new QLineEdit(QString::number(geometry->nX));
+  nZ_input=new QLineEdit(QString::number(geometry->nZ_max));
+  depth_input=new QLineEdit(QString::number(geometry->depth));
+
+  //Labels
+  lX_label->setTextFormat(Qt::RichText);
+  nX_label->setTextFormat(Qt::RichText);
+  nZ_label->setTextFormat(Qt::RichText);
+  depth_label->setTextFormat(Qt::RichText);
+
+  //Button
+  refresh_button=new QPushButton("Refresh");
+
+  //Main layout
+  int vspace=20;
+  main_layout->addWidget(lX_label);
+  main_layout->addWidget(lX_input);
+  main_layout->addSpacing(vspace);
+  main_layout->addWidget(nX_label);
+  main_layout->addWidget(nX_input);
+  main_layout->addSpacing(vspace);
+  main_layout->addWidget(depth_label);
+  main_layout->addWidget(depth_input);
+  main_layout->addSpacing(vspace);
+  main_layout->addWidget(nZ_label);
+  main_layout->addWidget(nZ_input);
+  main_layout->addSpacing(2*vspace);
+  main_layout->addWidget(refresh_button);
+  main_layout->addStretch();
+
+  setLayout(main_layout);
+
+  //Validators
+  positive_double_validator=new QDoubleValidator;
+  positive_double_validator->setBottom(0);
+  positive_int_validator=new QIntValidator;
+  positive_int_validator->setBottom(1);
+  lX_input->setValidator(positive_double_validator);
+  nX_input->setValidator(positive_int_validator);
+  depth_input->setValidator(positive_double_validator);
+  nZ_input->setValidator(positive_int_validator);
+
+  connect(refresh_button,&QPushButton::clicked,this,&QtInputGeometry::emitGeometryChanged);
 }
 
-QtInputGeometry::~QtInputGeometry(){
+QWidget*
+QtInputGeometry::validate(){
+  if(not lX_input->hasAcceptableInput()) return lX_input;
+  if(not nX_input->hasAcceptableInput()) return nX_input;
+  if(not depth_input->hasAcceptableInput()) return depth_input;
+  if(not nZ_input->hasAcceptableInput()) return nZ_input;
+  return nullptr;
 }
+
+void
+QtInputGeometry::save(fstream& file){
+  double d;
+  size_t n;
+  d=lX_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  n=nX_input->text().toULong();
+  file.write((char*)&n,sizeof(size_t));
+  d=depth_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  n=nZ_input->text().toULong();
+  file.write((char*)&n,sizeof(size_t));
+}
+
+void
+QtInputGeometry::load(fstream& file){
+  double d;
+  size_t n;
+  file.read((char*)&d,sizeof(double));
+  lX_input->setText(QString::number(d));
+  file.read((char*)&n,sizeof(size_t));
+  nX_input->setText(QString::number(n));
+  file.read((char*)&d,sizeof(double));
+  depth_input->setText(QString::number(d));
+  file.read((char*)&n,sizeof(size_t));
+  nZ_input->setText(QString::number(n));
+}
+
+

+ 45 - 1
src/qt/input_geometry.hpp

@@ -2,16 +2,60 @@
 #define QT_INPUT_GEOMETRY_HPP
 
 #include <iostream>
+#include <fstream>
 
 #include <QWidget>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QLineEdit>
+#include <QDoubleValidator>
+#include <QIntValidator>
+#include <QPushButton>
+#include "geometry.hpp"
+
+static const double def_lX=10;
+static const size_t def_nX=100;
+static const size_t def_depth=1;
+static const size_t def_nZ=100;
 
 using namespace std;
 
 class QtInputGeometry:public QWidget{
+  Q_OBJECT
 private:
+  Geometry* geometry;
+  QVBoxLayout* main_layout;
+  QLabel* lX_label;
+  QLabel* nX_label;
+  QLabel* nZ_label;
+  QLabel* depth_label;
+  QLineEdit* lX_input;
+  QLineEdit* nX_input;
+  QLineEdit* nZ_input;
+  QLineEdit* depth_input;
+  QPushButton* refresh_button;
+  QDoubleValidator* positive_double_validator;
+  QIntValidator* positive_int_validator;
+  
 public:
-  QtInputGeometry();
+  QtInputGeometry(Geometry* geometry);
   ~QtInputGeometry();
+  QWidget* validate();
+  void save(fstream& file);
+  void load(fstream& file);
+public slots:
+  void emitGeometryChanged();
+signals:
+  void geometryChanged();
 };
 
+inline
+QtInputGeometry::~QtInputGeometry(){
+}
+
+inline void
+QtInputGeometry::emitGeometryChanged(){
+  emit geometryChanged();
+}
+
 #endif

+ 163 - 0
src/qt/input_geometry_curves.cpp

@@ -0,0 +1,163 @@
+#include "input_geometry_curves.hpp"
+
+QtInputGeometryCurves::QtInputGeometryCurves(){
+  margin=10;
+  radius=8;
+  min_d=0.01;
+  initPoints();
+  hbot.setPoints(point,np);
+  hbot.compute();
+  hsoil.setPoints(&point[np],np);
+  hsoil.compute();
+}
+
+void
+QtInputGeometryCurves::initPoints(){
+  for(size_t i=0;i<np;++i){
+    double x=double(i)/(np-1);
+    point[i].x=x;
+    point[i].y=0.7;
+    point[i+np].x=x;
+    point[i+np].y=0.3;
+  }
+}
+
+int
+QtInputGeometryCurves::get_x(float x,int w){
+  return margin+x*w;
+}
+
+int
+QtInputGeometryCurves::get_y(float y,int h){
+  return y*h;
+}
+
+void
+QtInputGeometryCurves::paintEvent(QPaintEvent* event){
+  QPainter painter(this);
+  painter.setRenderHint(QPainter::Antialiasing);
+  int w=width()-2*margin;
+  int h=height();
+  // Hbot
+  painter.setBrush(Qt::SolidPattern);
+  painter.setPen(QColor(102,102,102));
+  drawSpline(hbot,painter);
+  painter.setPen(QColor(154,77,0));
+  drawSpline(hsoil,painter);
+  painter.setPen(Qt::black);
+
+  //Control points
+  for(size_t i=0;i<2*np;++i){
+    Point& P=point[i];
+    painter.drawEllipse(get_x(P.x,w)-radius,get_y(P.y,h)-radius,2*radius,2*radius);
+  }
+}
+
+void
+QtInputGeometryCurves::mousePressEvent(QMouseEvent* event){
+  int mx=event->x();
+  int my=event->y();
+  selected=findPoint(mx,my);
+}
+
+void
+QtInputGeometryCurves::mouseMoveEvent(QMouseEvent* event){
+  if(selected<2*np){
+    int w=width()-2*margin;
+    int h=height();
+    float mx=event->x();
+    float my=event->y();
+    float x=(mx-margin)/w;
+    float y=my/h;
+    moveSelected(x,y);
+    update();
+  }
+}
+
+void
+QtInputGeometryCurves::mouseReleaseEvent(QMouseEvent* event){
+  selected=2*np;
+}
+
+size_t
+QtInputGeometryCurves::findPoint(int x,int y){
+  int w=width()-2*margin;
+  int h=height();
+  for(size_t i=0;i<2*np;++i){
+    Point& P=point[i];
+    int px=get_x(P.x,w);
+    int py=get_y(P.y,h);
+    int dx=x-px;
+    int dy=y-py;
+    int d=dx*dx+dy*dy;
+    if(d<=radius*radius) return i;
+  }
+  return 2*np;
+}
+
+void
+QtInputGeometryCurves::moveSelected(float x,float y){
+  double xp=point[selected].x;
+  double yp=point[selected].y;
+  if(selected!=0 and selected!=np-1){
+    float xmin=point[selected-1].x+min_d;
+    float xmax=point[selected+1].x-min_d;
+    if(xmin<=x and x<=xmax){
+      point[selected].x=x;
+    }
+  }
+  if(0<=y and y<=1){
+    point[selected].y=y;
+  }
+  
+  if(selected<np) hbot.compute();
+  else hsoil.compute();
+  double w=width()-2*margin;
+  bool ok=true;
+  for(int i=1;i<=w;++i){
+    double x=i/w;
+    double ybot=hbot(x);
+    double ysoil=hsoil(x);
+    if(ybot<min_d or ybot>1-min_d or ysoil<min_d or ysoil>1-min_d or ybot<ysoil+min_d){
+      point[selected].x=xp;
+      point[selected].y=yp;
+      if(selected<np) hbot.compute();
+      else hsoil.compute();
+      return;
+    }
+  }
+}
+
+void
+QtInputGeometryCurves::drawSpline(Spline& S,QPainter& painter){
+  double w=width()-2*margin;
+  double h=height();
+  double xp=0;
+  double yp=S(0);
+  for(int i=1;i<=w;i+=2){
+    double x=i/w;
+    double y=S(x);
+    painter.drawLine(margin+xp*w,yp*h,margin+x*w,y*h);
+    xp=x;
+    yp=y;
+  }
+}
+
+void
+QtInputGeometryCurves::save(fstream& file){
+  for(size_t i=0;i<2*np;++i){
+    file.write((char*)&point[i].x,sizeof(double));
+    file.write((char*)&point[i].y,sizeof(double));
+  }
+}
+
+void
+QtInputGeometryCurves::load(fstream& file){
+  for(size_t i=0;i<2*np;++i){
+    file.read((char*)&point[i].x,sizeof(double));
+    file.read((char*)&point[i].y,sizeof(double));
+  }
+  hbot.compute();
+  hsoil.compute();
+  update();
+}

+ 61 - 0
src/qt/input_geometry_curves.hpp

@@ -0,0 +1,61 @@
+#ifndef QT_INPUT_GEOMETRY_CURVES_HPP
+#define QT_INPUT_GEOMETRY_CURVES_HPP
+
+#include <iostream>
+#include <fstream>
+#include <QWidget>
+#include <QMouseEvent>
+#include <QPainter>
+
+#include "math/point.hpp"
+#include "math/spline.hpp"
+
+using namespace std;
+
+static const size_t np = 10;
+
+class QtInputGeometryCurves:public QWidget{
+private:
+  int margin;
+  int radius;
+  float min_d;
+  size_t selected;
+  Point point[2*np];
+  Spline hsoil;
+  Spline hbot;
+  
+  size_t findPoint(int x,int y);
+  int get_x(float x,int w);
+  int get_y(float y,int h);
+  void moveSelected(float x,float y);
+  void drawSpline(Spline& S,QPainter& painter);
+public:
+  QtInputGeometryCurves();
+  ~QtInputGeometryCurves();
+  void save(fstream& file);
+  void load(fstream& file);
+  Spline& getSsoil();
+  Spline& getSbot();
+protected:
+  void initPoints();
+  void paintEvent(QPaintEvent* event);
+  void mousePressEvent(QMouseEvent* event) override;
+  void mouseMoveEvent(QMouseEvent* event) override;
+  void mouseReleaseEvent(QMouseEvent* event) override;
+};
+
+inline
+QtInputGeometryCurves::~QtInputGeometryCurves(){
+}
+
+inline Spline&
+QtInputGeometryCurves::getSsoil(){
+  return hsoil;
+}
+
+inline Spline&
+QtInputGeometryCurves::getSbot(){
+  return hbot;
+}
+
+#endif

+ 7 - 0
src/qt/input_initial_state.cpp

@@ -0,0 +1,7 @@
+#include "input_initial_state.hpp"
+
+QtInputInitialState::QtInputInitialState(){
+}
+
+QtInputInitialState::~QtInputInitialState(){
+}

+ 18 - 0
src/qt/input_initial_state.hpp

@@ -0,0 +1,18 @@
+#ifndef QT_INITIAL_STATE_HPP
+#define QT_INITIAL_STATE_HPP
+
+#include <iostream>
+#include <fstream>
+
+#include <QWidget>
+
+#include "initial_state.hpp"
+
+class QtInputInitialState:public QWidget{
+private:
+public:
+  QtInputInitialState();
+  ~QtInputInitialState();
+  
+};
+#endif

+ 99 - 20
src/qt/input_physics.cpp

@@ -1,30 +1,37 @@
 #include "input_physics.hpp"
 
-QtInputPhysics::QtInputPhysics():QWidget(){  
+QtInputPhysics::QtInputPhysics():QWidget(){
   g_label=new QLabel("Gravity (g) : ");
   rho_label=new QLabel("Fluid density (&rho;) : ");
-  rho_label->setTextFormat(Qt::RichText);
   phi_label=new QLabel("Porosity of the soil (&phi;) : ");
-  phi_label->setTextFormat(Qt::RichText);
   k0_label=new QLabel("Conductivity of the saturated soil (k<sub>0</sub>) : ");
-  k0_label->setTextFormat(Qt::RichText);
   nivrivsat_label=new QLabel("Water pressure at the bottom of overland water (nivrivsat) : ");
-  g_input=new QLineEdit(QString::number(def_g));
-  rho_input=new QLineEdit(QString::number(def_rho));
-  phi_input=new QLineEdit(QString::number(def_phi));
-  k0_input=new QLineEdit(QString::number(def_k0));
-  nivrivsat_input=new QLineEdit(QString::number(def_nivrivsat));
+  g_input=new QLineEdit();
+  rho_input=new QLineEdit();
+  phi_input=new QLineEdit();
+  k0_input=new QLineEdit();
+  nivrivsat_input=new QLineEdit();
   for(size_t i=0;i<max_model_parameters;++i){
     model_label[i]=new QLabel(this);
+    model_input[i]=new QLineEdit(this);
+  }
+
+  //Text format
+  rho_label->setTextFormat(Qt::RichText);
+  phi_label->setTextFormat(Qt::RichText);
+  k0_label->setTextFormat(Qt::RichText);
+  for(size_t i=0;i<max_model_parameters;++i){
     model_label[i]->setTextFormat(Qt::RichText);
+  }
+
+  //Hide model parameters
+  for(size_t i=0;i<max_model_parameters;++i){
     model_label[i]->hide();
-    model_input[i]=new QLineEdit(this);
     model_input[i]->hide();
   }
-
   //Input validators
   double_validator=new QDoubleValidator;
-  positive_double_validator=new QDoubleValidator;;
+  positive_double_validator=new QDoubleValidator;
   positive_double_validator->setBottom(0);
 
  
@@ -37,14 +44,14 @@ QtInputPhysics::QtInputPhysics():QWidget(){
   //Boxes
   phy_common_box=new QGroupBox("Common parameters");
   phy_model_box=new QGroupBox("Model parameters");
-  phy_model_selection_box=new QComboBox();
+  phy_model_selection_box=new QComboBox;
   phy_model_selection_box->addItem("Brooks and Corey");
 
   
   //Layouts
-  base_layout=new QHBoxLayout();
-  phy_common_layout=new QVBoxLayout();
-  phy_model_layout=new QVBoxLayout();
+  base_layout=new QHBoxLayout;
+  phy_common_layout=new QVBoxLayout;
+  phy_model_layout=new QVBoxLayout;
   
   //Phy commont layout
   int vspace=20;
@@ -88,6 +95,8 @@ QtInputPhysics::QtInputPhysics():QWidget(){
   //Display model specific interface
   nb_model_parameters=0;
   modelChoosed(phy_model_selection_box->currentIndex());
+
+  loadData();
 }
 
 QtInputPhysics::~QtInputPhysics(){
@@ -103,19 +112,20 @@ QtInputPhysics::modelChoosed(int index){
   switch(index){
   case 0:
     //Brooks and Corey
+    Physics::setModel(Physics::BrooksCorey);
     nb_model_parameters=4;
     model_label[0]->setText("Minimal pressure p<sub>sat</sub> such that s(p<sub>sat</sub>)=1");
     model_input[0]->setValidator(double_validator);
-    model_input[0]->setText(QString::number(BC_psat));
+    model_input[0]->setText(QString::number(Physics::model_data[0]));
     model_label[1]->setText("Minimal residual pressure (s<sub>res</sub>)");
     model_input[1]->setValidator(double_validator);
-    model_input[1]->setText(QString::number(BC_sres));
+    model_input[1]->setText(QString::number(Physics::model_data[1]));
     model_label[2]->setText("&lambda; exponent");
     model_input[2]->setValidator(double_validator);
-    model_input[2]->setText(QString::number(BC_lambda));
+    model_input[2]->setText(QString::number(Physics::model_data[2]));
     model_label[3]->setText("&alpha; exponent");
     model_input[3]->setValidator(double_validator);
-    model_input[3]->setText(QString::number(BC_alpha));
+    model_input[3]->setText(QString::number(Physics::model_data[3]));
     break;
   default:
     break;
@@ -125,3 +135,72 @@ QtInputPhysics::modelChoosed(int index){
     model_input[i]->show();
   }
 }
+
+QWidget*
+QtInputPhysics::validate(){
+  if(not g_input->hasAcceptableInput()) return g_input;
+  if(not rho_input->hasAcceptableInput()) return rho_input;
+  if(not phi_input->hasAcceptableInput()) return phi_input;
+  if(not k0_input->hasAcceptableInput()) return k0_input;
+  if(not nivrivsat_input->hasAcceptableInput()) return nivrivsat_input;
+  for(size_t i=0;i<nb_model_parameters;++i){
+    if(not model_input[i]->hasAcceptableInput()) return model_input[i];
+  }
+  return nullptr;
+}
+
+void
+QtInputPhysics::save(fstream& file){
+  double d;
+  size_t s;
+  d=g_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  d=rho_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  d=phi_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  d=k0_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  d=nivrivsat_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  s=phy_model_selection_box->currentIndex();
+  file.write((char*)&s,sizeof(size_t));
+  s=nb_model_parameters;
+  file.write((char*)&s,sizeof(size_t));
+  for(size_t i=0;i<nb_model_parameters;++i){
+    d=model_input[i]->text().toDouble();
+    file.write((char*)&d,sizeof(double));
+  }
+}
+
+void
+QtInputPhysics::load(fstream& file){
+  double d;
+  size_t s;
+  file.read((char*)&d,sizeof(double));
+  g_input->setText(QString::number(d));
+  file.read((char*)&d,sizeof(double));
+  rho_input->setText(QString::number(d));
+  file.read((char*)&d,sizeof(double));
+  phi_input->setText(QString::number(d));
+  file.read((char*)&d,sizeof(double));
+  k0_input->setText(QString::number(d));
+  file.read((char*)&d,sizeof(double));
+  nivrivsat_input->setText(QString::number(d));
+  file.read((char*)&s,sizeof(size_t));
+  phy_model_selection_box->setCurrentIndex(s);
+  file.read((char*)&s,sizeof(size_t));
+  for(size_t i=0;i<s;++i){
+    file.read((char*)&d,sizeof(double));
+    model_input[i]->setText(QString::number(d));
+  }
+}
+
+void
+QtInputPhysics::loadData(){
+  g_input->setText(QString::number(Physics::g));
+  rho_input->setText(QString::number(Physics::rho));
+  phi_input->setText(QString::number(Physics::phi));
+  k0_input->setText(QString::number(Physics::k0));
+  nivrivsat_input->setText(QString::number(Physics::nivrivsat));
+}

+ 6 - 13
src/qt/input_physics.hpp

@@ -10,23 +10,12 @@
 #include <QVBoxLayout>
 #include <QLineEdit>
 #include <QDoubleValidator>
+#include <fstream>
 
-#include "../physics.hpp"
+#include "physics.hpp"
 
 using namespace std;
 
-static const double def_g=9.81;
-static const double def_rho=1e3;
-static const double def_phi=3e-1;
-static const double def_k0=3e-5;
-static const double def_nivrivsat=1e-2;
-
-//Brooks & Corey
-static const double BC_psat=-2000;
-static const double BC_sres=0;
-static const double BC_lambda=3;
-static const double BC_alpha=11;
-
 static const size_t max_model_parameters=6;
 
 class QtInputPhysics:public QWidget{
@@ -57,6 +46,10 @@ private:
 public:
   QtInputPhysics();
   ~QtInputPhysics();
+  QWidget* validate();
+  void save(fstream& file);
+  void load(fstream& file);
+  void loadData();
 private slots:
   void modelChoosed(int index);
 };

+ 7 - 0
src/qt/input_sources.cpp

@@ -0,0 +1,7 @@
+#include "input_sources.hpp"
+
+QtInputSources::QtInputSources(){
+}
+
+QtInputSources::~QtInputSources(){
+}

+ 18 - 0
src/qt/input_sources.hpp

@@ -0,0 +1,18 @@
+#ifndef QT_INPUT_SOURCES
+#define QT_INPUT_SOURCES
+
+#include <iostream>
+#include <fstream>
+
+#include <QWidget>
+
+#include "source.hpp"
+
+class QtInputSources:public QWidget{
+private:
+public:
+  QtInputSources();
+  ~QtInputSources();
+};
+
+#endif

+ 34 - 3
src/qt/input_time.cpp

@@ -4,9 +4,17 @@ QtInputTime::QtInputTime():QWidget(){
   main_layout=new QVBoxLayout;
   T_label=new QLabel("Total duration of the simulation (T)");
   nT_label=new QLabel("Number of time steps (nT)");
-  T_input=new QLineEdit(QString::number(def_T));
-  nT_input=new QLineEdit(QString::number(def_nT));
 
+  T_input=new QLineEdit(QString::number(Time::T));
+  nT_input=new QLineEdit(QString::number(Time::nT));
+
+  positive_double_validator=new QDoubleValidator;
+  positive_double_validator->setBottom(0);
+  positive_int_validator=new QIntValidator;
+  positive_int_validator->setBottom(1);
+  T_input->setValidator(positive_double_validator);
+  nT_input->setValidator(positive_int_validator);
+  
   int vspace=20;
   main_layout->addWidget(T_label);
   main_layout->addWidget(T_input);
@@ -18,5 +26,28 @@ QtInputTime::QtInputTime():QWidget(){
   setLayout(main_layout);
 }
 
-QtInputTime::~QtInputTime(){
+QWidget*
+QtInputTime::validate(){
+  if(not T_input->hasAcceptableInput()) return T_input;
+  if(not nT_input->hasAcceptableInput()) return nT_input;
+  return nullptr;
+}
+
+void
+QtInputTime::save(fstream& file){
+  double d=T_input->text().toDouble();
+  file.write((char*)&d,sizeof(double));
+  size_t s=nT_input->text().toULong();
+  file.write((char*)&s,sizeof(size_t));
 }
+
+void
+QtInputTime::load(fstream& file){
+  double d;
+  size_t s;
+  file.read((char*)&d,sizeof(double));
+  T_input->setText(QString::number(d));
+  file.read((char*)&s,sizeof(size_t));
+  nT_input->setText(QString::number(s));
+}
+

+ 13 - 4
src/qt/input_time.hpp

@@ -6,12 +6,13 @@
 #include <QWidget>
 #include <QLineEdit>
 #include <QVBoxLayout>
+#include <QDoubleValidator>
+#include <QIntValidator>
+#include <fstream>
 
-#include "../time.hpp"
+#include "time.hpp"
 
 using namespace std;
-static const double def_T=10;
-static const size_t def_nT=1000;
 
 class QtInputTime:public QWidget{
 private:
@@ -20,10 +21,18 @@ private:
   QLineEdit* T_input;
   QLineEdit* nT_input;
   QVBoxLayout* main_layout;
+  QDoubleValidator* positive_double_validator;
+  QIntValidator* positive_int_validator;
+  
 public:
   QtInputTime();
   ~QtInputTime();
-  
+  QWidget* validate();
+  void save(fstream& file);
+  void load(fstream& file);
 };
 
+inline
+QtInputTime::~QtInputTime(){
+}
 #endif

+ 39 - 0
src/qt/input_view.cpp

@@ -0,0 +1,39 @@
+#include "qt/input_view.hpp"
+
+QtInputView::QtInputView():QtView(){
+}
+
+void
+QtInputView::initPoints(){
+  for(size_t i=0;i<np;++i){
+    double x=double(i)/(np-1);
+    point[i].x=x;
+    point[i].y=0.3;
+    point[np+i].x=x;
+    point[np+i].y=0.5;
+    point[2*np+i].x=x;
+    point[2*np+i].y=0.7;
+  }
+}
+
+void
+QtInputView::drawSplinePoints(Spline& spline){  
+}
+
+void
+QtInputView::paintGL(){
+  QtView::paintGL();
+}
+
+void
+QtInputView::mousePressEvent(QMouseEvent* event){
+  /*double x=double(event->x())/width()*kernel->geometry.lX;
+  double y=1-(double(event->y())/height());
+  displayInfos(x,y);*/
+}
+
+
+void
+QtInputView::updateGeometry(){
+  
+}

+ 27 - 0
src/qt/input_view.hpp

@@ -0,0 +1,27 @@
+#ifndef QT_INPUT_VIEW_HPP
+#define QT_INPUT_VIEW_HPP
+
+#include "view.hpp"
+
+using namespace std;
+
+static const size_t np=10;
+
+class QtInputView:public QtView{
+  Q_OBJECT
+private:
+  int margin;
+  int radius;
+  float min_d;
+  size_t selected;
+  Point point[3*np];
+  void drawSplinePoints(Spline& spline);
+  void initPoints();
+public:
+  QtInputView();
+  void paintGL() override;  
+  void mousePressEvent(QMouseEvent* event);
+public slots:
+  void updateGeometry();
+};
+#endif

+ 73 - 2
src/qt/mainwindow.cpp

@@ -1,10 +1,81 @@
 #include "mainwindow.hpp"
 
 QtMainWindow::QtMainWindow():QMainWindow(){
-  QtInput* input=new QtInput();
-  setCentralWidget(input);
+  input=nullptr;
+  view_solution=nullptr;
+  
+  //Actions
+  new_act=new QAction("New input",this);
+  load_act=new QAction("Load input",this);
+  exit_act=new QAction("Exit",this);
   
+  //Menu bar
+  input_menu=menuBar()->addMenu("File");
+  input_menu->addAction(new_act);
+  input_menu->addAction(load_act);
+  input_menu->addAction(exit_act);
+    
+  connect(new_act,&QAction::triggered,this,&QtMainWindow::new_input);
+  connect(load_act,&QAction::triggered,this,&QtMainWindow::load_input);
+  connect(exit_act,&QAction::triggered,this,&QtMainWindow::exit);
+}
+
+QtMainWindow::QtMainWindow(string filename):QtMainWindow(){
+  input=new QtInput(QString::fromStdString(filename));
+  run_input();
+
 }
 
 QtMainWindow::~QtMainWindow(){
 }
+
+void
+QtMainWindow::new_input(){
+  input=new QtInput;
+  setCentralWidget(input);
+  connect(input,&QtInput::run_signal,this,&QtMainWindow::run_input);
+  connect(input,&QtInput::exit_signal,this,&QtMainWindow::exit_input);
+  new_act->setEnabled(false);
+  load_act->setEnabled(false);
+}
+
+void
+QtMainWindow::run_input(){
+  /*disconnect(input,nullptr,nullptr,nullptr);
+  new_act->setEnabled(false);
+  load_act->setEnabled(false);
+  kernel=new Kernel(input->getPhysics(),input->getTime(),input->getGeometry());
+  delete input;
+  input=nullptr;
+  view_solution=new QtViewSolution(kernel);
+  setCentralWidget(view_solution);*/
+}
+
+void
+QtMainWindow::exit_input(){
+  disconnect(input,nullptr,nullptr,nullptr);
+  delete input;
+  input=nullptr;
+  setCentralWidget(nullptr);
+  new_act->setEnabled(true);
+  load_act->setEnabled(true);
+}
+
+void
+QtMainWindow::load_input(){
+  QString filename=QFileDialog::getOpenFileName(this,"Load input","inputs/","QT input file (*.input)");
+  input=new QtInput(filename);
+  //input=new QtInput;
+  setCentralWidget(input);
+  connect(input,&QtInput::run_signal,this,&QtMainWindow::run_input);
+  connect(input,&QtInput::exit_signal,this,&QtMainWindow::exit_input);
+  new_act->setEnabled(false);
+  load_act->setEnabled(false);
+}
+
+void
+QtMainWindow::exit(){
+  QApplication::quit();
+}
+
+

+ 23 - 2
src/qt/mainwindow.hpp

@@ -2,14 +2,35 @@
 #define QT_MAINWINDOW_HPP
 
 #include <QMainWindow>
-#include "input.hpp"
-//#include "view"
+#include <QMenu>
+#include <QMenuBar>
+#include <QAction>
+#include <QApplication>
+
+#include "qt/input.hpp"
+#include "qt/view_solution.hpp"
+#include "kernel.hpp"
 
 class QtMainWindow:public QMainWindow{
+  Q_OBJECT
 private:
+  QtInput* input;
+  QtViewSolution* view_solution;
+  QMenu* input_menu;
+  QAction* new_act;
+  QAction* load_act;
+  QAction* exit_act;
+  Kernel* kernel;
 public:
   QtMainWindow();
+  QtMainWindow(string filename);
   ~QtMainWindow();
+private slots:
+  void new_input();
+  void load_input();
+  void exit();
+  void run_input();
+  void exit_input();
 };
 
 

+ 11 - 0
src/qt/spline.hpp

@@ -0,0 +1,11 @@
+#ifndef QSPLINE_HPP
+#define QSPLINE_HPP
+
+#include <GL/glut.h>
+
+class QSpline:public Spline{
+public:
+  void QSpline(float z);
+  void draw_points_GL()
+};
+#endif

+ 74 - 0
src/qt/view.cpp

@@ -0,0 +1,74 @@
+#include "view.hpp"
+
+
+
+void
+QtView::initializeGL(){
+  glClearColor(1,1,1,1);
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_LIGHTING);
+  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+  glEnable(GL_COLOR_MATERIAL);
+}
+
+void
+QtView::resizeGL(int w,int h){
+  glViewport(0,0,w,h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluOrtho2D(0,geometry->lX,0,1);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+}
+
+void
+QtView::paintGL(){
+  cout<<"PaintGL"<<endl;
+  glBegin(GL_TRIANGLES);
+  for(size_t i=0;i<geometry->nX-1;++i){
+    size_t max_left=geometry->nZ[i];
+    size_t max_right=geometry->nZ[i+1];
+    size_t left=0;
+    size_t right=0;
+    while(left<max_left-1 and right<max_right-1){
+      if(geometry->Z[i][left+1]<geometry->Z[i+1][right+1]){
+	drawTriangle(i,left,i+1,right,i,left+1);
+	++left;
+      }
+      else{
+	drawTriangle(i,left,i+1,right,i+1,right+1);
+	++right;
+      }
+    }
+    if(left==max_left-1){
+      while(right<max_right-1){
+	drawTriangle(i,left,i+1,right,i+1,right+1);
+	++right;
+      }
+    }
+    if(right==max_right-1){
+      while(left<max_left-1){
+	drawTriangle(i,left,i+1,right,i,left+1);
+	++left;
+      }
+    }
+  }
+  glEnd();
+}
+
+void
+QtView::drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3){
+  double dX=geometry->dX;
+  double x1=ix1*dX;
+  double x2=ix2*dX;
+  double x3=ix3*dX;
+  double y1=geometry->Z[ix1][iz1];
+  double y2=geometry->Z[ix2][iz2];
+  double y3=geometry->Z[ix3][iz3];
+  glColor3f(1,0,0);
+  glVertex2f(x1,y1);
+  glVertex2f(x2,y2);
+  glVertex2f(x3,y3);
+
+}

+ 35 - 2
src/qt/view.hpp

@@ -1,6 +1,39 @@
+#ifndef QT_VIEW_HPP
+#define QT_VIEW_HPP
+
+#include <iostream>
+
+#include <QWidget>
+#include <QPainter>
 #include <QOpenGLWidget>
+#include <QMouseEvent>
+
+#include <GL/glut.h>
+
+#include "geometry.hpp"
 
-class View:public QOpenGLWidget{
-  
+using namespace std;
 
+class QtView:public QOpenGLWidget{
+protected:
+  Geometry* geometry;
+public:
+  QtView();
+  void setGeometry(Geometry* geometry);
+  void initializeGL();
+  void paintGL();
+  void resizeGL(int x,int h);
+  void drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3);
 };
+
+inline
+QtView::QtView():QOpenGLWidget(){
+  geometry=nullptr;
+}
+
+inline void
+QtView::setGeometry(Geometry* _geometry){
+  geometry=_geometry;
+}
+
+#endif

+ 44 - 0
src/qt/view_solution.cpp

@@ -0,0 +1,44 @@
+#include "qt/view_solution.hpp"
+
+QtViewSolution::QtViewSolution(Kernel* _kernel):QWidget(){
+  kernel=_kernel;
+  main_layout=new QVBoxLayout;
+  time_bar=new QScrollBar(Qt::Horizontal);
+  solution_geometry=new QtViewSolutionGeometry(_kernel);
+  info_widget=new QWidget;
+  info_layout=new QGridLayout;
+  time_label=new QLabel;
+  
+  time_bar->setMinimum(0);
+  time_bar->setMaximum(Time::nT);
+  info_layout->addWidget(time_label);
+  info_widget->setLayout(info_layout);
+  main_layout->addWidget(solution_geometry,1);
+  main_layout->addWidget(time_bar);
+  main_layout->addWidget(info_widget);
+  setLayout(main_layout);
+  step=0;
+  update();
+  connect(time_bar,&QScrollBar::valueChanged,this,&QtViewSolution::time_change);
+}
+
+
+QtViewSolution::~QtViewSolution(){
+}
+
+void
+QtViewSolution::update(){
+  update_infos();
+  solution_geometry->draw(step);
+}
+
+void
+QtViewSolution::update_infos(){
+  time_label->setText("Time : "+QString::number(step*Time::dT));
+}
+
+void
+QtViewSolution::time_change(int val){
+  step=val;
+  update();
+}

+ 33 - 0
src/qt/view_solution.hpp

@@ -0,0 +1,33 @@
+#ifndef VIEW_SOLUTION_HPP
+#define VIEW_SOLUTION_HPP
+
+#include <QWidget>
+#include <QVBoxLayout>
+#include <QScrollBar>
+#include <QGridLayout>
+#include <QLabel>
+
+#include "qt/view_solution_geometry.hpp"
+#include "kernel.hpp"
+
+class QtViewSolution:public QWidget{
+  Q_OBJECT
+private:
+  QVBoxLayout* main_layout;
+  QScrollBar* time_bar;
+  QWidget* info_widget;
+  QGridLayout* info_layout;
+  QLabel* time_label;
+  Kernel* kernel;
+  QtViewSolutionGeometry* solution_geometry;
+  size_t step;
+public:
+  QtViewSolution(Kernel* kernel);
+  ~QtViewSolution();
+  void update();
+  void update_infos();
+private slots:
+  void time_change(int);
+};
+
+#endif

+ 194 - 0
src/qt/view_solution_geometry.cpp

@@ -0,0 +1,194 @@
+#include "qt/view_solution_geometry.hpp"
+
+QtViewSolutionGeometry::QtViewSolutionGeometry(Kernel* _kernel){
+  kernel=_kernel;
+
+};
+
+void
+QtViewSolutionGeometry::initializeGL(){
+  glClearColor(1,1,1,1);
+  glEnable(GL_DEPTH_TEST);
+  glEnable(GL_LIGHT0);
+  glEnable(GL_LIGHTING);
+  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+  glEnable(GL_COLOR_MATERIAL);
+}
+
+void
+QtViewSolutionGeometry::paintGL(){
+  cout<<"PaintGL"<<endl;
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+  if(step>kernel->step){
+    cout<<"Pas encore calculé"<<endl;
+  }
+  else{
+    double dX=kernel->geometry.dX;
+    double lX=kernel->geometry.lX;
+    double h=height();
+    double w=width();
+    glBegin(GL_TRIANGLES);
+    for(size_t i=0;i<kernel->geometry.nX-1;++i){
+      size_t max_left=kernel->nZ(i);
+      size_t max_right=kernel->nZ(i+1);
+      size_t left=0;
+      size_t right=0;
+      while(left<max_left-1 and right<max_right-1){
+	if(kernel->Z(i,left+1)<=kernel->Z(i+1,right+1)){
+	  drawTriangle(i,left,i+1,right,i,left+1);
+	  ++left;
+	}
+	else{
+	  drawTriangle(i,left,i+1,right,i+1,right+1);
+	  ++right;
+	}
+      }
+      if(left==max_left-1){
+	while(right<max_right-1){
+	  drawTriangle(i,left,i+1,right,i+1,right+1);
+	  ++right;
+	}
+      }
+      if(right==max_right-1){
+	while(left<max_left-1){
+	  drawTriangle(i,left,i+1,right,i,left+1);
+	  ++left;
+	}
+      }
+    }
+    glEnd();
+  }
+}
+
+void
+QtViewSolutionGeometry::resizeGL(int w,int h){
+  glViewport(0,0,w,h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluOrtho2D(0,kernel->geometry.lX,0,1);
+  //gluPerspective(45, (float)w/h, 0.01, 100.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  //gluLookAt(0,0,5,0,0,0,0,1,0);
+}
+/*void
+QtViewSolutionGeometry::paintEvent(QPaintEvent* event){
+  QPainter painter(this);
+  painter.beginNativePainting();
+
+  glClearColor(0, 0, 0, 1);
+        glEnable(GL_DEPTH_TEST);
+        glEnable(GL_LIGHT0);
+        glEnable(GL_LIGHTING);
+        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+        glEnable(GL_COLOR_MATERIAL);
+glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+        glBegin(GL_TRIANGLES);
+    glColor3f(1.0, 0.0, 0.0);
+        glVertex3f(0, 10, 0);
+        glColor3f(0.0, 1.0, 0.0);
+        glVertex3f(20, -20, 0);
+        glColor3f(0.0, 0.0, 1.0);
+        glVertex3f(0.0, 50, 0);
+        glEnd();
+
+
+	/*if(step>kernel->step){
+    cout<<"Pas encore calculé"<<endl;
+  }
+  else{
+    double dX=kernel->geometry.dX;
+    double lX=kernel->geometry.lX;
+    double h=height();
+    double w=width();
+    for(size_t i=0;i<kernel->geometry.nX-1;++i){
+      size_t max_left=kernel->nZ(i);
+      size_t max_right=kernel->nZ(i+1);
+      size_t left=0;
+      size_t right=0;
+      while(left<max_left-1 and right<max_right-1){
+	if(kernel->Z(i,left+1)<=kernel->Z(i+1,right+1)){
+	  drawTriangle(painter,i,left,i+1,right,i,left+1);
+	  ++left;
+	}
+	else{
+	  drawTriangle(painter,i,left,i+1,right,i+1,right+1);
+	  ++right;
+	}
+      }
+      if(left==max_left-1){
+	while(right<max_right-1){
+	  drawTriangle(painter,i,left,i+1,right,i+1,right+1);
+	  ++right;
+	}
+      }
+      if(right==max_right-1){
+	while(left<max_left-1){
+	  drawTriangle(painter,i,left,i+1,right,i,left+1);
+	  ++left;
+	}
+      }
+    }
+    }
+	painter.endNativePainting();
+	painter.end();
+}
+*/
+
+void
+QtViewSolutionGeometry::drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3){
+  double dX=kernel->geometry.dX;
+  double lX=kernel->geometry.lX;
+  double h=height();
+  double w=width();
+  double x1=ix1*dX;
+  double x2=ix2*dX;
+  double x3=ix3*dX;
+  double y1=kernel->Z(ix1,iz1);
+  double y2=kernel->Z(ix2,iz2);
+  double y3=kernel->Z(ix3,iz3);
+
+  glColor3f(1,0,0);
+  glVertex2f(x1,y1);
+  glVertex2f(x2,y2);
+  glVertex2f(x3,y3);
+
+}
+
+void
+QtViewSolutionGeometry::draw(size_t _step){
+  step=_step;
+  update();
+}
+
+void
+QtViewSolutionGeometry::mousePressEvent(QMouseEvent* event){
+  double x=double(event->x())/width()*kernel->geometry.lX;
+  double y=1-(double(event->y())/height());
+  displayInfos(x,y);
+}
+
+void
+QtViewSolutionGeometry::displayInfos(double x,double z){
+  cout<<"---------------------------------"<<endl;
+  cout<<"x = "<<x<<endl;
+  cout<<"z = "<<z<<endl;
+  size_t ix=floor(x/kernel->geometry.dX+0.5);
+  if(ix==kernel->geometry.nX) --ix;
+  cout<<"ix = "<<ix<<endl;
+ 
+  double hbot=kernel->geometry.hbot[ix];
+  cout<<"hbot = "<<hbot<<endl;
+  double hsoil=kernel->geometry.hsoil[ix];
+  cout<<"hsoil = "<<hsoil<<endl;
+  if(z>hbot and z<hsoil){
+    double dZ=kernel->geometry.dZ[ix];
+    cout<<"dZ = "<<dZ<<endl;
+    size_t nz=kernel->geometry.nZ[ix];
+    cout<<"nZ = "<<nz<<endl;
+    size_t iz=floor((z-hbot)/dZ+0.5);
+    if(iz==nz) --iz;
+    cout<<"iz = "<<iz<<endl;
+  }
+}

+ 27 - 0
src/qt/view_solution_geometry.hpp

@@ -0,0 +1,27 @@
+#ifndef VIEW_SOLUTION_GEOMETRY_HPP
+#define VIEW_SOLUTION_GEOMETRY_HPP
+
+#include <QWidget>
+#include <QPainter>
+#include <QOpenGLWidget>
+#include <QMouseEvent>
+#include <GL/glut.h>
+#include "kernel.hpp"
+
+
+class QtViewSolutionGeometry:public QOpenGLWidget{
+private:
+  Kernel* kernel;
+  size_t step;
+public:
+  QtViewSolutionGeometry(Kernel* kernel);
+  void initializeGL();
+  void resizeGL(int x,int h);
+  void paintGL();
+  /*  void paintEvent(QPaintEvent* event);*/
+  void draw(size_t t);
+  void drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3);
+  void mousePressEvent(QMouseEvent* event);
+  void displayInfos(double x,double y);
+};
+#endif

+ 1 - 0
src/source.cpp

@@ -0,0 +1 @@
+#include "source.hpp"

+ 8 - 0
src/source.hpp

@@ -0,0 +1,8 @@
+#ifndef SOURCE_HPP
+#define SOURCE_HPP
+
+
+class Source{
+
+};
+#endif

+ 7 - 0
src/time.cpp

@@ -0,0 +1,7 @@
+#include "time.hpp"
+
+namespace Time{
+  double T=10;
+  size_t nT=1000;
+  double dT;
+}

+ 9 - 7
src/time.hpp

@@ -1,16 +1,18 @@
 #ifndef TIME_HPP
 #define TIME_HPP
 
-//! The Time class contains information on time discretisation
-class Time{
-public:
+#include <iostream>
+
+using namespace std;
+
+namespace Time{
   //! Total duration of the simulation
-  double T;
+  extern double T;
 
   //! Number of time steps
-  size_t nT;
+  extern size_t nT;
 
   //! Time step
-  double dT;
-};
+  extern double dT;
+}
 #endif