TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
IJK_Finite_Difference_One_Dimensional_Matrix_Assembler.cpp
1/****************************************************************************
2* Copyright (c) 2023, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <IJK_Finite_Difference_One_Dimensional_Matrix_Assembler.h>
17
18Implemente_instanciable_sans_constructeur( IJK_Finite_Difference_One_Dimensional_Matrix_Assembler, "IJK_Finite_Difference_One_Dimensional_Matrix_Assembler", Objet_U ) ;
19
20// static IntVect arg_sort(DoubleVect matrix_column_indices)
21static std::vector<int> arg_sort(DoubleVect matrix_column_indices)
22{
23 const int n = matrix_column_indices.size();
24 // IntVect indices(n);
25 std::vector<int> indices(n);
26 for (int j=0; j<n; j++)
27 indices[j]=j;
28 std::sort(indices.begin(), indices.end(), [&matrix_column_indices](int i, int j) {return matrix_column_indices[i] < matrix_column_indices[j];});
29 return indices;
30}
31
32static void sort_stencil(Matrice_Morse& sparse_matrix)
33{
34 auto& matrix_values = sparse_matrix.get_set_coeff();
35 auto& non_zero_coeff_per_line = sparse_matrix.get_set_tab1();
36 auto& matrix_column_indices = sparse_matrix.get_set_tab2();
37 for (int i = 0; i + 1 < non_zero_coeff_per_line.size_array(); i++) //indice de ligne
38 {
39 const int index_ini = non_zero_coeff_per_line[i] - FORTRAN_INDEX_INI;
40 const int index_end = non_zero_coeff_per_line[i+1] - FORTRAN_INDEX_INI;
41 int n = index_end - index_ini;
42 DoubleVect matrix_column_indices_local(n);
43 DoubleVect matrix_values_local(n);
44 for (int j=0; j<n; j++)
45 {
46 matrix_column_indices_local(j) = matrix_column_indices(j + index_ini);
47 matrix_values_local(j) = matrix_values(j + index_ini);
48 }
49 std::vector<int> indices;
50 indices = arg_sort(matrix_column_indices_local);
51 for (int j=0; j<n; j++)
52 if (j != indices[j])
53 matrix_values[j + index_ini] = matrix_values_local[indices[j]];
54 }
55}
56
57IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::IJK_Finite_Difference_One_Dimensional_Matrix_Assembler()
58{
59 // Forward
61 // Centred
63 // Backward
65
66 // Forward
68 // Centred
70 // Backward
72
73 //Identity
74 for(int i=0; i<MAX_ORDER_DERIVATIVE; i++)
75 {
76 identity_coefficient_[i][0] = DoubleVect(1);
77 identity_coefficient_[i][0](0) = 0.;
78 identity_coefficient_[i][1] = DoubleVect(1);
79 identity_coefficient_[i][1](0) = 1.;
80 }
81}
82
84{
85 // Objet_U::printOn( os );
86 Nom front_space = " ";
87 Nom end_space = " ";
88 Nom escape = "\n";
89 os << escape;
90 os << front_space << "{" << escape;
92 os << front_space << " reduce_side_precision" << escape;
93 os << front_space << " precision_order" << end_space << precision_order_ << escape;
94 os << front_space << "}" << escape;
95 return os;
96}
97
99{
100 /*
101 * Parse the datafile
102 */
103 Param param(que_suis_je());
104 set_param(param);
105 param.lire_avec_accolades(is);
106 Cout << "IJK_Thermal_base::readOn : Parameters summary. " << finl;
107 printOn(Cout);
108 return is;
109}
110
112{
113 param.ajouter("precision_order", &precision_order_);
114 param.ajouter_flag("reduce_side_precision", &reduce_side_precision_);
115}
116
117void IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::set_operators_size(const std::vector<std::vector<double>>& fd_operator_vector,
118 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE>& fd_operator)
119{
120 int i,j;
121 for(i=0; i<MAX_ORDER_DERIVATIVE; i++)
122 {
123 const int fd_operator_size = (int) fd_operator_vector[i].size();
124 fd_operator[i][0] = DoubleVect(fd_operator_size);
125 fd_operator[i][1] = DoubleVect(fd_operator_size);
126 for (j=0; j<fd_operator_size; j++)
127 fd_operator[i][1](j) = fd_operator_vector[i][j];
128 }
129}
130
131void IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::set_operators_indices(const std::vector<std::vector<double>>& fd_operator_vector,
132 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE>& fd_operator,
133 const int& fd_coefficient_type)
134{
135 int i,j;
136 set_operators_size(fd_operator_vector, fd_operator);
137 switch (fd_coefficient_type)
138 {
139 case forward:
140 for(i=0; i<MAX_ORDER_DERIVATIVE; i++)
141 for (j=0; j < fd_operator[i][0].size(); j++)
142 fd_operator[i][0](j) = j;
143 break;
144 case centred:
145 for(i=0; i<MAX_ORDER_DERIVATIVE; i++)
146 {
147 const int fd_operator_size = fd_operator[i][0].size();
148 const int offset = (int) (fd_operator_size/2);
149 for (j=0; j < fd_operator_size; j++)
150 fd_operator[i][0](j) = j-offset;
151 }
152 break;
153 case backward:
154 for(i=0; i<MAX_ORDER_DERIVATIVE; i++)
155 for (j=0; j < fd_operator[i][0].size(); j++)
156 fd_operator[i][0](j) = -j;
157 break;
158 default:
159 for(i=0; i<MAX_ORDER_DERIVATIVE; i++)
160 {
161 const int fd_operator_size = fd_operator[i][0].size();
162 const int offset = (int) (fd_operator_size/2);
163 for (j=0; j < fd_operator_size; j++)
164 fd_operator[i][0](j) = j-offset;
165 }
166 break;
167 }
168}
169
171{
172 int non_zero_elem = 0;
173 const int stencil_width = fd_operator[precision_order_-1][1].size();
174 for (int i=0; i<stencil_width; i++)
175 if (fd_operator[precision_order_-1][1][i] != 0)
176 non_zero_elem++;
177 return non_zero_elem;
178}
179
181 const FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE>& fd_operator_diff,
182 int (&stencil_left_offset) [3], int (&stencil_right_offset) [3])
183{
184 std::vector<int> indices_op;
185 const int stencil_width_conv = fd_operator_conv[precision_order_-1][0].size();
186 const int stencil_width_diff = fd_operator_diff[precision_order_-1][0].size();
187 int min_conv = 0;
188 int min_diff = 0;
189 int max_conv = 0;
190 int max_diff = 0;
191 int min_identity = 0;
192 int max_identity = 0;
193 int i;
194 for (i=0; i<stencil_width_conv; i++)
195 {
196 const int index = (int) fd_operator_conv[precision_order_-1][0](i);
197 min_conv = std::min(min_conv, (int) fd_operator_conv[precision_order_-1][0](i));
198 max_conv = std::max(max_conv, (int) fd_operator_conv[precision_order_-1][0](i));
199 if (std::find(indices_op.begin(), indices_op.end(), index) == indices_op.end())
200 indices_op.push_back(index);
201 }
202 for (i=0; i<stencil_width_diff; i++)
203 {
204 const int index = (int) fd_operator_diff[precision_order_-1][0](i);
205 min_diff = std::min(min_diff, (int) fd_operator_diff[precision_order_-1][0](i));
206 max_diff = std::max(max_diff, (int) fd_operator_diff[precision_order_-1][0](i));
207 if (std::find(indices_op.begin(), indices_op.end(), index) == indices_op.end())
208 indices_op.push_back(index);
209 }
210 const int min_conv_diff_identity = std::min(std::min(min_conv, min_diff), min_identity);
211 const int max_conv_diff_identity = std::max(std::max(max_conv, max_diff), max_identity);
212
213 const int left_offset_conv = (int) fabs(min_conv-min_conv_diff_identity);
214 const int right_offset_conv = (int) fabs(max_conv-max_conv_diff_identity);
215 const int left_offset_diff = (int) fabs(min_diff-min_conv_diff_identity);
216 const int right_offset_diff = (int) fabs(max_diff-max_conv_diff_identity);
217 const int left_offset_identity = (int) fabs(min_identity-min_conv_diff_identity);
218 const int right_offset_identity = (int) fabs(max_identity-max_conv_diff_identity);
219
220 stencil_left_offset[0] = left_offset_conv;
221 stencil_left_offset[1] = left_offset_diff;
222 stencil_left_offset[2] = left_offset_identity;
223 stencil_right_offset[0] = right_offset_conv;
224 stencil_right_offset[1] = right_offset_diff;
225 stencil_right_offset[2] = right_offset_identity;
226
227 int non_zero_elem = (int) indices_op.size();
228 return non_zero_elem;
229}
230
232 int& non_zero_elem_max,
233 int& stencil_forward_max,
234 int& stencil_centred_max,
235 int& stencil_backward_max)
236{
237 int stencil_forward_size = 0;
238 int stencil_centred_size = 0;
239 int stencil_backward_size = 0;
240 switch (equation_type_)
241 {
246 break;
247 case linear_diffusion:
248 stencil_forward_size = second_order_derivative_forward_[precision_order_-1][1].size();
249 stencil_centred_size = second_order_derivative_centred_[precision_order_-1][1].size();
250 stencil_backward_size = second_order_derivative_backward_[precision_order_-1][1].size();
251 break;
252 default:
256 break;
257 }
258 stencil_forward_max = stencil_forward_size;
259 stencil_centred_max = stencil_centred_size;
260 stencil_backward_max = stencil_backward_size;
261 const int core_lines = (nb_elem - 2);
262 non_zero_elem_max = stencil_forward_max + stencil_backward_max + stencil_centred_max * core_lines;
263}
264
274
275int IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::build(Matrice& matrix, const int& nb_elem, const int& derivative_order)
276{
277 if (known_pattern_)
278 return build_with_known_pattern(matrix, nb_elem, derivative_order);
279 else
280 return build_with_unknown_pattern(matrix, nb_elem, derivative_order);
281}
282
283int IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::build_with_known_pattern(Matrice& matrix, const int& nb_elem, const int& derivative_order)
284{
285 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * forward_derivative = nullptr;
286 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * centred_derivative = nullptr;
287 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * backward_derivative = nullptr;
288 switch(derivative_order)
289 {
290 case identity:
291 forward_derivative = &identity_coefficient_;
292 centred_derivative = &identity_coefficient_;
293 backward_derivative = &identity_coefficient_;
294 break;
295 case first:
296 forward_derivative = &first_order_derivative_forward_;
297 centred_derivative = &first_order_derivative_centred_;
298 backward_derivative = &first_order_derivative_backward_;
299 break;
300 case second:
301 forward_derivative = &second_order_derivative_forward_;
302 centred_derivative = &second_order_derivative_centred_;
303 backward_derivative = &second_order_derivative_backward_;
304 break;
305 default:
306 forward_derivative = &first_order_derivative_forward_;
307 centred_derivative = &first_order_derivative_centred_;
308 backward_derivative = &first_order_derivative_backward_;
309 break;
310 }
312 // Cast the finite difference matrix
313 matrix.typer("Matrice_Morse");
314 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, matrix.valeur());
315 sparse_matrix.dimensionner(nb_elem, nb_elem, non_zero_elem_);
316
317 auto& matrix_values = sparse_matrix.get_set_coeff();
318 auto& non_zero_coeff_per_line = sparse_matrix.get_set_tab1();
319 auto& matrix_column_indices = sparse_matrix.get_set_tab2();
320
321 Cerr << matrix_values[0] << finl;
322 Cerr << non_zero_coeff_per_line[0] << finl;
323 Cerr << matrix_column_indices[0] << finl;
324
325 Cerr << (*forward_derivative)[precision_order_-1][0](0) << finl;
326 Cerr << (*centred_derivative) [precision_order_-1][0](0) << finl;
327 Cerr << (*backward_derivative)[precision_order_-1][0](0) << finl;
328
329 int derivative_offset = derivative_order;
330 if (derivative_order==identity)
331 derivative_offset = 2;
332//
333// // Fortran start at one
334// int non_zero_values_counter = 0;
335//
336// /*
337// * TODO: Re-write the matrix filling routines
338// */
339 const int core_lines = (nb_elem - 2);
340 int non_zero_values_counter = 0;
341
342 /*
343 * Ini
344 */
345 {
346 const int forward_derivative_size = (*forward_derivative)[precision_order_-1][0].size();
347 const int forward_left_offset = forward_left_offset_[derivative_offset];
348 const int forward_right_offset = forward_right_offset_[derivative_offset];
349 for (int i=0; i < forward_left_offset; i++)
350 {
351 matrix_column_indices[non_zero_values_counter] = i + FORTRAN_INDEX_INI;
352 non_zero_values_counter++;
353 }
354 for (int i=0; i < forward_derivative_size; i++)
355 {
356 const int indices = (int) (*forward_derivative)[precision_order_-1][0](i);
357 const double fd_coeff = (*forward_derivative)[precision_order_-1][1](i);
358 matrix_column_indices[non_zero_values_counter] = indices + forward_left_offset + FORTRAN_INDEX_INI;
359 matrix_values[non_zero_values_counter] = fd_coeff;
360 non_zero_values_counter++;
361 }
362 for (int i=0; i < forward_right_offset; i++)
363 {
364 matrix_column_indices[non_zero_values_counter] = i + (forward_left_offset + forward_derivative_size) + FORTRAN_INDEX_INI;
365 non_zero_values_counter++;
366 }
367 non_zero_coeff_per_line[1] = non_zero_values_counter + FORTRAN_INDEX_INI;
368 }
369 /*
370 * Core
371 */
372 {
373 const int centred_derivative_size = (*centred_derivative)[precision_order_-1][0].size();
374 const int centred_left_offset = centred_left_offset_[derivative_offset];
375 const int centred_right_offset = centred_right_offset_[derivative_offset];
376 for (int j=1; j<(core_lines+1); j++)
377 {
378 for (int i=0; i < centred_left_offset; i++)
379 {
380 // matrix_column_indices[non_zero_values_counter] = i + j + FORTRAN_INDEX_INI; // Add MG 12/02/24
381 matrix_column_indices[non_zero_values_counter] = i + j + FORTRAN_INDEX_INI - centred_left_offset; // Add MG 12/02/24
382 non_zero_values_counter++;
383 }
384 for (int i=0; i < centred_derivative_size; i++)
385 {
386 const int indices = (int) (*centred_derivative)[precision_order_-1][0](i);
387 const double fd_coeff = (*centred_derivative)[precision_order_-1][1](i);
388 // matrix_column_indices[non_zero_values_counter] = indices + j + centred_left_offset + FORTRAN_INDEX_INI;
389 matrix_column_indices[non_zero_values_counter] = indices + j + FORTRAN_INDEX_INI;
390 matrix_values[non_zero_values_counter] = fd_coeff;
391 non_zero_values_counter++;
392 }
393 for (int i=0; i < centred_right_offset; i++)
394 {
395 // matrix_column_indices[non_zero_values_counter] = i + (centred_left_offset + centred_derivative_size) + FORTRAN_INDEX_INI;
396 matrix_column_indices[non_zero_values_counter] = i + j + centred_derivative_size + FORTRAN_INDEX_INI;
397 non_zero_values_counter++;
398 }
399 non_zero_coeff_per_line[j + 1] = non_zero_values_counter + FORTRAN_INDEX_INI;
400 }
401 }
402
403 /*
404 * End
405 */
406 {
407 const int backward_derivative_size = (*backward_derivative)[precision_order_-1][0].size();
408 int backward_left_offset = backward_left_offset_[derivative_offset];
409 int backward_right_offset = backward_right_offset_[derivative_offset];
410 int end_counter = non_zero_values_counter - 1 + backward_derivative_size + backward_left_offset + backward_right_offset;
411 const int last_column = (nb_elem - 1);
412 for (int i=0; i < backward_right_offset; i++)
413 {
414 matrix_column_indices[end_counter] = last_column -i + FORTRAN_INDEX_INI;
415 end_counter--;
416 non_zero_values_counter++;
417 }
418 for (int i=0; i < backward_derivative_size; i++)
419 {
420 const int indices = (int) (*backward_derivative)[precision_order_-1][0](i);
421 const double fd_coeff = (*backward_derivative)[precision_order_-1][1](i);
422 matrix_column_indices[end_counter] = last_column + indices + FORTRAN_INDEX_INI;
423 matrix_values[end_counter] = fd_coeff;
424 end_counter--;
425 non_zero_values_counter++;
426
427 }
428 for (int i=0; i < backward_left_offset; i++)
429 {
430 matrix_column_indices[end_counter] = last_column - i - (backward_right_offset + backward_derivative_size) + FORTRAN_INDEX_INI;
431 end_counter--;
432 non_zero_values_counter++;
433 }
434 non_zero_coeff_per_line[last_column + 1] = non_zero_values_counter + FORTRAN_INDEX_INI;
435 }
436
437 return non_zero_elem_;
438}
439
440/*
441 *
442 */
443int IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::build_with_unknown_pattern(Matrice& matrix, const int& nb_elem, const int& derivative_order)
444{
445 int non_zero_elem = 0;
446 int stencil_forward = 0;
447 int stencil_centred = 0;
448 int stencil_backward = 0;
449 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * forward_derivative = nullptr;
450 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * centred_derivative = nullptr;
451 FixedVector<FixedVector<DoubleVect,2>,MAX_ORDER_DERIVATIVE> * backward_derivative = nullptr;
452 switch(derivative_order)
453 {
454 case identity:
455 forward_derivative = &identity_coefficient_;
456 centred_derivative = &identity_coefficient_;
457 backward_derivative = &identity_coefficient_;
458 break;
459 case first:
463 forward_derivative = &first_order_derivative_forward_;
464 centred_derivative = &first_order_derivative_centred_;
465 backward_derivative = &first_order_derivative_backward_;
466 break;
467 case second:
471 forward_derivative = &second_order_derivative_forward_;
472 centred_derivative = &second_order_derivative_centred_;
473 backward_derivative = &second_order_derivative_backward_;
474 break;
475 default:
479 forward_derivative = &first_order_derivative_forward_;
480 centred_derivative = &first_order_derivative_centred_;
481 backward_derivative = &first_order_derivative_backward_;
482 break;
483 }
484 const int core_lines = (nb_elem - 2);
485 non_zero_elem = stencil_forward + stencil_backward + stencil_centred * (nb_elem - 2);
486 // Cast the finite difference matrix
487 matrix.typer("Matrice_Morse");
488 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, matrix.valeur());
489 sparse_matrix.dimensionner(nb_elem, nb_elem, non_zero_elem);
490
491 auto& matrix_values = sparse_matrix.get_set_coeff();
492 auto& non_zero_coeff_per_line = sparse_matrix.get_set_tab1();
493 auto& matrix_column_indices = sparse_matrix.get_set_tab2();
494 // Fortran start at one
495 int non_zero_values_counter = 0;
496
497 /*
498 * Ini
499 */
500 {
501 const int forward_derivative_size = (*forward_derivative)[precision_order_-1][0].size();
502 for (int i=0; i < forward_derivative_size; i++)
503 {
504 const int indices = (int) (*forward_derivative)[precision_order_-1][0](i);
505 const double fd_coeff = (*forward_derivative)[precision_order_-1][1](i);
506 if (fd_coeff != 0)
507 {
508 matrix_column_indices[non_zero_values_counter] = indices + FORTRAN_INDEX_INI;
509 matrix_values[non_zero_values_counter] = fd_coeff;
510 non_zero_values_counter++;
511 }
512 }
513 non_zero_coeff_per_line[1] = non_zero_values_counter + FORTRAN_INDEX_INI;
514 }
515 /*
516 * Core
517 */
518 {
519 const int centred_derivative_size = (*centred_derivative)[precision_order_-1][0].size();
520 for (int j=1; j<(core_lines+1); j++)
521 {
522 for (int i=0; i < centred_derivative_size; i++)
523 {
524 const int indices = (int) (*centred_derivative)[precision_order_-1][0](i);
525 const double fd_coeff = (*centred_derivative)[precision_order_-1][1](i);
526 if (fd_coeff != 0)
527 {
528 matrix_column_indices[non_zero_values_counter] = indices + j + FORTRAN_INDEX_INI;
529 matrix_values[non_zero_values_counter] = fd_coeff;
530 non_zero_values_counter++;
531 }
532 }
533 non_zero_coeff_per_line[j + 1] = non_zero_values_counter + FORTRAN_INDEX_INI;
534 }
535 }
536
537 /*
538 * End
539 */
540 {
541 const int backward_derivative_size = (*backward_derivative)[precision_order_-1][0].size();
542 int end_counter = non_zero_values_counter - 1 + stencil_backward;
543 const int last_column = (nb_elem - 1);
544 for (int i=0; i < backward_derivative_size; i++)
545 {
546 const int indices = (int) (*backward_derivative)[precision_order_-1][0](i);
547 const double fd_coeff = (*backward_derivative)[precision_order_-1][1](i);
548 if (fd_coeff != 0)
549 {
550 matrix_column_indices[end_counter] = last_column + indices + FORTRAN_INDEX_INI;
551 matrix_values[end_counter] = fd_coeff;
552 end_counter--;
553 non_zero_values_counter++;
554 }
555 }
556 non_zero_coeff_per_line[last_column + 1] = non_zero_values_counter + FORTRAN_INDEX_INI;
557 }
558
559 sparse_matrix.compacte(remove_zeros);
560 return non_zero_elem;
561}
562
564 const int& use_sparse_matrix,
565 const int& debug)
566{
567 if (use_sparse_matrix)
568 sum_sparse_matrices_subproblems(matrix_A, matrix_B, debug);
569 else
570 sum_matrices_subproblems(matrix_A, matrix_B);
571
572}
573
575{
576 Matrice_Morse& sparse_matrix_A = ref_cast(Matrice_Morse, matrix_A.valeur());
577 Matrice_Morse& sparse_matrix_B = ref_cast(Matrice_Morse, matrix_B.valeur());
578 sparse_matrix_A += sparse_matrix_B;
579
580 if (debug)
581 {
582 const auto& tab1 = sparse_matrix_A.get_tab1();
583 Cerr << "tab1[tab1.size_array() - 1]" << tab1[tab1.size_array() - 1] << finl;
584 }
585
586 // Don't forget to call my own sort_stencil() if matrices have been compacted !
587 if (!known_pattern_)
588 {
589 sort_stencil(sparse_matrix_A);
590 sparse_matrix_A.sort_stencil();
591 }
592}
593
595{
596 Matrice_Bloc& block_matrix_A =ref_cast(Matrice_Bloc, matrix_A.valeur());
597 Matrice_Bloc& block_matrix_B =ref_cast(Matrice_Bloc, matrix_B.valeur());
598 const int dim = block_matrix_A.dim(0);
599 for (int i=0; i<dim ; i++)
600 {
601 Matrice_Morse& sparse_matrix_A = ref_cast(Matrice_Morse, block_matrix_A.get_bloc(i,i).valeur());
602 Matrice_Morse& sparse_matrix_B = ref_cast(Matrice_Morse, block_matrix_B.get_bloc(i,i).valeur());
603 sparse_matrix_A += sparse_matrix_B;
604
605 // Don't forget to call my own sort_stencil() if matrices have been compacted !
606 if (!known_pattern_)
607 {
608 sort_stencil(sparse_matrix_A);
609 sparse_matrix_A.sort_stencil();
610 }
611 // Cerr << "Convection and Diffusion matrices have been assembled. "<< finl;
612 }
613}
614
616{
617 Matrice_Morse& sparse_matrix_A = ref_cast(Matrice_Morse, matrix_A.valeur());
618 Matrice_Morse& sparse_matrix_B = ref_cast(Matrice_Morse, matrix_B.valeur());
619 sparse_matrix_A += sparse_matrix_B;
620}
621
623 Matrice& fd_operator,
624 const int& max_subproblems_predicted)
625{
626 matrix_subproblems.typer("Matrice_Bloc");
627 Matrice_Bloc& block_matrix_subproblems =ref_cast(Matrice_Bloc, matrix_subproblems.valeur());
628 block_matrix_subproblems.dimensionner(max_subproblems_predicted,max_subproblems_predicted);
629
630 Matrice_Morse& fd_operator_sparse = ref_cast(Matrice_Morse, fd_operator.valeur());
631
632 for (int i=0; i<max_subproblems_predicted; i++)
633 {
634 for (int j=0; j<max_subproblems_predicted; j++)
635 if (j != i)
636 {
637 // Same structure for zeros
638 block_matrix_subproblems.get_bloc(i,j).typer("Matrice_Morse");
639 Matrice_Morse& sparse_matrix_zeros = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,j).valeur());
640 sparse_matrix_zeros.dimensionner(fd_operator_sparse.nb_lignes(), fd_operator_sparse.nb_colonnes(), fd_operator_sparse.nb_coeff());
641 sparse_matrix_zeros.compacte(remove_zeros);
642 }
643 block_matrix_subproblems.get_bloc(i,i).typer("Matrice_Morse");
644 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,i).valeur());
645 sparse_matrix.dimensionner(fd_operator_sparse.nb_lignes(), fd_operator_sparse.nb_colonnes(), fd_operator_sparse.nb_coeff());
646 }
647}
648
650 Matrice& fd_operator,
651 const int& max_subproblems)
652{
653 Matrice_Morse& fd_operator_sparse = ref_cast(Matrice_Morse, fd_operator.valeur());
654 const int nb_rows = (fd_operator_sparse.nb_lignes()) * max_subproblems;
655 const int nb_column = (fd_operator_sparse.nb_colonnes()) * max_subproblems;
656 const int nb_coeff = (fd_operator_sparse.nb_coeff()) * max_subproblems;
657
658 matrix_subproblems.typer("Matrice_Morse");
659 Matrice_Morse& sparse_matrix_subproblems = ref_cast(Matrice_Morse, matrix_subproblems.valeur());
660 sparse_matrix_subproblems.dimensionner(nb_rows, nb_column, nb_coeff);
661}
662
663
664
666 Matrice& fd_operator,
667 const int& empty_problem_start_index,
668 const int& empty_problem_end_index)
669{
670 Matrice_Bloc& block_matrix_subproblems =ref_cast(Matrice_Bloc, matrix_subproblems.valeur());
671 Matrice_Morse& fd_operator_morse =ref_cast(Matrice_Morse, fd_operator.valeur());
672 const auto& coeff = fd_operator_morse.get_coeff();
673 const auto& tab1 = fd_operator_morse.get_tab1();
674 const auto& tab2 = fd_operator_morse.get_tab2();
675 for (int i=empty_problem_start_index; i<empty_problem_end_index; i++)
676 {
677 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,i).valeur());
678 sparse_matrix.get_set_coeff() = coeff;
679 sparse_matrix.get_set_tab1() = tab1;
680 sparse_matrix.get_set_tab2() = tab2;
681 }
682}
683
685 Matrice& fd_operator,
686 const int& nb_subproblems,
687 const int& first_time_step_varying_probes,
688 FixedVector<ArrOfInt, 6>& first_indices_sparse_matrix,
689 const int& first_initialisation,
690 int& initialise_sparse_indices)
691{
692
693 if (first_initialisation)
694 {
695 matrix_subproblems.typer("Matrice_Morse");
696 }
697 if (initialise_sparse_indices)
698 {
699 for (int l=0; l<6; l++)
700 first_indices_sparse_matrix[l].reset();
701 }
702
703 Matrice_Morse& sparse_matrix_subproblems =ref_cast(Matrice_Morse, matrix_subproblems.valeur());
704 Matrice_Morse& fd_operator_sparse = ref_cast(Matrice_Morse, fd_operator.valeur());
705
706 const auto& tab1_operator = fd_operator_sparse.get_tab1();
707 const auto& tab2_operator = fd_operator_sparse.get_tab2();
708 const auto& coeff_operator = fd_operator_sparse.get_coeff();
709
710 const int nb_rows_operator = fd_operator_sparse.nb_lignes();
711 const int nb_columns_operator = fd_operator_sparse.nb_colonnes();
712
713 const int nb_rows = nb_rows_operator * nb_subproblems;
714 const int nb_columns = nb_columns_operator * nb_subproblems;
715
716 const int nb_val_non_zero_per_operator = fd_operator_sparse.nb_coeff();
717 const int nb_val_non_zero_sparse = nb_subproblems * nb_val_non_zero_per_operator;
718
719 auto& tab1 = sparse_matrix_subproblems.get_set_tab1();
720 auto& tab2 = sparse_matrix_subproblems.get_set_tab2();
721 auto& coeff = sparse_matrix_subproblems.get_set_coeff();
722
723 int j;
724 /*
725 * dimensionner resize each IntVect tab1 and tab2 and DoubleVect coeff
726 */
727 sparse_matrix_subproblems.dimensionner(nb_rows, nb_columns, nb_val_non_zero_sparse);
728 for (int i=0; i<nb_subproblems; i++)
729 {
730 const int first_index = i * nb_val_non_zero_per_operator;
731 const int column_index = i * nb_columns_operator;
732 const int row_index = i * nb_rows_operator;
733 if (initialise_sparse_indices)
734 {
735 first_indices_sparse_matrix[0].append_array(first_index);
736 first_indices_sparse_matrix[1].append_array(nb_val_non_zero_per_operator);
737 first_indices_sparse_matrix[2].append_array(column_index);
738 first_indices_sparse_matrix[3].append_array(nb_columns_operator);
739 first_indices_sparse_matrix[4].append_array(row_index);
740 first_indices_sparse_matrix[5].append_array(nb_rows_operator);
741 }
742 for (j=0; j<nb_val_non_zero_per_operator; j++)
743 {
744 tab2(j + first_index) = tab2_operator(j) + column_index;
745 coeff(j + first_index) = coeff_operator(j);
746 }
747 for (j=1; j<=nb_rows_operator; j++)
748 tab1(j + row_index) = tab1_operator(j) + first_index;
749 }
750 initialise_sparse_indices = 0;
751//if (!first_time_step_varying_probes)
752// {
753// Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,i).valeur());
754// sparse_matrix = Matrice_Morse(fd_operator_sparse);
755// }
756}
757
759 Matrice& fd_operator,
760 const int& nb_subproblems,
761 const int& first_time_step_varying_probes)
762{
763 /*
764 * Work only for constant number of points on probes
765 * TODO: Adapt for varying numbers of points
766 */
767 matrix_subproblems.typer("Matrice_Bloc");
768 Matrice_Bloc& block_matrix_subproblems =ref_cast(Matrice_Bloc, matrix_subproblems.valeur());
769 block_matrix_subproblems.dimensionner(nb_subproblems,nb_subproblems);
770
771 Matrice_Morse& fd_operator_sparse = ref_cast(Matrice_Morse, fd_operator.valeur());
772
773 for (int i=0; i<nb_subproblems; i++)
774 {
775 for (int j=0; j<nb_subproblems; j++)
776 if (j != i)
777 {
778 // Same structure for zeros
779 block_matrix_subproblems.get_bloc(i,j).typer("Matrice_Morse");
780 Matrice_Morse& sparse_matrix_zeros = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,j).valeur());
781 sparse_matrix_zeros.dimensionner(fd_operator_sparse.nb_lignes(), fd_operator_sparse.nb_colonnes(), fd_operator_sparse.nb_coeff());
782 sparse_matrix_zeros.compacte(remove_zeros);
783 }
784 block_matrix_subproblems.get_bloc(i,i).typer("Matrice_Morse");
785 if (!first_time_step_varying_probes)
786 {
787 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(i,i).valeur());
788 sparse_matrix = Matrice_Morse(fd_operator_sparse);
789 }
790 }
791}
792
794 const Matrice * fd_operator,
795 const int& nb_subproblems,
796 const int& use_sparse_matrix,
797 FixedVector<ArrOfInt,6> * first_indices_sparse_matrix,
798 const int& first_initialisation,
799 const int& keep_global_probes_discretisation)
800{
801 if (use_sparse_matrix)
802 reinitialise_sparse_matrix_subproblem(matrix_subproblems, fd_operator, nb_subproblems, first_indices_sparse_matrix, first_initialisation, keep_global_probes_discretisation);
803 else
804 reinitialise_matrix_subproblem(matrix_subproblems, fd_operator, nb_subproblems, keep_global_probes_discretisation);
805}
806
808 const Matrice * fd_operator,
809 const int& nb_subproblems,
810 FixedVector<ArrOfInt,6> * first_indices_sparse_matrix,
811 const int& first_initialisation,
812 const int& keep_global_probes_discretisation)
813{
814 Matrice_Morse& sparse_matrix_subproblems =ref_cast(Matrice_Morse, (*matrix_subproblems).valeur());
815 auto& tab1 = sparse_matrix_subproblems.get_set_tab1();
816 auto& tab2 = sparse_matrix_subproblems.get_set_tab2();
817 auto& coeff = sparse_matrix_subproblems.get_set_coeff();
818
819 const Matrice_Morse& fd_operator_morse =ref_cast(Matrice_Morse, (*fd_operator).valeur());
820 const auto& tab1_operator = fd_operator_morse.get_tab1();
821 const auto& tab2_operator = fd_operator_morse.get_tab2();
822 const auto& coeff_operator = fd_operator_morse.get_coeff();
823
824 int nb_rows_operator = fd_operator_morse.nb_lignes();
825 int nb_columns_operator = fd_operator_morse.nb_colonnes();
826 int nb_coeff_operator = fd_operator_morse.nb_coeff();
827
828 int nb_rows = nb_rows_operator;
829 int nb_columns = nb_columns_operator;
830 int nb_coeff = nb_coeff_operator;
831
832 int nb_rows_ini = sparse_matrix_subproblems.nb_lignes();
833 int nb_columns_ini = sparse_matrix_subproblems.nb_colonnes();
834 int nb_coeff_ini = sparse_matrix_subproblems.nb_coeff();
835
836 /*
837 * Re-write the entire matrix (can be usefull if probe discretisation changes)
838 */
839 if (!nb_subproblems)
840 {
841 if (!keep_global_probes_discretisation)
842 {
843 nb_rows_ini = 0;
844 nb_columns_ini = 0;
845 nb_coeff_ini = 0;
846 }
847 else
848 {
849 nb_rows_ini = (*first_indices_sparse_matrix)[4][nb_subproblems];
850 nb_columns_ini = (*first_indices_sparse_matrix)[2][nb_subproblems];
851 nb_coeff_ini = (*first_indices_sparse_matrix)[0][nb_subproblems];
852 }
853 }
854 else
855 {
856 if (!keep_global_probes_discretisation)
857 {
858 nb_rows += nb_rows_ini;
859 nb_columns += nb_columns_ini;
860 nb_coeff += nb_coeff_ini;
861 }
862 else
863 {
864 nb_rows_ini = (*first_indices_sparse_matrix)[4][nb_subproblems];
865 nb_columns_ini = (*first_indices_sparse_matrix)[2][nb_subproblems];
866 nb_coeff_ini = (*first_indices_sparse_matrix)[0][nb_subproblems];
867 nb_rows = nb_rows_ini;
868 nb_columns = nb_columns_ini;
869 nb_coeff = nb_coeff_ini;
870 }
871 }
872
873 if (!keep_global_probes_discretisation)
874 sparse_matrix_subproblems.dimensionner(nb_rows, nb_columns, nb_coeff);
875 assert(nb_rows>=nb_rows_ini && nb_columns>=nb_columns_ini && nb_rows>=nb_rows_ini);
876
877 if (first_initialisation && !keep_global_probes_discretisation)
878 {
879 (*first_indices_sparse_matrix)[0][nb_subproblems] = nb_coeff_ini;
880 (*first_indices_sparse_matrix)[1][nb_subproblems] = nb_coeff_operator;
881 (*first_indices_sparse_matrix)[2][nb_subproblems] = nb_columns_ini;
882 (*first_indices_sparse_matrix)[3][nb_subproblems] = nb_columns_operator;
883 (*first_indices_sparse_matrix)[4][nb_subproblems] = nb_rows_ini;
884 (*first_indices_sparse_matrix)[5][nb_subproblems] = nb_rows_operator;
885 // (*first_indices_sparse_matrix)[4][nb_subproblems] = nb_coeff_ini;
886 }
887
888 const int coeff_offset = nb_coeff_ini;
889 const int column_offset = nb_columns_ini;
890 const int row_offset = nb_coeff_ini;
891
892 int i;
893 if (!keep_global_probes_discretisation)
894 {
895 for (i=0; i<nb_coeff_operator; i++)
896 {
897 tab2(i + coeff_offset) = tab2_operator(i) + column_offset;
898 coeff(i + coeff_offset) = coeff_operator(i);
899 }
900 for (i=1; i<=nb_rows_operator; i++)
901 tab1(i + row_offset) = tab1_operator(i) + coeff_offset;
902 }
903 else
904 for (i=0; i<nb_coeff_operator; i++)
905 coeff(i + coeff_offset) = coeff_operator(i);
906}
907
909 const Matrice * fd_operator,
910 const int& nb_subproblems,
911 const int& keep_global_probes_discretisation)
912{
913 Matrice_Bloc& block_matrix_subproblems =ref_cast(Matrice_Bloc, (*matrix_subproblems).valeur());
914 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, block_matrix_subproblems.get_bloc(nb_subproblems,nb_subproblems).valeur());
915 const Matrice_Morse& fd_operator_morse =ref_cast(Matrice_Morse, (*fd_operator).valeur());
916 sparse_matrix = Matrice_Morse(fd_operator_morse);
917}
918
920 const DoubleVect& vector,
921 const int& boundary_conditions)
922{
923 /*
924 * Don't scale the first and last row (where B.Cs are applied)
925 */
926 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, matrix.valeur());
927 DoubleVect vector_tmp = vector;
928 if (boundary_conditions)
929 {
930 vector_tmp[0] = 1.;
931 vector_tmp[vector.size() - 1] = 1.;
932 }
933 sparse_matrix *= vector_tmp;
934 if (!known_pattern_)
935 sparse_matrix.compacte(remove_zeros);
936}
937
939 const DoubleVect& vector,
940 const int& subproblem_index,
941 const int& boundary_conditions,
942 const int& use_sparse_matrix,
943 const FixedVector<ArrOfInt,6> * first_indices_sparse_matrix)
944{
945 if (use_sparse_matrix)
946 {
947 Matrice local_sub_matrix;
949 matrix,
950 subproblem_index,
951 first_indices_sparse_matrix);
952 scale_matrix_by_vector(local_sub_matrix, vector, boundary_conditions);
954 matrix,
955 subproblem_index,
956 first_indices_sparse_matrix);
957 }
958 else
959 {
960 Matrice_Bloc& block_matrix = ref_cast(Matrice_Bloc, (*matrix).valeur());
961 Matrice& sub_matrix = block_matrix.get_bloc(subproblem_index, subproblem_index);
962 scale_matrix_by_vector(sub_matrix, vector, boundary_conditions);
963 }
964}
965
967 Matrice * matrix,
968 const int& subproblem_index,
969 const FixedVector<ArrOfInt,6> * first_indices_sparse_matrix)
970{
971 local_sub_matrix.typer("Matrice_Morse");
972 Matrice_Morse& local_sparse_sub_matrix = ref_cast(Matrice_Morse, local_sub_matrix.valeur());
973
974 const int nb_coeff = (*first_indices_sparse_matrix)[1][subproblem_index];
975 const int nb_column = (*first_indices_sparse_matrix)[3][subproblem_index];
976 const int nb_rows = (*first_indices_sparse_matrix)[5][subproblem_index];
977 local_sparse_sub_matrix.dimensionner(nb_rows, nb_column, nb_coeff);
978
979 auto& tab1_local = local_sparse_sub_matrix.get_set_tab1();
980 auto& tab2_local = local_sparse_sub_matrix.get_set_tab2();
981 auto& coeff_local = local_sparse_sub_matrix.get_set_coeff();
982
983 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, (*matrix).valeur());
984 const auto& tab1 = sparse_matrix.get_tab1();
985 const auto& tab2 = sparse_matrix.get_tab2();
986 const auto& coeff = sparse_matrix.get_coeff();
987
988 const int coeff_offset = (*first_indices_sparse_matrix)[0][subproblem_index];
989 const int column_offset = (*first_indices_sparse_matrix)[2][subproblem_index];
990 const int row_offset = (*first_indices_sparse_matrix)[4][subproblem_index];
991 int i;
992 for (i=0; i<nb_coeff; i++)
993 {
994 tab2_local(i) = tab2(i + coeff_offset) - column_offset;
995 coeff_local(i) = coeff(i + coeff_offset);
996 }
997 tab1_local(0) = FORTRAN_INDEX_INI;
998 for (i=1; i<=nb_rows; i++)
999 tab1_local(i) = tab1(i + row_offset) - coeff_offset;
1000}
1001
1003 Matrice * matrix,
1004 const int& subproblem_index,
1005 const FixedVector<ArrOfInt,6> * first_indices_sparse_matrix)
1006{
1007 Matrice_Morse& local_sparse_sub_matrix = ref_cast(Matrice_Morse, local_sub_matrix.valeur());
1008 const auto& tab1_local = local_sparse_sub_matrix.get_tab1();
1009 const auto& tab2_local = local_sparse_sub_matrix.get_tab2();
1010 const auto& coeff_local = local_sparse_sub_matrix.get_coeff();
1011
1012 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, (*matrix).valeur());
1013 auto& tab1 = sparse_matrix.get_set_tab1();
1014 auto& tab2 = sparse_matrix.get_set_tab2();
1015 auto& coeff = sparse_matrix.get_set_coeff();
1016
1017 const int nb_coeff = (*first_indices_sparse_matrix)[1][subproblem_index];
1018 const int nb_rows = (*first_indices_sparse_matrix)[5][subproblem_index];
1019
1020 const int coeff_offset = (*first_indices_sparse_matrix)[0][subproblem_index];
1021 const int column_offset = (*first_indices_sparse_matrix)[2][subproblem_index];
1022 const int row_offset = (*first_indices_sparse_matrix)[4][subproblem_index];
1023
1024 int i;
1025 for (i=0; i<nb_coeff; i++)
1026 {
1027 tab2(i + coeff_offset) = tab2_local(i) + column_offset;
1028 coeff(i + coeff_offset) = coeff_local(i);
1029 }
1030 for (i=1; i<=nb_rows; i++)
1031 tab1(i + row_offset) = tab1_local(i) + coeff_offset;
1032}
1033
1035 DoubleVect * global_rhs,
1036 DoubleVect& local_rhs,
1037 const int& ini_boundary_conditions,
1038 const double& interfacial_value,
1039 const int& end_boundary_conditions,
1040 const double& end_value,
1041 const int& subproblem_index,
1042 const double& dr_inv,
1043 const int& first_time_step_temporal,
1044 const int& first_time_step_explicit,
1045 const DoubleVect& temperature_ini_temporal_schemes,
1046 const int& start_index,
1047 const FixedVector<ArrOfInt, 6> * first_indices_sparse_matrix,
1048 const int& use_sparse_matrix)
1049{
1050 if (use_sparse_matrix)
1051 {
1052 Matrice local_sub_matrix;
1053 make_operation_on_sub_matrix_sparse(local_sub_matrix,
1054 matrix,
1055 subproblem_index,
1056 first_indices_sparse_matrix);
1057 impose_boundary_conditions(local_sub_matrix,
1058 local_rhs,
1059 ini_boundary_conditions,
1060 interfacial_value,
1061 end_boundary_conditions,
1062 end_value,
1063 dr_inv,
1064 first_time_step_temporal,
1065 first_time_step_explicit,
1066 temperature_ini_temporal_schemes);
1068 matrix,
1069 subproblem_index,
1070 first_indices_sparse_matrix);
1071 }
1072 else
1073 {
1074 Matrice_Bloc& block_matrix =ref_cast(Matrice_Bloc, (*matrix).valeur());
1075 Matrice& sub_matrix = block_matrix.get_bloc(subproblem_index, subproblem_index);
1076 impose_boundary_conditions(sub_matrix,
1077 local_rhs,
1078 ini_boundary_conditions,
1079 interfacial_value,
1080 end_boundary_conditions,
1081 end_value,
1082 dr_inv,
1083 first_time_step_temporal,
1084 first_time_step_explicit,
1085 temperature_ini_temporal_schemes);
1086 }
1087 /*
1088 * Fill global RHS
1089 */
1090 for (int i=0; i<local_rhs.size(); i++)
1091 (*global_rhs)[i + start_index] = local_rhs[i];
1092}
1093
1094
1096 DoubleVect& modified_rhs,
1097 const int& ini_boundary_conditions,
1098 const double& interfacial_value,
1099 const int& end_boundary_conditions,
1100 const double& end_value,
1101 const double& dr_inv,
1102 const int& first_time_step_temporal,
1103 const int& first_time_step_explicit,
1104 const DoubleVect& temperature_ini_temporal_schemes)
1105{
1106 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, modified_matrix.valeur());
1107 auto& matrix_values = sparse_matrix.get_set_coeff();
1108 auto& non_zero_coeff_per_line = sparse_matrix.get_set_tab1();
1109 const int nb_lines = sparse_matrix.nb_lignes();
1110 const int nb_coeff = sparse_matrix.nb_coeff();
1111 double interfacial_value_rhs;
1112 int ini_boundary_conditions_static_temporal = ini_boundary_conditions;
1113 if (first_time_step_temporal)
1114 {
1115 interfacial_value_rhs = temperature_ini_temporal_schemes[0];
1116 ini_boundary_conditions_static_temporal = dirichlet;
1117 }
1118 else
1119 interfacial_value_rhs = interfacial_value;
1120 {
1121 /*
1122 * Consider a constant interfacial temperature value at saturation
1123 * A jump condition could be implemented later by equating
1124 * the fluxes crossing the interface
1125 */
1126 switch(ini_boundary_conditions_static_temporal)
1127 {
1128 case dirichlet:
1129 {
1130 const int non_zero_elem_ini = non_zero_coeff_per_line[1] - FORTRAN_INDEX_INI;
1131 matrix_values[0] = 1.;
1132 for (int i=1; i<non_zero_elem_ini; i++)
1133 matrix_values[i] = 0.;
1134 modified_rhs[0] = interfacial_value_rhs;
1135 }
1136 break;
1137 case neumann:
1138 {
1139 // Refill with first order finite difference coefficients
1140 const int stencil_forward = non_zero_stencil_values(first_order_derivative_forward_);
1141 const int non_zero_elem_ini = non_zero_coeff_per_line[1] - FORTRAN_INDEX_INI;
1142 int counter_fd_coeff = 0;
1143 for (int i=0; i < non_zero_elem_ini; i++)
1144 {
1145 if (i < stencil_forward)
1146 {
1147 const double fd_coeff = first_order_derivative_forward_[precision_order_-1][1](counter_fd_coeff);
1148 matrix_values[i] = fd_coeff * dr_inv;
1149 counter_fd_coeff++;
1150 }
1151 else
1152 matrix_values[i] = 0.;
1153 }
1154 modified_rhs[0] = interfacial_value;
1155 }
1156 break;
1157 case flux_jump:
1158 Cerr << "Flux_jump condition necessitates a sub-problem in each phase : not implemented yet !" << finl;
1159 break;
1160 case implicit:
1161 break;
1162 default:
1163 {
1164 const int non_zero_elem_ini = non_zero_coeff_per_line[1] - FORTRAN_INDEX_INI;
1165 matrix_values[0] = 1.;
1166 for (int i=1; i<non_zero_elem_ini; i++)
1167 matrix_values[i] = 0.;
1168 modified_rhs[0] = 0.;
1169 }
1170 break;
1171 }
1172 }
1173 /*
1174 * The probe's end will never be coupled to a sub-resolution in the other phase
1175 */
1176 if (!first_time_step_temporal)
1177 {
1178 switch(end_boundary_conditions)
1179 {
1180 case dirichlet:
1181 {
1182 const int non_zero_elem_end = sparse_matrix.nb_vois(nb_lines - 1);
1183 const int last_index = nb_coeff - 1;
1184 matrix_values[last_index] = 1.;
1185 for (int i=last_index - 1; i > ( last_index - non_zero_elem_end); i--)
1186 matrix_values[i] = 0.;
1187 modified_rhs[modified_rhs.size() - 1] = end_value;
1188 }
1189 break;
1190 case neumann:
1191 {
1192 // Refill with first order finite difference coefficients
1193 const int non_zero_elem_end = sparse_matrix.nb_vois(nb_lines - 1);
1194 const int stencil_backward = first_order_derivative_backward_[precision_order_-1][1].size_array();
1195 // const int stencil_backward = non_zero_stencil_values(first_order_derivative_backward_);
1196 int counter_fd_coeff = stencil_backward - 1;
1197 for (int i=0; i < non_zero_elem_end; i++)
1198 {
1199 const int index = i + nb_coeff - non_zero_elem_end;
1200 if (index + stencil_backward >= nb_coeff)
1201 {
1202 const double fd_coeff = first_order_derivative_backward_[precision_order_-1][1](counter_fd_coeff);
1203 matrix_values[index] = fd_coeff * dr_inv;
1204 counter_fd_coeff--;
1205 }
1206 else
1207 matrix_values[index] = 0.;
1208 }
1209 modified_rhs[modified_rhs.size() - 1] = end_value;
1210 }
1211 break;
1212 case implicit:
1213 {
1214 // Refill with first order finite difference coefficients
1215 const int non_zero_elem_end = sparse_matrix.nb_vois(nb_lines - 1);
1216 const int stencil_backward = first_order_derivative_backward_[precision_order_-1][1].size_array();
1217 // const int stencil_backward = non_zero_stencil_values(first_order_derivative_backward_);
1218 int counter_fd_coeff = stencil_backward - 1;
1219 for (int i=0; i < non_zero_elem_end; i++)
1220 {
1221 const int index = i + nb_coeff - non_zero_elem_end;
1222 if (index + stencil_backward >= nb_coeff)
1223 {
1224 const double fd_coeff = first_order_derivative_backward_[precision_order_-1][1](counter_fd_coeff);
1225 matrix_values[index] = fd_coeff * dr_inv;
1226 counter_fd_coeff--;
1227 }
1228 else
1229 matrix_values[index] = 0.;
1230 }
1231 const int stencil_centred = first_order_derivative_centred_[precision_order_-1][1].size_array();
1232 // const int stencil_centred = non_zero_stencil_values(first_order_derivative_centred_);
1233 counter_fd_coeff = 0;
1234 for (int i=0; i < non_zero_elem_end; i++)
1235 {
1236 const int index = i + nb_coeff - non_zero_elem_end;
1237 if (index + stencil_centred >= nb_coeff)
1238 {
1239 const double fd_coeff = first_order_derivative_centred_[precision_order_-1][1](counter_fd_coeff);
1240 matrix_values[index] += - (fd_coeff * dr_inv);
1241 counter_fd_coeff++;
1242 }
1243 }
1244 modified_rhs[modified_rhs.size() - 1] = end_value;
1245 }
1246 break;
1247 default:
1248 {
1249 const int non_zero_elem_end = sparse_matrix.nb_vois(nb_lines - 1);
1250 const int last_index = nb_coeff - 1;
1251 matrix_values[last_index] = 1.;
1252 for (int i = last_index - 1; i > (last_index - non_zero_elem_end); i--)
1253 matrix_values[i] = 0.;
1254 modified_rhs[modified_rhs.size() - 1] = -1.;
1255 }
1256 break;
1257 }
1258 }
1259 else
1260 Cerr << "First iteration is done with Euler implicit or explicit" << finl;
1261 // TODO: Maybe remove this one
1262 if (!known_pattern_)
1263 sparse_matrix.compacte(remove_zeros);
1264
1265 // sparse_matrix.sort_stencil();
1266 if (!(first_time_step_temporal && first_time_step_explicit))
1267 if ((ini_boundary_conditions != neumann && ini_boundary_conditions != flux_jump)
1268 || (end_boundary_conditions != neumann))
1269 modify_rhs_for_bc(modified_matrix,
1270 modified_rhs,
1271 ini_boundary_conditions,
1272 end_boundary_conditions);
1273}
1274
1275/*
1276 * Modifcations of the rhs to apply BCs to the resolved 1D field
1277 */
1279 DoubleVect& modified_rhs,
1280 const int& ini_boundary_conditions,
1281 const int& end_boundary_conditions)
1282{
1283 /*
1284 * Copy the matrix into modified matrix
1285 */
1286 Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, modified_matrix.valeur());
1287 auto& matrix_values = sparse_matrix.get_set_coeff();
1288
1289 auto& non_zero_coeff_per_line = sparse_matrix.get_set_tab1();
1290 auto& matrix_column_indices = sparse_matrix.get_set_tab2();
1291 const int nb_lines = sparse_matrix.nb_lignes();
1292 const int nb_column = sparse_matrix.nb_colonnes();
1293
1294 const DoubleVect rhs_ini = modified_rhs;
1295 DoubleVect rhs = modified_rhs;
1296
1297 const int ini_boundary_bool = ((ini_boundary_conditions==default_bc) || (ini_boundary_conditions==dirichlet));
1298 const int end_boundary_bool = ((end_boundary_conditions==default_bc) || (end_boundary_conditions==dirichlet));
1299 /*
1300 * Get the modified rhs
1301 */
1302 if (ini_boundary_conditions == neumann && ini_boundary_conditions == flux_jump)
1303 rhs[0] = 0.;
1304 if (end_boundary_conditions == neumann)
1305 rhs[rhs.size() - 1] = 0.;
1306
1307 /*
1308 * Build B_BCs = A * X_BC
1309 * and B_modif = B - B_BC
1310 */
1311 // modified_rhs = sparse_matrix * rhs;
1312 sparse_matrix.multvect(rhs, modified_rhs);
1313
1314
1315 modified_rhs -= rhs;
1316 modified_rhs *= -1.;
1317 modified_rhs += rhs;
1318
1319 if (ini_boundary_conditions == neumann && ini_boundary_conditions == flux_jump)
1320 modified_rhs[0] = rhs_ini[0];
1321 if (end_boundary_conditions == neumann)
1322 modified_rhs[modified_rhs.size() - 1] = rhs_ini[rhs_ini.size() - 1];
1323
1324 /*
1325 * Remove useless coefficients
1326 * and build A_modif
1327 * A_modif X = B_modif
1328 */
1329 for (int j=2; j<nb_lines; j++)
1330 {
1331 const int non_zero_elem_core_series = non_zero_coeff_per_line[j] - FORTRAN_INDEX_INI;
1332 const int non_zero_elem_core = non_zero_coeff_per_line[j] - non_zero_coeff_per_line[j-1];
1333 for (int i = 0; i < non_zero_elem_core; i++)
1334 {
1335 const int index_sparse = non_zero_elem_core_series - non_zero_elem_core + i;
1336 const int column_index = matrix_column_indices[index_sparse] - FORTRAN_INDEX_INI;
1337 if (column_index == 0 && ini_boundary_bool)
1338 matrix_values[index_sparse] = 0.;
1339 if (column_index == (nb_column - 1) && end_boundary_bool)
1340 matrix_values[index_sparse] = 0.;
1341 }
1342 }
1343
1344 // TODO: Maybe remove this one
1345 if (!known_pattern_)
1346 sparse_matrix.compacte(remove_zeros);
1347
1348
1349// sparse_matrix.sort_stencil();
1350// for (int i=0; i<modified_rhs.size(); i++)
1351// if (fabs(modified_rhs[i]) > 1.e9)
1352// Cerr << "Check the modified RHS" << modified_rhs[i] << finl;
1353}
1354
1355void IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::add_source_terms(DoubleVect * thermal_subproblems_rhs_assembly,
1356 DoubleVect& rhs_assembly,
1357 const DoubleVect& source_terms,
1358 const int& index_start,
1359 const int& boundary_condition_interface,
1360 const int& boundary_condition_end)
1361{
1362 /*
1363 * Fill global RHS
1364 */
1365 const int local_rhs_size = source_terms.size();
1366 int index_ini = 0;
1367 int index_end = local_rhs_size;
1368 switch(boundary_condition_interface)
1369 {
1370 case dirichlet:
1371 index_ini++;
1372 break;
1373 case neumann:
1374 index_ini++;
1375 break;
1376 case flux_jump:
1377 break;
1378 case implicit:
1379 break;
1380 default:
1381 index_ini++;
1382 break;
1383 }
1384 switch(boundary_condition_end)
1385 {
1386 case dirichlet:
1387 index_end--;
1388 break;
1389 case neumann:
1390 index_end--;
1391 break;
1392 case flux_jump:
1393 break;
1394 case implicit:
1395 // index_end--;
1396 break;
1397 default:
1398 index_end--;
1399 break;
1400 }
1401 for (int i=index_ini; i<index_end; i++)
1402 {
1403 (*thermal_subproblems_rhs_assembly)[i + index_start] += source_terms[i];
1404 rhs_assembly[i] += source_terms[i];
1405 }
1406}
1407
1408void IJK_Finite_Difference_One_Dimensional_Matrix_Assembler::compute_operator(const Matrice * fd_operator, const DoubleVect& solution, DoubleVect& res)
1409{
1410 const Matrice_Morse& sparse_matrix = ref_cast(Matrice_Morse, (*fd_operator).valeur());
1411 sparse_matrix.multvect(solution, res);
1412 // res = (*fd_operator) * solution;
1413}
1414
1416 Matrice * diffusion_matrix,
1417 const int& subproblem_index,
1418 const double& local_time_step,
1419 const double& alpha)
1420{
1421 Matrice_Bloc& convection_block_matrix =ref_cast(Matrice_Bloc, (*convection_matrix).valeur());
1422 Matrice& convection_sub_matrix = convection_block_matrix.get_bloc(subproblem_index, subproblem_index);
1423 convection_sub_matrix *= (local_time_step * alpha);
1424
1425 Matrice_Bloc& diffusion_block_matrix =ref_cast(Matrice_Bloc, (*diffusion_matrix).valeur());
1426 Matrice& diffusion_sub_matrix = diffusion_block_matrix.get_bloc(subproblem_index, subproblem_index);
1427 diffusion_sub_matrix *= (local_time_step * alpha);
1428}
1429
1431 Matrice * diffusion_matrix,
1432 const int& subproblem_index,
1433 const double& local_time_step,
1434 const double& alpha)
1435{
1436 Matrice_Bloc& convection_block_matrix =ref_cast(Matrice_Bloc, (*convection_matrix).valeur());
1437 Matrice& convection_sub_matrix = convection_block_matrix.get_bloc(subproblem_index, subproblem_index);
1438 convection_sub_matrix *= (- local_time_step * alpha);
1439
1440 Matrice_Bloc& diffusion_block_matrix =ref_cast(Matrice_Bloc, (*diffusion_matrix).valeur());
1441 Matrice& diffusion_sub_matrix = diffusion_block_matrix.get_bloc(subproblem_index, subproblem_index);
1442 diffusion_sub_matrix *= (- local_time_step * alpha);
1443}
1444
1446 Matrice_Morse& sparse_matrix_solver_reduced,
1447 const int& nb_points,
1448 const int& pre_initialise_thermal_subproblems_list)
1449{
1450 if (pre_initialise_thermal_subproblems_list)
1451 {
1452 const auto& tab1 = sparse_matrix_solver.get_tab1();
1453 const auto& tab2 = sparse_matrix_solver.get_tab2();
1454 const auto& coeff = sparse_matrix_solver.get_coeff();
1455 sparse_matrix_solver_reduced.dimensionner(nb_points, nb_points, tab1[nb_points] - FORTRAN_INDEX_INI);
1456 auto& tab1_reduced = sparse_matrix_solver_reduced.get_set_tab1();
1457 auto& tab2_reduced = sparse_matrix_solver_reduced.get_set_tab2();
1458 auto& coeff_reduced = sparse_matrix_solver_reduced.get_set_coeff();
1459 const int nb_coeff = coeff_reduced.size_array();
1460 const int nb_rows = tab1_reduced.size_array();
1461
1462// tab1_reduced = tab1;
1463// tab2_reduced = tab2;
1464// coeff_reduced = coeff;
1465// tab1_reduced.resize(nb_rows, RESIZE_OPTIONS::COPY_NOINIT);
1466// tab2_reduced.resize(nb_coeff, RESIZE_OPTIONS::COPY_NOINIT);
1467// coeff_reduced.resize(nb_coeff, RESIZE_OPTIONS::COPY_NOINIT);
1468
1469 int i;
1470 for (i=0; i<nb_rows; i++)
1471 tab1_reduced(i) = tab1(i);
1472 for (i=0; i<nb_coeff; i++)
1473 {
1474 tab2_reduced(i) = tab2(i);
1475 coeff_reduced(i) = coeff(i);
1476 }
1477 }
1478 else
1479 sparse_matrix_solver_reduced = sparse_matrix_solver;
1480}
1481
1482
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
void scale_matrix_by_vector(Matrice &matrix, const DoubleVect &vector, const int &boundary_conditions)
void impose_boundary_conditions(Matrice &modified_matrix, DoubleVect &mdified_rhs, const int &ini_boundary_conditions, const double &interfacial_value, const int &end_boundary_conditions, const double &end_values, const double &dr_inv, const int &first_time_step_temporal, const int &first_time_step_explicit, const DoubleVect &temperature_ini_temporal_schemes)
int non_zero_stencil_values(const FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > &fd_operator)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > identity_coefficient_
void reinitialise_any_matrix_subproblem(Matrice *matrix_subproblems, const Matrice *fd_operator, const int &nb_subproblems, const int &use_sparse_matrix, FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix, const int &first_initialisation, const int &keep_global_probes_discretisation)
void reinitialise_sparse_matrix_subproblem(Matrice *matrix_subproblems, const Matrice *fd_operator, const int &nb_subproblems, FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix, const int &first_initialisation, const int &keep_global_probes_discretisation)
void set_operators_indices(const std::vector< std::vector< double > > &fd_operator_vector, FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > &fd_operator, const int &fd_coefficient_type)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > second_order_derivative_forward_
void apply_euler_time_step(Matrice *convection_matrix, Matrice *diffusion_matrix, const int &subproblem_index, const double &local_time_step, const double &alpha)
int build_with_unknown_pattern(Matrice &matrix, const int &nb_elem, const int &derivative_order)
void add_source_terms(DoubleVect *thermal_subproblems_rhs_assembly, DoubleVect &rhs_assembly, const DoubleVect &source_terms, const int &index_start, const int &boundary_condition_interface, const int &boundary_condition_end)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > first_order_derivative_backward_
void make_operation_on_sub_matrix_sparse(Matrice &local_sub_matrix, Matrice *matrix, const int &subproblem_index, const FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix)
int get_max_operators(const FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > &fd_operator_conv, const FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > &fd_operator_diff, int(&stencil_left_offset)[3], int(&stencil_right_offset)[3])
int build_with_known_pattern(Matrice &matrix, const int &nb_elem, const int &derivative_order)
void initialise_sparse_matrix_subproblems(Matrice &matrix_subproblems, Matrice &fd_operator, const int &nb_subproblems, const int &first_time_step_varying_probes, FixedVector< ArrOfInt, 6 > &first_indices_sparse_matrix, const int &first_initialisation, int &initialise_sparse_indices)
void compute_operator(const Matrice *fd_operator, const DoubleVect &solution, DoubleVect &res)
void set_operators_size(const std::vector< std::vector< double > > &fd_operator_vector, FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > &fd_operator)
void impose_boundary_conditions_subproblem(Matrice *matrix, DoubleVect *global_rhs, DoubleVect &local_rhs, const int &ini_boundary_conditions, const double &interfacial_value, const int &end_boundary_conditions, const double &end_value, const int &subproblem_index, const double &dr_inv, const int &first_time_step_temporal, const int &first_time_step_explicit, const DoubleVect &temperature_ini_temporal_schemes, const int &start_index, const FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix, const int &use_sparse_matrix)
void sum_sparse_matrices_subproblems(Matrice &matrix_A, Matrice &matrix_B, const int &debug)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > first_order_derivative_forward_
void recombined_local_sub_matrix_with_matrix(Matrice &local_sub_matrix, Matrice *matrix, const int &subproblem_index, const FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix)
void reinitialise_matrix_subproblem(Matrice *matrix_subproblems, const Matrice *fd_operator, const int &nb_subproblems, const int &keep_global_probes_discretisation)
void sum_any_matrices_subproblems(Matrice &matrix_A, Matrice &matrix_B, const int &use_sparse_matrix, const int &debug)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > second_order_derivative_backward_
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > first_order_derivative_centred_
void modify_rhs_for_bc(Matrice &modified_matrix, DoubleVect &modified_rhs, const int &ini_boundary_conditions, const int &end_boundary_conditions)
void initialise_matrix_subproblems(Matrice &matrix_subproblems, Matrice &fd_operator, const int &subproblems, const int &first_time_step_varying_probes)
void reduce_solver_matrix(const Matrice_Morse &thermal_subproblems_matrix_assembly_for_solver, Matrice_Morse &thermal_subproblems_matrix_assembly_for_solver_reduced, const int &nb_points, const int &pre_initialise_thermal_subproblems_list)
void correct_sign_temporal_schemes_subproblems(Matrice *convection_matrix, Matrice *diffusion_matrix, const int &subproblem_index, const double &local_time_step, const double &alpha)
void complete_empty_matrices_initialisation(Matrice &matrix_subproblems, Matrice &fd_operator, const int &empty_problem_start_index, const int &empty_problem_end_index)
void scale_matrix_subproblem_by_vector(Matrice *matrix, const DoubleVect &vector, const int &subproblem_index, const int &boundary_conditions, const int &use_sparse_matrix, const FixedVector< ArrOfInt, 6 > *first_indices_sparse_matrix)
int build(Matrice &matrix, const int &nb_elem, const int &derivative_order)
FixedVector< FixedVector< DoubleVect, 2 >, MAX_ORDER_DERIVATIVE > second_order_derivative_centred_
void get_max_stencil(const int &nb_elem, int &non_zero_elem_max, int &stencil_forward_max, int &stencil_centred_max, int &stencil_backward_max)
void pre_initialise_sparse_matrix_subproblems(Matrice &matrix_subproblems, Matrice &fd_operator, const int &max_subproblems_predicted)
void pre_initialise_matrix_subproblems(Matrice &matrice, Matrice &fd_operator, const int &max_subproblems_predicted)
virtual DoubleVect & multvect(const DoubleVect &, DoubleVect &) const
Multiplication d'un vecteur par la matrice.
virtual void dimensionner(int N, int M)
int dim(int d) const
virtual const Matrice & get_bloc(int i, int j) const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
auto nb_coeff() const
int nb_vois(int i) const
auto & get_set_tab2()
const auto & get_tab2() const
void dimensionner(int n, _SIZE_ nnz)
Size the matrix with n lines and n columns and nnz zero-values coefficients.
const auto & get_tab1() const
auto & get_set_coeff()
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
auto & get_set_tab1()
const auto & get_coeff() const
int nb_lignes() const override
Return local number of lines (=size on the current proc).
void compacte(int elim_coeff_nul=0)
Method to check/clean the Matrice_Morse matrix: -Suppress coefficient defined several times.
Classe Matrice Classe generique de la hierarchie des matrices.
Definition Matrice.h:34
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
Definition Param.cpp:474
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size() const
Definition TRUSTVect.tpp:45