7 #ifndef __SparseMatrix3x3_h__ 8 #define __SparseMatrix3x3_h__ 16 class FE_DL_EXPORT SparseMatrix3x3 :
public Component,
17 public CastableAs< SparseMatrix3x3<T> >
21 typedef Vector<3, t_real> t_v3;
22 typedef Matrix<3,3,t_real> t_matrix;
24 virtual ~SparseMatrix3x3(
void) {}
25 virtual void multiply(std::vector<t_v3> &a_b,
26 const std::vector<t_v3> &a_x)
const = 0;
27 virtual void scale(t_real a_scale) = 0;
31 class FE_DL_EXPORT
FullVMR :
public SparseMatrix3x3<Real>
37 virtual void multiply(std::vector<SpatialVector> &a_b,
38 const std::vector<SpatialVector> &a_x)
const;
39 virtual void scale(Real a_scale);
41 typedef std::map<unsigned int, SpatialMatrix> t_row;
44 void setRows(
unsigned int a_count);
45 unsigned int rows(
void);
46 t_row &row(
unsigned int a_index);
52 std::vector<t_row> m_rows;
63 virtual void multiply(std::vector<SpatialVector> &a_b,
64 const std::vector<SpatialVector> &a_x)
const;
70 class FE_DL_EXPORT CRS
76 std::vector<T> m_values;
77 std::vector<int> m_colind;
78 std::vector<int> m_rowptr;
83 class FE_DL_EXPORT FullBCRS :
public SparseMatrix3x3<T>
90 virtual ~FullBCRS(
void);
93 virtual void multiply(std::vector<t_v3> &a_b,
94 const std::vector<t_v3> &a_x)
const;
95 virtual void scale(t_real a_scale);
100 t_matrix &insert(
unsigned int a_columnIndex,
101 const t_matrix &a_block);
103 void dump(
void)
const;
105 void write(
const String &a_filename);
106 void read(
const String &a_filename);
108 void writeDense(
const String &a_filename);
109 void readDense(
const String &a_filename,
unsigned int a_M,
unsigned int a_N);
111 void writeStructure(
const String &a_filename)
const;
116 void write(CRS<T> &aCRS)
const;
117 void read(
const CRS<T> &aCRS);
121 std::vector<t_matrix> &blocks(
void) {
return m_blocks; }
122 std::vector<unsigned int> &colind(
void) {
return m_colind; }
123 std::vector<unsigned int> &rowptr(
void) {
return m_rowptr; }
126 std::vector<t_matrix> m_blocks;
127 std::vector<unsigned int> m_colind;
128 std::vector<unsigned int> m_rowptr;
133 template <
typename T>
134 class FE_DL_EXPORT UpperTriangularBCRS :
public FullBCRS<T>
140 UpperTriangularBCRS(
void){}
141 virtual ~UpperTriangularBCRS(
void){}
143 virtual void multiply(std::vector<t_v3> &a_b,
144 const std::vector<t_v3> &a_x)
const;
146 void incompleteSqrt(
void);
147 void backSub(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b);
148 void transposeForeSub(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b);
149 void backSolve(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b);
155 template <
typename T>
156 inline FullBCRS<T>::FullBCRS(
void)
159 m_zeroVector =
t_v3(0.0,0.0,0.0);
162 template <
typename T>
163 inline FullBCRS<T>::~FullBCRS(
void)
167 template <
typename T>
168 inline void FullBCRS<T>::clear(
void)
176 template <
typename T>
177 inline void FullBCRS<T>::startrow(
void)
179 m_rowptr.push_back(m_r);
182 template <
typename T>
183 inline void FullBCRS<T>::done(
void)
185 m_rowptr.push_back(m_r);
188 template <
typename T>
191 m_blocks.push_back(a_block);
192 m_colind.push_back(a_columnIndex);
194 return m_blocks.back();
197 template <
typename T>
198 inline void FullBCRS<T>::multiply(std::vector<t_v3> &a_b,
const std::vector<t_v3> &a_x)
const 200 unsigned int n = m_rowptr.size() - 1;
201 for(
unsigned int i = 0; i < n; i++)
203 a_b[i] = m_zeroVector;
204 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
206 a_b[i] += fe::multiply(m_blocks[k], a_x[m_colind[k]]);
211 template <
typename T>
212 inline void FullBCRS<T>::dump(
void)
const 215 setAll(offdiagonal_sum, 0.0);
216 unsigned int n = m_rowptr.size() - 1;
217 for(
unsigned int i = 0; i < n; i++)
219 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
223 offdiagonal_sum = offdiagonal_sum + m_blocks[k];
229 s = print(offdiagonal_sum);
230 feLogGroup(
"BCRS",
"off diagonal\n%s\n", s.
c_str());
233 template <
typename T>
234 inline void FullBCRS<T>::writeStructure(
const String &a_filename)
const 236 FILE *fp = fopen(a_filename.
c_str(),
"w");
239 feLog(
"WARNING: FullBCRS::writeStructure failed\n");
244 unsigned int n = m_rowptr.size() - 1;
245 for(
unsigned int i = 0; i < n; i++)
248 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
250 while(m_colind[k] > j)
255 if(m_blocks[k] == zero)
270 fe_fprintf(fp,
"\n");
275 template <
typename T>
276 inline void FullBCRS<T>::write(
const String &a_filename)
278 FILE *fp = fopen(a_filename.
c_str(),
"w");
281 feLog(
"WARNING: FullBCRS::write failed\n");
284 fe_fprintf(fp,
"%d\n", (
int)m_blocks.size());
285 for(
unsigned int i = 0; i < m_blocks.size(); i++)
287 fe_fprintf(fp,
"%g %g %g\n", m_blocks[i](0,0), m_blocks[i](0,1), m_blocks[i](0,2));
288 fe_fprintf(fp,
"%g %g %g\n", m_blocks[i](1,0), m_blocks[i](1,1), m_blocks[i](1,2));
289 fe_fprintf(fp,
"%g %g %g\n", m_blocks[i](2,0), m_blocks[i](2,1), m_blocks[i](2,2));
291 fe_fprintf(fp,
"%d\n", (
int)m_rowptr.size());
292 for(
unsigned int i = 0; i < m_rowptr.size(); i++)
294 fe_fprintf(fp,
"%d ", m_rowptr[i]);
296 fe_fprintf(fp,
"\n");
298 fe_fprintf(fp,
"%d\n", (
int)m_colind.size());
299 for(
unsigned int i = 0; i < m_colind.size(); i++)
301 fe_fprintf(fp,
"%d ", m_colind[i]);
303 fe_fprintf(fp,
"\n");
305 fe_fprintf(fp,
"%d\n", m_r);
309 template <
typename T>
310 inline void FullBCRS<T>::read(
const String &a_filename)
312 std::ifstream infile(a_filename.
c_str());
316 for(
int i = 0; i < m; i++)
318 infile >> m_blocks[i](0,0);
319 infile >> m_blocks[i](0,1);
320 infile >> m_blocks[i](0,2);
321 infile >> m_blocks[i](1,0);
322 infile >> m_blocks[i](1,1);
323 infile >> m_blocks[i](1,2);
324 infile >> m_blocks[i](2,0);
325 infile >> m_blocks[i](2,1);
326 infile >> m_blocks[i](2,2);
331 for(
int i = 0; i < m; i++)
333 infile >> m_rowptr[i];
338 for(
int i = 0; i < m; i++)
340 infile >> m_colind[i];
348 template <
typename T>
349 inline void FullBCRS<T>::writeDense(
const String &a_filename)
351 FILE *fp = fopen(a_filename.
c_str(),
"w");
354 feLog(
"WARNING: FullBCRS::write failed\n");
357 unsigned int n = m_rowptr.size() - 1;
359 std::vector< std::vector<double> > dense_matrix;
360 dense_matrix.resize(n*3);
361 for(
unsigned int i = 0; i < n*3; i++)
363 dense_matrix[i].resize(n*3);
366 #define FMT " % 10.8e % 10.8e % 10.8e" 368 for(
unsigned int i = 0; i < n; i++)
370 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
372 unsigned int j = m_colind[k];
374 for(
unsigned int ii = 0; ii < 3; ii++)
376 for(
unsigned int jj = 0; jj < 3; jj++)
378 unsigned int m = i*3 + ii;
379 unsigned int n = j*3 + jj;
380 dense_matrix[m][n] = m_blocks[k](ii,jj);
381 dense_matrix[n][m] = dense_matrix[m][n];
387 for(
unsigned int i = 0; i < n*3; i++)
389 for(
unsigned int j = 0; j < n*3; j++)
391 fe_fprintf(fp,
"%+10.8e ", dense_matrix[i][j]);
393 fe_fprintf(fp,
"\n");
398 for(
unsigned int i = 0; i < n; i++)
400 for(
unsigned int r = 0; r < 3; r++)
403 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
405 unsigned int c = m_colind[k];
409 fe_fprintf(fp, FMT, 0.0, 0.0, 0.0);
412 fe_fprintf(fp, FMT, m_blocks[k](r,0), m_blocks[k](r,1), m_blocks[k](r,2));
417 fe_fprintf(fp, FMT, 0.0, 0.0, 0.0);
419 fe_fprintf(fp,
"\n");
427 template <
typename T>
428 inline void FullBCRS<T>::readDense(
const String &a_filename,
unsigned int a_M,
unsigned int a_N)
433 for(
unsigned int i = 0; i < a_M; i++)
435 m_rowptr.push_back(m_colind.size());
436 for(
unsigned int j = 0; j < a_N; j++)
440 m_colind.push_back(j);
444 m_rowptr.push_back(m_colind.size());
445 m_r = m_colind.size();
446 m_blocks.resize(m_r);
448 std::ifstream infile(a_filename.
c_str());
450 for(
unsigned int i = 0; i < a_M; i++)
453 for(
unsigned int ii = 0; ii < 3; ii++)
456 for(
unsigned int j = 0; j < a_N; j++)
458 for(
unsigned int jj = 0; jj < 3; jj++)
462 infile >> m_blocks[k](ii,jj);
478 template <
typename T>
479 inline void FullBCRS<T>::write(CRS<T> &aCRS)
const 481 unsigned int n = m_rowptr.size() - 1;
483 aCRS.m_values.resize(m_blocks.size() * 9);
484 aCRS.m_colind.resize(m_blocks.size() * 9);
485 aCRS.m_rowptr.resize(n*3 + 1);
488 for(
unsigned int i = 0; i < n; i++)
490 aCRS.m_rowptr[i] = ii;
491 for(
unsigned int r = 0; r < 3; r++)
493 unsigned int m = i*3 + r;
494 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
496 unsigned int c = m_colind[k];
497 aCRS.m_colind[ii + 0] = c*3 + 0;
498 aCRS.m_colind[ii + 1] = c*3 + 1;
499 aCRS.m_colind[ii + 2] = c*3 + 2;
501 aCRS.m_values[ii + 0] = m_blocks[k](r, 0);
502 aCRS.m_values[ii + 1] = m_blocks[k](r, 1);
503 aCRS.m_values[ii + 2] = m_blocks[k](r, 2);
509 aCRS.m_rowptr[n] = ii;
510 assert(ii == aCRS.m_values.size());
514 for(
unsigned int i = 0; i < n; i++)
516 for(
unsigned int r = 0; r < 3; r++)
519 for(
unsigned int k = m_rowptr[i]; k < m_rowptr[i+1]; k++)
521 unsigned int c = m_colind[k];
525 fe_fprintf(fp, FMT, 0.0, 0.0, 0.0);
528 fe_fprintf(fp, FMT, m_blocks[k](r,0), m_blocks[k](r,1), m_blocks[k](r,2));
533 fe_fprintf(fp, FMT, 0.0, 0.0, 0.0);
535 fe_fprintf(fp,
"\n");
542 template <
typename T>
543 inline void FullBCRS<T>::read(
const CRS<T> &aCRS)
548 template <
typename T>
549 inline void FullBCRS<T>::scale(t_real a_scale)
551 unsigned int n = m_blocks.size();
552 for(
unsigned int i = 0; i < n; i++)
554 m_blocks[i] *= a_scale;
558 template <
typename T>
559 inline void UpperTriangularBCRS<T>::multiply(std::vector<t_v3> &a_b,
const std::vector<t_v3> &a_x)
const 561 unsigned int n = FullBCRS<T>::m_rowptr.size() - 1;
562 for(
unsigned int i = 0; i < n; i++)
564 a_b[i] = FullBCRS<T>::m_zeroVector;
566 for(
unsigned int i = 0; i < n; i++)
568 unsigned int k = FullBCRS<T>::m_rowptr[i];
569 a_b[i] += fe::multiply(FullBCRS<T>::m_blocks[k], a_x[i]);
570 for(k=k+1; k < FullBCRS<T>::m_rowptr[i+1]; k++)
572 a_b[i] += fe::multiply(FullBCRS<T>::m_blocks[k], a_x[FullBCRS<T>::m_colind[k]]);
573 a_b[FullBCRS<T>::m_colind[k]] += fe::transposeMultiply(FullBCRS<T>::m_blocks[k], a_x[i]);
578 template <
typename T>
587 template <
typename T>
588 inline void FullBCRS<T>::sparse(
const sp<FullBCRS> &a_other)
596 unsigned int n = a_other->m_rowptr.size()-1;
597 for(
unsigned int i = 0; i < n; i++)
600 int d = a_other->m_rowptr[i];
601 for(
int k=d; k < a_other->m_rowptr[i+1]; k++)
603 int c = a_other->m_colind[k];
604 if(!(zero == a_other->m_blocks[k]))
606 insert(c, a_other->m_blocks[k]);
613 template <
typename T>
616 unsigned int n = a_other->m_rowptr.size()-1;
617 for(
unsigned int i = 0; i < n; i++)
619 int d = a_other->m_rowptr[i];
620 int d_self = m_rowptr[i];
621 for(
int k=d; k < a_other->m_rowptr[i+1]; k++)
623 int c = a_other->m_colind[k];
624 for(
int k_self=d_self; k_self < m_rowptr[i+1]; k_self++)
626 int c_self = m_colind[k_self];
629 m_blocks[k_self] = a_other->m_blocks[k];
636 template <
typename T>
637 inline void UpperTriangularBCRS<T>::backSub(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b)
643 unsigned int n = FullBCRS<T>::m_rowptr.size()-1;
645 fe::backSub(FullBCRS<T>::m_blocks[FullBCRS<T>::m_rowptr[n-1]], a_x[n-1], a_b[n-1]);
648 for(
int i = n-2; i >= 0; i--)
652 int d = FullBCRS<T>::m_rowptr[i];
653 for(
unsigned int k=d+1; k < FullBCRS<T>::m_rowptr[i+1]; k++)
655 int c = FullBCRS<T>::m_colind[k];
656 fe::multiply(tmp, FullBCRS<T>::m_blocks[k], a_x[c]);
659 if(! (zero == m_blocks[k]))
661 fe_fprintf(stderr,
"bs c %d -- %d <- T %d\n", c, i, k);
662 fprint(stderr, m_blocks[k]);
663 fe_fprintf(stderr,
"\n");
668 fe::backSub(FullBCRS<T>::m_blocks[d], a_x[i], a_x[i]);
675 template <
typename T>
676 inline void UpperTriangularBCRS<T>::transposeForeSub(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b)
680 unsigned int n = FullBCRS<T>::m_rowptr.size()-1;
681 std::vector<unsigned int> ptr = FullBCRS<T>::m_rowptr;
682 fe::transposeForeSub(FullBCRS<T>::m_blocks[FullBCRS<T>::m_rowptr[0]], a_x[0], a_b[0]);
685 for(
unsigned int i = 1; i < n; i++)
689 for(
unsigned int m = 0; m < i; m++)
691 unsigned int c = FullBCRS<T>::m_colind[ptr[m]];
692 while(c < i && ptr[m] < FullBCRS<T>::m_rowptr[m+1]-1)
695 c = FullBCRS<T>::m_colind[ptr[m]];
707 a_x[i] -= fe::transposeMultiply(FullBCRS<T>::m_blocks[ptr[m]], a_x[m]);
711 fe::transposeForeSub(FullBCRS<T>::m_blocks[FullBCRS<T>::m_rowptr[i]], a_x[i], a_x[i]);
717 template <
typename T>
718 inline void UpperTriangularBCRS<T>::backSolve(std::vector<t_v3> &a_x,
const std::vector<t_v3> &a_b)
720 std::vector<t_v3> y(a_x.size());
722 transposeForeSub(y, a_b);
727 inline bool nanCheck(
const t_matrix &aM,
const char *aMsg)
729 for(
unsigned int i = 0; i < 3; i++)
731 for(
unsigned int j = 0; j < 3; j++)
735 fe_fprintf(stderr,
"M: %s\n", aMsg);
744 inline bool nanCheck(
const t_v3 &aV,
const char *aMsg)
746 for(
unsigned int i = 0; i < 3; i++)
750 fe_fprintf(stderr,
"V: %s\n", aMsg);
759 template <
typename T>
760 inline void UpperTriangularBCRS<T>::incompleteSqrt(
void)
763 unsigned int n = FullBCRS<T>::m_rowptr.size()-1;
765 for(
unsigned int k = 0; k < n-1; k++)
767 d = FullBCRS<T>::m_rowptr[k];
769 just_upper(FullBCRS<T>::m_blocks[d]);
774 squareroot(FullBCRS<T>::m_blocks[d], FullBCRS<T>::m_blocks[d]);
776 z = FullBCRS<T>::m_blocks[d];
794 fe::multiply(x, inv_tz, sv);
797 fe::multiply(x_sv, tz, x);
803 fe::multiply(re_tz, transpose(z), z);
806 fe::transposeForeSub(z, y, sv);
807 fe::backSub(z, x, y);
810 fe::multiply(x_sv, tz, x);
815 for(
unsigned int i=d+1; i < FullBCRS<T>::m_rowptr[k+1]; i++)
824 fe::multiply(z, FullBCRS<T>::m_blocks[i], inv_z);
832 FullBCRS<T>::m_blocks[i] = z;
835 for(
unsigned int i=d+1; i < FullBCRS<T>::m_rowptr[k+1]; i++)
838 z = transpose(FullBCRS<T>::m_blocks[i]);
840 unsigned int h = FullBCRS<T>::m_colind[i];
843 for(
unsigned int j = FullBCRS<T>::m_rowptr[h]; j < FullBCRS<T>::m_rowptr[h+1]; j++)
846 for(; g < FullBCRS<T>::m_rowptr[k+1] && FullBCRS<T>::m_colind[g] <= FullBCRS<T>::m_colind[j]; g++)
849 if (FullBCRS<T>::m_colind[g] == FullBCRS<T>::m_colind[j])
854 fe::multiply(t, z, FullBCRS<T>::m_blocks[g]);
859 subtract(FullBCRS<T>::m_blocks[j], FullBCRS<T>::m_blocks[j], t);
866 d = FullBCRS<T>::m_rowptr[n-1];
869 just_upper(FullBCRS<T>::m_blocks[d]);
876 FullBCRS<T>::m_blocks[d] = tmp;
881 inline FullVMR::FullVMR(
void)
885 inline FullVMR::~FullVMR(
void)
889 inline void UpperTriangularVMR::multiply(std::vector<t_v3> &a_b,
const std::vector<t_v3> &a_x)
const 891 unsigned int n = a_b.size();
892 for(
unsigned int i = 0; i < n; i++)
899 for(
unsigned int i = 0; i < n; i++)
901 t_row::const_iterator i_row = m_rows[i].begin();
904 assert((*i_row).first == r);
905 a_b[r] += fe::multiply(block, a_x[r]);
908 for(;i_row != m_rows[i].end(); i_row++)
913 a_b[r] += fe::multiply(block, a_x[c]);
914 a_b[c] += fe::transposeMultiply(block, a_x[r]);
919 inline void FullVMR::multiply(std::vector<t_v3> &a_b,
const std::vector<t_v3> &a_x)
const 922 unsigned int n = m_rows.size();
923 for(
unsigned int i = 0; i < n; i++)
927 for(t_row::const_iterator i_row = m_rows[i].begin();
928 i_row != m_rows[i].end(); i_row++)
932 a_b[r] += fe::multiply(block, a_x[c]);
937 inline void FullVMR::zero(
void)
939 unsigned int n = m_rows.size();
940 for(
unsigned int i = 0; i < n; i++)
942 for(t_row::iterator i_row = m_rows[i].begin();
943 i_row != m_rows[i].end(); i_row++)
951 inline void FullVMR::scale(t_real a_scale)
953 unsigned int n = m_rows.size();
954 for(
unsigned int i = 0; i < n; i++)
956 for(t_row::iterator i_row = m_rows[i].begin();
957 i_row != m_rows[i].end(); i_row++)
960 fe::multiply(block, a_scale);
965 inline void FullVMR::clear(
void)
970 inline void FullVMR::setRows(
unsigned int a_count)
972 m_rows.resize(a_count);
975 inline unsigned int FullVMR::rows(
void)
977 return m_rows.size();
980 inline UpperTriangularVMR::t_row &FullVMR::row(
unsigned int a_index)
982 return m_rows[a_index];
985 inline SpatialMatrix &FullVMR::block(
unsigned int a_i,
unsigned int a_j)
988 t_row::iterator i_row = m_rows[a_i].find(a_j);
989 if(i_row != m_rows[a_i].end())
991 return i_row->second;
Vector Map Rows (vector of row maps)
Definition: SparseMatrix3x3.h:31
const FESTRING_I8 * c_str(void) const
Return the contents of the 8-bit buffer cast as signed bytes.
Definition: String.h:352
kernel
Definition: namespace.dox:3
Matrix< 4, 4, T > & invert(Matrix< 4, 4, T > &a_inverted, const Matrix< 4, 4, T > &a_matrix)
4x4 full matrix inversion
Definition: Matrix.h:1033
Upper Triangular Vector Map Rows (vector of row maps)
Definition: SparseMatrix3x3.h:57
Automatically reference-counted string container.
Definition: String.h:128
void project(Vector< 4, T > &a_r, const Matrix< 4, 4, T > &a_m, const Vector< 4, T > &a_v)
project vector through matrix. divides by transformed w
Definition: Matrix.h:1182
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
void squareroot(Matrix< M, N, T > &a_U, const Matrix< M, N, T > &a_A)
Square root of a matrix.
Definition: Matrix.h:567