NeoPZ
pzblock.cpp
Go to the documentation of this file.
1 
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include "pzerror.h"
9 #include "pzblock.h"
10 #include "TPZStream.h"
11 
12 #include <sstream>
13 #include "pzlog.h"
14 #ifdef LOG4CXX
15 static LoggerPtr logger(Logger::getLogger("pz.matrix.tpzblock"));
16 #endif
17 
18 using namespace std;
19 template<class TVar>
20 REAL TPZBlock<TVar>::gZero = 0;
21 
22 
23 /*************************** Public ***************************/
24 
25 /******************/
26 /*** Construtor ***/
27 template<class TVar>
28 TPZBlock<TVar>::TPZBlock( TPZMatrix<TVar> *const pMatrix,const int nBlocks,const int dim )
29 : TPZRegisterClassId(&TPZBlock::ClassId)
30 {
31  int MaxBlocks = 0;
32  if(pMatrix) MaxBlocks = ( nBlocks ? nBlocks : pMatrix->Rows() );
33  else MaxBlocks = nBlocks;
34 
35  // fBlock = 0;
36  if(MaxBlocks) fBlock.Resize(MaxBlocks);
37  fpMatrix = pMatrix;
38 
39  // sugestao de implementacao:
40  // o construtor adaptaria a dimensao das matrizes da diagonal ao
41  // numero de blocos: por exemplo, 4 blocos em uma matriz M 8x8
42  // ( TPZBlock(&M,4) ) teriam dimensao 2.
43  // PROBLEMA: cria uma variavel interna, dim2
44  int dim2 = dim;
45  int mat_size = 1;
46  if(pMatrix) {
47  // The row dimension of the matrix determines the size of the block object
48  mat_size = pMatrix->Rows();
49  if ( (dim*nBlocks!=mat_size) )
50  dim2 = mat_size/MaxBlocks;
51  }
52  // fim de sugestao
53 
54  int pos = 0;
55  for ( int i = 0; i < fBlock.NElements(); i++, pos += dim2 )
56  {
57  fBlock[i].pos = pos;
58  fBlock[i].dim = dim2;
59  }
60  if(MaxBlocks && dim2) fBlock[MaxBlocks-1].dim = dim2 + mat_size%dim2;
61  else if(MaxBlocks) fBlock[MaxBlocks-1].dim = mat_size-dim2;
62 }
63 
64 template<class TVar>
66 fBlock(bl.fBlock) {
67  fpMatrix = bl.fpMatrix;
68 }
69 
70 /*******************/
71 /*** operator = ***/
72 template<class TVar>
74  if(this == &bl) return *this;
75  fBlock = bl.fBlock;
76  fpMatrix = bl.fpMatrix;
77  return *this;
78 }
79 
80 /******************/
81 /*** Destrutor ***/
82 template<class TVar>
84 }
85 
86 
87 /******************/
88 /*** Set Blocks ***/
89 template<class TVar>
90 int
91 TPZBlock<TVar>::SetNBlocks(const int num_of_blocks )
92 {
93  //modified Philippe 24/7/97
94  // a small optimization
95  int MaxBlocks = fBlock.NAlloc();
96  if(num_of_blocks >= MaxBlocks) fBlock.Expand((int) (num_of_blocks*1.2));
97  TNode copy;
98  fBlock.Resize(num_of_blocks,copy);
99  if(num_of_blocks == MaxBlocks) return 1;
100  return ( 1 );
101 }
102 
103 template<class TVar>
104 int TPZBlock<TVar>::Set(const int b,const int dim,const int pos ) {
105  if ( b >= fBlock.NElements() ) {
106  cout << "TPZBlock::Set called with parameter out of range\n";
107  return( 0 );
108  }
109 
110  fBlock[b].dim = dim;
111  if ( pos >= 0 )
112  fBlock[b].pos = pos;
113  else
114  fBlock[b].pos = (b ? fBlock[b-1].pos + fBlock[b-1].dim : 0);
115 
116  return( 1 );
117 }
118 
119 
120 /**************/
121 /*** SetAll ***/
122 template<class TVar>
123 int
125 {
126  int total_dim=0;
127  int i,nel = dimensions.NElements() ;
128  for(i=0;i<nel;i++) total_dim += dimensions[i];
129  if ( total_dim != fpMatrix->Rows() ||
130  total_dim > fpMatrix->Rows() )
131  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__,"SetAll <new block dimensions not compatible whit matrix dimension>");
132 
133  int pos=0;
134 
135  //SetNumBlocks( nel );
136  SetNBlocks( nel );
137 
138  for(i=0; i<nel;i++ )
139  {
140  fBlock[i].pos=pos;
141  pos=pos+(fBlock[i].dim=dimensions[i]);
142  }
143 
144  return ( 1 );
145 }
146 
147 /*****************/
148 /*** Resequence **/
149 template<class TVar>
150 int TPZBlock<TVar>::Resequence(const int start) {
151  int MaxBlocks = fBlock.NElements();
152  if (start>=MaxBlocks) return 0;
153  for (int i= start+1; i < MaxBlocks; i++)
154  fBlock[i].pos=fBlock[i-1].pos+fBlock[i-1].dim;
155  return ( 1 );
156 }
157 
158 /**************/
159 /*** Remove ***/
160 template<class TVar>
161 int
162 TPZBlock<TVar>::Remove(const int index )
163 {
164  int MaxBlocks = fBlock.NElements();
165  if ( index >= MaxBlocks )
166  return( 0 );
167 
168  fBlock[index].dim = 0; // and the corresponding elements into the fpMatrix???
169  return( 1 );
170 }
171 
172 /***************/
173 /*** Verify ****/
174 template<class TVar>
175 int
177 {
178  int MaxBlocks = fBlock.NElements();
179  for ( int i = 0; i < MaxBlocks-1; i++ )
180  if (fBlock[i].pos + fBlock[i].dim != fBlock[i+1].pos) return ( 0 );
181 
182  if (fBlock[MaxBlocks-1].pos + fBlock[MaxBlocks-1].dim != fpMatrix->Rows())
183  return ( 0 );
184  return ( 1 );
185 }
186 
187 /***********/
188 /*** Get ***/
189 template<class TVar>
190 const TVar &
191 TPZBlock<TVar>::Get(const int bRow,const int bCol,const int r,const int c ) const
192 {
193  int row(r),col(c);
194  int MaxBlocks = fBlock.NElements();
195  if ( (bRow >= MaxBlocks) || (bCol >= MaxBlocks) )
196  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <block index out of range>" );
197 
198  int rowDim = fBlock[bRow].dim;
199  int colDim = fBlock[bCol].dim;
200 
201 
202  if ( !rowDim || !colDim )
203  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <inexistent block>" );
204 
205  if ( (row >= rowDim) || (col >= colDim) )
206  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <elemente is out of the block>" );
207 
208  row += fBlock[bRow].pos;
209  col += fBlock[bCol].pos;
210  return( fpMatrix->Get( row, col ) );
211 }
212 
213 /***********/
214 /*** Put ***/
215 template<class TVar>
216 int
217 TPZBlock<TVar>::Put(const int bRow,const int bCol,const int r,const int c,
218  const TVar& value )
219 {
220  int MaxBlocks = fBlock.NElements();
221  int row(r),col(c);
222  if ( (bRow >= MaxBlocks) || (bCol >= MaxBlocks) )
223  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <block index out of range>" );
224 
225  int rowDim = fBlock[bRow].dim;
226  int colDim = fBlock[bCol].dim;
227 
228  if ( !rowDim || !colDim )
229  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <inexistent block>" );
230 
231  if ( (row >= rowDim) || (col >= colDim) )
232  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <elemente is out of the block>" );
233 
234  row += fBlock[bRow].pos;
235  col += fBlock[bCol].pos;
236  return( fpMatrix->Put( row, col, value ) );
237 }
238 
239 /***********/
240 /*** Get ***/
241 template<class TVar>
242 const TVar &
243 TPZBlock<TVar>::Get(const int bRow,const int r,const int c ) const
244 {
245  int row(r),col(c);
246  int MaxBlocks = fBlock.NElements();
247  if ( (bRow >= MaxBlocks) )
248  {
249  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <block index out of range>" );
250  }
251 
252  int rowDim = fBlock[bRow].dim;
253 
254 
255  if ( !rowDim )
256  {
257  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <inexistent block>" );
258  }
259 
260  if ( (row >= rowDim) || (col >= fpMatrix->Cols()) )
261  {
262  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Get <elemente is out of the block>" );
263  }
264 
265  row += fBlock[bRow].pos;
266  return( fpMatrix->Get( row, col ) );
267 }
268 
269 /***********/
270 /*** Put ***/
271 template<class TVar>
272 int
273 TPZBlock<TVar>::Put(const int bRow,const int r,const int c,
274  const TVar& value )
275 {
276  int MaxBlocks = fBlock.NElements();
277  int row(r),col(c);
278  if ( (bRow >= MaxBlocks) )
279  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <block index out of range>" );
280 
281  int rowDim = fBlock[bRow].dim;
282 
283  if ( !rowDim )
284  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <inexistent block>" );
285 
286  if ( (row >= rowDim) || (col >= fpMatrix->Cols()) )
287  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "Put <elemente is out of the block>" );
288 
289  row += fBlock[bRow].pos;
290  return( fpMatrix->Put( row, col, value ) );
291 }
292 
293 /**************/
294 /*** GetVal ***/
295 template<class TVar>
296 const TVar &
297 TPZBlock<TVar>::GetVal(const int bRow,const int bCol,const int r,const int c ) const
298 {
299  int MaxBlocks = fBlock.NElements();
300  int row(r),col(c);
301  if(bRow <0 || bRow >= MaxBlocks || bCol <0 || bCol >= MaxBlocks || row < 0 || row >= fBlock[bRow].dim) {
302  cout << "TPZBlock::GetVal indexes out of range\n";
303  DebugStop();
304  }
305  row += fBlock[bRow].pos;
306  col += fBlock[bCol].pos;
307  return( fpMatrix->Get( row, col ) );
308 }
309 
310 template<class TVar>
311 TVar &
312 TPZBlock<TVar>::operator()(const int bRow,const int bCol,const int r,const int c ) const
313 {
314  int MaxBlocks = fBlock.NElements();
315  int row(r),col(c);
316  if(bRow <0 || bRow >= MaxBlocks || bCol <0 || bCol >= MaxBlocks || row < 0 || row >= fBlock[bRow].dim) {
317  cout << "TPZBlock::operator() indexes out of range\n";
318  DebugStop();
319  }
320  row += fBlock[bRow].pos;
321  col += fBlock[bCol].pos;
322  return( (*fpMatrix)( row, col ) );
323 }
324 
325 /**************/
326 /*** PutVal ***/
327 template<class TVar>
328 int
329 TPZBlock<TVar>::PutVal(const int bRow,const int bCol,const int r,const int c,
330  const TVar& value )
331 {
332  int row(r),col(c);
333  row += fBlock[bRow].pos;
334  col += fBlock[bCol].pos;
335  return( fpMatrix->Put( row, col, value ) );
336 }
337 
338 /*****************/
339 /*** Put Block ***/
340 template<class TVar>
341 int
342 TPZBlock<TVar>::PutBlock(const int bRow,const int bCol,const TPZFMatrix<TVar> & block )
343 {
344  return( fpMatrix->PutSub( fBlock[bRow].pos,
345  fBlock[bCol].pos, block ) );
346 }
347 
348 /*****************/
349 /*** Get Block ***/
350 template<class TVar>
351 int
352 TPZBlock<TVar>::GetBlock(const int bRow,const int bCol, TPZFMatrix<TVar> &block ) const
353 {
354  int row = fBlock[bRow].pos;
355  int col = fBlock[bCol].pos;
356  int rowDim = fBlock[bRow].dim;
357  int colDim = fBlock[bCol].dim;
358  if ( rowDim && colDim )
359  return( fpMatrix->GetSub( row, col, rowDim, colDim, block ) );
360  else
361  return( 0 );
362 }
363 
364 /*****************/
365 /*** Add Block ***/
366 template<class TVar>
367 int
368 TPZBlock<TVar>::AddBlock(const int bRow,const int bCol,const TPZFMatrix<TVar>& block )
369 {
370  return( fpMatrix->AddSub( fBlock[bRow].pos,
371  fBlock[bCol].pos, block ) );
372 }
373 
374 /********************/
375 /**** InsertBLock****/
376 template<class TVar>
377 int
378 TPZBlock<TVar>::InsertBlock(const int block_row,const int block_col,
379  const int target_row,const int target_col, TPZMatrix<TVar> &target) const
380 {
381  int rowDim = fBlock[block_row].dim;
382  int colDim = fBlock[block_col].dim;
383  int row = target_row;
384  int col = target_col;
385 
386  if ( ((target_row + rowDim) > target.Rows()) ||
387  ((target_col + colDim) > target.Cols()) ) {
388  TPZMatrix<TVar>::Error(__PRETTY_FUNCTION__, "GetSub <the sub-matrix is too big>" ) ;
389  return ( 0 );
390  }
391 
392  for ( int r = 0; r < rowDim; r++,row++){
393  int pcol=col;
394  for ( int c = 0; c < colDim; c++,pcol++ )
395  target.PutVal( row, pcol, GetVal(block_row , block_col , r, c ) );
396  }
397 
398  return( 1 );
399 }
400 
401 /*******************/
402 /*** Print Block ***/
403 template<class TVar>
404 int
405 TPZBlock<TVar>::PrintBlock(const int bRow,const int bCol,const char *title,
406  TPZostream &out ) const
407 {
408  out << title << ":";
409 
410  for ( int r = 0; r < fBlock[bRow].dim; r++ )
411  {
412  out << "\n ";
413  for ( int c = 0; c < fBlock[bCol].dim; c++ )
414  out << GetVal( bRow, bCol, r, c ) << " ";
415  }
416  out << "\n";
417  return( 1 );
418 }
419 
420 /*************/
421 /*** Print ***/
422 template<class TVar>
423 void
424 TPZBlock<TVar>::Print(const char *title, TPZostream &out,TPZMatrix<TVar> *mat) {
426  if (mat) SetMatrix(mat);
427  char block_title[58];
428 
429  int MaxBlocks = fBlock.NElements();
430  out << title << ":\n";
431  for ( int bRow = 0; bRow < MaxBlocks; bRow++ )
432  {
433  out << "row block " << bRow << " pos " << fBlock[bRow].pos << " dim " << fBlock[bRow].dim << "\n";
434  for ( int bCol = 0; bCol < MaxBlocks; bCol++ )
435  {
436  out << "col block " << bCol << " pos " << fBlock[bCol].pos << " dim " << fBlock[bCol].dim << "\n";
437  out << "\n";
438  sprintf( block_title, "Block (%d,%d) of %dX%d:", bRow, bCol,
439  fBlock[bRow].dim,fBlock[bCol].dim );
440  PrintBlock(bRow,bCol,block_title,out);
441  }
442  }
443  out << "\n";
444  SetMatrix( sol);
445 }
446 
447 /*************/
448 /*** Print ***/
449 template<class TVar>
450 void
451 TPZBlock<TVar>::PrintSolution(const char *title, TPZostream &out) {
453 
454  char block_title[32];
455 
456  int MaxBlocks = fBlock.NElements();
457  out << title << ":";
458  for ( int bRow = 0; bRow < MaxBlocks; bRow++ )
459  {
460  out << "\n";
461  sprintf( block_title, "Block (%d,%d) of %dX%d:", bRow, 0,
462  fBlock[bRow].dim,fBlock[0].dim );
463  PrintBlock(bRow,0,block_title,out);
464  }
465  out << "\n";
466  SetMatrix( sol);
467 }
468 
469 /*************************** Private ***************************/
470 
471 template<class TVar>
472 void TPZBlock<TVar>::TNode::Read(TPZStream &buf, void *context) { //ok
473  buf.Read(&pos,1);
474  buf.Read(&dim,1);
475 }
476 
477 template<class TVar>
478 void TPZBlock<TVar>::TNode::Write(TPZStream &buf, int withclassid) const { //ok
479  buf.Write(&pos,1);
480  buf.Write(&dim,1);
481 }
482 
483 #ifndef BORLAND
484 template class TPZRestoreClass< TPZBlock<float> >;
485 template class TPZRestoreClass< TPZBlock<double> >;
487 
491 #endif
492 
493 
495 template<class TVar>
496 void TPZBlock<TVar>::Write(TPZStream &buf, int withclassid) const { //ok
497  buf.Write(fBlock);
499 
500 }
501 
503 template<class TVar>
504 void TPZBlock<TVar>::Read(TPZStream &buf, void *context) { //ok
505  buf.Read<TNode>(fBlock,context);
507 }
508 
509 template class TPZBlock<float>;
510 template class TPZBlock<double>;
511 template class TPZBlock<long double>;
512 
513 template class TPZBlock<std::complex<float> >;
514 template class TPZBlock<std::complex<double> >;
515 template class TPZBlock<std::complex<long double> >;
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
Definition: pzblock.cpp:478
int Set(const int index, const int dim, const int pos=-1)
Modifies existing block dimensions or creates a new block with given index.
Definition: pzblock.cpp:104
int InsertBlock(const int block_row, const int block_col, const int row, const int col, TPZMatrix< TVar > &target) const
Inserts a block (block_row , block_col) on current matrix target.
Definition: pzblock.cpp:378
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
void PrintSolution(const char *title, TPZostream &out)
Definition: pzblock.cpp:451
TVar & operator()(const int block_row, const int block_col, const int r, const int c) const
Definition: pzblock.cpp:312
static int Error(const char *msg, const char *msg2=0)
Returns error messages.
Definition: pzmatrix.cpp:1402
int GetBlock(const int block_row, const int block_col, TPZFMatrix< TVar > &block) const
Gets a block on current matrix.
Definition: pzblock.cpp:352
Defines PZError.
const TVar & Get(const int block_row, const int block_col, const int r, const int c) const
Gets a element from matrix verifying.
Definition: pzblock.cpp:191
int PutVal(const int bRow, const int bCol, const int r, const int c, const TVar &value)
Puts a element to matrix but not verify the existence.
Definition: pzblock.cpp:329
static TPZSavable * GetInstance(const int64_t &objId)
void Read(TPZStream &buf, void *context) override
Read the element data from a stream.
Definition: pzblock.cpp:504
int Verify() const
Verifies if blocks are sequential and does not overcome matrix size.
Definition: pzblock.cpp:176
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
int SetAll(TPZVec< int > &dimensions)
Computes blocks sequence.
Definition: pzblock.cpp:124
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
int ClassId() const override
returns the unique identifier for reading/writing objects to streams
Definition: pzblock.h:226
int PrintBlock(const int block_row, const int block_col, const char *title="", TPZostream &out=std::cout) const
Prints a matrix block.
Definition: pzblock.cpp:405
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
#define TPZostream
Definition: TPZStream.h:33
int AddBlock(const int block_row, const int block_col, const TPZFMatrix< TVar > &block)
Adds a block on current matrix.
Definition: pzblock.cpp:368
TPZManVector< TNode > fBlock
Nodes vector.
Definition: pzblock.h:218
int SetNBlocks(const int num_of_blocks)
Sets number of blocks on diagonal matrix.
Definition: pzblock.cpp:91
Full matrix class. Matrix.
Definition: pzfmatrix.h:32
virtual int PutVal(const int64_t, const int64_t, const TVar &val)
Put values without bounds checking This method is faster than "Put" if DEBUG is defined.
Definition: pzmatrix.h:154
int Put(const int block_row, const int block_col, const int r, const int c, const TVar &value)
Puts a element to matrix verifying.
Definition: pzblock.cpp:217
const TVar & GetVal(const int bRow, const int bCol, const int r, const int c) const
Gets a element from matrix but not verify the existence.
Definition: pzblock.cpp:297
Implements block matrices. Matrix utility.
TPZMatrix< TVar > * fpMatrix
Pointer to TPZMatrix.
Definition: pzblock.h:220
void SetMatrix(TPZMatrix< TVar > *const other)
Changes pointer to other.
Definition: pzblock.h:51
TPZBlock< TVar > & operator=(const TPZBlock< TVar > &)
Definition: pzblock.cpp:73
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
Contains declaration of the abstract TPZStream class. TPZStream defines the interface for saving and ...
int PutBlock(const int block_row, const int block_col, const TPZFMatrix< TVar > &block)
Puts a block on current matrix.
Definition: pzblock.cpp:342
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
void Read(TPZStream &buf, void *context) override
read objects from the stream
Definition: pzblock.cpp:472
void Print(const char *title="", TPZostream &out=std::cout, TPZMatrix< TVar > *mat=NULL)
Prints all the blocks of the matrix.
Definition: pzblock.cpp:424
int Remove(const int index)
Removes a block.
Definition: pzblock.cpp:162
static void WritePointer(const TPZSavable *obj, TPZStream *stream)
void Write(TPZStream &buf, int withclassid) const override
Save the element data to a stream.
Definition: pzblock.cpp:496
virtual ~TPZBlock()
Simple Destrutor.
Definition: pzblock.cpp:83
Implements an interface to register a class id and a restore function. Persistence.
Definition: TPZSavable.h:150
TPZBlock()
Definition: pzblock.h:25
int Resequence(const int start=0)
Resequences blocks positioning.
Definition: pzblock.cpp:150
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
Root matrix class (abstract). Matrix.
Definition: pzmatrix.h:60