LCOV - code coverage report
Current view: top level - ugbase/lib_algebra/small_algebra - solve_deficit.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 46 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2014:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Martin Rupp
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "solve_deficit.h"
      34              : 
      35              : #include "common/log.h"
      36              : #include "common/debug_print.h"
      37              : #include "lib_algebra/common/operations_vec.h"
      38              : 
      39              : typedef int lapack_int;
      40              : typedef float lapack_float;
      41              : typedef double lapack_double;
      42              : typedef int lapack_ftnlen;
      43              : 
      44              : 
      45              : inline double dabs(double a) { return a > 0 ? a : -a; }
      46              : /*
      47              : extern "C"
      48              : {
      49              : 
      50              :         // factor system *GETRF
      51              : void dsytrs_(char *uplo, int *n, int *nrhs, double *a, int *lda,
      52              :              int *ipivot, double *b, int *ldb, int *info);
      53              : }
      54              : 
      55              : 
      56              : inline lapack_int sytrs(char uplo, int n, int nrhs, double *a, int  lda,
      57              :         int *ipivot, double *b, int ldb)
      58              : {
      59              :     lapack_int info;
      60              :     dsytrs_(&uplo, &n, &nrhs, a, &lda, ipivot, b, &ldb, &info);
      61              :     return info;
      62              : }
      63              : 
      64              : bool SolveDeficit2(DenseMatrix< VariableArray2<double> > &A,
      65              :                 DenseVector<VariableArray1<double> > &x, DenseVector<VariableArray1<double> > &rhs)
      66              : {
      67              :         DenseMatrix< VariableArray2<double> > A2=A;
      68              :         DenseVector<VariableArray1<double> > rhs2=rhs;
      69              : 
      70              :         std::vector<int> interchange(A.num_rows());
      71              :         int info = sytrs('U', A.num_rows(), 1, &A(0,0), A.num_rows(), &interchange[0], &rhs[0], A.num_rows());
      72              :         x=rhs;
      73              :         DenseVector<VariableArray1<double> > f;
      74              :                 f = A2*x - rhs2;
      75              :                 if(VecNormSquared(f) > 1e-12)
      76              :                 {
      77              :                         UG_LOG("solving was wrong:");
      78              :                         UG_LOGN(CPPString(A2, "Aold"));
      79              :                         rhs2.maple_print("rhs");
      80              :                         UG_LOGN(CPPString(A, "Adecomp"));
      81              :                         rhs.maple_print("rhsDecomp");
      82              :                         x.maple_print("x");
      83              :                         f.maple_print("f");
      84              : 
      85              :                 }
      86              : 
      87              : }*/
      88              : 
      89              : namespace ug{
      90              : 
      91              : /*
      92              : |   free variable
      93              : xxxxxxxx
      94              : 0xxxxxxx
      95              : 000xxxxx
      96              : 0000xxxx
      97              : 00000xxx        <- iNonNullRows = 5
      98              : 00000000        \
      99              : 00000000        |       lin. dep.
     100              : 00000000        /
     101              : 
     102              :          iNonNullRows = number of bounded variable (that is: number of linear independent rows)
     103              :          returns true if solveable.
     104              : 
     105              :  */
     106            0 : bool Decomp(DenseMatrix< VariableArray2<double> > &A, DenseVector<VariableArray1<double> > &rhs,
     107              :                 size_t &iNonNullRows, std::vector<size_t> &xinterchange, double deficitTolerance)
     108              : {
     109              :         // LU Decomposition, IKJ Variant
     110              :         size_t rows = A.num_rows();
     111              :         size_t cols = A.num_cols();
     112              : 
     113            0 :         xinterchange.resize(cols);
     114            0 :         for(size_t k=0; k<cols; k++)
     115            0 :                 xinterchange[k] = k;
     116              : 
     117              : //      UG_LOG("DECOMP " << rows << " x " << cols << "\n");
     118              : 
     119              :         std::vector<size_t> colInterchange;
     120              :         size_t k;
     121            0 :         for(k=0; k<cols; k++)
     122              :         {
     123              : //              UG_LOG("-----------------" << k << " < " << cols << " ------\n");
     124              :                 size_t biggestR=k, biggestC=k;
     125            0 :                 double dBiggest = dabs(A(k,k));
     126              : 
     127            0 :                 for(size_t r=k; r<rows; r++)
     128            0 :                         for(size_t c=k; c<cols; c++)
     129              :                         {
     130            0 :                                 double n = dabs(A(r,c));
     131            0 :                                 if(dBiggest < n)
     132              :                                 {
     133              :                                         dBiggest=n;
     134              :                                         biggestR = r;
     135              :                                         biggestC = c;
     136              :                                 }
     137              :                         }
     138              : 
     139              : 
     140              : //              UG_LOG(CPPString(A, "BeforeSwap"));
     141            0 :                 if(dBiggest < 1e-14)
     142              :                 {
     143              : //                      UG_LOG("k = " << k << " abort");
     144              :                         break;
     145              :                 }
     146              : //              UG_LOG("k = " << k << " biggest = " << biggestR << ", " << biggestC << "\n");
     147            0 :                 if(biggestR != k)
     148              :                 {
     149            0 :                         for(size_t j=0; j<cols; j++)
     150              :                                 std::swap(A(k, j), A(biggestR, j));
     151              :                         std::swap(rhs[k], rhs[biggestR]);
     152              :                 }
     153            0 :                 if(biggestC != k)
     154              :                 {
     155            0 :                         for(size_t j=0; j<rows; j++)
     156              :                                 std::swap(A(j, k), A(j, biggestC));
     157              :                         std::swap(xinterchange[k], xinterchange[biggestC]);
     158              :                 }
     159              : //              UG_LOG(CPPString(A, "AfterSwap"));
     160              : 
     161            0 :                 for(size_t i=k+1; i<rows; i++)
     162              :                 {
     163            0 :                         double a = A(i,k)/A(k,k);
     164            0 :                         for(size_t j=k+1; j<cols; j++)
     165            0 :                                 A(i,j) = A(i,j) - a*A(k,j);
     166            0 :                         rhs[i] -= a*rhs[k];
     167            0 :                         A(i,k) = 0;
     168              : 
     169              :                 }
     170              : 
     171              : 
     172              : //              UG_LOG(CPPString(A, "MAT"));
     173              : //              PrintVector(rhs, "rhs");
     174              :         }
     175            0 :         iNonNullRows = k;
     176              :         // every row below iNonNullRows is zero.
     177              :         // equation system is solveable if every rhs[k] = 0 for k>=iNonNullRows
     178            0 :         for(; k<rows; k++)
     179            0 :                 if(dabs(rhs[k]) > deficitTolerance )
     180              :                 {
     181              : //                      UG_LOG("row " << k << " > 1e-7" << "\n")
     182              :                         return false;
     183              :                 }
     184              :                 else
     185            0 :                         rhs[k] = 0.0;
     186              : //      UG_LOGN("iNonNullRows = " << iNonNullRows << " abort");
     187              :         return true;
     188            0 : }
     189              : 
     190              : 
     191            0 : bool SolveDeficit(DenseMatrix< VariableArray2<double> > &A,
     192              :                 DenseVector<VariableArray1<double> > &x, DenseVector<VariableArray1<double> > &rhs, double deficitTolerance)
     193              : {
     194              :         DenseMatrix< VariableArray2<double> > A2=A;
     195              :         DenseVector<VariableArray1<double> > rhs2=rhs;
     196              : 
     197              :         UG_ASSERT(A.num_rows() == rhs.size(), "");
     198              :         UG_ASSERT(A.num_cols() == x.size(), "");
     199              : 
     200              :         size_t iNonNullRows;
     201            0 :         x.resize(A.num_cols());
     202            0 :         for(size_t i=0; i<x.size(); i++)
     203            0 :                 x[i] = 0.0;
     204              :         std::vector<size_t> interchange;
     205            0 :         if(Decomp(A, rhs, iNonNullRows, interchange, deficitTolerance) == false) return false;
     206              : 
     207              : //      A.maple_print("Adecomp");
     208              : //      rhs.maple_print("rhs decomp");
     209              : 
     210            0 :         for(int i=iNonNullRows-1; i>=0; i--)
     211              :         {
     212            0 :                 double d=A(i,i);
     213              :                 double s=0;
     214            0 :                 for(size_t k=i+1; k<A.num_cols(); k++)
     215            0 :                         s += A(i,k)*x[interchange[k]];
     216            0 :                 x[interchange[i]] = (rhs[i] - s)/d;
     217              :         }
     218              :         DenseVector<VariableArray1<double> > f;
     219            0 :         f = A2*x - rhs2;
     220            0 :         if(VecNormSquared(f) > 1e-2)
     221              :         {
     222            0 :                 UG_LOGN("iNonNullRows = " << iNonNullRows);
     223              :                 UG_LOG("solving was wrong:");
     224            0 :                 UG_LOGN(CPPString(A2, "Aold"));
     225            0 :                 rhs2.maple_print("rhs");
     226            0 :                 UG_LOGN(CPPString(A, "Adecomp"));
     227            0 :                 rhs.maple_print("rhsDecomp");
     228            0 :                 x.maple_print("x");
     229            0 :                 f.maple_print("f");
     230              : 
     231              :         }
     232              : 
     233              :         return true;
     234            0 : }
     235              : }
        

Generated by: LCOV version 2.0-1