OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
dyncompcol.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 // inspired by SL++
36 
37 #include "dyncompcol.h"
38 #include "floatarray.h"
39 #include "engngm.h"
40 #include "domain.h"
41 #include "mathfem.h"
42 #include "element.h"
43 #include "sparsemtrxtype.h"
44 #include "activebc.h"
45 #include "classfactory.h"
46 
47 namespace oofem {
49 
51 {
52 #ifndef DynCompCol_USE_STL_SETS
53  columns_ = NULL;
54  rowind_ = NULL;
55 #else
56  columns = NULL;
57 #endif
58 }
59 
60 
62 {
63 #ifndef DynCompCol_USE_STL_SETS
64  columns_ = NULL;
65  rowind_ = NULL;
66 #else
67  columns = NULL;
68 #endif
69 
70  nRows = nColumns = n;
71 }
72 
73 
74 /*****************************/
75 /* Copy constructor */
76 /*****************************/
77 
79 {
80 #ifndef DynCompCol_USE_STL_SETS
81  int i;
82  if ( S.columns_ ) {
83  this->columns_ = new FloatArray * [ S.nColumns ];
84  for ( i = 0; i < S.nColumns; i++ ) {
85  this->columns_ [ i ] = new FloatArray(*S.columns_ [ i ]);
86  }
87  } else {
88  this->columns_ = NULL;
89  }
90 
91  if ( S.rowind_ ) {
92  this->rowind_ = new IntArray * [ S.nColumns ];
93  for ( i = 0; i < S.nColumns; i++ ) {
94  this->rowind_ [ i ] = new IntArray(*S.rowind_ [ i ]);
95  }
96  } else {
97  this->rowind_ = NULL;
98  }
99 
100 #else
101  int i;
102  if ( S.columns ) {
103  this->columns = new std :: map< int, double > * [ S.nColumns ];
104  for ( i = 0; i < S.nColumns; i++ ) {
105  this->columns [ i ] = new std :: map< int, double >(*S.columns [ i ]);
106  }
107  } else {
108  this->columns = NULL;
109  }
110 
111 #endif
112 
113  this->nRows = S.nRows;
114  this->nColumns = S.nColumns;
115  this->version = S.version;
116 }
117 
118 
119 // Destructor
121 {
122 #ifndef DynCompCol_USE_STL_SETS
123  int i;
124 
125  if ( this->columns_ ) {
126  for ( i = 0; i < nColumns; i++ ) {
127  delete this->columns_ [ i ];
128  }
129 
130  delete this->columns_;
131  }
132 
133  if ( this->rowind_ ) {
134  for ( i = 0; i < nColumns; i++ ) {
135  delete this->rowind_ [ i ];
136  }
137 
138  delete this->rowind_;
139  }
140 
141 #else
142  int i;
143 
144  if ( this->columns ) {
145  for ( i = 0; i < nColumns; i++ ) {
146  delete this->columns [ i ];
147  }
148 
149  delete this->columns;
150  }
151 
152 #endif
153 }
154 
155 
156 
157 /***************************/
158 /* Assignment operator... */
159 /***************************/
160 
162 {
163  base_ = C.base_;
164 
165 #ifndef DynCompCol_USE_STL_SETS
166  int i;
167 
168  if ( this->columns_ ) {
169  for ( i = 0; i < nColumns; i++ ) {
170  delete this->columns_ [ i ];
171  }
172 
173  delete this->columns_;
174  }
175 
176  if ( C.columns_ ) {
177  this->columns_ = new FloatArray * [ C.nColumns ];
178  for ( i = 0; i < C.nColumns; i++ ) {
179  this->columns_ [ i ] = new FloatArray(*C.columns_ [ i ]);
180  }
181  } else {
182  this->columns_ = NULL;
183  }
184 
185 
186  if ( this->rowind_ ) {
187  for ( i = 0; i < nColumns; i++ ) {
188  delete this->rowind_ [ i ];
189  }
190 
191  delete this->rowind_;
192  }
193 
194  if ( C.rowind_ ) {
195  this->rowind_ = new IntArray * [ C.nColumns ];
196  for ( i = 0; i < C.nColumns; i++ ) {
197  this->rowind_ [ i ] = new IntArray(*C.rowind_ [ i ]);
198  }
199  } else {
200  this->rowind_ = NULL;
201  }
202 
203 #else
204  int i;
205 
206  if ( this->columns ) {
207  for ( i = 0; i < nColumns; i++ ) {
208  this->columns [ i ] = C.columns [ i ];
209  }
210  }
211 
212 #endif
213 
214  nRows = C.nRows;
215  nColumns = C.nColumns;
216  version = C.version;
217 
218  return * this;
219 }
220 
222 {
223  DynCompCol *result = new DynCompCol(*this);
224  return result;
225 }
226 
227 void DynCompCol :: times(const FloatArray &x, FloatArray &answer) const
228 {
229  // Check for compatible dimensions:
230  if ( x.giveSize() != nColumns ) {
231  OOFEM_ERROR("incompatible dimensions");
232  }
233 
234  answer.resize(nRows);
235  answer.zero();
236 
237 #ifndef DynCompCol_USE_STL_SETS
238  int j, t;
239  double rhs;
240 
241  for ( j = 0; j < nColumns; j++ ) {
242  rhs = x(j);
243  for ( t = 1; t <= columns_ [ j ]->giveSize(); t++ ) {
244  answer( rowind_ [ j ]->at(t) ) += columns_ [ j ]->at(t) * rhs;
245  }
246  }
247 
248 #else
249  double rhs;
250 
251  for ( int j = 0; j < nColumns; j++ ) {
252  rhs = x(j);
253  for ( auto &val: columns [ j ] ) {
254  answer(val.first) += val.second * rhs;
255  }
256  }
257 
258 #endif
259 }
260 
261 void DynCompCol :: times(double x)
262 {
263 #ifndef DynCompCol_USE_STL_SETS
264  for ( int j = 0; j < nColumns; j++ ) {
265  columns_ [ j ]->times(x);
266  }
267 
268 #else
269  for ( int j = 0; j < nColumns; j++ ) {
270  for ( auto &val: columns [ j ] ) {
271  val.second *= x;
272  }
273  }
274 
275 #endif
276 
277  // increment version
278  this->version++;
279 }
280 
282 {
283  int neq = eModel->giveNumberOfDomainEquations(di, s);
284 
285 #ifndef DynCompCol_USE_STL_SETS
286  IntArray loc;
287  Domain *domain = eModel->giveDomain(di);
288 
289  nColumns = nRows = neq;
290 
291  if ( rowind_ ) {
292  for ( int i = 0; i < nColumns; i++ ) {
293  delete this->rowind_ [ i ];
294  }
295 
296  delete this->rowind_;
297  }
298 
299  rowind_ = ( IntArray ** ) new IntArray * [ neq ];
300  for ( int j = 0; j < neq; j++ ) {
301  rowind_ [ j ] = new IntArray();
302  }
303 
304  // allocate value array
305  if ( columns_ ) {
306  for ( int i = 0; i < nColumns; i++ ) {
307  delete this->columns_ [ i ];
308  }
309 
310  delete this->columns_;
311  }
312 
313  columns_ = ( FloatArray ** ) new FloatArray * [ neq ];
314  for ( int j = 0; j < neq; j++ ) {
315  columns_ [ j ] = new FloatArray();
316  }
317 
318  for ( auto &elem : domain->giveElements() ) {
319  elem->giveLocationArray(loc, s);
320 
321  for ( int ii : loc ) {
322  if ( ii > 0 ) {
323  for ( int jj : loc ) {
324  if ( jj > 0 ) {
325  this->insertRowInColumn(ii - 1, jj - 1);
326  }
327  }
328  }
329  }
330  }
331 
332  // loop over active boundary conditions
333  std :: vector< IntArray >r_locs;
334  std :: vector< IntArray >c_locs;
335 
336  for ( auto &gbc : domain->giveBcs() ) {
337  ActiveBoundaryCondition *bc = dynamic_cast< ActiveBoundaryCondition * >( gbc.get() );
338  if ( bc != NULL ) {
339  bc->giveLocationArrays(r_locs, c_locs, UnknownCharType, s, s);
340  for ( std :: size_t k = 0; k < r_locs.size(); k++ ) {
341  IntArray &krloc = r_locs [ k ];
342  IntArray &kcloc = c_locs [ k ];
343  for ( int ii : krloc ) {
344  if ( ii > 0 ) {
345  for ( int jj : kcloc ) {
346  if ( jj > 0 ) {
347  this->insertRowInColumn(jj - 1, ii - 1);
348  }
349  }
350  }
351  }
352  }
353  }
354  }
355 
356  int nz_ = 0;
357  for ( int j = 0; j < neq; j++ ) {
358  nz_ += this->rowind_ [ j ]->giveSize();
359  }
360 
361  OOFEM_LOG_DEBUG("DynCompCol info: neq is %d, nelem is %d\n", neq, nz_);
362 #else
363  nColumns = nRows = neq;
364 
365  columns.resize( neq );
366  for ( auto &col: columns ) {
367  col.clear();
368  }
369 
370 #endif
371 
372  // increment version
373  this->version++;
374 
375  return true;
376 }
377 
378 
379 int DynCompCol :: assemble(const IntArray &loc, const FloatMatrix &mat)
380 {
381  int i, j, ii, jj, dim;
382 
383 # ifdef DEBUG
384  dim = mat.giveNumberOfRows();
385  if ( dim != loc.giveSize() ) {
386  OOFEM_ERROR("dimension of 'k' and 'loc' mismatch");
387  }
388 
389 # endif
390 
391  dim = mat.giveNumberOfRows();
392 
393  for ( j = 1; j <= dim; j++ ) {
394  jj = loc.at(j);
395  if ( jj ) {
396  for ( i = 1; i <= dim; i++ ) {
397  ii = loc.at(i);
398  if ( ii ) {
399  this->at(ii, jj) += mat.at(i, j);
400  }
401  }
402  }
403  }
404 
405  // increment version
406  this->version++;
407 
408  return 1;
409 }
410 
411 int DynCompCol :: assemble(const IntArray &rloc, const IntArray &cloc, const FloatMatrix &mat)
412 {
413 #ifndef DynCompCol_USE_STL_SETS
414  /*
415  * /// slow and safe
416  * int i,j,ii,jj,dim1,dim2 ;
417  *
418  * this->checkSizeTowards(rloc, cloc);
419  *
420  * dim1 = mat.giveNumberOfRows() ;
421  * dim2 = mat.giveNumberOfColumns() ;
422  * for (i=1 ; i<= dim1; i++) {
423  * ii = rloc.at(i);
424  * if (ii) for (j=1 ; j<= dim2; j++) {
425  * jj = cloc.at(j);
426  * if (jj) this->at(ii,jj) += mat.at(i,j);
427  * }
428  * }
429  * return 1;
430  */
431 
433  IntArray rowsToAdd( rloc.giveSize() );
434  int i, ii, ii1, j, jj, jj1, rowindx;
435  int rsize = rloc.giveSize();
436  int csize = cloc.giveSize();
437 
438  /*
439  * // adjust the size of receiver
440  * int maxid=0;
441  * for (i=0; i<rsize; i++) maxid = max(maxid, rloc(i));
442  * for (i=0; i<csize; i++) maxid = max(maxid, cloc(i));
443  * this->growTo (maxid);
444  */
445 
446  for ( i = 0; i < csize; i++ ) {
447  if ( ( ii = cloc(i) ) ) {
448  ii1 = ii - 1;
449  for ( j = 0; j < rsize; j++ ) {
450  if ( ( jj = rloc(j) ) ) {
451  jj1 = jj - 1;
452 
453  /*
454  * rowindx = 0;
455  * for (int t=columns_[ii1]->giveSize(); t > 0; t--)
456  * if (rowind_[ii1]->at(t) == (jj1)) {rowindx = t; break;}
457  */
458 
459  // rowindx = this->giveRowIndx (ii1, jj1);
460  // if (rowindx == 0) {
461  /*
462  * int oldsize = rowind_[ii1]->giveSize();
463  * rowind_[ii1]->resizeWithValues(oldsize+1, DynCompCol_CHUNK);
464  * columns_[ii1]->resizeWithValues(oldsize+1, DynCompCol_CHUNK);
465  * rowindx = oldsize+1;
466  * rowind_[ii1]->at(oldsize+1) = jj1;
467  */
468  // rowindx = this->insertRowInColumn (ii1, jj1);
469  // }
470 
471  rowindx = this->insertRowInColumn(ii1, jj1);
472  //if (rowind_[j-1]->at(t) == (i-1)) return columns_[j-1]->at(t);
473  columns_ [ ii1 ]->at(rowindx) += mat(j, i);
474  }
475  }
476  }
477  }
478 
479 #else
480  int i, ii, ii1, j, jj, jj1;
481  int rsize = rloc.giveSize();
482  int csize = cloc.giveSize();
483 
484  for ( i = 0; i < csize; i++ ) {
485  if ( ( ii = cloc(i) ) ) {
486  ii1 = ii - 1;
487  for ( j = 0; j < rsize; j++ ) {
488  if ( ( jj = rloc(j) ) ) {
489  jj1 = jj - 1;
490  this->columns [ ii1 ] [ jj1 ] += mat(j, i);
491  }
492  }
493  }
494  }
495 
496 #endif
497  // increment version
498  this->version++;
499 
500  return 1;
501 }
502 
504 {
505 #ifndef DynCompCol_USE_STL_SETS
506  for ( int j = 0; j < nColumns; j++ ) {
507  columns_ [ j ]->zero();
508  }
509 
510 #else
511  for ( auto &col: columns ) {
512  for ( auto &val: col ) {
513  val.second = 0.;
514  }
515  }
516 
517 #endif
518  // increment version
519  this->version++;
520 }
521 
523 {
524  int j, nz_ = 0;
525 #ifndef DynCompCol_USE_STL_SETS
526  for ( j = 0; j < nColumns; j++ ) {
527  nz_ += rowind_ [ j ]->giveSize();
528  }
529 
530 #else
531  for ( j = 0; j < nColumns; j++ ) {
532  nz_ += columns [ j ].size();
533 #endif
534  OOFEM_LOG_DEBUG("DynCompCol info: neq is %d, nelem is %d\n", nColumns, nz_);
535 }
536 
537 
538 /*********************/
539 /* Array access */
540 /*********************/
541 
542 double &DynCompCol :: at(int i, int j)
543 {
544  // increment version
545  this->version++;
546 #ifndef DynCompCol_USE_STL_SETS
547  /*
548  * for (int t=1; t<=columns_[j-1]->giveSize(); t++)
549  * if (rowind_[j-1]->at(t) == (i-1)) return columns_[j-1]->at(t);
550  * printf ("DynCompCol::operator(): Array accessing exception -- out of bounds.\n");
551  * exit(1);
552  * return columns_[0]->at(1); // return to suppress compiler warning message
553  */
554  int rowIndx;
555  if ( ( rowIndx = this->giveRowIndx(j - 1, i - 1) ) ) {
556  return columns_ [ j - 1 ]->at(rowIndx);
557  }
558 
559  OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
560  return columns_ [ 0 ]->at(1); // return to suppress compiler warning message
561 
562 #else
563  return this->columns [ j - 1 ] [ i - 1 ];
564 
565 #endif
566 }
567 
568 
569 double DynCompCol :: at(int i, int j) const
570 {
571 #ifndef DynCompCol_USE_STL_SETS
572  /*
573  * for (int t=1; t<=columns_[j-1]->giveSize(); t++)
574  * if (rowind_[j-1]->at(t) == (i-1)) return columns_[j-1]->at(t);
575  * if (i <= nRows && j <= nColumns) return 0.0;
576  * else
577  * {
578  * printf ("DynCompCol::operator(): Array accessing exception -- out of bounds.\n");
579  * exit(1);
580  * return (0); // return to suppress compiler warning message
581  * }
582  */
583  int rowIndx;
584  if ( ( rowIndx = this->giveRowIndx(j - 1, i - 1) ) ) {
585  return columns_ [ j - 1 ]->at(rowIndx);
586  }
587 
588  if ( i <= nRows && j <= nColumns ) {
589  return 0.0;
590  } else {
591  OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
592  return columns_ [ 0 ]->at(1); // return to suppress compiler warning message
593  }
594 
595 #else
596  auto pos = this->columns [ j - 1 ].find(i - 1);
597  if ( pos != this->columns [ j - 1 ].end() ) {
598  return pos->second;
599  } else {
600  OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
601  return 0.0;
602  }
603 
604 #endif
605 }
606 
607 double DynCompCol :: operator() (int i, int j) const
608 {
609 #ifndef DynCompCol_USE_STL_SETS
610  /*
611  * for (int t=1; t<=columns_[j]->giveSize(); t++)
612  * if (rowind_[j]->at(t) == i) return columns_[j]->at(t);
613  * if (i < nRows && j < nColumns) return 0.0;
614  * else
615  * {
616  * printf ("DynCompCol::operator(): Array accessing exception -- out of bounds.\n");
617  * exit(1);
618  * return (0); // return to suppress compiler warning message
619  * }
620  */
621  int rowIndx;
622  if ( ( rowIndx = this->giveRowIndx(j, i) ) ) {
623  return columns_ [ j ]->at(rowIndx);
624  }
625 
626  if ( i < nRows && j < nColumns ) {
627  return 0.0;
628  } else {
629  OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
630  return columns_ [ 0 ]->at(1); // return to suppress compiler warning message
631  }
632 
633 #else
634  auto pos = this->columns [ j ].find(i);
635  if ( pos != this->columns [ j ].end() ) {
636  return pos->second;
637  } else {
638  OOFEM_ERROR("Array accessing exception -- (%d,%d) out of bounds", i, j);
639  return 0.0;
640  }
641 
642 #endif
643 }
644 
645 double &DynCompCol :: operator() (int i, int j)
646 {
647  // increment version
648  this->version++;
649 #ifndef DynCompCol_USE_STL_SETS
650  /*
651  * for (int t=1; t<=columns_[j]->giveSize(); t++)
652  * if (rowind_[j]->at(t) == i) return columns_[j]->at(t);
653  *
654  * printf ("DynCompCol::set: Array element (%d,%d) not in sparse structure -- cannot assign.\n",i,j);
655  * exit(1);
656  * return columns_[j]->at(1); // return to suppress compiler warning message
657  */
658 
659  int rowIndx;
660  if ( ( rowIndx = this->giveRowIndx(j, i) ) ) {
661  return columns_ [ j ]->at(rowIndx);
662  }
663 
664  OOFEM_ERROR("Array element (%d,%d) not in sparse structure -- cannot assign", i, j);
665  return columns_ [ 0 ]->at(1); // return to suppress compiler warning message
666 
667 #else
668  return this->columns [ j ] [ i ];
669 
670 #endif
671 }
672 
673 
674 void DynCompCol :: timesT(const FloatArray &x, FloatArray &answer) const
675 {
676  // Check for compatible dimensions:
677  if ( x.giveSize() != nRows ) {
678  OOFEM_ERROR("Error in CompCol -- incompatible dimensions");
679  }
680  answer.resize(nColumns);
681  answer.zero();
682 
683 #ifndef DynCompCol_USE_STL_SETS
684  int i, t;
685  double r;
686 
687  for ( i = 0; i < nColumns; i++ ) {
688  r = 0.0;
689  for ( t = 1; t <= columns_ [ i ]->giveSize(); t++ ) {
690  r += columns_ [ i ]->at(t) * x( rowind_ [ i ]->at(t) );
691  }
692 
693  answer(i) = r;
694  }
695 
696 #else
697  double r;
698  for ( int i = 0; i < nColumns; i++ ) {
699  double r = 0.0;
700  for ( auto &val: columns [ i ] ) {
701  r += val.second * x(val.first);
702  }
703 
704  answer(i) = r;
705  }
706 
707 #endif
708 }
709 
710 
711 
713 {
714  int i, maxid = 0;
715  int size = loc.giveSize();
716  // adjust the size of receiver
717  for ( i = 0; i < size; i++ ) {
718  maxid = max( maxid, loc(i) );
719  }
720 
721  this->growTo(maxid);
722 
723 #ifndef DynCompCol_USE_STL_SETS
724  int ii, j, jj;
725 
726  for ( i = 0; i < size; i++ ) {
727  if ( ( ii = loc(i) ) ) {
728  for ( j = 0; j < size; j++ ) {
729  if ( ( jj = loc(j) ) ) {
730  this->insertRowInColumn(ii - 1, jj - 1);
731  }
732  }
733  }
734  }
735 
736 #endif
737 }
738 
739 
740 void DynCompCol :: checkSizeTowards(const IntArray &rloc, const IntArray &cloc)
741 {
742  int i, maxid = 0;
743  int rsize = rloc.giveSize();
744  int csize = cloc.giveSize();
745 
746  // adjust the size of receiver
747  for ( i = 0; i < rsize; i++ ) {
748  maxid = max( maxid, rloc(i) );
749  }
750 
751  for ( i = 0; i < csize; i++ ) {
752  maxid = max( maxid, cloc(i) );
753  }
754 
755  this->growTo(maxid);
756 
757 #ifndef DynCompCol_USE_STL_SETS
758  IntArray rowsToAdd( rloc.giveSize() );
759  int ii, j, jj;
760 
761  for ( i = 0; i < csize; i++ ) {
762  if ( ( ii = cloc(i) ) ) {
763  for ( j = 0; j < rsize; j++ ) {
764  if ( ( jj = rloc(j) ) ) {
765  insertRowInColumn(ii - 1, jj - 1);
766  }
767  }
768  }
769  }
770 
771 #endif
772 }
773 
774 
775 
777 {
778  if ( ns > nColumns ) {
779 #ifndef DynCompCol_USE_STL_SETS
780  FloatArray **newcolumns_ = new FloatArray * [ ns ];
781  IntArray **newrowind_ = new IntArray * [ ns ];
782 
783  // copy existing columns
784  for ( int i = 0; i < nColumns; i++ ) {
785  newcolumns_ [ i ] = columns_ [ i ];
786  newrowind_ [ i ] = rowind_ [ i ];
787  }
788 
789  delete columns_;
790  delete rowind_;
791 
792  columns_ = newcolumns_;
793  rowind_ = newrowind_;
794 #else
795  columns.resize(ns);
796 #endif
797 
798  nColumns = nRows = ns;
799  }
800 }
801 
802 
803 #ifndef DynCompCol_USE_STL_SETS
804 int DynCompCol :: giveRowIndx(int col, int row) const
805 {
806  // fast row indx search, based on assumption, that row indices are sorted
807  int left = 1, right = this->rowind_ [ col ]->giveSize();
808  int middle = ( left + right ) / 2;
809  int middleVal;
810 
811  if ( right == 0 ) {
812  return 0;
813  }
814 
815  if ( this->rowind_ [ col ]->at(right) == row ) {
816  return right;
817  }
818 
819  while ( !( ( ( middleVal = this->rowind_ [ col ]->at(middle) ) == row ) || ( middle == left ) ) ) {
820  if ( row > middleVal ) {
821  left = middle;
822  } else {
823  right = middle;
824  }
825 
826  middle = ( left + right ) / 2;
827  }
828 
829  if ( middleVal == row ) {
830  return middle;
831  }
832 
833  return 0;
834 }
835 
836 
837 
838 int
840 {
841  // insert row into column, preserving order of row indexes.
842  int i, oldsize = this->rowind_ [ col ]->giveSize();
843  int left = 1, right = oldsize;
844  int middle = ( left + right ) / 2;
845  int middleVal;
846 
847  if ( oldsize == 0 ) {
850  columns_ [ col ]->at(1) = 0.0;
851  rowind_ [ col ]->at(1) = row;
852  return 1;
853  }
854 
855  if ( this->rowind_ [ col ]->at(right) == row ) {
856  return right;
857  }
858 
859  while ( !( ( ( middleVal = this->rowind_ [ col ]->at(middle) ) == row ) || ( middle == left ) ) ) {
860  if ( row > middleVal ) {
861  left = middle;
862  } else {
863  right = middle;
864  }
865 
866  middle = ( left + right ) / 2;
867  }
868 
869  if ( middleVal == row ) {
870  return middle;
871  }
872 
873  // we have to insert new row entry
874  if ( row > this->rowind_ [ col ]->at(oldsize) ) {
875  right = oldsize + 1;
876  } else if ( row < this->rowind_ [ col ]->at(1) ) {
877  right = 1;
878  }
879 
880  // insert row at middle+1 position
881  rowind_ [ col ]->resizeWithValues(oldsize + 1, DynCompCol_CHUNK);
882  columns_ [ col ]->resizeWithValues(oldsize + 1, DynCompCol_CHUNK);
883 
884  for ( i = oldsize; i >= right; i-- ) {
885  rowind_ [ col ]->at(i + 1) = rowind_ [ col ]->at(i);
886  columns_ [ col ]->at(i + 1) = columns_ [ col ]->at(i);
887  }
888 
889  columns_ [ col ]->at(right) = 0.0;
890  rowind_ [ col ]->at(right) = row;
891  return right;
892 }
893 
894 #endif
895 } // end namespace oofem
int nColumns
Number of columns.
Definition: sparsemtrx.h:69
Class and object Domain.
Definition: domain.h:115
virtual int giveNumberOfDomainEquations(int di, const UnknownNumberingScheme &num)
Returns number of equations for given domain in active (current time step) time step.
Definition: engngm.C:391
Dynamically growing compressed column.
Base class for all matrices stored in sparse format.
Definition: sparsemtrx.h:60
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
int max(int i, int j)
Returns bigger value form two given decimals.
Definition: mathfem.h:71
double operator()(int i, int j) const
Implements 0-based access.
Definition: dyncompcol.C:607
void checkSizeTowards(IntArray &)
Definition: dyncompcol.C:712
SparseMtrx * GiveCopy() const
Returns a newly allocated copy of receiver.
Definition: dyncompcol.C:221
#define S(p)
Definition: mdm.C:481
virtual int assemble(const IntArray &loc, const FloatMatrix &mat)
Assembles sparse matrix from contribution of local elements.
Definition: dyncompcol.C:379
#define OOFEM_LOG_DEBUG(...)
Definition: logger.h:128
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
virtual double & at(int i, int j)
Returns coefficient at position (i,j).
Definition: dyncompcol.C:542
int nRows
Number of rows.
Definition: sparsemtrx.h:67
virtual void timesT(const FloatArray &x, FloatArray &answer) const
Evaluates .
Definition: dyncompcol.C:674
Implementation of sparse matrix stored in compressed column storage.
Definition: dyncompcol.h:62
virtual void printStatistics() const
Prints the receiver statistics (one-line) to stdout.
Definition: dyncompcol.C:522
std::vector< std::unique_ptr< GeneralBoundaryCondition > > & giveBcs()
Definition: domain.h:322
IntArray ** rowind_
Definition: dyncompcol.h:68
#define OOFEM_ERROR(...)
Definition: error.h:61
REGISTER_SparseMtrx(CompCol, SMT_CompCol)
Abstract base class allowing to control the way, how equations are assigned to individual DOFs...
virtual void zero()
Zeroes the receiver.
Definition: dyncompcol.C:503
void resizeWithValues(int n, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: intarray.C:115
int giveRowIndx(int col, int row) const
Returns the row index of given row at given column, else returns zero.
Definition: dyncompcol.C:804
Abstract base class for all active boundary conditions.
Definition: activebc.h:63
void resizeWithValues(int s, int allocChunk=0)
Checks size of receiver towards requested bounds.
Definition: floatarray.C:615
virtual ~DynCompCol()
Destructor.
Definition: dyncompcol.C:120
double at(int i, int j) const
Coefficient access function.
Definition: floatmatrix.h:176
void resize(int n)
Checks size of receiver towards requested bounds.
Definition: intarray.C:124
FloatArray ** columns_
Definition: dyncompcol.h:67
DynCompCol & operator=(const DynCompCol &C)
Assignment operator.
Definition: dyncompcol.C:161
#define DynCompCol_CHUNK
Definition: dyncompcol.h:50
int insertRowInColumn(int col, int row)
Insert row entry into column, preserving order of row indexes, returns the index of new row...
Definition: dyncompcol.C:839
SparseMtrxVersionType version
Allows to track if receiver changes.
Definition: sparsemtrx.h:80
virtual int buildInternalStructure(EngngModel *, int, const UnknownNumberingScheme &)
Builds internal structure of receiver.
Definition: dyncompcol.C:281
Class representing vector of real numbers.
Definition: floatarray.h:82
Implementation of matrix containing floating point numbers.
Definition: floatmatrix.h:94
void zero()
Zeroes all coefficients of receiver.
Definition: floatarray.C:658
void growTo(int)
Definition: dyncompcol.C:776
void times(double s)
Multiplies receiver with scalar.
Definition: floatarray.C:818
std::vector< std::unique_ptr< Element > > & giveElements()
Definition: domain.h:279
virtual void times(const FloatArray &x, FloatArray &answer) const
Evaluates .
Definition: dyncompcol.C:227
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
Domain * giveDomain(int n)
Service for accessing particular problem domain.
Definition: engngm.C:1720
int giveNumberOfRows() const
Returns number of rows of receiver.
Definition: floatmatrix.h:156
DynCompCol()
Constructor.
Definition: dyncompcol.C:50
virtual void giveLocationArrays(std::vector< IntArray > &rows, std::vector< IntArray > &cols, CharType type, const UnknownNumberingScheme &r_s, const UnknownNumberingScheme &c_s)
Gives a list of location arrays that will be assembled.
Definition: activebc.h:138
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011