Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
NormalizeOpt.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7#pragma once
8
11#include <alien/data/IMatrix.h>
12#include <alien/data/IVector.h>
13#include <alien/kernels/composite/CompositeMatrix.h>
14#include <alien/kernels/composite/CompositeVector.h>
15#include <alien/kernels/simple_csr/SimpleCSRMatrix.h>
16#include <alien/kernels/simple_csr/SimpleCSRVector.h>
17#include <alien/utils/Precomp.h>
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Alien
23{
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
32class ALIEN_EXPORT NormalizeOpt
33{
34 public:
37 {
38 StdLU,
39 EigenLU
40 };
41
44 {
45 SumFirstEq
46 };
47
50 {
51 NoError,
52 PivotError,
53 WithErrors
54 };
55
60
63
65 virtual ~NormalizeOpt() {}
66
71 void setAlgo(eAlgoType algo);
72
78 void setOpt(eOptType opt, bool flag);
79
86 eErrorType normalize(IMatrix& matrix, IVector& vector) const;
87
95 eErrorType normalize(CompositeMatrix& matrix, CompositeVector& vector,
96 ConstArrayView<Integer> eq_ids) const;
97
98 template <int N, bool check_null_pivot = false>
99 class LU;
100 class Op;
101 class Op2;
102
103 private:
110 eErrorType _normalize(MatrixImpl& matrix, VectorImpl& vector) const;
111
121 eErrorType _normalize(MatrixImpl& matrix, MatrixImpl& matrix2, bool trans,
122 ConstArrayView<Integer> eq_ids, VectorImpl& vector) const;
123
134 Arccore::ConstArrayView<Arccore::Integer> eq_ids, MatrixImpl& matrix2, bool trans,
135 VectorImpl& vector) const;
136
141};
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
151template <int N, bool check_null_pivot>
153{
154 public:
156 typedef Arccore::Real Block2DType[N][N];
157 /*
158 * \brief Constructor
159 * \param[in] Ap The matrix
160 * \param[in] factorize Whether or not the matrix should be factorized
161 */
162 LU(Arccore::Real* Ap, bool factorize = true)
163 : m_A(*(Block2DType*)Ap)
164 {
165 if (factorize) {
166 Block2DType& A = *(Block2DType*)Ap;
167
168 for (int k = 0; k < N; ++k) {
169 if (check_null_pivot) {
170 assert(A[k][k] != 0);
171 A[k][k] = 1 / A[k][k];
172 }
173 else {
174 if (A[k][k] == 0)
175 A[k][k] = 0;
176 else
177 A[k][k] = 1 / A[k][k];
178 }
179 for (int i = k + 1; i < N; ++i) {
180 A[i][k] *= A[k][k];
181 // TOCHECK : to be removed ?
182 // A[i][k] /= A[k][k];
183 }
184 for (int i = k + 1; i < N; ++i) {
185 for (int j = k + 1; j < N; ++j) {
186 A[i][j] -= A[i][k] * A[k][j];
187 }
188 }
189 }
190 }
191 }
192
195 {
196 for (int i = 0; i < N; ++i) {
197 for (int j = 0; j < i; ++j) {
198 m_A[i][j] = 0;
199 }
200 m_A[i][i] = 1;
201 for (int j = i + 1; j < N; ++j) {
202 m_A[i][j] = 0;
203 }
204 }
205 }
206
208 void setZero()
209 {
210 Real* ptr = (Real*)m_A;
211 for (int i = 0; i < N * N; ++i) {
212 ptr[i] = 0;
213 }
214 }
215
222 template <int NRhs, bool TransRhs>
223 void LXSolve(Arccore::Real* Xp) const
224 {
225 if (TransRhs) {
226 typedef Real Rhs2DType[NRhs][N];
227 Rhs2DType& X = *(Rhs2DType*)Xp;
228
229 for (int k = 0; k < NRhs; ++k) {
230 for (int i = 1; i < N; ++i) {
231 for (int j = 0; j < i; ++j) {
232 X[k][i] -= m_A[i][j] * X[k][j];
233 }
234 }
235 }
236 }
237 else {
238 typedef Real Rhs2DType[N][NRhs];
239 Rhs2DType& X = *(Rhs2DType*)Xp;
240
241 for (int i = 1; i < N; ++i) {
242 for (int j = 0; j < i; ++j) {
243 for (int k = 0; k < NRhs; ++k) {
244 X[i][k] -= m_A[i][j] * X[j][k];
245 }
246 }
247 }
248 }
249 }
250
257 template <int NRhs, bool TransRhs>
258 void UXSolve(Arccore::Real* Xp) const
259 {
260 if (TransRhs) {
261 typedef Real Rhs2DType[NRhs][N];
262 Rhs2DType& X = *(Rhs2DType*)Xp;
263 for (int i = N - 1; i >= 0; --i) {
264 for (int k = NRhs - 1; k >= 0; --k) {
265 for (int j = N - 1; j > i; --j) {
266 X[k][i] -= m_A[i][j] * X[k][j];
267 }
268 }
269 for (int k = NRhs - 1; k >= 0; --k) {
270 // TOCHECK : to be removed ?
271 // X[k][i] /= m_A[i][i];
272 X[k][i] *= m_A[i][i];
273 }
274 }
275 }
276 else {
277 typedef Real Rhs2DType[N][NRhs];
278 Rhs2DType& X = *(Rhs2DType*)Xp;
279
280 for (int i = N - 1; i >= 0; --i) {
281 for (int j = N - 1; j > i; --j) {
282 for (int k = NRhs - 1; k >= 0; --k) {
283 X[i][k] -= m_A[i][j] * X[j][k];
284 }
285 }
286 for (int k = NRhs - 1; k >= 0; --k) {
287 X[i][k] *= m_A[i][i];
288 // TOCHECK: to be removed ?
289 // X[i][k] /= m_A[i][i];
290 }
291 }
292 }
293 }
294
301 template <int NRhs, bool TransRhs>
302 void solve(Arccore::Real* Xp) const
303 {
306 }
307
308 private:
311};
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
320{
321 public:
329 Op(MatrixImpl& m, VectorImpl& x, eAlgoType algo, bool sum_first_eq)
330 : m_local_size(m.getCSRProfile().getNRow())
331 , m_local_offset(m.getLocalOffset())
332 , m_cols(m.getCSRProfile().getCols())
333 , m_row_offset(m.getCSRProfile().getRowOffset())
334 , m_matrix(m.internal()->getDataPtr())
335 , m_rhs(x.getDataPtr())
336 , m_sum_first_eq(sum_first_eq)
337 , m_algo(algo)
338 {
339 // TOCHECK : to be removed ?
340 // m_equations_num = m.space().structInfo().size() ;
341 m_equations_num = 1;
342 if (m.block() && m.block()->size())
343 m_equations_num = m.block()->size();
346 m_diag_first = m.getCSRProfile().getDiagFirstOpt();
347 if (!m_diag_first)
348 {
349 if(m.isParallel())
350 m_upper_diag_offset = m.getDistStructInfo().getUpperDiagOffset(m.getCSRProfile());
351 else
352 m_upper_diag_offset = m.getCSRProfile().getUpperDiagOffset().constView();
353 }
354 m_keep_diag = true;
355 if (m_sum_first_eq) {
356 if (m_diag_first)
358 else
360 }
361 }
362
368 void checkNullEq(Arccore::Integer irow, Arccore::Integer diag_offset)
369 {
370 // search line with only zero
371 for (Integer ieq = 0; ieq < m_equations_num; ++ieq) {
372 bool ok = false;
373 Integer col = m_row_offset[irow] + diag_offset;
374 for (Integer ui = 0; ui < m_unknowns_num; ++ui)
375 if (m_matrix[col * m_block_size + ij(ieq, ui)] != 0) {
376 ok = true;
377 break;
378 }
379 if (!ok) {
380 // search null column
381 for (Arccore::Integer ui = 0; ui < m_unknowns_num; ++ui) {
382 bool ok2 = false;
383 for (Integer jeq = 0; jeq < m_equations_num; ++jeq)
384 if (m_matrix[col * m_block_size + ij(jeq, ui)] != 0) {
385 ok2 = true;
386 break;
387 }
388 if (!ok2) {
389 // put 1 on ui column
390 m_matrix[col * m_block_size + ij(ieq, ui)] = 1.;
391 break;
392 }
393 }
394 }
395 }
396 }
397
402 template <bool diag_first>
404 {
405 for (Integer irow = 0; irow < m_local_size; ++irow) {
406 checkNullEq(irow, (diag_first ? 0 : m_upper_diag_offset[irow] - m_row_offset[irow]));
407 for (Integer col = m_row_offset[irow]; col < m_row_offset[irow + 1]; ++col) {
408 for (Integer ieq = 1; ieq < m_equations_num; ++ieq)
409 for (Integer ui = 0; ui < m_unknowns_num; ++ui)
410 m_matrix[col * m_block_size + ij(0, ui)] +=
411 m_matrix[col * m_block_size + ij(ieq, ui)];
412 }
413 for (Integer ieq = 1; ieq < m_equations_num; ++ieq)
414 m_rhs[irow * m_equations_num] += m_rhs[irow * m_equations_num + ieq];
415 }
416 }
417
419 template <int N>
420 void multInvDiag();
421
422 protected:
423 Integer ijk(Integer i, Integer j, Integer k) const
424 {
425 return k * m_block_size + i * m_unknowns_num + j;
426 }
427
428 Arccore::Integer ij(Arccore::Integer i, Arccore::Integer j) const
429 {
430 return i * m_unknowns_num + j;
431 }
432
433 Arccore::Integer ik(Arccore::Integer i, Arccore::Integer k) const
434 {
435 return k * m_equations_num + i;
436 }
437
438 Arccore::Integer jk(Arccore::Integer j, Arccore::Integer k) const
439 {
440 return k * m_unknowns_num + j;
441 }
442
444 Arccore::Integer m_local_size;
446 Arccore::Integer m_local_offset;
448 Arccore::ConstArrayView<Arccore::Integer> m_cols;
450 Arccore::ConstArrayView<Arccore::Integer> m_row_offset;
452 Arccore::ConstArrayView<Arccore::Integer> m_upper_diag_offset;
454 Arccore::Integer m_equations_num;
456 Arccore::Integer m_unknowns_num;
458 Arccore::Integer m_block_size;
460 Arccore::Real* m_matrix;
462 Arccore::Real* m_rhs;
471};
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
476// TOCHECK : to be removed ?
477/*
478 class NormalizeOpt::Op
479 {
480 public :
481 Op(MatrixImpl& m, VectorImpl& x,eAlgoType algo,bool sum_first_eq)
482 : m_local_size(m.getCSRProfile().getNRow())
483 , m_local_offset(m.getLocalOffset())
484 , m_cols(m.getCSRProfile().getCols())
485 , m_row_offset(m.getCSRProfile().getRowOffset())
486 , m_matrix(m.internal().getDataPtr())
487 , m_rhs(x.getDataPtr())
488 , m_sum_first_eq(sum_first_eq)
489 , m_algo(algo)
490 {
491 m_equations_num = m.space().structInfo().size() ;
492 m_unknowns_num = m_equations_num ;
493 m_block_size = m_equations_num*m_unknowns_num ;
494 m_diag_first = m.getCSRProfile().getDiagFirstOpt() ;
495 if(!m_diag_first)
496 m_upper_diag_offset = m.getCSRProfile().getUpperDiagOffset() ;
497 m_keep_diag = true ;
498 if(m_sum_first_eq)
499 {
500 if(m_diag_first)
501 sumBlockEq<true>() ;
502 else
503 sumBlockEq<false>() ;
504 }
505 }
506
507 void checkNullEq(Integer irow,Integer diag_offset)
508 {
509 //search line with only zero
510 for(Integer ieq=0;ieq<m_equations_num;++ieq)
511 {
512 bool ok = false ;
513 Integer col = m_row_offset[irow]+diag_offset ;
514 for(Integer ui=0;ui<m_unknowns_num;++ui)
515 if(m_matrix[col*m_block_size+ij(ieq,ui)]!=0)
516 {
517 ok = true ;
518 break ;
519 }
520 if(!ok)
521 {
522 //search null colonne
523 for(Integer ui=0;ui<m_unknowns_num;++ui)
524 {
525 bool ok2 = false ;
526 for(Integer jeq=0;jeq<m_equations_num;++jeq)
527 if(m_matrix[col*m_block_size+ij(jeq,ui)]!=0)
528 {
529 ok2 = true ;
530 break ;
531 }
532 if(!ok2)
533 {
534 //put 1 on ui colonne
535 m_matrix[col*m_block_size+ij(ieq,ui)] = 1. ;
536 break ;
537 }
538 }
539 }
540 }
541 }
542
543 template<bool diag_first>
544 void
545 sumBlockEq()
546 {
547 for(Integer irow=0;irow<m_local_size;++irow)
548 {
549 checkNullEq(irow,(diag_first?0:m_upper_diag_offset[irow]-m_row_offset[irow])) ;
550 for(Integer col= m_row_offset[irow];col<m_row_offset[irow+1];++col)
551 {
552 for(Integer ieq=1;ieq<m_equations_num;++ieq)
553 for(Integer ui=0;ui<m_unknowns_num;++ui)
554 m_matrix[col*m_block_size+ij(0,ui)] += m_matrix[col*m_block_size+ij(ieq,ui)] ;
555 }
556 for(Integer ieq=1;ieq<m_equations_num;++ieq)
557 m_rhs[irow*m_equations_num] += m_rhs[irow*m_equations_num+ieq] ;
558 }
559 }
560
561 template<int N>
562 void multInvDiag() ;
563 protected :
564 Integer ijk(Integer i, Integer j, Integer k) const {
565 return k*m_block_size+i*m_unknowns_num+j ;
566 }
567 Integer ij(Integer i, Integer j) const {
568 return i*m_unknowns_num+j ;
569 }
570 Integer ik(Integer i, Integer k) const {
571 return k*m_equations_num+i ;
572 }
573 Integer jk(Integer j, Integer k) const {
574 return k*m_unknowns_num+j ;
575 }
576
577 Integer m_local_size ;
578 Integer m_local_offset ;
579 ConstArrayView<Integer> m_cols ;
580 ConstArrayView<Integer> m_row_offset ;
581 ConstArrayView<Integer> m_upper_diag_offset ;
582 Integer m_equations_num ;
583 Integer m_unknowns_num ;
584 Integer m_block_size ;
585 Real* m_matrix ;
586 Real* m_rhs ;
587 bool m_keep_diag ;
588 bool m_diag_first ;
589 bool m_sum_first_eq;
590 eAlgoType m_algo ;
591 } ;
592*/
593
598{
599 public:
610 Op2(MatrixImpl& m, MatrixImpl& m2, bool trans,
611 Arccore::ConstArrayView<Arccore::Integer> eq_ids, VectorImpl& x, eAlgoType algo,
612 bool sum_first_eq)
613 : Op(m, x, algo, sum_first_eq)
614 , m_nb_extra_eq(m2.getCSRProfile().getNRow())
615 , m_eq_ids(eq_ids)
616 , m_submatrix1(false)
617 , m_submatrix2(true)
618 , m_trans(trans)
619 , m_nuk2(0)
620 , m_extra_eq_cols(m2.getCSRProfile().getCols())
621 , m_extra_eq_row_offset(m2.getCSRProfile().getRowOffset())
622 , m_extra_eq_matrix(m2.internal()->getDataPtr())
623 {
624 if (m_sum_first_eq) {
625 if (m_trans) {
626 // TOCHECK : to be removed ?
627 // Integer neq = m2.space().structInfo().size() ;
628 Integer neq = 1;
629 if (m2.block() && m2.block()->size())
630 neq = m2.block()->size();
631 for (Integer i = 0; i < m_eq_ids.size(); ++i) {
632 Integer ieq = m_eq_ids[i];
633 for (Integer k = m_extra_eq_row_offset[ieq]; k < m_extra_eq_row_offset[ieq + 1];
634 ++k) {
635 Real val = m_extra_eq_matrix[k * neq];
636 for (Integer ieq = 1; ieq < neq; ++ieq)
637 val += m_extra_eq_matrix[k * neq + ieq];
638 m_extra_eq_matrix[k * neq] = val;
639 }
640 }
641 }
642 else {
643 // TOCHECK : to be removed ?
644 // Integer neq = m2.eqSpace().structInfo().size() ;
645 Integer neq = 1;
646 if (m2.rowBlock() && m2.rowBlock()->maxBlockSize())
647 neq = m2.rowBlock()->maxBlockSize();
648 for (Integer i = 0; i < m_eq_ids.size(); ++i) {
649 Integer irow = m_eq_ids[i];
650 for (Integer k = m_extra_eq_row_offset[irow];
651 k < m_extra_eq_row_offset[irow + 1]; ++k) {
652 Real val = m_extra_eq_matrix[k * neq];
653 for (Integer ieq = 1; ieq < neq; ++ieq)
654 val += m_extra_eq_matrix[k * neq + ieq];
655 m_extra_eq_matrix[k * neq] = val;
656 }
657 }
658 }
659 }
660 }
661
672 Op2(MatrixImpl& m, Arccore::ConstArrayView<Arccore::Integer> eq_ids, MatrixImpl& m2,
673 bool trans, VectorImpl& x, eAlgoType algo, bool sum_first_eq)
674 : Op(m, x, algo, sum_first_eq)
675 , m_nb_extra_eq(m2.getCSRProfile().getNRow())
676 , m_eq_ids(eq_ids)
677 , m_submatrix1(true)
678 , m_submatrix2(false)
679 , m_trans(trans)
680 , m_nuk2(0)
681 , m_extra_eq_cols(m2.getCSRProfile().getCols())
682 , m_extra_eq_row_offset(m2.getCSRProfile().getRowOffset())
683 , m_extra_eq_matrix(m2.internal()->getDataPtr())
684 {
685 if (m_trans)
686 // TOCHECK : to be removed
687 // m_nuk2 = m2.eqSpace().structInfo().size() ;
688 m_nuk2 = m2.rowBlock()->maxBlockSize();
689 else
690 // TOCHECK : to be removed
691 // m_nuk2 = m2.uSpace().structInfo().size() ;
692 m_nuk2 = m2.colBlock()->maxBlockSize();
693 }
694
696 template <int N>
697 void multInvDiag();
698
699 private:
701 Arccore::Integer m_nb_extra_eq;
703 Arccore::ConstArrayView<Arccore::Integer> m_eq_ids;
711 Arccore::Integer m_nuk2;
713 Arccore::ConstArrayView<Arccore::Integer> m_extra_eq_cols;
715 Arccore::ConstArrayView<Arccore::Integer> m_extra_eq_row_offset;
717 Arccore::Real* m_extra_eq_matrix;
718};
719
720/*---------------------------------------------------------------------------*/
721/*---------------------------------------------------------------------------*/
722
723} // namespace Alien
724
725/*---------------------------------------------------------------------------*/
726/*---------------------------------------------------------------------------*/
IMatrix.h.
IVector.h.
Arccore::Integer size() const
Get square block size.
Definition Block.cc:90
Composite matrix for heterogenous matrices.
Composite vector for heterogenous vector.
virtual const VBlock * rowBlock() const
Get row block datas of the matrix.
virtual const VBlock * colBlock() const
Get col block datas of the matrix.
virtual const Block * block() const
Get block datas of the matrix.
Interface for all matrices.
Definition IMatrix.h:51
Interface for all vectors.
Definition IVector.h:51
LU normalization.
Arccore::Real Block2DType[N][N]
Type of the blocks.
void setIdentity()
Set identity.
void LXSolve(Arccore::Real *Xp) const
LXSolve.
void solve(Arccore::Real *Xp) const
Solve.
void UXSolve(Arccore::Real *Xp) const
UXSolve.
void setZero()
Set zero.
Block2DType & m_A
The matrix.
Normalize operator for composite matrices.
Arccore::ConstArrayView< Arccore::Integer > m_eq_ids
Ids of the equations.
Arccore::ConstArrayView< Arccore::Integer > m_extra_eq_cols
Pointer on extra equations unknowns columns.
Op2(MatrixImpl &m, Arccore::ConstArrayView< Arccore::Integer > eq_ids, MatrixImpl &m2, bool trans, VectorImpl &x, eAlgoType algo, bool sum_first_eq)
Constructor.
bool m_trans
Transposed flag.
Arccore::ConstArrayView< Arccore::Integer > m_extra_eq_row_offset
Pointer on extra equations unknowns rows.
Arccore::Integer m_nb_extra_eq
Number of extra equations.
Arccore::Integer m_nuk2
Number of unknowns in extra equations.
Op2(MatrixImpl &m, MatrixImpl &m2, bool trans, Arccore::ConstArrayView< Arccore::Integer > eq_ids, VectorImpl &x, eAlgoType algo, bool sum_first_eq)
Constructor.
void multInvDiag()
Invert diagonal.
bool m_submatrix2
Whether or not the second submatrix should be normalized.
Arccore::Real * m_extra_eq_matrix
Pointer of extra equations datas.
bool m_submatrix1
Whether or not the first submatrix should be normalized.
Normalize operator.
void checkNullEq(Arccore::Integer irow, Arccore::Integer diag_offset)
Check if an equation is null.
Arccore::ConstArrayView< Arccore::Integer > m_cols
Column pointer.
Arccore::Integer m_equations_num
The number of equations.
Arccore::Integer m_local_size
The local size.
Arccore::Real * m_rhs
The rhs.
Op(MatrixImpl &m, VectorImpl &x, eAlgoType algo, bool sum_first_eq)
Constructor.
Arccore::Integer m_local_offset
The local offset.
eAlgoType m_algo
The algorithm type.
void sumBlockEq()
Row sum of blocks equation.
Arccore::Integer m_block_size
The block size.
void multInvDiag()
Invert diagonal.
bool m_keep_diag
Whether or not diagonal should be kept.
Arccore::ConstArrayView< Arccore::Integer > m_upper_diag_offset
The indices of the upper diagonal.
Arccore::ConstArrayView< Arccore::Integer > m_row_offset
The rows offset.
Arccore::Integer m_unknowns_num
The number of unknowns.
Arccore::Real * m_matrix
The matrix.
bool m_diag_first
Whether or not the diagonal entry is stored first.
bool m_sum_first_eq
Whether or not to sum the first equation.
eErrorType
Type of the error.
eAlgoType
Type of algorithm.
eOptType
Type of the options.
SimpleCSRVector< Arccore::Real > VectorImpl
Type of the vector implementation.
bool m_sum_first_eq
Flag to sum the fist equation.
SimpleCSRMatrix< Arccore::Real > MatrixImpl
Type of the matrix implementation.
virtual ~NormalizeOpt()
Free resources.
eErrorType _normalize(MatrixImpl &matrix, Arccore::ConstArrayView< Arccore::Integer > eq_ids, MatrixImpl &matrix2, bool trans, VectorImpl &vector) const
Normalize a linear system.
NormalizeOpt()
Constructor.
eAlgoType m_algo
The algorithm.
Arccore::Integer maxBlockSize() const
Get the max size of all block size.
Definition VBlock.cc:175
CompositeMatrix.h.
CompositeVector.h.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17