11/* !
22 * \file CPyWrapperMatrixView.hpp
3- * \brief A simple matrix view to use with the python wrapper.
3+ * \brief Simple matrix views to use with the python wrapper.
44 * \author P. Gomes
55 * \version 7.5.1 "Blackbird"
66 *
2727
2828#pragma once
2929
30+ #include < string>
3031#include < utility>
3132#include < vector>
32- #include < string>
3333
34- #include " C2DContainer .hpp"
34+ #include " ../geometry/dual_grid/CVertex .hpp"
3535#include " ../parallelization/mpi_structure.hpp"
36+ #include " C2DContainer.hpp"
37+
38+ /* !
39+ * \brief Python wrapper matrix interface
40+ * The accessors in this macro provide a passive double interface to matrix of
41+ * su2double. This can be extended to allow access to derivative information.
42+ * Classes that use this macro encapsulate the access to the raw data (su2double)
43+ * via the functions "Access(row, col) -> su2double&" (const and non-const versions).
44+ * We use a macro because it is diffult to use modern C++ idioms (e.g. CRTP) with
45+ * SWIG. In addition to "Access" classes must have member variables "rows_", "cols_",
46+ * and "read_only_".
47+ */
48+ #define PY_WRAPPER_MATRIX_INTERFACE \
49+ /* ! \brief Returns the shape of the matrix. */ \
50+ std::pair<unsigned long , unsigned long > Shape () const { return std::make_pair (rows_, cols_); } \
51+ \
52+ /* ! \brief Returns whether the data is read-only [true] or if it can be modified [false]. */ \
53+ bool IsReadOnly () const { return read_only_; } \
54+ \
55+ /* ! \brief Gets the value for a (row, column) pair. */ \
56+ passivedouble operator ()(unsigned long row, unsigned long col) const { return Get (row, col); } \
57+ \
58+ /* ! \brief Gets the value for a (row, column) pair. */ \
59+ passivedouble Get (unsigned long row, unsigned long col) const { return SU2_TYPE::GetValue (Access (row, col)); } \
60+ \
61+ /* ! \brief Gets the values for a row of the matrix. */ \
62+ std::vector<passivedouble> Get (unsigned long row) const { \
63+ std::vector<passivedouble> vals (cols_); \
64+ for (unsigned long j = 0 ; j < cols_; ++j) vals[j] = Get (row, j); \
65+ return vals; \
66+ } \
67+ /* ! \brief Sets the value for a (row, column) pair. This clears derivative information. */ \
68+ void Set (unsigned long row, unsigned long col, passivedouble val) { Access (row, col) = val; } \
69+ \
70+ /* ! \brief Sets the values for a row of the matrix. */ \
71+ void Set (unsigned long row, std::vector<passivedouble> vals) { \
72+ unsigned long j = 0 ; \
73+ for (const auto & val : vals) Set (row, j++, val); \
74+ }
3675
3776/* !
3877 * \class CPyWrapperMatrixView
3978 * \ingroup PySU2
40- * \brief A simple matrix view to use with the python wrapper. The accessors
41- * in this class provide a passive double interface to su2activematrix.
42- * This can be extended to allow access to derivative information of su2double.
79+ * \brief This class wraps su2activematrix for the python wrapper matrix interface.
80+ * It is generaly used to wrap access to solver variables defined for the entire volume.
4381 */
4482class CPyWrapperMatrixView {
45- private :
83+ protected :
4684 static_assert (su2activematrix::IsRowMajor, " " );
4785 su2double* data_ = nullptr ;
4886 unsigned long rows_ = 0 , cols_ = 0 ;
4987 std::string name_;
5088 bool read_only_ = false ;
5189
90+ /* --- Define the functions required by the interface macro. ---*/
5291 inline const su2double& Access (unsigned long row, unsigned long col) const {
5392 if (row > rows_ || col > cols_) SU2_MPI::Error (name_ + " out of bounds" , " CPyWrapperMatrixView" );
5493 return data_[row * cols_ + col];
@@ -68,48 +107,59 @@ class CPyWrapperMatrixView {
68107 * \note "read_only" can be set to true to prevent the data from being modified.
69108 */
70109 CPyWrapperMatrixView (su2activematrix& mat, const std::string& name, bool read_only)
71- : data_(mat.data()), rows_(mat.rows()), cols_(mat.cols()), name_(name), read_only_(read_only) {}
72-
73- /* !
74- * \brief Returns the shape of the matrix.
75- */
76- std::pair<unsigned long , unsigned long > Shape () const { return std::make_pair (rows_, cols_); }
77-
78- /* !
79- * \brief Returns whether the data is read-only [true] or if it can be modified [false].
80- */
81- bool IsReadOnly () const { return read_only_; }
110+ : data_(mat.data()), rows_(mat.rows()), cols_(mat.cols()), name_(name), read_only_(read_only) {}
82111
83- /* !
84- * \brief Gets the value for a (row, column) pair.
85- */
86- passivedouble operator () (unsigned long row, unsigned long col) const { return Get (row, col); }
112+ /* --- Use the macro to generate the interface. ---*/
113+ PY_WRAPPER_MATRIX_INTERFACE
114+ };
87115
88- /* !
89- * \brief Gets the value for a (row, column) pair.
90- */
91- passivedouble Get (unsigned long row, unsigned long col) const { return SU2_TYPE::GetValue (Access (row, col)); }
116+ /* !
117+ * \class CPyWrapperMarkerMatrixView
118+ * \ingroup PySU2
119+ * \brief This class wraps su2activematrix for the python wrapper matrix interface restricting it
120+ * to the vertices of a given marker.
121+ */
122+ class CPyWrapperMarkerMatrixView {
123+ private:
124+ static_assert (su2activematrix::IsRowMajor, " " );
125+ su2double* data_ = nullptr ;
126+ const CVertex* const * vertices_ = nullptr ;
127+ unsigned long rows_ = 0 , cols_ = 0 ;
128+ std::string name_;
129+ bool read_only_ = false ;
92130
93- /* !
94- * \brief Gets the values for a row of the matrix.
95- */
96- std::vector<passivedouble> Get (unsigned long row) const {
97- std::vector<passivedouble> vals (cols_);
98- for (unsigned long j = 0 ; j < cols_; ++j) vals[j] = Get (row, j);
99- return vals;
131+ /* --- Define the functions required by the interface macro. ---*/
132+ inline const su2double& Access (unsigned long row, unsigned long col) const {
133+ if (row > rows_ || col > cols_) SU2_MPI::Error (name_ + " out of bounds" , " CPyWrapperMarkerMatrixView" );
134+ return data_[vertices_[row]->GetNode () * cols_ + col];
135+ }
136+ inline su2double& Access (unsigned long row, unsigned long col) {
137+ if (read_only_) SU2_MPI::Error (name_ + " is read-only" , " CPyWrapperMarkerMatrixView" );
138+ const auto & const_me = *this ;
139+ return const_cast <su2double&>(const_me.Access (row, col));
100140 }
101141
102- /* !
103- * \brief Sets the value for a (row, column) pair.
104- * \note This clears derivative information (consistently with C++ operator= with passive rhs).
105- */
106- void Set (unsigned long row, unsigned long col, passivedouble val) { Access (row, col) = val; }
142+ public:
143+ CPyWrapperMarkerMatrixView () = default ;
107144
108145 /* !
109- * \brief Sets the values for a row of the matrix.
146+ * \brief Construct the view of the matrix.
147+ * \note "name" should be set to the variable name being returned to give better information to users.
148+ * \note "read_only" can be set to true to prevent the data from being modified.
110149 */
111- void Set (unsigned long row, std::vector<passivedouble> vals) {
112- unsigned long j = 0 ;
113- for (const auto & val : vals) Set (row, j++, val);
150+ CPyWrapperMarkerMatrixView (su2activematrix& mat, const CVertex* const * vertices, unsigned long n_vertices,
151+ const std::string& name, bool read_only)
152+ : data_(mat.data()),
153+ vertices_ (vertices),
154+ rows_(n_vertices),
155+ cols_(mat.cols()),
156+ name_(name),
157+ read_only_(read_only) {
158+ if (mat.rows () < n_vertices) {
159+ SU2_MPI::Error (name + " has fewer rows than the number of vertices in the marker." , " CPyWrapperMarkerMatrixView" );
160+ }
114161 }
162+
163+ /* --- Use the macro to generate the interface. ---*/
164+ PY_WRAPPER_MATRIX_INTERFACE
115165};
0 commit comments