Nektar++
TestBlockMatrix.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestBlockMatrix.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description:
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <boost/test/unit_test.hpp>
36
39
40#include <boost/test/tools/floating_point_comparison.hpp>
41#include <boost/test/unit_test.hpp>
42
44{
45BOOST_AUTO_TEST_CASE(TestRowsAndColumnsPerBlockAccess)
46{
47 NekMatrix<NekMatrix<double>, BlockMatrixTag> m(2, 3, 7, 10);
48 BOOST_CHECK_EQUAL(7, m.GetNumberOfRowsInBlockRow(0));
49 BOOST_CHECK_EQUAL(7, m.GetNumberOfRowsInBlockRow(1));
50 BOOST_CHECK_EQUAL(10, m.GetNumberOfColumnsInBlockColumn(0));
51 BOOST_CHECK_EQUAL(10, m.GetNumberOfColumnsInBlockColumn(1));
52 BOOST_CHECK_EQUAL(10, m.GetNumberOfColumnsInBlockColumn(2));
53}
54
55BOOST_AUTO_TEST_CASE(TestMultiplication)
56{
57 typedef NekMatrix<double> InnerType;
59
60 double m1_buf[] = {1, 6, 2, 7, 3, 8};
61 double m2_buf[] = {4, 9, 5, 10};
62 double m3_buf[] = {11, 16, 12, 17, 13, 18};
63 double m4_buf[] = {14, 19, 15, 20};
64
65 std::shared_ptr<InnerType> m1(new InnerType(2, 3, m1_buf));
66 std::shared_ptr<InnerType> m2(new InnerType(2, 2, m2_buf));
67 std::shared_ptr<InnerType> m3(new InnerType(2, 3, m3_buf));
68 std::shared_ptr<InnerType> m4(new InnerType(2, 2, m4_buf));
69
70 unsigned int rowCounts[] = {2, 2};
71 unsigned int colCounts[] = {3, 2};
72
73 BlockType b(2, 2, rowCounts, colCounts);
74 b.SetBlock(0, 0, m1);
75 b.SetBlock(0, 1, m2);
76 b.SetBlock(1, 0, m3);
77 b.SetBlock(1, 1, m4);
78
79 double rhs_buf[] = {10, 20, 30, 40, 50};
80 NekVector<double> rhs(5, rhs_buf);
81
82 NekVector<double> result = b * rhs;
83
84 double expected_buf[] = {550, 1300, 2050, 2800};
85 NekVector<double> expected_result(4, expected_buf);
86
87 BOOST_CHECK_EQUAL(expected_result, result);
88}
89
90BOOST_AUTO_TEST_CASE(TestBlockMatrixTranspose)
91{
92 typedef NekMatrix<double> InnerType;
94
95 double m00_buf[] = {1, 2, 3, 4, 5, 6, 7, 8};
96 double m01_buf[] = {9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
97 double m02_buf[] = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
98 double m10_buf[] = {31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
99 double m11_buf[] = {43, 44, 45, 46, 47, 48, 49, 50,
100 51, 52, 53, 54, 55, 56, 57};
101 double m12_buf[] = {58, 59, 60, 61, 62, 63, 64, 65, 66,
102 67, 68, 69, 70, 71, 72, 73, 74, 75};
103
104 std::shared_ptr<InnerType> m00(new InnerType(2, 4, m00_buf));
105 std::shared_ptr<InnerType> m01(new InnerType(2, 5, m01_buf));
106 std::shared_ptr<InnerType> m02(new InnerType(2, 6, m02_buf));
107 std::shared_ptr<InnerType> m10(new InnerType(3, 4, m10_buf));
108 std::shared_ptr<InnerType> m11(new InnerType(3, 5, m11_buf));
109 std::shared_ptr<InnerType> m12(new InnerType(3, 6, m12_buf));
110
111 unsigned int rowCounts[] = {2, 3};
112 unsigned int colCounts[] = {4, 5, 6};
113
114 BlockType b(2, 3, rowCounts, colCounts);
115 b.SetBlock(0, 0, m00);
116 b.SetBlock(0, 1, m01);
117 b.SetBlock(0, 2, m02);
118 b.SetBlock(1, 0, m10);
119 b.SetBlock(1, 1, m11);
120 b.SetBlock(1, 2, m12);
121
122 BOOST_CHECK_EQUAL(2, b.GetNumberOfBlockRows());
123 BOOST_CHECK_EQUAL(3, b.GetNumberOfBlockColumns());
124 BOOST_CHECK_EQUAL(2, b.GetNumberOfRowsInBlockRow(0));
125 BOOST_CHECK_EQUAL(3, b.GetNumberOfRowsInBlockRow(1));
126 BOOST_CHECK_EQUAL(4, b.GetNumberOfColumnsInBlockColumn(0));
127 BOOST_CHECK_EQUAL(5, b.GetNumberOfColumnsInBlockColumn(1));
128 BOOST_CHECK_EQUAL(6, b.GetNumberOfColumnsInBlockColumn(2));
129
130 BOOST_CHECK_EQUAL(0, b.CalculateBlockIndex(0, 0));
131 BOOST_CHECK_EQUAL(1, b.CalculateBlockIndex(1, 0));
132 BOOST_CHECK_EQUAL(2, b.CalculateBlockIndex(0, 1));
133 BOOST_CHECK_EQUAL(3, b.CalculateBlockIndex(1, 1));
134 BOOST_CHECK_EQUAL(4, b.CalculateBlockIndex(0, 2));
135 BOOST_CHECK_EQUAL(5, b.CalculateBlockIndex(1, 2));
136
137 BOOST_CHECK_EQUAL(m00->GetRawPtr(), b.GetBlock(0, 0)->GetRawPtr());
138 BOOST_CHECK_EQUAL(m01->GetRawPtr(), b.GetBlock(0, 1)->GetRawPtr());
139 BOOST_CHECK_EQUAL(m02->GetRawPtr(), b.GetBlock(0, 2)->GetRawPtr());
140 BOOST_CHECK_EQUAL(m10->GetRawPtr(), b.GetBlock(1, 0)->GetRawPtr());
141 BOOST_CHECK_EQUAL(m11->GetRawPtr(), b.GetBlock(1, 1)->GetRawPtr());
142 BOOST_CHECK_EQUAL(m12->GetRawPtr(), b.GetBlock(1, 2)->GetRawPtr());
143
144 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 0)->GetTransposeFlag());
145 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 1)->GetTransposeFlag());
146 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 2)->GetTransposeFlag());
147 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 0)->GetTransposeFlag());
148 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 1)->GetTransposeFlag());
149 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 2)->GetTransposeFlag());
150
151 double v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
152 NekVector<double> v(15, v_buf);
153 NekVector<double> result = b * v;
154
155 BOOST_CHECK_EQUAL(5, result.GetRows());
156 BOOST_CHECK_EQUAL(2360, result[0]);
157 BOOST_CHECK_EQUAL(2480, result[1]);
158 BOOST_CHECK_EQUAL(7080, result[2]);
159 BOOST_CHECK_EQUAL(7200, result[3]);
160 BOOST_CHECK_EQUAL(7320, result[4]);
161
162 b.Transpose();
163
164 BOOST_CHECK_EQUAL(3, b.GetNumberOfBlockRows());
165 BOOST_CHECK_EQUAL(2, b.GetNumberOfBlockColumns());
166
167 BOOST_CHECK_EQUAL(2, b.GetNumberOfColumnsInBlockColumn(0));
168 BOOST_CHECK_EQUAL(3, b.GetNumberOfColumnsInBlockColumn(1));
169 BOOST_CHECK_EQUAL(4, b.GetNumberOfRowsInBlockRow(0));
170 BOOST_CHECK_EQUAL(5, b.GetNumberOfRowsInBlockRow(1));
171 BOOST_CHECK_EQUAL(6, b.GetNumberOfRowsInBlockRow(2));
172
173 BOOST_CHECK_EQUAL(0, b.CalculateBlockIndex(0, 0));
174 BOOST_CHECK_EQUAL(1, b.CalculateBlockIndex(0, 1));
175 BOOST_CHECK_EQUAL(2, b.CalculateBlockIndex(1, 0));
176 BOOST_CHECK_EQUAL(3, b.CalculateBlockIndex(1, 1));
177 BOOST_CHECK_EQUAL(4, b.CalculateBlockIndex(2, 0));
178 BOOST_CHECK_EQUAL(5, b.CalculateBlockIndex(2, 1));
179
180 BOOST_CHECK_EQUAL(m00->GetRawPtr(), b.GetBlock(0, 0)->GetRawPtr());
181 BOOST_CHECK_EQUAL(m01->GetRawPtr(), b.GetBlock(1, 0)->GetRawPtr());
182 BOOST_CHECK_EQUAL(m02->GetRawPtr(), b.GetBlock(2, 0)->GetRawPtr());
183 BOOST_CHECK_EQUAL(m10->GetRawPtr(), b.GetBlock(0, 1)->GetRawPtr());
184 BOOST_CHECK_EQUAL(m11->GetRawPtr(), b.GetBlock(1, 1)->GetRawPtr());
185 BOOST_CHECK_EQUAL(m12->GetRawPtr(), b.GetBlock(2, 1)->GetRawPtr());
186
187 BOOST_CHECK_EQUAL('T', b.GetBlock(0, 0)->GetTransposeFlag());
188 BOOST_CHECK_EQUAL('T', b.GetBlock(1, 0)->GetTransposeFlag());
189 BOOST_CHECK_EQUAL('T', b.GetBlock(2, 0)->GetTransposeFlag());
190 BOOST_CHECK_EQUAL('T', b.GetBlock(0, 1)->GetTransposeFlag());
191 BOOST_CHECK_EQUAL('T', b.GetBlock(1, 1)->GetTransposeFlag());
192 BOOST_CHECK_EQUAL('T', b.GetBlock(2, 1)->GetTransposeFlag());
193
194 double v_transpose_buf[] = {1, 2, 3, 4, 5};
195 NekVector<double> v_transpose(5, v_transpose_buf);
196 NekVector<double> result_transpose = b * v_transpose;
197
198 BOOST_CHECK_EQUAL(15, result_transpose.GetRows());
199 BOOST_CHECK_EQUAL(391, result_transpose[0]);
200 BOOST_CHECK_EQUAL(433, result_transpose[1]);
201 BOOST_CHECK_EQUAL(475, result_transpose[2]);
202 BOOST_CHECK_EQUAL(517, result_transpose[3]);
203 BOOST_CHECK_EQUAL(559, result_transpose[4]);
204 BOOST_CHECK_EQUAL(601, result_transpose[5]);
205 BOOST_CHECK_EQUAL(643, result_transpose[6]);
206 BOOST_CHECK_EQUAL(685, result_transpose[7]);
207 BOOST_CHECK_EQUAL(727, result_transpose[8]);
208 BOOST_CHECK_EQUAL(769, result_transpose[9]);
209 BOOST_CHECK_EQUAL(811, result_transpose[10]);
210 BOOST_CHECK_EQUAL(853, result_transpose[11]);
211 BOOST_CHECK_EQUAL(895, result_transpose[12]);
212 BOOST_CHECK_EQUAL(937, result_transpose[13]);
213 BOOST_CHECK_EQUAL(979, result_transpose[14]);
214
215 BlockType globalTranspose = Transpose(b);
216 NekVector<double> globalResult = globalTranspose * v;
217 BOOST_CHECK_EQUAL(5, globalResult.GetRows());
218 BOOST_CHECK_EQUAL(2360, globalResult[0]);
219 BOOST_CHECK_EQUAL(2480, globalResult[1]);
220 BOOST_CHECK_EQUAL(7080, globalResult[2]);
221 BOOST_CHECK_EQUAL(7200, globalResult[3]);
222 BOOST_CHECK_EQUAL(7320, globalResult[4]);
223 //
224}
225
226BOOST_AUTO_TEST_CASE(TestBlockScaledMatrix)
227{
228 typedef NekMatrix<NekMatrix<double>, ScaledMatrixTag> InnerType;
229 typedef NekMatrix<InnerType, BlockMatrixTag> BlockType;
230
231 double m00_buf[] = {1, 2, 3, 4, 5, 6, 7, 8};
232 double m01_buf[] = {9, 10, 11, 12, 13, 14, 15, 16, 17, 18};
233 double m02_buf[] = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
234 double m10_buf[] = {31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
235 double m11_buf[] = {43, 44, 45, 46, 47, 48, 49, 50,
236 51, 52, 53, 54, 55, 56, 57};
237 double m12_buf[] = {58, 59, 60, 61, 62, 63, 64, 65, 66,
238 67, 68, 69, 70, 71, 72, 73, 74, 75};
239
240 std::shared_ptr<NekMatrix<double>> m00(
241 new NekMatrix<double>(2, 4, m00_buf));
242 std::shared_ptr<NekMatrix<double>> m01(
243 new NekMatrix<double>(2, 5, m01_buf));
244 std::shared_ptr<NekMatrix<double>> m02(
245 new NekMatrix<double>(2, 6, m02_buf));
246 std::shared_ptr<NekMatrix<double>> m10(
247 new NekMatrix<double>(3, 4, m10_buf));
248 std::shared_ptr<NekMatrix<double>> m11(
249 new NekMatrix<double>(3, 5, m11_buf));
250 std::shared_ptr<NekMatrix<double>> m12(
251 new NekMatrix<double>(3, 6, m12_buf));
252
253 std::shared_ptr<InnerType> sm00(new InnerType(2.0, m00));
254 std::shared_ptr<InnerType> sm01(new InnerType(2.0, m01));
255 std::shared_ptr<InnerType> sm02(new InnerType(2.0, m02));
256 std::shared_ptr<InnerType> sm10(new InnerType(2.0, m10));
257 std::shared_ptr<InnerType> sm11(new InnerType(2.0, m11));
258 std::shared_ptr<InnerType> sm12(new InnerType(2.0, m12));
259
260 unsigned int rowCounts[] = {2, 3};
261 unsigned int colCounts[] = {4, 5, 6};
262
263 BlockType b(2, 3, rowCounts, colCounts);
264 b.SetBlock(0, 0, sm00);
265 b.SetBlock(0, 1, sm01);
266 b.SetBlock(0, 2, sm02);
267 b.SetBlock(1, 0, sm10);
268 b.SetBlock(1, 1, sm11);
269 b.SetBlock(1, 2, sm12);
270
271 BOOST_CHECK_EQUAL(2, b.GetNumberOfBlockRows());
272 BOOST_CHECK_EQUAL(3, b.GetNumberOfBlockColumns());
273 BOOST_CHECK_EQUAL(2, b.GetNumberOfRowsInBlockRow(0));
274 BOOST_CHECK_EQUAL(3, b.GetNumberOfRowsInBlockRow(1));
275 BOOST_CHECK_EQUAL(4, b.GetNumberOfColumnsInBlockColumn(0));
276 BOOST_CHECK_EQUAL(5, b.GetNumberOfColumnsInBlockColumn(1));
277 BOOST_CHECK_EQUAL(6, b.GetNumberOfColumnsInBlockColumn(2));
278
279 BOOST_CHECK_EQUAL(0, b.CalculateBlockIndex(0, 0));
280 BOOST_CHECK_EQUAL(1, b.CalculateBlockIndex(1, 0));
281 BOOST_CHECK_EQUAL(2, b.CalculateBlockIndex(0, 1));
282 BOOST_CHECK_EQUAL(3, b.CalculateBlockIndex(1, 1));
283 BOOST_CHECK_EQUAL(4, b.CalculateBlockIndex(0, 2));
284 BOOST_CHECK_EQUAL(5, b.CalculateBlockIndex(1, 2));
285
286 BOOST_CHECK_EQUAL(m00->GetRawPtr(), b.GetBlock(0, 0)->GetRawPtr());
287 BOOST_CHECK_EQUAL(m01->GetRawPtr(), b.GetBlock(0, 1)->GetRawPtr());
288 BOOST_CHECK_EQUAL(m02->GetRawPtr(), b.GetBlock(0, 2)->GetRawPtr());
289 BOOST_CHECK_EQUAL(m10->GetRawPtr(), b.GetBlock(1, 0)->GetRawPtr());
290 BOOST_CHECK_EQUAL(m11->GetRawPtr(), b.GetBlock(1, 1)->GetRawPtr());
291 BOOST_CHECK_EQUAL(m12->GetRawPtr(), b.GetBlock(1, 2)->GetRawPtr());
292
293 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 0)->GetTransposeFlag());
294 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 1)->GetTransposeFlag());
295 BOOST_CHECK_EQUAL('N', b.GetBlock(0, 2)->GetTransposeFlag());
296 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 0)->GetTransposeFlag());
297 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 1)->GetTransposeFlag());
298 BOOST_CHECK_EQUAL('N', b.GetBlock(1, 2)->GetTransposeFlag());
299
300 double v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
301 NekVector<double> v(15, v_buf);
302 NekVector<double> result = b * v;
303
304 BOOST_CHECK_EQUAL(5, result.GetRows());
305 BOOST_CHECK_EQUAL(2360 * 2, result[0]);
306 BOOST_CHECK_EQUAL(2480 * 2, result[1]);
307 BOOST_CHECK_EQUAL(7080 * 2, result[2]);
308 BOOST_CHECK_EQUAL(7200 * 2, result[3]);
309 BOOST_CHECK_EQUAL(7320 * 2, result[4]);
310
311 b.Transpose();
312
313 BOOST_CHECK_EQUAL(3, b.GetNumberOfBlockRows());
314 BOOST_CHECK_EQUAL(2, b.GetNumberOfBlockColumns());
315
316 BOOST_CHECK_EQUAL(2, b.GetNumberOfColumnsInBlockColumn(0));
317 BOOST_CHECK_EQUAL(3, b.GetNumberOfColumnsInBlockColumn(1));
318 BOOST_CHECK_EQUAL(4, b.GetNumberOfRowsInBlockRow(0));
319 BOOST_CHECK_EQUAL(5, b.GetNumberOfRowsInBlockRow(1));
320 BOOST_CHECK_EQUAL(6, b.GetNumberOfRowsInBlockRow(2));
321
322 BOOST_CHECK_EQUAL(0, b.CalculateBlockIndex(0, 0));
323 BOOST_CHECK_EQUAL(1, b.CalculateBlockIndex(0, 1));
324 BOOST_CHECK_EQUAL(2, b.CalculateBlockIndex(1, 0));
325 BOOST_CHECK_EQUAL(3, b.CalculateBlockIndex(1, 1));
326 BOOST_CHECK_EQUAL(4, b.CalculateBlockIndex(2, 0));
327 BOOST_CHECK_EQUAL(5, b.CalculateBlockIndex(2, 1));
328
329 BOOST_CHECK_EQUAL(m00->GetRawPtr(), b.GetBlock(0, 0)->GetRawPtr());
330 BOOST_CHECK_EQUAL(m01->GetRawPtr(), b.GetBlock(1, 0)->GetRawPtr());
331 BOOST_CHECK_EQUAL(m02->GetRawPtr(), b.GetBlock(2, 0)->GetRawPtr());
332 BOOST_CHECK_EQUAL(m10->GetRawPtr(), b.GetBlock(0, 1)->GetRawPtr());
333 BOOST_CHECK_EQUAL(m11->GetRawPtr(), b.GetBlock(1, 1)->GetRawPtr());
334 BOOST_CHECK_EQUAL(m12->GetRawPtr(), b.GetBlock(2, 1)->GetRawPtr());
335
336 BOOST_CHECK_EQUAL('T', b.GetBlock(0, 0)->GetTransposeFlag());
337 BOOST_CHECK_EQUAL('T', b.GetBlock(1, 0)->GetTransposeFlag());
338 BOOST_CHECK_EQUAL('T', b.GetBlock(2, 0)->GetTransposeFlag());
339 BOOST_CHECK_EQUAL('T', b.GetBlock(0, 1)->GetTransposeFlag());
340 BOOST_CHECK_EQUAL('T', b.GetBlock(1, 1)->GetTransposeFlag());
341 BOOST_CHECK_EQUAL('T', b.GetBlock(2, 1)->GetTransposeFlag());
342
343 double v_transpose_buf[] = {1, 2, 3, 4, 5};
344 NekVector<double> v_transpose(5, v_transpose_buf);
345 NekVector<double> result_transpose = b * v_transpose;
346
347 BOOST_CHECK_EQUAL(15, result_transpose.GetRows());
348 BOOST_CHECK_EQUAL(391 * 2, result_transpose[0]);
349 BOOST_CHECK_EQUAL(433 * 2, result_transpose[1]);
350 BOOST_CHECK_EQUAL(475 * 2, result_transpose[2]);
351 BOOST_CHECK_EQUAL(517 * 2, result_transpose[3]);
352 BOOST_CHECK_EQUAL(559 * 2, result_transpose[4]);
353 BOOST_CHECK_EQUAL(601 * 2, result_transpose[5]);
354 BOOST_CHECK_EQUAL(643 * 2, result_transpose[6]);
355 BOOST_CHECK_EQUAL(685 * 2, result_transpose[7]);
356 BOOST_CHECK_EQUAL(727 * 2, result_transpose[8]);
357 BOOST_CHECK_EQUAL(769 * 2, result_transpose[9]);
358 BOOST_CHECK_EQUAL(811 * 2, result_transpose[10]);
359 BOOST_CHECK_EQUAL(853 * 2, result_transpose[11]);
360 BOOST_CHECK_EQUAL(895 * 2, result_transpose[12]);
361 BOOST_CHECK_EQUAL(937 * 2, result_transpose[13]);
362 BOOST_CHECK_EQUAL(979 * 2, result_transpose[14]);
363}
364
365BOOST_AUTO_TEST_CASE(TestBlockBlockMatrixTranspose)
366{
370
371 double m_00_buf[] = {1, 2, 3, 4, 5, 6};
372 double m_01_buf[] = {7, 8, 9, 10, 11, 12, 13, 14};
373 double m_10_buf[] = {15, 16, 17, 18, 19, 20};
374 double m_11_buf[] = {21, 22, 23, 24, 25, 26, 27, 28};
375 double m_20_buf[] = {29, 30, 31, 32, 33, 34};
376 double m_21_buf[] = {35, 36, 37, 38, 39, 40, 41, 42};
377 std::shared_ptr<Matrix> m00(new Matrix(2, 3, m_00_buf));
378 std::shared_ptr<Matrix> m01(new Matrix(2, 4, m_01_buf));
379 std::shared_ptr<Matrix> m10(new Matrix(2, 3, m_10_buf));
380 std::shared_ptr<Matrix> m11(new Matrix(2, 4, m_11_buf));
381 std::shared_ptr<Matrix> m20(new Matrix(2, 3, m_20_buf));
382 std::shared_ptr<Matrix> m21(new Matrix(2, 4, m_21_buf));
383
384 unsigned int rowCounts[] = {2, 2, 2};
385 unsigned int colCounts[] = {3, 4};
386
387 std::vector<std::shared_ptr<InnerMatrix>> innerMatrices;
388
389 for (int i = 0; i < 6; ++i)
390 {
391 std::shared_ptr<Matrix> t00(new Matrix(*m00));
392 std::shared_ptr<Matrix> t01(new Matrix(*m01));
393 std::shared_ptr<Matrix> t10(new Matrix(*m10));
394 std::shared_ptr<Matrix> t11(new Matrix(*m11));
395 std::shared_ptr<Matrix> t20(new Matrix(*m20));
396 std::shared_ptr<Matrix> t21(new Matrix(*m21));
397
398 (*t00) *= (i + 1);
399 (*t01) *= (i + 1);
400 (*t10) *= (i + 1);
401 (*t11) *= (i + 1);
402 (*t20) *= (i + 1);
403 (*t21) *= (i + 1);
404
405 std::shared_ptr<InnerMatrix> matrix(
406 new InnerMatrix(3, 2, rowCounts, colCounts));
407 matrix->SetBlock(0, 0, t00);
408 matrix->SetBlock(0, 1, t01);
409 matrix->SetBlock(1, 0, t10);
410 matrix->SetBlock(1, 1, t11);
411 matrix->SetBlock(2, 0, t20);
412 matrix->SetBlock(2, 1, t21);
413
414 innerMatrices.push_back(matrix);
415 }
416
417 unsigned int topLevelRowCounts[] = {6, 6};
418 unsigned int topLevelColumnCounts[] = {7, 7, 7};
419 BlockMatrix topLevelMatrix(2, 3, topLevelRowCounts, topLevelColumnCounts);
420 topLevelMatrix.SetBlock(0, 0, innerMatrices[0]);
421 topLevelMatrix.SetBlock(0, 1, innerMatrices[1]);
422 topLevelMatrix.SetBlock(0, 2, innerMatrices[2]);
423 topLevelMatrix.SetBlock(1, 0, innerMatrices[3]);
424 topLevelMatrix.SetBlock(1, 1, innerMatrices[4]);
425 topLevelMatrix.SetBlock(1, 2, innerMatrices[5]);
426
427 double v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
428 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
429 NekVector<double> v(21, v_buf);
430
431 NekVector<double> result = topLevelMatrix * v;
432
433 double expected_result_buf[] = {4256, 4816, 12096, 12656, 19936, 20496,
434 9611, 10864, 27153, 28406, 44695, 45948};
435 NekVector<double> expected_result(12, expected_result_buf);
436
437 BOOST_CHECK_EQUAL(expected_result, result);
438
439 topLevelMatrix.Transpose();
440
441 double transposed_v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
442 NekVector<double> transposed_v(12, transposed_v_buf);
443 NekVector<double> transposed_result = topLevelMatrix * transposed_v;
444
445 double expected_transpose_result_buf[] = {
446 4427, 4925, 5423, 5921, 6419, 6917, 7415, 5863, 6517, 7171, 7825,
447 8479, 9133, 9787, 7299, 8109, 8919, 9729, 10539, 11349, 12159};
448 NekVector<double> expected_transpose_result(21,
449 expected_transpose_result_buf);
450
451 BOOST_CHECK_EQUAL(expected_transpose_result, transposed_result);
452}
453
454BOOST_AUTO_TEST_CASE(TestBlockBlockScaledMatrixTranspose)
455{
457 typedef NekMatrix<NekMatrix<double>, ScaledMatrixTag> ScaledMatrix;
460
461 double m_00_buf[] = {1, 2, 3, 4, 5, 6};
462 double m_01_buf[] = {7, 8, 9, 10, 11, 12, 13, 14};
463 double m_10_buf[] = {15, 16, 17, 18, 19, 20};
464 double m_11_buf[] = {21, 22, 23, 24, 25, 26, 27, 28};
465 double m_20_buf[] = {29, 30, 31, 32, 33, 34};
466 double m_21_buf[] = {35, 36, 37, 38, 39, 40, 41, 42};
467 std::shared_ptr<Matrix> m00(new Matrix(2, 3, m_00_buf));
468 std::shared_ptr<Matrix> m01(new Matrix(2, 4, m_01_buf));
469 std::shared_ptr<Matrix> m10(new Matrix(2, 3, m_10_buf));
470 std::shared_ptr<Matrix> m11(new Matrix(2, 4, m_11_buf));
471 std::shared_ptr<Matrix> m20(new Matrix(2, 3, m_20_buf));
472 std::shared_ptr<Matrix> m21(new Matrix(2, 4, m_21_buf));
473
474 unsigned int rowCounts[] = {2, 2, 2};
475 unsigned int colCounts[] = {3, 4};
476
477 std::vector<std::shared_ptr<InnerMatrix>> innerMatrices;
478
479 for (int i = 0; i < 6; ++i)
480 {
481 std::shared_ptr<Matrix> t00(new Matrix(*m00));
482 std::shared_ptr<Matrix> t01(new Matrix(*m01));
483 std::shared_ptr<Matrix> t10(new Matrix(*m10));
484 std::shared_ptr<Matrix> t11(new Matrix(*m11));
485 std::shared_ptr<Matrix> t20(new Matrix(*m20));
486 std::shared_ptr<Matrix> t21(new Matrix(*m21));
487
488 std::shared_ptr<ScaledMatrix> s00(new ScaledMatrix(i + 1, t00));
489 std::shared_ptr<ScaledMatrix> s01(new ScaledMatrix(i + 1, t01));
490 std::shared_ptr<ScaledMatrix> s10(new ScaledMatrix(i + 1, t10));
491 std::shared_ptr<ScaledMatrix> s11(new ScaledMatrix(i + 1, t11));
492 std::shared_ptr<ScaledMatrix> s20(new ScaledMatrix(i + 1, t20));
493 std::shared_ptr<ScaledMatrix> s21(new ScaledMatrix(i + 1, t21));
494
495 std::shared_ptr<InnerMatrix> matrix(
496 new InnerMatrix(3, 2, rowCounts, colCounts));
497 matrix->SetBlock(0, 0, s00);
498 matrix->SetBlock(0, 1, s01);
499 matrix->SetBlock(1, 0, s10);
500 matrix->SetBlock(1, 1, s11);
501 matrix->SetBlock(2, 0, s20);
502 matrix->SetBlock(2, 1, s21);
503
504 innerMatrices.push_back(matrix);
505 }
506
507 unsigned int topLevelRowCounts[] = {6, 6};
508 unsigned int topLevelColumnCounts[] = {7, 7, 7};
509 BlockMatrix topLevelMatrix(2, 3, topLevelRowCounts, topLevelColumnCounts);
510 topLevelMatrix.SetBlock(0, 0, innerMatrices[0]);
511 topLevelMatrix.SetBlock(0, 1, innerMatrices[1]);
512 topLevelMatrix.SetBlock(0, 2, innerMatrices[2]);
513 topLevelMatrix.SetBlock(1, 0, innerMatrices[3]);
514 topLevelMatrix.SetBlock(1, 1, innerMatrices[4]);
515 topLevelMatrix.SetBlock(1, 2, innerMatrices[5]);
516
517 double v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
518 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
519 NekVector<double> v(21, v_buf);
520
521 NekVector<double> result = topLevelMatrix * v;
522
523 double expected_result_buf[] = {4256, 4816, 12096, 12656, 19936, 20496,
524 9611, 10864, 27153, 28406, 44695, 45948};
525 NekVector<double> expected_result(12, expected_result_buf);
526
527 BOOST_CHECK_EQUAL(expected_result, result);
528
529 topLevelMatrix.Transpose();
530
531 double transposed_v_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
532 NekVector<double> transposed_v(12, transposed_v_buf);
533 NekVector<double> transposed_result = topLevelMatrix * transposed_v;
534
535 double expected_transpose_result_buf[] = {
536 4427, 4925, 5423, 5921, 6419, 6917, 7415, 5863, 6517, 7171, 7825,
537 8479, 9133, 9787, 7299, 8109, 8919, 9729, 10539, 11349, 12159};
538 NekVector<double> expected_transpose_result(21,
539 expected_transpose_result_buf);
540
541 BOOST_CHECK_EQUAL(expected_transpose_result, transposed_result);
542}
543
544BOOST_AUTO_TEST_CASE(TestMultiplicationBlock_1)
545{
546 typedef NekMatrix<double> InnerType;
547 typedef NekMatrix<InnerType, BlockMatrixTag> BlockType;
548
549 double m_00_buf[] = {3, 1, 5, 5};
550 double m_01_buf[] = {2, 4, 4, 1, 1, 3};
551 double m_02_buf[] = {3, 1, 2, 2, 4, 1, 4, 2};
552
553 double m_10_buf[] = {1, 3, 5, 1, 4, 2};
554 double m_11_buf[] = {4, 4, 1, 1, 1, 4, 5, 5, 3};
555 double m_12_buf[] = {5, 2, 1, 2, 3, 1, 1, 3, 1, 4, 1, 1};
556
557 double m_20_buf[] = {3, 1, 4, 2, 5, 1, 4, 2};
558 double m_21_buf[] = {4, 5, 2, 4, 4, 2, 3, 5, 2, 2, 5, 3};
559 double m_22_buf[] = {3, 4, 3, 1, 2, 1, 2, 4, 4, 5, 2, 3, 5, 4, 1, 1};
560
561 double m_30_buf[] = {2, 2, 1, 4, 5, 5};
562 double m_31_buf[] = {1, 1, 3, 2, 1, 2, 3, 3, 2};
563 double m_32_buf[] = {3, 1, 3, 1, 2, 2, 4, 2, 5, 5, 1, 1};
564
565 std::shared_ptr<InnerType> m00(new InnerType(2, 2, m_00_buf));
566 std::shared_ptr<InnerType> m01(new InnerType(2, 3, m_01_buf));
567 std::shared_ptr<InnerType> m02(new InnerType(2, 4, m_02_buf));
568
569 std::shared_ptr<InnerType> m10(new InnerType(3, 2, m_10_buf));
570 std::shared_ptr<InnerType> m11(new InnerType(3, 3, m_11_buf));
571 std::shared_ptr<InnerType> m12(new InnerType(3, 4, m_12_buf));
572
573 std::shared_ptr<InnerType> m20(new InnerType(4, 2, m_20_buf));
574 std::shared_ptr<InnerType> m21(new InnerType(4, 3, m_21_buf));
575 std::shared_ptr<InnerType> m22(new InnerType(4, 4, m_22_buf));
576
577 std::shared_ptr<InnerType> m30(new InnerType(3, 2, m_30_buf));
578 std::shared_ptr<InnerType> m31(new InnerType(3, 3, m_31_buf));
579 std::shared_ptr<InnerType> m32(new InnerType(3, 4, m_32_buf));
580
581 unsigned int rowCounts[] = {2, 3, 4, 3};
582 unsigned int colCounts[] = {2, 3, 4};
583
584 BlockType b(4, 3, rowCounts, colCounts);
585 b.SetBlock(0, 0, m00);
586 b.SetBlock(0, 1, m01);
587 b.SetBlock(0, 2, m02);
588 b.SetBlock(1, 0, m10);
589 b.SetBlock(1, 1, m11);
590 b.SetBlock(1, 2, m12);
591 b.SetBlock(2, 0, m20);
592 b.SetBlock(2, 1, m21);
593 b.SetBlock(2, 2, m22);
594 b.SetBlock(3, 0, m30);
595 b.SetBlock(3, 1, m31);
596 b.SetBlock(3, 2, m32);
597
598 Array<OneD, unsigned int> arrayRowCounts(4, rowCounts);
599 Array<OneD, unsigned int> arrayColCounts(3, colCounts);
600 BlockType b_initializedWithArray(arrayRowCounts, arrayColCounts);
601 b_initializedWithArray.SetBlock(0, 0, m00);
602 b_initializedWithArray.SetBlock(0, 1, m01);
603 b_initializedWithArray.SetBlock(0, 2, m02);
604 b_initializedWithArray.SetBlock(1, 0, m10);
605 b_initializedWithArray.SetBlock(1, 1, m11);
606 b_initializedWithArray.SetBlock(1, 2, m12);
607 b_initializedWithArray.SetBlock(2, 0, m20);
608 b_initializedWithArray.SetBlock(2, 1, m21);
609 b_initializedWithArray.SetBlock(2, 2, m22);
610 b_initializedWithArray.SetBlock(3, 0, m30);
611 b_initializedWithArray.SetBlock(3, 1, m31);
612 b_initializedWithArray.SetBlock(3, 2, m32);
613
614 double rhs_buf[] = {4, 2, 5, 5, 3, 1, 3, 2, 3};
615 NekVector<double> rhs(9, rhs_buf);
616
617 NekVector<double> result = b * rhs;
618 NekVector<double> result1 = b_initializedWithArray * rhs;
619
620 double expected_buf[] = {84, 63, 71, 80, 67, 100, 76, 80, 88, 69, 51, 67};
621 NekVector<double> expected_result(12, expected_buf);
622
623 BOOST_CHECK_EQUAL(expected_result, result);
624 BOOST_CHECK_EQUAL(expected_result, result1);
625}
626
627BOOST_AUTO_TEST_CASE(TestDiagonalBlockMatrixMultiplication)
628{
629 typedef NekMatrix<double> InnerType;
630 typedef NekMatrix<InnerType, BlockMatrixTag> BlockType;
631
632 double m_00_buf[] = {1, 3, 2, 4};
633 double m_11_buf[] = {1, 4, 2, 5, 3, 6};
634 double m_22_buf[] = {1, 3, 5, 2, 4, 6};
635
636 std::shared_ptr<InnerType> m00(new InnerType(2, 2, m_00_buf));
637 std::shared_ptr<InnerType> m11(new InnerType(2, 3, m_11_buf));
638 std::shared_ptr<InnerType> m22(new InnerType(3, 2, m_22_buf));
639
640 unsigned int rowCounts[] = {2, 2, 3};
641 unsigned int colCounts[] = {2, 3, 2};
642
643 BlockType b(3, 3, rowCounts, colCounts, eDIAGONAL);
644 b.SetBlock(0, 0, m00);
645 b.SetBlock(1, 1, m11);
646 b.SetBlock(2, 2, m22);
647
648 double rhs_buf[] = {1, 2, 3, 4, 5, 6, 7};
649 NekVector<double> rhs(7, rhs_buf);
650
651 NekVector<double> result = b * rhs;
652
653 double expected_buf[] = {5, 11, 26, 62, 20, 46, 72};
654 NekVector<double> expected_result(7, expected_buf);
655
656 BOOST_CHECK_EQUAL(expected_result, result);
657}
658
659BOOST_AUTO_TEST_CASE(TestDiagonalBlockMatrixMultiplicationWith0SizeBlocks)
660{
661 typedef NekMatrix<double> InnerType;
662 typedef NekMatrix<InnerType, BlockMatrixTag> BlockType;
663
664 double m_22_buf[] = {1, 2, 3, 4, 5, 6, 7, 8};
665
666 std::shared_ptr<InnerType> m22(new InnerType(1, 8, m_22_buf));
667
668 unsigned int rowCounts[] = {0, 0, 1};
669 unsigned int colCounts[] = {6, 6, 8};
670
671 BlockType b(3, 3, rowCounts, colCounts, eDIAGONAL);
672 b.SetBlock(2, 2, m22);
673
674 double rhs_buf[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
675 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
676 NekVector<double> rhs(20, rhs_buf);
677
678 NekVector<double> result = b * rhs;
679
680 double expected_buf[] = {1 * 1 + 2 * 2 + 3 * 3 + 4 * 4 + 5 * 5 + 6 * 6 +
681 7 * 7 + 8 * 8};
682 NekVector<double> expected_result(1, expected_buf);
683
684 BOOST_CHECK_EQUAL(expected_result, result);
685}
686
687BOOST_AUTO_TEST_CASE(TestBlockMatrixMultiplicationWith0SizeBlocks)
688{
689 typedef NekMatrix<double> InnerType;
690 typedef NekMatrix<InnerType, BlockMatrixTag> BlockType;
691
692 double m_22_buf[] = {1, 2, 3, 4, 5, 6, 7, 8};
693
694 std::shared_ptr<InnerType> m22(new InnerType(1, 8, m_22_buf));
695
696 unsigned int rowCounts[] = {0, 0, 1};
697 unsigned int colCounts[] = {6, 6, 8};
698
699 BlockType b(3, 3, rowCounts, colCounts, eFULL);
700 b.SetBlock(2, 2, m22);
701
702 double rhs_buf[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
703 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
704 NekVector<double> rhs(20, rhs_buf);
705
706 NekVector<double> result = b * rhs;
707
708 double expected_buf[] = {1 * 1 + 2 * 2 + 3 * 3 + 4 * 4 + 5 * 5 + 6 * 6 +
709 7 * 7 + 8 * 8};
710 NekVector<double> expected_result(1, expected_buf);
711
712 BOOST_CHECK_EQUAL(expected_result, result);
713}
714
715BOOST_AUTO_TEST_CASE(TestBlockMatrixErrorFrom6_10)
716{
717
718 // Array<OneD, NekDouble> f_bnd(m_BCinv->GetRows());
719 // NekVector< NekDouble > F_bnd(f_bnd.size(), f_bnd, eWrapper);
720
721 // Array<OneD, NekDouble> f_int(m_BCinv->GetColumns());
722 // NekVector< NekDouble > F_int(f_int.size(),f_int, eWrapper);
723
724 // Array<OneD, NekDouble > f_p(m_D_int->GetRows());
725 // NekVector< NekDouble > F_p(f_p.size(),f_p,eWrapper);
726
727 // typedef NekMatrix<DNekScalBlkMat, BlockMatrixTag> BlkMatDNekScalBlkMat;
728 // typedef std::shared_ptr<BlkMatDNekScalBlkMat>
729 // BlkMatDNekScalBlkMatSharedPtr;
730
731 // BlkMatDNekScalBlkMatSharedPtr m_Btilde =
732 // MemoryManager<BlkMatDNekScalBlkMat>
733 // ::AllocateSharedPtr(nsize_int,nsize_bndry,blkmatStorage);
734 // BlkMatDNekScalBlkMatSharedPtr m_Cinv =
735 // MemoryManager<BlkMatDNekScalBlkMat>
736 // ::AllocateSharedPtr(nsize_int,nsize_int,eFull);
737
738 typedef NekMatrix<double> M1;
742
743 std::vector<std::shared_ptr<M2>> scaledMatrices;
744 for (unsigned int i = 0; i < 36; ++i)
745 {
746 double values[] = {i * 4.0, i * 4.0 + 1.0, i * 4.0 + 2.0,
747 i * 4.0 + 3.0};
748 std::shared_ptr<M1> matrix(new M1(2, 2, values));
749 std::shared_ptr<M2> scaled(new M2(1.0, matrix));
750 scaledMatrices.push_back(scaled);
751 }
752
753 std::vector<std::shared_ptr<M3>> blockMatrices;
754 for (unsigned int i = 0; i < 6; ++i)
755 {
756 std::shared_ptr<M3> blockMatrix(new M3(2, 3, 2, 2));
757 blockMatrix->SetBlock(0, 0, scaledMatrices[i * 6]);
758 blockMatrix->SetBlock(0, 1, scaledMatrices[i * 6 + 1]);
759 blockMatrix->SetBlock(0, 2, scaledMatrices[i * 6 + 2]);
760 blockMatrix->SetBlock(1, 0, scaledMatrices[i * 6 + 3]);
761 blockMatrix->SetBlock(1, 1, scaledMatrices[i * 6 + 4]);
762 blockMatrix->SetBlock(1, 2, scaledMatrices[i * 6 + 5]);
763 blockMatrices.push_back(blockMatrix);
764 }
765
766 std::shared_ptr<M4> matrix(new M4(3, 2, 4, 6));
767 matrix->SetBlock(0, 0, blockMatrices[0]);
768 matrix->SetBlock(0, 1, blockMatrices[1]);
769 matrix->SetBlock(1, 0, blockMatrices[2]);
770 matrix->SetBlock(1, 1, blockMatrices[3]);
771 matrix->SetBlock(2, 0, blockMatrices[4]);
772 matrix->SetBlock(2, 1, blockMatrices[5]);
773
774 double b_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
775 NekVector<double> b(12, b_buf);
776
777 {
778 NekVector<double> result = (*matrix) * b;
779
780 double expected_buf[] = {1828, 1906, 2764, 2842, 5572, 5650,
781 6508, 6586, 9316, 9394, 10252, 10330};
782 NekVector<double> expected_result(12, expected_buf);
783 BOOST_CHECK_EQUAL(result, expected_result);
784 }
785
786 {
787 NekVector<double> result = b - (*matrix) * b;
788
789 double expected_buf[] = {-1827, -1904, -2761, -2838, -5567, -5644,
790 -6501, -6578, -9307, -9384, -10241, -10318};
791
792 NekVector<double> expected_result(12, expected_buf);
793 BOOST_CHECK_EQUAL(expected_result, result);
794 }
795
796 {
797 NekVector<double> result = b;
798 result = result - (*matrix) * b;
799
800 double expected_buf[] = {-1827, -1904, -2761, -2838, -5567, -5644,
801 -6501, -6578, -9307, -9384, -10241, -10318};
802
803 NekVector<double> expected_result(12, expected_buf);
804 BOOST_CHECK_EQUAL(expected_result, result);
805 }
806
807 // #if 0
808 // F_int = (F_int - (*m_Btilde)*F_bnd);
809 // #else
810 // for(i = 0; i < m_Btilde->GetRows(); ++i)
811 // {
812 // for(j = 0; j < m_Btilde->GetColumns(); ++j)
813 // {
814 // F_int[i] -= (*m_Btilde)(i,j)*F_bnd[j];
815 // }
816 // }
817 // #endif
818 //
819 // F_int = (F_int + Transpose(*m_D_int)*F_p);
820 //
821 // #if 0
822 // F_int = (*m_Cinv)*F_int;
823 // #else
824 // Array<OneD, NekDouble> ftmp(F_int.GetDimension(),0.0);
825 // for(i = 0; i < m_Cinv->GetRows(); ++i)
826 // {
827 // for(j = 0; j < m_Cinv->GetColumns(); ++j)
828 // {
829 // ftmp[i] += (*m_Cinv)(i,j)*F_int[j];
830 // }
831 // }
832 // for(i = 0; i < ftmp.size(); ++i)
833 // {
834 // F_int[i] = ftmp[i];
835 // }
836 // #endif
837}
838
839} // namespace Nektar::BlockMatrixUnitTests
unsigned int GetRows() const
Definition: NekVector.cpp:206
BOOST_AUTO_TEST_CASE(TestEqualSizedBlockConstruction)
NekMatrix< DenseMatrix, BlockMatrixTag > BlockMatrix
Definition: NekTypeDefs.hpp:59
NekMatrix< DenseMatrix, ScaledMatrixTag > ScaledMatrix
Definition: NekTypeDefs.hpp:55
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)