33 #ifndef __H__UG__LIB_ALGEBRA__PINVIT_H__
34 #define __H__UG__LIB_ALGEBRA__PINVIT_H__
101 template<
typename TAlgebra>
170 std::stringstream ss;
171 ss <<
"PINVIT Eigensolver by Martin Rupp / G-CSC 2013-2015." <<
175 "\n Number of EV = " <<
px.size() <<
178 ss <<
"Preconditioned Inverse Block Iteration [Neymeyr]";
179 else if(
m_iPINVIT==2) ss <<
"Preconditioned Block Gradient Method";
180 else if(
m_iPINVIT==3) ss <<
"LOBPCG (locally optimal block preconditioned gradient) [Knyazew]";
181 else if(
m_iPINVIT>=4) ss <<
"gerneralized method PINVIT-method looking back " <<
m_iPINVIT-1 <<
" ev approximations.";
182 ss <<
"\n Preconditioner: ";
184 else ss <<
" NOT SET!\n";
191 ss <<
"\n\tUsing additional Corrections.";
193 ss <<
"\n\tUsing LAPLACIAN!";
266 m_pA.template cast_dynamic<MatrixOperator<matrix_type, vector_type> >();
273 for(
size_t i=0; i<A.num_rows(); i++)
276 if(bFirst && A.is_isolated(i))
282 for(
typename matrix_type::row_iterator it = A.begin_row(i); it != A.end_row(i); ++it)
286 A(i, i) = A.num_connections(i)*1.0;
290 for(
size_t i=0; i<A.num_rows(); i++)
295 for(
size_t i=0; i<A.num_rows(); i++)
343 UG_ASSERT(iPINVIT >=1 && iPINVIT <= 3, "i has to be >= 1 and <= 3, but is
" << iPINVIT);
346 size_t num_eigenvalues()
351 double get_eigenvalue(size_t i)
353 if(lambda.size() != px.size()) return 0.0;
357 SmartPtr<vector_type> get_eigenvector(size_t i)
362 void set_print_eigenvalues_and_defect(bool b)
364 m_bPrintEigenvaluesAndDefect = b;
367 void set_print_projected_eigenvectors(bool b)
369 m_bPrintProjectedEigenvectors = b;
371 void set_print_projected_eigenvalues(bool b)
373 m_bPrintProjectedEigenvalues = b;
376 void set_print_projected_eigenproblem(bool b)
378 m_bPrintProjectedEigenproblem = b;
381 void set_print_used_testvectors(bool b)
383 m_bPrintUsedTestvectors = b;
386 void print_projected_eigenvectors(DenseMatrix<VariableArray2<double> > &r_ev, std::vector<std::complex<double> > &r_lambda, std::vector<std::string> &vTestVectorDescription)
389 for(size_t c=0; c < r_ev.num_cols(); c++)
391 UG_LOG("eigenvalue [
" << c << "] =
" << r_lambda[c] << ", vector:\n
");
392 std::vector<double> tmpEV(r_ev.num_rows());
393 for(size_t r=0; r<r_ev.num_rows(); r++)
394 tmpEV[r] = r_ev(r, c);
395 std::vector<size_t> s = GetSortedIndices(tmpEV, absCompare);
398 for(size_t i=0; i<r_ev.num_rows(); i++)
400 //if(r_ev.num_rows() > 3 && abs(r_ev(s[i], c))/abs(r_ev(s[r_ev.num_rows()-1], c)) < 0.01) continue;
402 UG_LOG(std::setw(14) << r_ev(j, c) << " " << vTestVectorDescription[j] << "\n
");
410 SmartPtr<vector_type> create_approximation_vector()
412 SmartPtr<vector_type> t = px(0).clone_without_values();
417 void set_store_defects(bool b)
422 void set_store_lambdas(bool b)
427 bool m_bStoreDefects;
428 bool m_bStoreLambdas;
430 std::vector<std::vector<double> > m_defects;
431 std::vector<std::vector<double> > m_lambdas;
433 size_t get_iterations()
438 double get_defect(size_t nev, size_t it)
440 UG_COND_THROW(m_bStoreDefects == false, "Not storing defects. Use
set_store_defects(
true).
");
441 UG_COND_THROW(nev > m_defects.size(), nev << " > #EV
" << m_defects.size());
442 UG_COND_THROW(it > m_defects[nev].size(), "Iteration
" << it << " not available.
");
443 return m_defects[nev][it];
446 double get_lambda(size_t nev, size_t it)
448 UG_COND_THROW(m_bStoreLambdas == false, "Not storing lambdas. Use
set_store_lambdas(
true).
");
449 UG_COND_THROW(nev > m_lambdas.size(), nev << " > #EV
" << m_lambdas.size());
450 UG_COND_THROW(it > m_lambdas[nev].size(), "Iteration
" << it << " not available.
");
452 return m_lambdas[nev][it];
461 PINVIT_PROFILE_FUNC();
462 UG_LOG(config_string() << "\nInitializing...
");
465 size_t nEigenvalues = px.size();
466 DenseMatrix<VariableArray2<double> > rA;
467 DenseMatrix<VariableArray2<double> > rB;
468 DenseMatrix<VariableArray2<double> > r_ev;
469 std::vector<std::complex<double> > r_lambda;
470 std::vector<std::string> vCorrectionName;
472 SmartPtrVector<vector_type> pTestVectors;
473 SmartPtrVector<vector_type> vAdditional;
474 SmartPtrVector<vector_type> vCorr;
475 SmartPtrVector<vector_type> vOldX;
477 std::vector<double> vDefectNorm(nEigenvalues, m_dPrecision*10);
478 std::vector<double> oldXnorm(nEigenvalues);
479 std::vector<bool> bConverged(nEigenvalues, false);
481 std::vector<std::string> vTestVectorDescription;
483 SmartPtr<vector_type> spDefect;
486 spDefect = create_approximation_vector();
488 m_currentAdditionalEigenvectors = 0;
490 //size_t size = px[0]->size();
492 ParallelMatrix<SparseMatrix<double> > B;
493 B.resize(size, size);
494 for(size_t i=0; i<size; i++)
496 B.set_storage_type(PST_ADDITIVE);*/
498 for(size_t i=0; i<m_additionalEigenvectorsToKeep; i++)
499 vAdditional.push_back(create_approximation_vector());
501 lambda.resize(nEigenvalues);
502 freq_change.resize(nEigenvalues);
503 for(size_t i=0; i<nEigenvalues; i++)
505 vCorr.push_back(create_approximation_vector() );
507 vOldX.push_back(create_approximation_vector() );
510 vCorrectionName.resize(nEigenvalues);
514 UG_LOG("PINVIT: Initializing preconditioner...
");
517 m_spPrecond->init(m_pA);
523 pcl::ProcessCommunicator pc;
529 m_defects.resize(nEigenvalues);
532 m_lambdas.resize(nEigenvalues);
534 for(m_iteration=0; m_iteration<m_maxIterations; m_iteration++)
538 // UG_LOG("normalize...\n
");
540 normalize_approximations();
542 // 2. compute rayleigh quotient, residuum, apply preconditioner, compute corrections norm
543 size_t nrofconverged=0;
546 size_t currentAdditionalCorrections = 0;
547 size_t numCorrections=0;
549 PROGRESS_START(prog, nEigenvalues, "PINVIT:
compute corrections
");
550 for(size_t i=0; i<nEigenvalues; i++)
552 PROGRESS_UPDATE(prog, i);
553 // UG_LOG("compute rayleigh
" << i << "...\n
");
557 if(m_bPrintFrequencies_linear_elasticity){
558 freq_old = 1.0/(2.0*PI)*sqrt(lambda[i]/m_dDensity_linear_elasticity);
561 compute_rayleigh_and_defect(px(i), lambda[i], *spDefect, vDefectNorm[i]);
563 if(m_bPrintFrequencies_linear_elasticity){
564 freq_change[i] = freq_old-1.0/(2.0*PI)*sqrt(lambda[i]/m_dDensity_linear_elasticity);
567 if((m_iteration != 0 && m_bRelativePrecision && vDefectNorm[i]/lambda[i] < m_dPrecision)
568 || (!m_bRelativePrecision && vDefectNorm[i] < m_dPrecision))
569 bConverged[i] = true;
571 bConverged[i] = false;
576 if(!m_bRelativePrecision &&
577 m_bUseAdditionalCorrections && currentAdditionalCorrections < m_currentAdditionalEigenvectors)
579 double additionalLambda, additionalDefect;
580 compute_rayleigh_and_defect(vAdditional(currentAdditionalCorrections),
581 additionalLambda, *spDefect, additionalDefect);
582 currentAdditionalCorrections++;
583 if(additionalDefect > m_dPrecision && additionalDefect < 1e5)
585 calculate_correction(*vCorr[numCorrections++], *spDefect);
586 vCorrectionName[numCorrections-1] = std::string("additional correction
") + ToString(currentAdditionalCorrections-1);
592 // UG_LOG("Calculating correction from defect
" << i << "\n
");
593 vCorrectionName[numCorrections] = std::string("correction
") + ToString(i);
594 calculate_correction(*vCorr[numCorrections++], *spDefect);
598 m_defects[i].push_back(vDefectNorm[i]);
600 m_lambdas[i].push_back(lambda[i]);
602 PROGRESS_FINISH(prog);
608 if(m_bPrintEigenvaluesAndDefect)
609 print_eigenvalues_and_defect(m_iteration, vDefectNorm, oldXnorm, lambda, bConverged);
611 if(nrofconverged==nEigenvalues)
613 UG_LOG("all eigenvectors converged\n
");
617 if(m_bAbortOnFreqConverged_linear_elasticity){
619 for(unsigned k = 0; k < freq_change.size(); ++k){
620 if(abs(freq_change[k]) >= m_dFreqPrecision){
627 UG_LOG("all eigenvectors converged according to frequency change\n
");
632 // 5. add Testvectors
633 //UG_LOG("5. add Testvectors\nEigenvalues
");
635 get_testvectors(m_iteration, vCorr, vCorrectionName, numCorrections, vOldX, vAdditional, pTestVectors, vTestVectorDescription, bConverged);
637 for(size_t i=0; i<nEigenvalues; i++)
639 write_debug(m_iteration, i, px(i), *spDefect, vCorr(i), bConverged[i]);
640 if(vOldX.size() > i) write_debug_old(m_iteration, i, vOldX(i));
643 /*for(size_t i=0; i<vTestVectorDescription.size(); i++)
644 { UG_LOG(vTestVectorDescription[i] << "\nEigenvalues
"); } */
646 // 5. compute reduced Matrices rA, rB
648 if(pTestVectors.size() < px.size()+1)
650 UG_LOG("ERROR: Projected Spaces has Dimension
" << pTestVectors.size() << ", but we need at least
" << px.size()+1 << " to make progress (
for " << px.size() << " eigenvalues)\n
");
654 get_projected_eigenvalue_problem(rA, rB, pTestVectors, vTestVectorDescription);
656 // 6. solve reduced eigenvalue problem
657 size_t iNrOfTestVectors = pTestVectors.size();
658 r_ev.resize(iNrOfTestVectors, iNrOfTestVectors);
659 r_lambda.resize(iNrOfTestVectors);
661 // solve rA x = lambda rB, --> r_ev, r_lambda
662 GeneralizedEigenvalueProblemComplex(rA, r_ev, r_lambda, rB, true);
664 if(m_bPrintProjectedEigenvalues)
665 print_projected_eigenvectors(r_ev, r_lambda, vTestVectorDescription);
668 if(m_bDebugCalcProjectedEigenvalues)
669 debug_calc_projected_eigenvalues(r_ev, pTestVectors, m_iteration, false);
670 set_new_approximations_and_save_old(r_ev, pTestVectors, vOldX, vAdditional);
672 assert_real_positive(r_lambda);
673 }UG_CATCH_THROW("PINVIT::apply iteration
" << m_iteration << " failed.
");
676 UG_LOG("not converged after
" << m_maxIterations << " steps.\n
");
680 // only use this type of vector creation if you don't use the preconditioner
681 void init_nonprecond_vector(vector_type &t)
683 CloneVector(t, px(0));
693 void debug_calc_projected_eigenvalues(DenseMatrix<VariableArray2<double> > &r_ev,
694 SmartPtrVector<vector_type> &pTestVectors, int iteration, bool bWrite)
696 PROFILE_FUNC_GROUP("debug
");
698 if(debug_writer() == SPNULL) return;
700 vector_type t, defect;
701 init_nonprecond_vector(t);
702 init_nonprecond_vector(defect);
705 for(size_t c=0; c<pTestVectors.size(); c++)
706 pTestVectors[c]->change_storage_type(PST_CONSISTENT);
709 for(size_t r=0; r<pTestVectors.size(); r++)
712 t.set_storage_type(PST_CONSISTENT);
713 defect.set_storage_type(PST_ADDITIVE);
715 for(size_t i=0; i<t.size(); i++)
720 for(size_t c=0; c<pTestVectors.size(); c++)
721 t[i] += r_ev(c, r) * (*pTestVectors[c])[i];
729 t.set_storage_type(PST_CONSISTENT);
730 defect.set_storage_type(PST_ADDITIVE);
732 m_pA->apply(defect, t);
734 double lambda = t.dotprod(defect);
739 defect.change_storage_type(PST_ADDITIVE);
740 t.change_storage_type(PST_CONSISTENT);
742 MatMultAdd(defect, 1.0, defect, -lambda, *m_pB, t);
745 VecScaleAdd(defect, 1.0, defect, -lambda, t);
749 UG_LOG(r << " lambda:
" << std::setw(14) << lambda << " defect:
" << std::setw(14) << defect.norm() << "\n
");
752 write_debug(t, ("pinvit_it_
" + ToString(iteration) + "_pev_
" + ToString(r)).c_str());
758 void set_new_approximations_and_save_old(DenseMatrix<VariableArray2<double> > &r_ev, SmartPtrVector<vector_type> &pTestVectors, SmartPtrVector<vector_type> &vOldX,
759 SmartPtrVector<vector_type> &vAdditional)
761 PINVIT_PROFILE_FUNC();
764 for(size_t i=0; i<pTestVectors.size(); i++)
765 pTestVectors[i]->change_storage_type(PST_CONSISTENT);
766 for(size_t i=0; i<px.size(); i++)
767 px[i]->change_storage_type(PST_CONSISTENT);
769 for(size_t i=0; i<vOldX.size(); i++)
770 vOldX[i]->set_storage_type(PST_CONSISTENT);
772 for(size_t i=0; i<vAdditional.size(); i++)
773 vAdditional[i]->set_storage_type(PST_CONSISTENT);
775 // assume r_lambda is sorted
777 size_t size = px[0]->size();
778 THROW_IF_NOT_EQUAL(pTestVectors.size(), r_ev.num_rows());
780 size_t numCalc = std::min(px.size()+m_additionalEigenvectorsToKeep, r_ev.num_cols()); //px.size()
781 m_currentAdditionalEigenvectors = numCalc-px.size();
782 // UG_LOG("current aditional eigenvectors:
" << m_currentAdditionalEigenvectors << "\n
");
784 std::vector<vector_value_type> x_tmp(numCalc);
785 for(size_t i=0; i<size; i++)
787 if(vbDirichlet[i]) continue;
789 // since vx can be part of the Testvectors, temporary safe result in x_tmp.
790 for(size_t r=0; r < numCalc; r++)
793 for(size_t c=0; c<pTestVectors.size(); c++)
794 x_tmp[r] += r_ev(c, r) * (*pTestVectors[c])[i];
798 for(size_t r=0; r<px.size(); r++)
801 /*for(int k=0; k<m_nrOfOld; k++)
802 vOldX[k][r][i] = vOldX[k][r][i];
803 vOldX[0][r][i] = (px[r])[i];*/
805 vOldX(r) [i] = px(r) [i];
807 px(r) [i] = x_tmp[r];
811 for(size_t r=px.size(); r<numCalc; r++)
812 vAdditional(r-px.size()) [i] = x_tmp[r];
818 void assert_real_positive(const std::vector<std::complex<double> > &r_lambda)
820 PINVIT_PROFILE_FUNC();
822 //#define UG_ASSERT2(cond, txt) {if(!cond) { UG_LOG("Warning:
" << txt << "\n
"); }}
824 for(size_t i=0; i<r_lambda.size(); i++) // px.size() or r_lambda.size()
826 if(r_lambda[i].imag() >= 1e-8)
827 {UG_LOG("WARNING: eigenvalue
" << i << " is imaginary (
" << r_lambda[i] << ")\n
"); }
828 if(r_lambda[i].real() <= 1e-8)
829 {UG_LOG("WARNING: eigenvalues
" << i << "<= 0\n
");}
832 if(m_bPrintProjectedEigenvalues && m_bPrintProjectedEigenvectors == false)
834 for(size_t i=0; i<r_lambda.size(); i++)
835 UG_LOG(i << ".:
" << r_lambda[i] << "\n
");
839 for(size_t i=0; i<r_lambda.size(); i++) // px.size() or r_lambda.size()
841 UG_ASSERT(r_lambda[i].imag() < 1e-4 && r_lambda[i].imag() > -1e-4, "eigenvalue
" << i << " =
" << r_lambda[i] << " is imaginary (
" << r_lambda[i] << ")\n
");
842 UG_ASSERT(r_lambda[i].real() > -1e-4, "eigenvalues
" << i << " =
" << r_lambda[i] << " < 0\n
");
848 void get_max_deflection_of_a_mode(vector_type& maxDeflect, vector_type& statSol,
849 const vector_type& eigenVec, const matrix_type& massMat)
851 PINVIT_PROFILE_FUNC();
853 statSol.set_storage_type(PST_CONSISTENT);
854 maxDeflect.set_storage_type(PST_CONSISTENT);
857 SmartPtr<vector_type> Bv = statSol.clone_without_values();
858 SmartPtr<vector_type> vwBv = statSol.clone_without_values();
860 // compute Bv = massMat * eigenVec;
861 massMat.axpy(*Bv, 0.0, eigenVec, 1.0, eigenVec);
863 // vwBv = eigenVec * < statSol, Bv >
864 number scalarProd = 0.0;
865 for(size_t i = 0; i < statSol.size(); i++)
866 scalarProd += VecProd((*Bv)[i], statSol[i]);
868 for(size_t i = 0; i < statSol.size(); i++)
870 (*vwBv)[i] = eigenVec[i] * (-1.0) * scalarProd;
871 // maxDeflect += vwBv
872 maxDeflect[i] = maxDeflect[i] + (*vwBv)[i];
878 void write_debug(int iteration, int i, vector_type &x, vector_type &defect, vector_type &corr, bool bConverged)
880 PROFILE_FUNC_GROUP("debug
");
881 write_debug(x, ("pinvit_it_
" + ToString(iteration) + "_ev_
" + ToString(i)).c_str());
882 write_debug(defect, ("pinvit_it_
" + ToString(iteration) + "_defect_
" + ToString(i)).c_str());
884 write_debug(corr, ("pinvit_it_
" + ToString(iteration) + "_corr_
" + ToString(i)).c_str());
887 void write_debug_old(int iteration, int i, vector_type &oldX)
889 write_debug(oldX, ("pinvit_it_
" + ToString(iteration) + "_old_
" + ToString(i)).c_str());
892 double B_norm(vector_type &x)
894 PINVIT_PROFILE_FUNC();
896 return EnergyNorm(x, *m_pB);
901 void normalize_approximations()
903 PINVIT_PROFILE_FUNC();
904 for(size_t i=0; i< px.size(); i++)
905 px(i) *= 1/ B_norm(px(i));
908 void calculate_correction(vector_type &corr, vector_type &defect)
910 PINVIT_PROFILE_FUNC();
913 defect.change_storage_type(PST_ADDITIVE);
914 corr.set_storage_type(PST_CONSISTENT);
917 // d. apply preconditioner
920 m_spPrecond->apply(corr, defect);
924 m_spPrecond->apply_update_defect(corr, defect);
926 corr *= 1/ B_norm(corr);
928 corr.change_storage_type(PST_UNIQUE);
941 void compute_rayleigh_and_defect(vector_type &x, double &lambda, vector_type &defect, double &defectNorm)
943 PINVIT_PROFILE_FUNC();
945 // a. compute rayleigh quotients
948 x.change_storage_type(PST_CONSISTENT);
949 defect.set_storage_type(PST_ADDITIVE);
951 m_pA->apply(defect, x);
955 defect.change_storage_type(PST_UNIQUE);
956 x.change_storage_type(PST_UNIQUE);
958 lambda = x.dotprod(defect); // / <px[i], Bpx[i]> = 1.0.
959 //UG_LOG("lambda[
" << i << "] =
" << lambda << "\n
");
961 // b. calculate residuum
962 // defect = A px[i] - lambda[i] B px[i]
966 defect.change_storage_type(PST_ADDITIVE);
967 x.change_storage_type(PST_CONSISTENT);
969 MatMultAdd(defect, 1.0, defect, -lambda, *m_pB, x);
973 VecScaleAdd(defect, 1.0, defect, -lambda, x);
975 // c. check if converged
979 defect.change_storage_type(PST_UNIQUE);
981 defectNorm = defect.norm();
992 void print_eigenvalues_and_defect(int iteration, const std::vector<double> &vDefectNorm,
993 std::vector<double> &vOldDefectNorm, const std::vector<double> &vLambda, std::vector<bool> &bConverged)
995 PINVIT_PROFILE_FUNC();
996 UG_LOG("=====================================================================================\n
");
997 UG_LOG("iteration
" << iteration << "\n
");
999 for(size_t i=0; i<vLambda.size(); i++)
1001 UG_LOG(i << " lambda:
" << std::setw(20) << vLambda[i]);
1002 if(m_bPrintFrequencies_linear_elasticity){
1003 UG_LOG(" freq:
" << std::setw(20) << 1.0/(2.0*PI)*sqrt(vLambda[i]/m_dDensity_linear_elasticity) );
1004 UG_LOG(" change:
" << std::setw(20) << freq_change[i]);
1007 UG_LOG(" defect:
" << std::setw(20) << vDefectNorm[i]);
1008 if(iteration != 0) { UG_LOG(" reduction:
" << std::setw(14) << vDefectNorm[i]/vOldDefectNorm[i]); }
1009 if(m_bPrintFrequencies_linear_elasticity && abs(freq_change[i]) < m_dFreqPrecision) { UG_LOG(" (freq. converged)
"); }
1010 if(bConverged[i]) { UG_LOG(" (converged)
"); }
1012 vOldDefectNorm[i] = vDefectNorm[i];
1034 void get_testvectors(int iteration, SmartPtrVector<vector_type> &vCorr,
1035 std::vector<std::string> &vCorrectionName,
1036 size_t numCorrections, SmartPtrVector<vector_type> &vOldX, SmartPtrVector<vector_type> &vAdditional,
1037 SmartPtrVector<vector_type> &pTestVectors, std::vector<std::string> &vTestVectorDescription,
1038 std::vector<bool> &bConverged)
1041 PINVIT_PROFILE_FUNC();
1042 pTestVectors.clear();
1043 vTestVectorDescription.clear();
1046 UG_ASSERT(0, "todo
");
1047 for(size_t i=0; i < px.size(); i++)
1051 VecScaleAdd(vCorr(i), -1.0, vCorr(i), 1.0, px(i));
1052 vTestVectorDescription.push_back(std::string("ev - vCorr [
") + ToString(i) + std::string("]
") );
1058 for(size_t i=0; i < px.size(); i++)
1060 if(IsFiniteAndNotTooBig(px(i)))
1062 pTestVectors.push_back(px[i]);
1063 vTestVectorDescription.push_back(std::string("eigenvector [
") + ToString(i) + std::string("]
") );
1065 if(!bConverged[i] && m_iPINVIT >= 3)
1069 UG_ASSERT(vOldX.size() > i, "?
");
1070 pTestVectors.push_back(vOldX[i]);
1071 vTestVectorDescription.push_back(std::string("old eigenvalue[
") + ToString(i) + std::string("]
") );
1074 /*if(iteration == 0)
1076 for(size_t j=0; j<px[i]->size(); j++)
1077 vOldX[i][j] = (px[i])[j] * urand(-1.0, 1.0);
1082 { UG_LOG("WARNING ev [
" << i << "] not normal or too big\n
"); }
1085 for(size_t i=0; i<numCorrections; i++)
1087 if(IsFiniteAndNotTooBig(vCorr(i)))
1089 pTestVectors.push_back(vCorr[i]);
1090 vTestVectorDescription.push_back(vCorrectionName[i]);
1094 UG_LOG("WARNING correction [
" << i << "] not normal or too big\n
");
1099 for(size_t i=0; i<m_currentAdditionalEigenvectors; i++)
1101 if(IsFiniteAndNotTooBig(vAdditional(i)))
1103 pTestVectors.push_back(vAdditional[i]);
1104 vTestVectorDescription.push_back(std::string("additional [
") + ToString(i) + std::string("]
") );
1107 { UG_LOG("WARNING additional [
" << i << "] not normal or too big\n
"); }
1118 void get_linear_independent_rows(DenseMatrix<VariableArray2<double> > mat, std::vector<bool> &bLinearIndependent)
1120 PINVIT_PROFILE_FUNC();
1121 // Remove linear depended vectors
1122 bLinearIndependent.resize(mat.num_rows(), true);
1123 for(size_t i=0; i<mat.num_rows(); i++)
1125 for(size_t j=0; j<i; j++)
1127 if(!bLinearIndependent[i]) continue;
1128 double val = mat(i, j)/mat(j,j);
1130 for(size_t k=j+1; k<mat.num_rows(); k++)
1131 mat(i,k) -= val*mat(j, k);
1133 if(mat(i,i) < m_linearDependentEps) bLinearIndependent[i] = false;
1134 else bLinearIndependent[i] = true;
1143 template<typename T>
1144 void remove_unused(T &v, const std::vector<bool> vbUse)
1146 PINVIT_PROFILE_FUNC();
1150 for(size_t i=0; i<tmp.size(); i++)
1152 v.push_back(tmp[i]);
1156 void print_used_testvectors(std::vector<std::string> &vTestVectorDescription, std::vector<bool> bUse)
1158 UG_LOG("used testvectors:\n
");
1159 for(size_t i=0; i<vTestVectorDescription.size(); i++)
1160 if(bUse[i]) { UG_LOG(vTestVectorDescription[i] << "\n
"); }
1161 UG_LOG("unused testvectors:\n
");
1162 for(size_t i=0; i<vTestVectorDescription.size(); i++)
1163 if(!bUse[i]) { UG_LOG(vTestVectorDescription[i] << "\n
"); }
1176 void get_projected_eigenvalue_problem(DenseMatrix<VariableArray2<double> > &rA,
1177 DenseMatrix<VariableArray2<double> > &rB, SmartPtrVector<vector_type> &pTestVectors,
1178 std::vector<std::string> &vTestVectorDescription)
1181 PINVIT_PROFILE_FUNC();
1182 // 1. calculate W as a subset of the testvectors so that those are linear B-independent
1184 size_t iNrOfTestVectors = pTestVectors.size();
1185 rA.resize(iNrOfTestVectors, iNrOfTestVectors);
1186 rB.resize(iNrOfTestVectors, iNrOfTestVectors);
1189 MultiEnergyProd(*m_pB, pTestVectors, rB, iNrOfTestVectors);
1191 MultiScalProd(pTestVectors, rB, iNrOfTestVectors);
1194 // Remove linear depended vectors
1195 std::vector<bool> bUse;
1196 get_linear_independent_rows(rB, bUse);
1199 if(m_bPrintUsedTestvectors)
1200 print_used_testvectors(vTestVectorDescription, bUse);
1202 // save used testvectors
1203 remove_unused(pTestVectors, bUse);
1204 remove_unused(vTestVectorDescription, bUse);
1206 iNrOfTestVectors = pTestVectors.size();
1208 // 2. & 3. compute reduced Matrices rA, rB
1209 rA.resize(iNrOfTestVectors, iNrOfTestVectors);
1210 rB.resize(iNrOfTestVectors, iNrOfTestVectors);
1212 // UG_LOG("iNrOfTestVectors =
" << iNrOfTestVectors << "\n
");
1215 MultiEnergyProd(*m_pB, pTestVectors, rB, iNrOfTestVectors);
1217 MultiScalProd(pTestVectors, rB, iNrOfTestVectors);
1219 MultiEnergyProd(*m_pA, pTestVectors, rA, iNrOfTestVectors);
1221 if(m_bPrintProjectedEigenproblem)
1223 PrintMaple(rA, "rA
");
1224 PrintMaple(rB, "rB
");
1230 void set_laplacian(bool b)
1235 void set_relative_precision(double precision)
1237 m_dPrecision = precision;
1238 m_dMinimumDefectToCalcCorrection = precision;
1239 m_bRelativePrecision = true;
1247 #endif // __H__UG__LIB_ALGEBRA__PINVIT_H__
Definition: smart_pointer.h:108
Definition: debug_writer.h:354
virtual void set_debug(SmartPtr< IDebugWriter< algebra_type > > spDebugWriter)
set debug writer
Definition: debug_writer.h:384
void write_debug(const matrix_type &mat, const char *filename)
write debug output for a matrix (if debug writer set)
Definition: debug_writer.h:399
SmartPtr< IDebugWriter< algebra_type > > debug_writer()
returns the debug writer
Definition: debug_writer.h:391
TAlgebra::matrix_type matrix_type
type of matrix
Definition: debug_writer.h:363
describes a linear iterator
Definition: linear_iterator.h:81
describes a linear mapping X->Y
Definition: linear_operator.h:80
Definition: matrix_operator.h:49
size_t m_currentAdditionalCorrections
Definition: pinvit.h:161
void set_store_defects(bool b)
Definition: pinvit.h:417
bool m_bRelativePrecision
Definition: pinvit.h:137
bool m_bPrintFrequencies_linear_elasticity
Definition: pinvit.h:148
SmartPtr< ILinearIterator< vector_type > > m_spPrecond
Definition: pinvit.h:133
void set_debug_calc_projected_eigenvalues(bool b)
Definition: pinvit.h:323
void set_new_approximations_and_save_old(DenseMatrix< VariableArray2< double > > &r_ev, SmartPtrVector< vector_type > &pTestVectors, SmartPtrVector< vector_type > &vOldX, SmartPtrVector< vector_type > &vAdditional)
Definition: pinvit.h:758
void set_linear_operator_B(matrix_operator_type &B)
Definition: pinvit.h:301
void set_use_additional_corrections(bool b)
Definition: pinvit.h:328
size_t m_currentAdditionalEigenvectors
Definition: pinvit.h:160
double m_dFreqPrecision
Definition: pinvit.h:150
std::vector< double > freq_change
Definition: pinvit.h:146
SmartPtr< ILinearOperator< vector_type > > m_pA
Definition: pinvit.h:125
std::string tostring()
Definition: pinvit.h:164
void set_abort_on_frequencies_converged_linear_elasticity(double freq_precision, double density)
Definition: pinvit.h:230
void set_linear_dependent_eps(double eps)
Definition: pinvit.h:238
matrix_operator_type * m_pB
Definition: pinvit.h:128
TAlgebra::vector_type vector_type
Definition: pinvit.h:110
void calculate_correction(vector_type &corr, vector_type &defect)
Definition: pinvit.h:908
bool m_bPrintEigenvaluesAndDefect
Definition: pinvit.h:152
bool m_bStoreDefects
Definition: pinvit.h:427
int apply()
Definition: pinvit.h:459
void add_vector(SmartPtr< vector_type > vec)
Definition: pinvit.h:246
std::vector< bool > vbDirichlet
Definition: pinvit.h:140
double m_dDensity_linear_elasticity
Definition: pinvit.h:147
double m_linearDependentEps
Definition: pinvit.h:142
void set_store_lambdas(bool b)
Definition: pinvit.h:422
DebugWritingObject< TAlgebra > base_type
Base type.
Definition: pinvit.h:115
double m_dPrecision
Definition: pinvit.h:136
size_t m_iPINVIT
Definition: pinvit.h:138
bool m_bUseAdditionalCorrections
Definition: pinvit.h:157
size_t m_additionalEigenvectorsToKeep
Definition: pinvit.h:159
IPreconditioner< TAlgebra >::matrix_operator_type matrix_operator_type
Definition: pinvit.h:127
std::vector< double > lambda
Definition: pinvit.h:139
bool m_bLaplacian
Definition: pinvit.h:144
TAlgebra::matrix_type matrix_type
Definition: pinvit.h:111
void set_preconditioner(SmartPtr< ILinearIterator< vector_type > > precond)
Definition: pinvit.h:256
bool m_bStoreLambdas
Definition: pinvit.h:428
size_t m_maxIterations
Definition: pinvit.h:135
bool m_bPrintUsedTestvectors
Definition: pinvit.h:156
vector_type::value_type vector_value_type
Definition: pinvit.h:112
virtual std::string config_string() const
Definition: pinvit.h:168
bool m_bPrintProjectedEigenproblem
Definition: pinvit.h:155
void set_precision(double precision)
Definition: pinvit.h:311
void debug_calc_projected_eigenvalues(DenseMatrix< VariableArray2< double > > &r_ev, SmartPtrVector< vector_type > &pTestVectors, int iteration, bool bWrite)
Definition: pinvit.h:693
void set_pinvit(size_t iPINVIT)
Definition: pinvit.h:340
void assert_real_positive(const std::vector< std::complex< double > > &r_lambda)
Definition: pinvit.h:818
bool m_bPrintProjectedEigenvalues
Definition: pinvit.h:153
void set_max_iterations(size_t maxIterations)
Definition: pinvit.h:306
void get_projected_eigenvalue_problem(DenseMatrix< VariableArray2< double > > &rA, DenseMatrix< VariableArray2< double > > &rB, SmartPtrVector< vector_type > &pTestVectors, std::vector< std::string > &vTestVectorDescription)
Definition: pinvit.h:1176
void set_additional_eigenvectors_to_keep(size_t i)
Definition: pinvit.h:318
void set_linear_operator_A(SmartPtr< ILinearOperator< vector_type > > loA)
Definition: pinvit.h:261
SmartPtrVector< vector_type > px
Definition: pinvit.h:132
bool m_bPrintProjectedEigenvectors
Definition: pinvit.h:154
bool m_bAbortOnFreqConverged_linear_elasticity
Definition: pinvit.h:149
TAlgebra algebra_type
Definition: pinvit.h:107
PINVIT()
Definition: pinvit.h:200
void compute_rayleigh_and_defect(vector_type &x, double &lambda, vector_type &defect, double &defectNorm)
Definition: pinvit.h:941
bool m_bDebugCalcProjectedEigenvalues
Definition: pinvit.h:158
double m_dMinimumDefectToCalcCorrection
Definition: pinvit.h:130
void get_testvectors(int iteration, SmartPtrVector< vector_type > &vCorr, std::vector< std::string > &vCorrectionName, size_t numCorrections, SmartPtrVector< vector_type > &vOldX, SmartPtrVector< vector_type > &vAdditional, SmartPtrVector< vector_type > &pTestVectors, std::vector< std::string > &vTestVectorDescription, std::vector< bool > &bConverged)
Definition: pinvit.h:1034
function util rates kinetic compute(ConvRateSetup)
const NullSmartPtr SPNULL
The equivalent to NULL for smart pointers.
Definition: smart_pointer.h:90
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
string ConfigShift(string s)
Definition: string_util.cpp:457
T value_type
Definition: sparsematrix_interface.h:2