NeoPZ
pzstrmatrixot.cpp
Go to the documentation of this file.
1 
6 #include "pzstrmatrixot.h"
7 
8 #include "pzvec.h"
9 #include "pzfmatrix.h"
10 #include "pzmanvector.h"
11 #include "pzadmchunk.h"
12 #include "pzcmesh.h"
13 #include "pzgmesh.h"
14 #include "pzelmat.h"
15 #include "pzcompel.h"
16 #include "pzintel.h"
17 #include "pzsubcmesh.h"
18 #include "pzanalysis.h"
19 #include "pzsfulmat.h"
20 
21 #include "pzgnode.h"
22 #include "TPZTimer.h"
23 #include "TPZThreadTools.h"
24 
25 
26 #include "pzcheckconsistency.h"
27 #include "TPZMaterial.h"
28 
29 using namespace std;
30 
31 #include "pzlog.h"
32 
33 #include "pz_pthread.h"
34 #include "run_stats_table.h"
35 
36 #ifdef LOG4CXX
37 static LoggerPtr logger(Logger::getLogger("pz.strmatrix.TPZStructMatrixOT"));
38 static LoggerPtr loggerel(Logger::getLogger("pz.strmatrix.element"));
39 static LoggerPtr loggerel2(Logger::getLogger("pz.strmatrix.elementinterface"));
40 static LoggerPtr loggerelmat(Logger::getLogger("pz.strmatrix.elementmat"));
41 static LoggerPtr loggerCheck(Logger::getLogger("pz.strmatrix.checkconsistency"));
42 #endif
43 
44 #ifdef CHECKCONSISTENCY
45 static TPZCheckConsistency stiffconsist("ElementStiff");
46 #endif
47 
48 RunStatsTable stat_ass_graph_ot("-ass_graph_ot", "Run statistics table for the graph creation and coloring TPZStructMatrixOT.");
49 
50 
53  TPZManVector<int64_t> ElementOrder;
54 
55 
56  TPZStructMatrixOT::OrderElement(this->Mesh(), ElementOrder);
57  TPZVec<int64_t> elcolors;
58  TPZStructMatrixOT::ElementColoring(this->Mesh(), ElementOrder, fElSequenceColor, fElBlocked, elcolors);
60 
61 
62 }
63 
66  TPZManVector<int64_t> ElementOrder;
67  TPZStructMatrixOT::OrderElement(this->Mesh(), ElementOrder);
68  TPZVec<int64_t> elcolors;
69  TPZStructMatrixOT::ElementColoring(this->Mesh(), ElementOrder, fElSequenceColor, fElBlocked, elcolors);
71 
72 
73 }
74 
77  fElBlocked = copy.fElBlocked;
82 
83 }
84 
86  cout << "TPZStructMatrixOT::Create should never be called\n";
87  return 0;
88 }
89 
91  cout << "TPZStructMatrixOT::Clone should never be called\n";
92  return 0;
93 }
94 
95 static RunStatsTable ass_stiff("-ass_stiff", "Assemble Stiffness");
96 static RunStatsTable ass_rhs("-ass_rhs", "Assemble Stiffness");
97 
99  ass_stiff.start();
100  if (fEquationFilter.IsActive()) {
101  int64_t neqcondense = fEquationFilter.NActiveEquations();
102 #ifdef PZDEBUG
103  if (stiffness.Rows() != neqcondense) {
104  DebugStop();
105  }
106 #endif
107  TPZFMatrix<STATE> rhsloc(neqcondense,rhs.Cols(),0.);
108  if(this->fNumThreads){
109  this->MultiThread_Assemble(stiffness,rhsloc,guiInterface);
110  }
111  else{
112  this->Serial_Assemble(stiffness,rhsloc,guiInterface);
113  }
114 
115  fEquationFilter.Scatter(rhsloc, rhs);
116  }
117  else
118  {
119  if(this->fNumThreads){
120  this->MultiThread_Assemble(stiffness,rhs,guiInterface);
121  }
122  else{
123  this->Serial_Assemble(stiffness,rhs,guiInterface);
124  }
125  }
126  ass_stiff.stop();
127 }
128 
130  ass_rhs.start();
132  {
133  int64_t neqcondense = fEquationFilter.NActiveEquations();
134  int64_t neqexpand = fEquationFilter.NEqExpand();
135  if(rhs.Rows() != neqexpand || Norm(rhs) != 0.)
136  {
137  DebugStop();
138  }
139  TPZFMatrix<STATE> rhsloc(neqcondense,1,0.);
140  if(this->fNumThreads)
141  {
142 #ifdef HUGEDEBUG
143  TPZFMatrix<STATE> rhsserial(rhsloc);
144  this->Serial_Assemble(rhsserial, guiInterface);
145 #endif
146  this->MultiThread_Assemble(rhsloc,guiInterface);
147 #ifdef HUGEDEBUG
148  rhsserial -= rhsloc;
149  REAL norm = Norm(rhsserial);
150  std::cout << "difference between serial and parallel " << norm << std::endl;
151 #endif
152  }
153  else
154  {
155  this->Serial_Assemble(rhsloc,guiInterface);
156  }
157  fEquationFilter.Scatter(rhsloc,rhs);
158  }
159  else
160  {
161  if(this->fNumThreads){
162 #ifdef HUGEDEBUG
163  TPZFMatrix<STATE> rhsserial(rhs);
164  this->Serial_Assemble(rhsserial, guiInterface);
165 #endif
166  this->MultiThread_Assemble(rhs,guiInterface);
167 #ifdef HUGEDEBUG
168  REAL normrhs = Norm(rhs);
169  REAL normrhsserial = Norm(rhsserial);
170  std::cout << "normrhs = " << normrhs << " normrhsserial " << normrhsserial << std::endl;
171  rhsserial -= rhs;
172  REAL norm = Norm(rhsserial);
173  std::cout << "difference between serial and parallel " << norm << std::endl;
174 #endif
175  }
176  else{
177  this->Serial_Assemble(rhs,guiInterface);
178  }
179  }
180  ass_rhs.stop();
181 }
182 
183 
184 
186 
187  if(!fMesh){
188  LOGPZ_ERROR(logger,"Serial_Assemble called without mesh")
189  DebugStop();
190  }
191 #ifdef LOG4CXX
192  if(dynamic_cast<TPZSubCompMesh * >(fMesh))
193  {
194  std::stringstream sout;
195  sout << "AllEig = {};";
196  LOGPZ_DEBUG(loggerelmat,sout.str())
197 
198  }
199 #endif
200 #ifdef PZDEBUG
201  if (rhs.Rows() != fEquationFilter.NActiveEquations()) {
202  DebugStop();
203  }
204 #endif
205 
206  int64_t iel;
207  int64_t nelem = fMesh->NElements();
209 #ifdef LOG4CXX
210  bool globalresult = true;
211  bool writereadresult = true;
212 #endif
213  TPZTimer calcstiff("Computing the stiffness matrices");
214  TPZTimer assemble("Assembling the stiffness matrices");
216 
217  int64_t count = 0;
218  for(iel=0; iel < nelem; iel++) {
219  TPZCompEl *el = elementvec[iel];
220  if(!el) continue;
221  int matidsize = fMaterialIds.size();
222  if(matidsize){
223  TPZMaterial * mat = el->Material();
224  TPZSubCompMesh *submesh = dynamic_cast<TPZSubCompMesh *> (el);
225  if (!mat)
226  {
227  if (!submesh) {
228  continue;
229  }
230  else if(submesh->NeedsComputing(fMaterialIds) == false) continue;
231  }
232  else
233  {
234  int matid = mat->Id();
235  if (this->ShouldCompute(matid) == false) continue;
236  }
237  }
238 
239  count++;
240  if(!(count%1000))
241  {
242  std::cout << '*';
243  std::cout.flush();
244  }
245  if(!(count%20000))
246  {
247  std::cout << "\n";
248  }
249  calcstiff.start();
250 
251  el->CalcStiff(ek,ef);
252 
253  if(guiInterface) if(guiInterface->AmIKilled()){
254  return;
255  }
256 
257 #ifdef LOG4CXX
258  if(dynamic_cast<TPZSubCompMesh * >(fMesh))
259  {
260  std::stringstream objname;
261  objname << "Element" << iel;
262  std::string name = objname.str();
263  objname << " = ";
264  std::stringstream sout;
265  ek.fMat.Print(objname.str().c_str(),sout,EMathematicaInput);
266  sout << "AppendTo[AllEig,Eigenvalues[" << name << "]];";
267 
268  LOGPZ_DEBUG(loggerelmat,sout.str())
269  /* if(iel == 133)
270  {
271  std::stringstream sout2;
272  el->Reference()->Print(sout2);
273  el->Print(sout2);
274  LOGPZ_DEBUG(logger,sout2.str())
275  }
276  */
277  }
278 
279 #endif
280 
281 #ifdef CHECKCONSISTENCY
282  //extern TPZCheckConsistency stiffconsist("ElementStiff");
283  stiffconsist.SetOverWrite(true);
284  bool result;
285  result = stiffconsist.CheckObject(ek.fMat);
286  if(!result)
287  {
288  globalresult = false;
289  std::stringstream sout;
290  sout << "element " << iel << " computed differently";
291  LOGPZ_ERROR(loggerCheck,sout.str())
292  }
293 
294 #endif
295 
296  calcstiff.stop();
297  assemble.start();
298 
299  if(!el->HasDependency()) {
300  ek.ComputeDestinationIndices();
301  fEquationFilter.Filter(ek.fSourceIndex, ek.fDestinationIndex);
302  // TPZSFMatrix<STATE> test(stiffness);
303  // TPZFMatrix<STATE> test2(stiffness.Rows(),stiffness.Cols(),0.);
304  // stiffness.Print("before assembly",std::cout,EMathematicaInput);
305  stiffness.AddKel(ek.fMat,ek.fSourceIndex,ek.fDestinationIndex);
306  rhs.AddFel(ef.fMat,ek.fSourceIndex,ek.fDestinationIndex);
307  // stiffness.Print("stiffness after assembly STK = ",std::cout,EMathematicaInput);
308  // rhs.Print("rhs after assembly Rhs = ",std::cout,EMathematicaInput);
309  // test2.AddKel(ek.fMat,ek.fSourceIndex,ek.fDestinationIndex);
310  // test -= stiffness;
311  // test.Print("matriz de rigidez diference",std::cout);
312  // test2.Print("matriz de rigidez interface",std::cout);
313 
314 #ifdef LOG4CXX
315  if(loggerel->isDebugEnabled())
316  {
317  std::stringstream sout;
318  TPZGeoEl *gel = el->Reference();
319  if(gel)
320  {
321  TPZManVector<REAL> center(gel->Dimension()),xcenter(3,0.);
322  gel->CenterPoint(gel->NSides()-1, center);
323  gel->X(center, xcenter);
324  sout << "Stiffness for computational element index " << el->Index() << std::endl;
325  sout << "Stiffness for geometric element " << gel->Index() << " center " << xcenter << std::endl;
326  }
327  else {
328  sout << "Stiffness for computational element without associated geometric element\n";
329  }
330  ek.Print(sout);
331  ef.Print(sout);
332  LOGPZ_DEBUG(loggerel,sout.str())
333  }
334 #endif
335  } else {
336  // the element has dependent nodes
337  ek.ApplyConstraints();
338  ef.ApplyConstraints();
339  ek.ComputeDestinationIndices();
340  fEquationFilter.Filter(ek.fSourceIndex, ek.fDestinationIndex);
341  stiffness.AddKel(ek.fConstrMat,ek.fSourceIndex,ek.fDestinationIndex);
342  rhs.AddFel(ef.fConstrMat,ek.fSourceIndex,ek.fDestinationIndex);
343 #ifdef LOG4CXX
344  if(loggerel->isDebugEnabled() && ! dynamic_cast<TPZSubCompMesh *>(fMesh))
345  {
346  std::stringstream sout;
347  TPZGeoEl *gel = el->Reference();
348  TPZManVector<REAL> center(gel->Dimension()),xcenter(3,0.);
349  gel->CenterPoint(gel->NSides()-1, center);
350  gel->X(center, xcenter);
351  sout << "Stiffness for geometric element " << gel->Index() << " center " << xcenter << std::endl;
352  ek.Print(sout);
353  ef.Print(sout);
354  LOGPZ_DEBUG(loggerel,sout.str())
355  }
356 #endif
357  }
358 
359  assemble.stop();
360  }//fim for iel
361  if(count > 20) std::cout << std::endl;
362 
363 #ifdef LOG4CXX
364  if(loggerCheck->isDebugEnabled())
365  {
366  std::stringstream sout;
367  sout << "The comparaison results are : consistency check " << globalresult << " write read check " << writereadresult;
368  //stiffness.Print("Matriz de Rigidez: ",sout);
369  stiffness.Print("Matriz de Rigidez: ",sout,EMathematicaInput);
370  rhs.Print("Right Handside", sout,EMathematicaInput);
371  LOGPZ_DEBUG(loggerCheck,sout.str())
372  }
373 
374 #endif
375 
376 }
377 
379 
380  int64_t iel;
381 // int64_t nelem = fMesh->NElements();
382 
383  TPZTimer calcresidual("Computing the residual vector");
384  TPZTimer assemble("Assembling the residual vector");
385 
387 
389  TPZManVector<int64_t> ElementOrder;
390  TPZStructMatrixOT::OrderElement(this->Mesh(), ElementOrder);
391  TPZVec<int64_t> elcolors;
392  TPZStructMatrixOT::ElementColoring(this->Mesh(), ElementOrder, fElSequenceColor, fElBlocked, elcolors);
394 
395  int64_t elseqsize = fElSequenceColor.size();
396  for (int64_t index = 0; index < elseqsize; index++) {
397  iel = fElSequenceColor[index];
398  TPZCompEl *el = elementvec[iel];
399  if(!el) continue;
400 
401  TPZMaterial * mat = el->Material();
402  if (!mat) continue;
403  int matid = mat->Id();
404  if (this->ShouldCompute(matid) == false) continue;
405 
407 
408  calcresidual.start();
409 
410  el->CalcResidual(ef);
411 
412  calcresidual.stop();
413 
414  assemble.start();
415 
416  if(!el->HasDependency()) {
419  rhs.AddFel(ef.fMat, ef.fSourceIndex, ef.fDestinationIndex);
420  } else {
421  // the element has dependent nodes
422  ef.ApplyConstraints();
426  }
427 
428  assemble.stop();
429 
430  }//fim for iel
431 #ifdef LOG4CXX
432  {
433  if(logger->isDebugEnabled())
434  {
435  std::stringstream sout;
436  sout << calcresidual.processName() << " " << calcresidual << std::endl;
437  sout << assemble.processName() << " " << assemble;
438  LOGPZ_DEBUG(logger,sout.str().c_str());
439  }
440  }
441 #endif
442  //std::cout << std::endl;
443 }
444 
446 {
447  TPZMatrix<STATE> *stiff = Create();
448 
449  //int64_t neq = stiff->Rows();
450  int64_t cols = MAX(1, rhs.Cols());
451  rhs.Redim(fEquationFilter.NEqExpand(),cols);
452  Assemble(*stiff,rhs,guiInterface);
453 
454 #ifdef LOG4CXX2
455  if(loggerel->isDebugEnabled())
456  {
457  std::stringstream sout;
458  stiff->Print("Stiffness matrix",sout);
459  rhs.Print("Right hand side", sout);
460  LOGPZ_DEBUG(loggerel,sout.str())
461  }
462 #endif
463  return stiff;
464 
465 }
466 
467 
469 {
470 
471  const int numthreads = this->fNumThreads;
472  std::cout << "Assemble numthreads = " << numthreads << std::endl;
473  TPZVec<pthread_t> allthreads(numthreads);
474  int itr;
475  if(guiInterface){
476  if(guiInterface->AmIKilled()){
477  return;
478  }
479  }
480  PZ_PTHREAD_MUTEX_INIT(&fAccessElement,NULL,"TPZStructMatrixOT::ThreadData::ThreadData()");
481  pthread_cond_init(&fCondition, NULL);
482 
483 #ifdef USING_BOOST
484  this->fCurrentIndex = 0;
485 #endif
486 
487  fElementCompleted = -1;
490  fSomeoneIsSleeping = 0;
491  TPZManVector<ThreadData*> allthreaddata(numthreads);
492 #ifdef PZDEBUG
493  {
494  for (int64_t i=1; i<fElBlocked.size(); i++) {
495  if (fElBlocked[i] < fElBlocked[i-1]) {
496  std::cout << "i = " << i << " fElBlocked[i-1] " << fElBlocked[i-1] << " fElBlocked[i] " << fElBlocked[i] << std::endl;
497  }
498  }
499  }
500 #endif
501 
502  for(itr=0; itr<numthreads; itr++)
503  {
504  allthreaddata[itr] = new ThreadData(this, itr, mat, rhs, fMaterialIds, guiInterface);
505  ThreadData &threaddata = *allthreaddata[itr];
506 
507  threaddata.fElBlocked=&fElBlocked;
509  threaddata.fElementCompleted = &fElementCompleted;
510  threaddata.fComputedElements = &fElementsComputed;
512  threaddata.fCondition = &fCondition;
513  threaddata.fAccessElement = &fAccessElement;
514  PZ_PTHREAD_CREATE(&allthreads[itr], NULL,ThreadData::ThreadWork,
515  &threaddata, __FUNCTION__);
516  }
517 
518  for(itr=0; itr<numthreads; itr++)
519  {
520  PZ_PTHREAD_JOIN(allthreads[itr], NULL, __FUNCTION__);
521  }
522 
523  for(itr=0; itr<numthreads; itr++)
524  {
525  delete allthreaddata[itr];
526  }
527  PZ_PTHREAD_MUTEX_DESTROY(&fAccessElement,"TPZStructMatrixOT::ThreadData::~ThreadData()");
528  pthread_cond_destroy(&fCondition);
529 
530 #ifdef LOG4CXX
531  if(loggerCheck->isDebugEnabled())
532  {
533  std::stringstream sout;
534  //stiffness.Print("Matriz de Rigidez: ",sout);
535  mat.Print("Matriz de Rigidez: ",sout,EMathematicaInput);
536  rhs.Print("Right Handside", sout,EMathematicaInput);
537  LOGPZ_DEBUG(loggerCheck,sout.str())
538  }
539 #endif
540 }
541 
542 
544 {
545  const int numthreads = this->fNumThreads;
546  TPZVec<pthread_t> allthreads(numthreads);
547  int itr;
548  if(guiInterface){
549  if(guiInterface->AmIKilled()){
550  return;
551  }
552  }
553 
554  PZ_PTHREAD_MUTEX_INIT(&fAccessElement,NULL,"TPZStructMatrixOT::ThreadData::ThreadData()");
555  pthread_cond_init(&fCondition, NULL);
556 
557 #ifdef USING_BOOST
558  this->fCurrentIndex = 0;
559 #endif
560  fElementCompleted = -1;
563  fSomeoneIsSleeping = 0;
564  TPZManVector<ThreadData*> allthreaddata(numthreads);
565 
566  for(itr=0; itr<numthreads; itr++)
567  {
568  allthreaddata[itr] = new ThreadData(this, itr, rhs, fMaterialIds, guiInterface);
569  ThreadData &threaddata = *allthreaddata[itr];
570  threaddata.fElBlocked=&fElBlocked;
572  threaddata.fElementCompleted = &fElementCompleted;
573  threaddata.fComputedElements = &fElementsComputed;
575  threaddata.fCondition = &fCondition;
576  threaddata.fAccessElement = &fAccessElement;
577 
578  PZ_PTHREAD_CREATE(&allthreads[itr], NULL,ThreadData::ThreadWorkResidual,
579  &threaddata, __FUNCTION__);
580  }
581 
582  for(itr=0; itr<numthreads; itr++)
583  {
584  PZ_PTHREAD_JOIN(allthreads[itr], NULL, __FUNCTION__);
585  }
586 
587  for(itr=0; itr<numthreads; itr++)
588  {
589  delete allthreaddata[itr];
590  }
591 
592  PZ_PTHREAD_MUTEX_DESTROY(&fAccessElement,"TPZStructMatrixOT::ThreadData::~ThreadData()");
593  pthread_cond_destroy(&fCondition);
594 
595 #ifdef LOG4CXX
596  if(loggerCheck->isDebugEnabled())
597  {
598  std::stringstream sout;
599  //stiffness.Print("Matriz de Rigidez: ",sout);
600  rhs.Print("Right Handside", sout,EMathematicaInput);
601  LOGPZ_DEBUG(loggerCheck,sout.str())
602  }
603 #endif
604 
605 }
606 
607 
608 
610  TPZFMatrix<STATE> &rhs,
611  std::set<int> &MaterialIds,
612  TPZAutoPointer<TPZGuiInterface> guiInterface)
613 : fStruct(strmat), fGuiInterface(guiInterface), fGlobMatrix(&mat), fGlobRhs(&rhs), fThreadSeqNum(seqnum)
614 {
615 #ifdef USING_BOOST
616  fCurrentIndex = &strmat->fCurrentIndex;
617 #endif
618 
619  /* sem_t *sem_open( ... );
620  int sem_close(sem_t *sem);
621  int sem_unlink(const char *name);
622  */
623  /*
624  #ifdef MACOSX
625  std::stringstream sout;
626  static int counter = 0;
627  sout << "AssemblySem" << counter++;
628  fAssembly = sem_open(sout.str().c_str(), O_CREAT,777,1);
629  if(fAssembly == SEM_FAILED)
630  {
631  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
632  DebugStop();
633  }
634  #else
635  int sem_result = sem_init(&fAssembly,0,0);
636  if(sem_result != 0)
637  {
638  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
639  }
640  #endif
641  */
642 }
643 
645  TPZFMatrix<STATE> &rhs,
646  std::set<int> &MaterialIds,
647  TPZAutoPointer<TPZGuiInterface> guiInterface)
648 : fStruct(strmat),fGuiInterface(guiInterface), fGlobMatrix(0), fGlobRhs(&rhs), fThreadSeqNum(seqnum)
649 {
650 #ifdef USING_BOOST
651  this->fCurrentIndex = &strmat->fCurrentIndex;
652 #endif
653  /* sem_t *sem_open( ... );
654  int sem_close(sem_t *sem);
655  int sem_unlink(const char *name);
656  */
657  /*
658  #ifdef MACOSX
659  std::stringstream sout;
660  static int counter = 0;
661  sout << "AssemblySem" << counter++;
662  fAssembly = sem_open(sout.str().c_str(), O_CREAT,777,1);
663  if(fAssembly == SEM_FAILED)
664  {
665  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
666  DebugStop();
667  }
668  #else
669  int sem_result = sem_init(&fAssembly,0,0);
670  if(sem_result != 0)
671  {
672  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
673  }
674  #endif
675  */
676 }
677 
679 {
680  /*
681  #ifdef MACOSX
682  sem_close(fAssembly);
683  #else
684  sem_destroy(&fAssembly);
685  #endif
686  */
687 }
688 
689 //#define DRY_RUN
690 
692 {
693  ThreadData *data = (ThreadData *) datavoid;
694 // TPZStructMatrixOT *strmat = data->fStruct;
695  TPZVec<int64_t> &ComputedElements = *(data->fComputedElements);
696  TPZVec<int64_t> &ElBlocked = *(data->fElBlocked);
697 
698  int &SomeoneIsSleeping = *(data->fSomeoneIsSleeping);
699 
700  TPZCompMesh *cmesh = data->fStruct->Mesh();
701  TPZAutoPointer<TPZGuiInterface> guiInterface = data->fGuiInterface;
704  int64_t numelements = data->fElSequenceColor->size();
705 #ifdef USING_BOOST
706  int64_t index = data->fCurrentIndex->fetch_add(1);
707 #else
708  int64_t index = data->fThreadSeqNum;
709 #endif
710 #ifdef LOG4CXX
711  if (logger->isDebugEnabled()) {
712  std::stringstream sout;
713  sout << "ThreadData starting with " << data->fThreadSeqNum << " total elements " << numelements << std::endl;
714  sout << "index = " << index << std::endl;
715  LOGPZ_DEBUG(logger, sout.str())
716  }
717 #endif
718 #ifdef HUGEDEBUG
720  std::cout << "ThreadData starting with " << data->fThreadSeqNum << " total elements " << numelements << std::endl;
721  std::cout << "index = " << index << std::endl;
722  std::cout.flush();
724 #endif
725 
726 #ifndef USING_BOOST
727  int nthreads = data->fStruct->GetNumThreads();
728  for (index = data->fThreadSeqNum; index < numelements; index += nthreads)
729 #else
730  while (index < numelements)
731 #endif
732  {
733 
734  int64_t iel = data->fElSequenceColor->operator[](index);
735 #ifdef LOG4CXX
736  if (logger->isDebugEnabled()) {
737  std::stringstream sout;
738  sout << "Computing element " << index;
739  LOGPZ_DEBUG(logger, sout.str())
740  }
741 #endif
742 #ifdef LOG4CXX
743  std::stringstream sout;
744  sout << "Element " << index << " elapsed time ";
745  TPZTimer timeforel(sout.str());
746  timeforel.start();
747 #endif
748 
749  if (iel >= 0){
750  TPZCompEl *el = cmesh->ElementVec()[iel];
751 #ifndef DRY_RUN
752  el->CalcStiff(ek,ef);
753 #else
754  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(el);
755  intel->InitializeElementMatrix(ek,ef);
756 #endif
757 
758  if(guiInterface) if(guiInterface->AmIKilled()){
759  break;
760  }
761 
762 #ifndef DRY_RUN
763  if(!el->HasDependency()) {
764 
767 
768 #ifdef LOG4CXX
769  if(loggerel->isDebugEnabled())
770  {
771  std::stringstream sout;
772  ek.fMat.Print("Element stiffness matrix",sout);
773  ef.fMat.Print("Element right hand side", sout);
774  LOGPZ_DEBUG(loggerel,sout.str())
775  }
776 #endif
777  } else {
778  // the element has dependent nodes
779  ek.ApplyConstraints();
780  ef.ApplyConstraints();
783  }
784 #endif
785 
786 #ifdef LOG4CXX
787  timeforel.stop();
788  if (logger->isDebugEnabled())
789  {
790  std::stringstream sout;
791  sout << timeforel.processName() << timeforel;
792  LOGPZ_DEBUG(logger, sout.str())
793  }
794 #endif
795 
796  int64_t localcompleted = *(data->fElementCompleted);
797  bool localupdated = false;
798  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
799  localcompleted++;
800  localupdated = true;
801  }
802  int64_t needscomputed = ElBlocked[index];
803 #ifdef LOG4CXX
804  if (logger->isDebugEnabled())
805  {
806  std::stringstream sout;
807  if (localupdated) {
808  sout << "Localcompleted updated without thread lock\n";
809  }
810 
811  sout << "Element " << index << " is computed and can assemble if required " << needscomputed << " is smaller than localcompleted " << localcompleted;
812  LOGPZ_DEBUG(logger, sout.str())
813  }
814 #endif
815 
816 #ifdef HUGEDEBUG
818  std::cout << "threadEK " << data->fThreadSeqNum << " index " << index << " localcompleted " << localcompleted << " needscomputed " << needscomputed << std::endl;
820 #endif
821 
822  bool hadtowait = false;
823  while (needscomputed > localcompleted) {
824  // block the thread till the element needed has been assembled
826  SomeoneIsSleeping = 1;
827  hadtowait = true;
828 #ifdef HUGEDEBUG
829  std::cout << "threadEK " <<data->fThreadSeqNum << " Index " << index << " going to sleep waiting for " << needscomputed << std::endl;
830  std::cout.flush();
831 #endif
832 #ifdef LOG4CXX
833  if (logger->isDebugEnabled())
834  {
835  std::stringstream sout;
836  sout << "Element " << index << " cannot be assembled - going to sleep";
837  LOGPZ_DEBUG(logger, sout.str())
838  }
839 #endif
840  pthread_cond_wait(data->fCondition, data->fAccessElement);
842 
843  localcompleted = *data->fElementCompleted;
844  localupdated = false;
845  while (ComputedElements[localcompleted+1] == 1) {
846  localcompleted++;
847  localupdated = true;
848  }
849 #ifdef LOG4CXX
850  if (logger->isDebugEnabled())
851  {
852  std::stringstream sout;
853  sout << "thread wakeup for element index " << index << std::endl;
854  if (localupdated) {
855  sout << "Localcompleted updated without thread lock\n";
856  }
857 
858  sout << "Element " << index << " is computed and can assemble if required " << needscomputed << " is smaller than localcompleted " << localcompleted;
859  LOGPZ_DEBUG(logger, sout.str())
860  }
861 #endif
862  }
863 
864 #ifdef HUGEDEBUG
865  if (hadtowait) {
867  std::cout << "threadEK " <<data->fThreadSeqNum << " Index " << index << " continuing\n";
869  }
870 #endif
871 
872 #ifndef DRY_RUN
873  if(data->fGlobMatrix){
874  // Assemble the matrix
875  if(!ek.HasDependency())
876  {
879  }
880  else
881  {
884  }
885 
886  }
887 #endif
888 
889  localupdated = false;
890  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
891  localcompleted++;
892  localupdated = true;
893  }
894  if (localcompleted == index-1) {
895  localcompleted++;
896  }
897  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
898  localcompleted++;
899  localupdated = true;
900  }
901  bool elementcompletedupdate = false;
902  if (*data->fElementCompleted < localcompleted) {
903 // std::cout << "Updating element completed " << localcompleted << std::endl;
904  *data->fElementCompleted = localcompleted;
905  elementcompletedupdate = true;
906  }
907 #ifdef LOG4CXX
908  if (logger->isDebugEnabled())
909  {
910  std::stringstream sout;
911  sout << "Element " << index << " has been assembled ";
912  if (localupdated) {
913  sout << "\nLocalcompleted updated without thread lock\n";
914  }
915  if (elementcompletedupdate) {
916  sout << "\nfElementCompleted updated to localcompleted\n";
917  }
918  sout << "local completed " << localcompleted;
919  LOGPZ_DEBUG(logger, sout.str())
920  }
921 #endif
922  ComputedElements[index] = 1;
923  if (SomeoneIsSleeping) {
925 #ifdef HUGEDEBUG
926  std::cout << "threadEK " <<data->fThreadSeqNum << " Computed index " << index << " Waking up ElementsCompleted " << *data->fElementCompleted << std::endl;
927  std::cout.flush();
928 #endif
929 
930 #ifdef LOG4CXX
931  if (logger->isDebugEnabled())
932  {
933  LOGPZ_DEBUG(logger, "condition broadcast")
934  }
935 #endif
936  SomeoneIsSleeping = 0;
937  pthread_cond_broadcast(data->fCondition);
939  }
940 
941  }
942  else
943  {
944  std::cout << "the element in ElColorSequence is negative???\n";
945  DebugStop();
946  }
947 #ifdef USING_BOOST
948  index = data->fCurrentIndex->fetch_add(1);
949 #endif
950 
951  }
952  // just make sure threads that were accidentally blocked get woken up
954  bool localupdated = false;
955  int64_t localcompleted = *(data->fElementCompleted);
956  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
957  localcompleted++;
958  localupdated = true;
959  }
960  if (localcompleted == index-1) {
961  localcompleted++;
962  }
963  bool elementcompletedupdate = false;
964  if (*data->fElementCompleted < localcompleted) {
965  // std::cout << "Updating element completed " << localcompleted << std::endl;
966  *data->fElementCompleted = localcompleted;
967  elementcompletedupdate = true;
968  }
969 
970 #ifdef LOG4CXX
971  if (logger->isDebugEnabled())
972  {
973  LOGPZ_DEBUG(logger, "Finishing up")
974  if (localupdated) {
975  LOGPZ_DEBUG(logger, "updated localcompleted")
976  }
977  if (elementcompletedupdate) {
978  LOGPZ_DEBUG(logger, "updated fElementCompleted")
979  }
980  if (localupdated || elementcompletedupdate) {
981  std::stringstream sout;
982  sout << "localcompleted " << localcompleted;
983  LOGPZ_DEBUG(logger, sout.str())
984  }
985  LOGPZ_DEBUG(logger, "finishing and condition broadcast")
986  }
987 #endif
988  pthread_cond_broadcast(data->fCondition);
989  SomeoneIsSleeping = 0;
991  return 0;
992 }
993 
995 {
996 #ifdef LOG4CXX
997  logger->setLevel(log4cxx::Level::getInfo());
998 #endif
999  ThreadData *data = (ThreadData *) datavoid;
1000  // TPZStructMatrixOT *strmat = data->fStruct;
1001  TPZVec<int64_t> &ComputedElements = *(data->fComputedElements);
1002  TPZVec<int64_t> &ElBlocked = *(data->fElBlocked);
1003 
1004  int &SomeoneIsSleeping = *(data->fSomeoneIsSleeping);
1005 
1006  TPZCompMesh *cmesh = data->fStruct->Mesh();
1007  TPZAutoPointer<TPZGuiInterface> guiInterface = data->fGuiInterface;
1009  int64_t numelements = data->fElSequenceColor->size();
1010 #ifdef USING_BOOST
1011  int64_t index = data->fCurrentIndex->fetch_add(1);
1012 #else
1013  int64_t index = data->fThreadSeqNum;
1014 #endif
1015 #ifdef LOG4CXX
1016  if (logger->isDebugEnabled()) {
1017  std::stringstream sout;
1018  sout << "ThreadData starting with " << data->fThreadSeqNum << " total elements " << numelements << std::endl;
1019  sout << "index = " << index << std::endl;
1020  LOGPZ_DEBUG(logger, sout.str())
1021  }
1022 #endif
1023 #ifdef HUGEDEBUG
1025  std::cout << "ThreadData starting with " << data->fThreadSeqNum << " total elements " << numelements << std::endl;
1026  std::cout << "index = " << index << std::endl;
1027  std::cout.flush();
1029 #endif
1030 
1031 #ifndef USING_BOOST
1032  int nthreads = data->fStruct->GetNumThreads();
1033  for (index = data->fThreadSeqNum; index < numelements; index += nthreads)
1034 #else
1035  while (index < numelements)
1036 #endif
1037  {
1038 
1039  int64_t iel = data->fElSequenceColor->operator[](index);
1040 #ifdef LOG4CXX
1041  if (logger->isDebugEnabled()) {
1042  std::stringstream sout;
1043  sout << "Computing element " << index;
1044  LOGPZ_DEBUG(logger, sout.str())
1045  }
1046 #endif
1047 #ifdef LOG4CXX
1048  std::stringstream sout;
1049  sout << "Element " << index << " elapsed time ";
1050  TPZTimer timeforel(sout.str());
1051  timeforel.start();
1052 #endif
1053 
1054  if (iel >= 0){
1055  TPZCompEl *el = cmesh->ElementVec()[iel];
1056 #ifndef DRY_RUN
1057  el->CalcResidual(ef);
1058 #else
1059  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *>(el);
1060  intel->InitializeElementMatrix(ef);
1061 #endif
1062  if(guiInterface) if(guiInterface->AmIKilled()){
1063  break;
1064  }
1065 
1066 #ifndef DRY_RUN
1067  if(!el->HasDependency()) {
1068 
1071 
1072 #ifdef LOG4CXX
1073  if(loggerel->isDebugEnabled())
1074  {
1075  std::stringstream sout;
1076  ef.fMat.Print("Element right hand side", sout);
1077  LOGPZ_DEBUG(loggerel,sout.str())
1078  }
1079 #endif
1080  } else {
1081  // the element has dependent nodes
1082  ef.ApplyConstraints();
1085  }
1086 #endif
1087 
1088 #ifdef LOG4CXX
1089  timeforel.stop();
1090  if (logger->isDebugEnabled())
1091  {
1092  std::stringstream sout;
1093  sout << timeforel.processName() << timeforel;
1094  LOGPZ_DEBUG(logger, sout.str())
1095  }
1096 #endif
1097 
1098  int64_t localcompleted = *(data->fElementCompleted);
1099  bool localupdated = false;
1100  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
1101  localcompleted++;
1102  localupdated = true;
1103  }
1104  int64_t needscomputed = ElBlocked[index];
1105 #ifdef LOG4CXX
1106  if (logger->isDebugEnabled())
1107  {
1108  std::stringstream sout;
1109  if (localupdated) {
1110  sout << "Localcompleted updated without thread lock\n";
1111  }
1112 
1113  sout << "Element " << index << " is computed and can assemble if required " << needscomputed << " is smaller than localcompleted " << localcompleted;
1114  LOGPZ_DEBUG(logger, sout.str())
1115  }
1116 #endif
1117 
1118 #ifdef HUGEDEBUG
1120  std::cout << "threadEK " << data->fThreadSeqNum << " index " << index << " localcompleted " << localcompleted << " needscomputed " << needscomputed << std::endl;
1122 #endif
1123 
1124  bool hadtowait = false;
1125 #ifdef LOG4CXX
1126  if (logger->isInfoEnabled() && needscomputed > localcompleted)
1127  {
1128  std::stringstream sout;
1129  sout << "Element " << index << " cannot be assembled - going to sleep";
1130  LOGPZ_INFO(logger, sout.str())
1131  }
1132 #endif
1133  while (needscomputed > localcompleted) {
1134  // block the thread till the element needed has been assembled
1136  SomeoneIsSleeping = 1;
1137  hadtowait = true;
1138 #ifdef HUGEDEBUG
1139  std::cout << "threadEK " <<data->fThreadSeqNum << " Index " << index << " going to sleep waiting for " << needscomputed << std::endl;
1140  std::cout.flush();
1141 #endif
1142 #ifdef LOG4CXX
1143  if (logger->isDebugEnabled())
1144  {
1145  std::stringstream sout;
1146  sout << "Element " << index << " cannot be assembled - going to sleep";
1147  LOGPZ_DEBUG(logger, sout.str())
1148  }
1149 #endif
1150  pthread_cond_wait(data->fCondition, data->fAccessElement);
1152 
1153  localcompleted = *data->fElementCompleted;
1154  localupdated = false;
1155  while (ComputedElements[localcompleted+1] == 1) {
1156  localcompleted++;
1157  localupdated = true;
1158  }
1159 #ifdef LOG4CXX
1160  if (logger->isDebugEnabled())
1161  {
1162  std::stringstream sout;
1163  sout << "thread wakeup for element index " << index << std::endl;
1164  if (localupdated) {
1165  sout << "Localcompleted updated without thread lock\n";
1166  }
1167 
1168  sout << "Element " << index << " is computed and can assemble if required " << needscomputed << " is smaller than localcompleted " << localcompleted;
1169  LOGPZ_DEBUG(logger, sout.str())
1170  }
1171 #endif
1172  }
1173 
1174 
1175 #ifdef LOG4CXX
1176  if (logger->isInfoEnabled() && hadtowait)
1177  {
1178  std::stringstream sout;
1179  sout << "thread wakeup for element index " << index << std::endl;
1180  LOGPZ_INFO(logger, sout.str())
1181  }
1182 #endif
1183 
1184 
1185 #ifdef HUGEDEBUG
1186  if (hadtowait) {
1188  std::cout << "threadEK " <<data->fThreadSeqNum << " Index " << index << " continuing\n";
1190  }
1191 #endif
1192 
1193 #ifndef DRY_RUN
1194  if(data->fGlobRhs){
1195  // Assemble the matrix
1196  if(!ef.HasDependency())
1197  {
1199  }
1200  else
1201  {
1203  }
1204 
1205  }
1206 #endif
1207 
1208  localupdated = false;
1209  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
1210  localcompleted++;
1211  localupdated = true;
1212  }
1213  if (localcompleted == index-1) {
1214  localcompleted++;
1215  }
1216  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
1217  localcompleted++;
1218  localupdated = true;
1219  }
1220  bool elementcompletedupdate = false;
1221  if (*data->fElementCompleted < localcompleted) {
1222  // std::cout << "Updating element completed " << localcompleted << std::endl;
1223  *data->fElementCompleted = localcompleted;
1224  elementcompletedupdate = true;
1225  }
1226 #ifdef LOG4CXX
1227  if (logger->isDebugEnabled())
1228  {
1229  std::stringstream sout;
1230  sout << "Element " << index << " has been assembled ";
1231  if (localupdated) {
1232  sout << "\nLocalcompleted updated without thread lock\n";
1233  }
1234  if (elementcompletedupdate) {
1235  sout << "\nfElementCompleted updated to localcompleted\n";
1236  }
1237  sout << "local completed " << localcompleted;
1238  LOGPZ_DEBUG(logger, sout.str())
1239  }
1240 #endif
1241  ComputedElements[index] = 1;
1242  if (SomeoneIsSleeping) {
1244 #ifdef HUGEDEBUG
1245  std::cout << "threadEK " <<data->fThreadSeqNum << " Computed index " << index << " Waking up ElementsCompleted " << *data->fElementCompleted << std::endl;
1246  std::cout.flush();
1247 #endif
1248 
1249 #ifdef LOG4CXX
1250  if (logger->isDebugEnabled())
1251  {
1252  LOGPZ_DEBUG(logger, "condition broadcast")
1253  }
1254 #endif
1255  SomeoneIsSleeping = 0;
1256  pthread_cond_broadcast(data->fCondition);
1258  }
1259 
1260  }
1261  else
1262  {
1263  std::cout << "the element in ElColorSequence is negative???\n";
1264  DebugStop();
1265  }
1266 #ifdef USING_BOOST
1267  index = data->fCurrentIndex->fetch_add(1);
1268 #endif
1269 
1270  }
1271  // just make sure threads that were accidentally blocked get woken up
1273  bool localupdated = false;
1274  int64_t localcompleted = *(data->fElementCompleted);
1275  while (localcompleted < numelements-1 && ComputedElements[localcompleted+1] == 1) {
1276  localcompleted++;
1277  localupdated = true;
1278  }
1279  if (localcompleted == index-1) {
1280  localcompleted++;
1281  }
1282  bool elementcompletedupdate = false;
1283  if (*data->fElementCompleted < localcompleted) {
1284  // std::cout << "Updating element completed " << localcompleted << std::endl;
1285  *data->fElementCompleted = localcompleted;
1286  elementcompletedupdate = true;
1287  }
1288 
1289 #ifdef LOG4CXX
1290  if (logger->isDebugEnabled())
1291  {
1292  LOGPZ_DEBUG(logger, "Finishing up")
1293  if (localupdated) {
1294  LOGPZ_DEBUG(logger, "updated localcompleted")
1295  }
1296  if (elementcompletedupdate) {
1297  LOGPZ_DEBUG(logger, "updated fElementCompleted")
1298  }
1299  if (localupdated || elementcompletedupdate) {
1300  std::stringstream sout;
1301  sout << "localcompleted " << localcompleted;
1302  LOGPZ_DEBUG(logger, sout.str())
1303  }
1304  LOGPZ_DEBUG(logger, "finishing and condition broadcast")
1305  }
1306 #endif
1307  pthread_cond_broadcast(data->fCondition);
1308  SomeoneIsSleeping = 0;
1310  return 0;
1311 }
1312 
1313 //static bool CanAssemble(TPZStack<int64_t> &connectlist, TPZVec<int> &elContribute)
1314 //{
1315 // for (int i = 0 ; i < connectlist.NElements() ; i++)
1316 // {
1317 // if (elContribute[connectlist[i]] >= 0){
1318 // return false;
1319 // }
1320 // }
1321 // return true;
1322 //}
1323 
1324 static void AssembleColor(int64_t el, TPZStack<int64_t> &connectlist, TPZVec<int64_t> &elContribute) {
1325  for (auto connect : connectlist) {
1326  elContribute[connect] = el;
1327  }
1328 }
1329 
1330 static int64_t WhoBlockedMe(TPZStack<int64_t> &connectlist, TPZVec<int64_t> &elContribute, TPZVec<int64_t> &elSequenceColorInv) {
1331  int64_t el = -1;
1332  for (auto connect : connectlist) {
1333  auto elBlocked = elContribute[connect];
1334  if (elBlocked == -1) continue;
1335  auto elBlockedIndex = elSequenceColorInv[elBlocked];
1336  if (el == -1) el = elBlockedIndex;
1337  if (elBlockedIndex > el) el = elBlockedIndex;
1338  }
1339  return el;
1340 }
1341 
1342 //static void RemoveEl(int el,TPZCompMesh *cmesh,TPZVec<int> &elContribute,int elSequence)
1343 //{
1344 // TPZCompEl *cel = cmesh->ElementVec()[el];
1345 // if(!cel) DebugStop();
1346 // TPZStack<int64_t> connectlist;
1347 // cel->BuildConnectList(connectlist);
1348 // for (int i = 0 ; i < connectlist.NElements() ; i++)
1349 // {
1350 // int conindex = connectlist[i];
1351 // if (elContribute[conindex] != elSequence){
1352 // DebugStop();
1353 // }
1354 // elContribute[conindex] = -1;
1355 // }
1356 //}
1357 
1358 static int64_t MinPassIndex(TPZStack<int64_t> &connectlist, TPZVec<int64_t> &elContribute, TPZVec<int64_t> &passIndex) {
1359  int64_t minPassIndex = -1;
1360  for (int64_t i = 0; i < connectlist.NElements(); i++) {
1361  int64_t elcont = elContribute[connectlist[i]];
1362  int64_t passindex = -1;
1363  if (elcont != -1) {
1364  passindex = passIndex[elcont];
1365  if (minPassIndex == -1) minPassIndex = passindex;
1366  }
1367  if (minPassIndex < passindex) minPassIndex = passindex;
1368  }
1369  return minPassIndex;
1370 }
1371 
1379  TPZVec<int64_t> &elBlocked, TPZVec<int64_t> &NumelColors) {
1380 
1381  const int64_t nnodes = cmesh->NConnects();
1382  const int64_t nel = cmesh->NElements();
1383 
1384  if (nel == 0) return;
1385 
1386  NumelColors.Resize(nel, -1);
1387 
1388  // elContribute contains the element index which last contributed to the node
1389  // passIndex contains the color of the element
1390  TPZManVector<int64_t> elContribute(nnodes, -1), passIndex(nel, -1), elSequenceColorInv(nel, -1);
1391  int64_t elsequencesize = elSequence.size();
1392  elSequenceColor.Resize(elsequencesize);
1393  elSequenceColor.Fill(-1);
1394  elBlocked.Resize(elsequencesize);
1395  elBlocked.Fill(-1);
1396  int64_t nelProcessed = 0;
1397  int64_t currentPassIndex = 0;
1398  while (nelProcessed < elSequence.NElements()) {
1399  for (auto elindex : elSequence) {
1400  // if this element hasn't been computed in a previous pass
1401  if (elSequenceColorInv[elindex] == -1) {
1402  TPZCompEl *cel = cmesh->Element(elindex);
1403  if (!cel) continue;
1404  TPZStack<int64_t> connectlist;
1405  cel->BuildConnectList(connectlist);
1406  // compute the lowest color (pass index) of the elements that have contributed to this set of nodes
1407  int64_t minPass = MinPassIndex(connectlist, elContribute, passIndex);
1408  // no element has ever seen any of these nodes
1409  if (minPass == -1) {
1410  passIndex[elindex] = currentPassIndex;
1411  // the element index is put into elContribute (from there it is possible to know the color as well)
1412  AssembleColor(elindex, connectlist, elContribute);
1413  // initialize the data structures
1414  elSequenceColor[nelProcessed] = elindex;
1415  elSequenceColorInv[elindex] = nelProcessed;
1416  nelProcessed++;
1417  } // this element cannot be computed as it is connected to another element of the current color
1418  else if (minPass == currentPassIndex) {
1419  } // the elements connected to this node are from a previous color
1420  else if (minPass < currentPassIndex) {
1421  // the element with largest index which contributes to the set of nodes
1422  // el is given in the new sequence order
1423  const int64_t el = WhoBlockedMe(connectlist, elContribute, elSequenceColorInv);
1424  // elblocked means the future element the element el will block
1425  if (elBlocked[nelProcessed] != -1) DebugStop();
1426  elBlocked[nelProcessed] = el;
1427  passIndex[elindex] = currentPassIndex;
1428  AssembleColor(elindex, connectlist, elContribute);
1429  elSequenceColor[nelProcessed] = elindex;
1430  elSequenceColorInv[elindex] = nelProcessed;
1431  nelProcessed++;
1432  } else {
1433  DebugStop();
1434  }
1435  }
1436  }
1437  NumelColors[currentPassIndex] = nelProcessed;
1438  currentPassIndex++;
1439  }
1440 
1441  NumelColors[currentPassIndex] = NumelColors[currentPassIndex - 1] + 1;
1442  NumelColors.Resize(currentPassIndex + 1);
1443 
1444 #ifdef PZDEBUG
1445  std::ofstream toto("../ColorMeshDebug.txt");
1446  toto << "elSequence\n" << elSequence << std::endl;
1447  toto << "elSequenceColor\n" << elSequenceColor << std::endl;
1448  toto << "elSequenceColorInv\n" << elSequenceColorInv << std::endl;
1449  toto << "elBlocked\n" << elBlocked << std::endl;
1450  toto << "elContribute\n" << elContribute << std::endl;
1451  toto << "passIndex\n" << passIndex << std::endl;
1452  toto << "NumelColors\n" << NumelColors << std::endl;
1453  toto.close();
1454 #endif
1455 }
1456 
1458  int64_t numelconnected = 0;
1459  int64_t nconnect = cmesh->NConnects();
1460  //firstelconnect contains the first element index in the elconnect vector
1461  TPZVec<int64_t> firstelconnect(nconnect + 1);
1462  firstelconnect[0] = 0;
1463  for (int64_t ic = 0; ic < nconnect; ic++) {
1464  numelconnected += cmesh->ConnectVec()[ic].NElConnected();
1465  firstelconnect[ic + 1] = firstelconnect[ic] + cmesh->ConnectVec()[ic].NElConnected();
1466  }
1467  //cout << "numelconnected " << numelconnected << endl;
1468  //cout << "firstelconnect ";
1469  // for(ic=0; ic<nconnect; ic++) cout << firstelconnect[ic] << ' ';
1470  TPZVec<int64_t> elconnect(numelconnected, -1);
1471  int64_t el;
1472  TPZCompEl *cel;
1473 
1474 #ifdef NOORDER
1475  int64_t count = 0;
1476  std::cout << __PRETTY_FUNCTION__ << " no element order\n";
1477  ElementOrder.Resize(cmesh->NElements(), -1);
1478  for (el = 0; el < cmesh->ElementVec().NElements(); el++) {
1479  cel = cmesh->ElementVec()[el];
1480  if (!cel) continue;
1481  ElementOrder[count] = el;
1482  count++;
1483  }
1484  ElementOrder.Resize(count);
1485  return;
1486 #endif
1487  for (el = 0; el < cmesh->ElementVec().NElements(); el++) {
1488  cel = cmesh->ElementVec()[el];
1489  if (!cel) continue;
1490  TPZStack<int64_t> connectlist;
1491  cel->BuildConnectList(connectlist);
1492  int64_t nc = connectlist.NElements();
1493  for (int64_t ic = 0; ic < nc; ic++) {
1494  int64_t cindex = connectlist[ic];
1495  elconnect[firstelconnect[cindex]] = el;
1496  firstelconnect[cindex]++;
1497  }
1498  }
1499  // for(ic=0; ic<numelconnected; ic++) cout << elconnect[ic] << endl;
1500  firstelconnect[0] = 0;
1501  for (int64_t ic = 0; ic < nconnect; ic++) {
1502  firstelconnect[ic + 1] = firstelconnect[ic] + cmesh->ConnectVec()[ic].NElConnected();
1503  }
1504  //cout << "elconnect\n";
1505  // int no;
1506  // for(no=0; no< fMesh->ConnectVec().NElements(); no++) {
1507  //cout << "no numero " << no << ' ' << " seq num " << fMesh->ConnectVec()[no].SequenceNumber() << ' ';
1508  // for(ic=firstelconnect[no]; ic<firstelconnect[no+1];ic++) cout << elconnect[ic] << ' ';
1509  //cout << endl;
1510  // }
1511 
1512  ElementOrder.Resize(cmesh->ElementVec().NElements(), -1);
1513  ElementOrder.Fill(-1);
1514  TPZVec<int64_t> nodeorder(cmesh->ConnectVec().NElements(), -1);
1515  firstelconnect[0] = 0;
1516  for (int64_t ic = 0; ic < nconnect; ic++) {
1517  int64_t seqnum = cmesh->ConnectVec()[ic].SequenceNumber();
1518  if (seqnum >= 0) nodeorder[seqnum] = ic;
1519  }
1520  // cout << "nodeorder ";
1521  /* for(ic=0; ic<fMesh->ConnectVec().NElements(); ic++) cout << nodeorder[ic] << ' ';
1522  cout << endl;
1523  cout.flush();*/
1524  int64_t elsequence = 0;
1525  TPZVec<int> elorderinv(cmesh->ElementVec().NElements(), -1);
1526  for (int64_t seq = 0; seq < nconnect; seq++) {
1527  int64_t ic = nodeorder[seq];
1528  if (ic == -1) continue;
1529  int64_t firstind = firstelconnect[ic];
1530  int64_t lastind = firstelconnect[ic + 1];
1531  for (int64_t ind = firstind; ind < lastind; ind++) {
1532  el = elconnect[ind];
1533  if (el == -1) {
1534  continue;
1535  }
1536  if (elorderinv[el] == -1) elorderinv[el] = elsequence++;
1537  }
1538  }
1539  // cout << "elorderinv ";
1540  // for(seq=0;seq<fMesh->ElementVec().NElements();seq++) cout << elorderinv[seq] << ' ';
1541  // cout << endl;
1542  elsequence = 0;
1543  for (int64_t seq = 0; seq < cmesh->ElementVec().NElements(); seq++) {
1544  if (elorderinv[seq] == -1) continue;
1545  ElementOrder[elorderinv[seq]] = seq;
1546  }
1547  int64_t seq;
1548  for (seq = 0; seq < cmesh->ElementVec().NElements(); seq++) {
1549  if (ElementOrder[seq] == -1) break;
1550  }
1551 
1552  ElementOrder.Resize(seq);
1553 }
1554 
1556  return Hash("TPZStructMatrixOT") ^ TPZStructMatrixBase::ClassId() << 1;
1557 }
1558 
1559 //#ifdef USING_TBB
1560 //
1561 //TPZStructMatrixOT::WorkResidualTBB::WorkResidualTBB(int elem, ThreadData *data)
1562 //:fElem(elem), data(data)
1563 //{
1564 //
1565 //
1566 //
1567 //}
1568 //void TPZStructMatrixOT::WorkResidualTBB::operator()()
1569 //{
1570 // TPZCompMesh *cmesh = data->fStruct->Mesh();
1571 // TPZAutoPointer<TPZGuiInterface> guiInterface = data->fGuiInterface;
1572 // TPZElementMatrix ek(cmesh,TPZElementMatrix::EK);
1573 // TPZElementMatrix ef(cmesh,TPZElementMatrix::EF);
1574 //
1575 // int element = (*data->felSequenceColor)[fElem];
1576 //
1577 // if (element >= 0) {
1578 //
1579 // TPZCompEl *el = cmesh->ElementVec()[element];
1580 //
1581 // if (data->fGlobMatrix) {
1582 // el->CalcStiff(ek,ef);
1583 // } else {
1584 // el->CalcResidual(ef);
1585 // }
1586 //
1587 // if(!el->HasDependency()) {
1588 // ef.ComputeDestinationIndices();
1589 // data->fStruct->FilterEquations(ef.fSourceIndex,ef.fDestinationIndex);
1590 // } else {
1591 // // the element has dependent nodes
1592 // ef.ApplyConstraints();
1593 // ef.ComputeDestinationIndices();
1594 // data->fStruct->FilterEquations(ef.fSourceIndex,ef.fDestinationIndex);
1595 //
1596 // if (data->fGlobMatrix) {
1597 // ek.ApplyConstraints();
1598 // ek.ComputeDestinationIndices();
1599 // }
1600 // }
1601 //
1602 // if(!ef.HasDependency()) {
1603 // data->fGlobRhs->AddFel(ef.fMat,ef.fSourceIndex,ef.fDestinationIndex);
1604 // if (data->fGlobMatrix) {
1605 // data->fGlobMatrix->AddKel(ek.fMat,ek.fSourceIndex,ek.fDestinationIndex);
1606 // }
1607 // }
1608 // else {
1609 // data->fGlobRhs->AddFel(ef.fConstrMat,ef.fSourceIndex,ef.fDestinationIndex);
1610 // if (data->fGlobMatrix) {
1611 // data->fGlobMatrix->AddKel(ek.fConstrMat,ek.fSourceIndex,ek.fDestinationIndex);
1612 // }
1613 // }
1614 // }
1615 //}
1616 //
1617 //#endif
1618 
1619 void TPZStructMatrixOT::Read(TPZStream& buf, void* context) {
1620  TPZStructMatrixBase::Read(buf, context);
1621 
1622  buf.Read(fElBlocked);
1623  buf.Read(fElSequenceColor);
1624  buf.Read(&fElementCompleted);
1625  buf.Read(&fSomeoneIsSleeping);
1626 #ifdef USING_BOOST
1627  int64_t fCurrentIndexLong;
1628  buf.Read(&fCurrentIndexLong);
1629  fCurrentIndex = fCurrentIndexLong;
1630 #endif
1631 }
1632 
1633 void TPZStructMatrixOT::Write(TPZStream& buf, int withclassid) const {
1634  TPZStructMatrixBase::Write(buf, withclassid);
1635 
1636  buf.Write(fElBlocked);
1637  buf.Write(fElSequenceColor);
1638  buf.Write(&fElementCompleted);
1639  buf.Write(&fSomeoneIsSleeping);
1640 #ifdef USING_BOOST
1641  int64_t fCurrentIndexLong;
1642  fCurrentIndexLong = fCurrentIndex;
1643  buf.Write(&fCurrentIndexLong);
1644 #endif
1645 }
1646 
1647 template class TPZRestoreClass<TPZStructMatrixOT>;
int64_t NElements() const
Number of computational elements allocated.
Definition: pzcmesh.h:169
Contains a class to record running statistics on CSV tables.
int fNumThreads
Number of threads in Assemble process.
int fSomeoneIsSleeping
variable indicating if a thread is sleeping
The timer class. Utility.
Definition: TPZTimer.h:46
Contains TPZAnalysis class which implements the sequence of actions to perform a finite element analy...
void Scatter(const TPZFMatrix< TVar > &vsmall, TPZFMatrix< TVar > &vexpand) const
RunStatsTable stat_ass_graph_ot("-ass_graph_ot", "Run statistics table for the graph creation and coloring TPZStructMatrixOT.")
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.
ThreadData(TPZStructMatrixOT *strmat, int seqnum, TPZMatrix< STATE > &mat, TPZFMatrix< STATE > &rhs, std::set< int > &MaterialIds, TPZAutoPointer< TPZGuiInterface > guiInterface)
Initialize the mutex semaphores and others.
TPZVec< int64_t > * fElSequenceColor
Contains the TPZStructMatrixOT class which responsible for a interface among Matrix and Finite Elemen...
TPZVec< int64_t > * fElBlocked
Vector for mesh coloring.
Timing class. Absolutely copied from GNU time. Take a look at
virtual void BuildConnectList(std::set< int64_t > &indepconnectlist, std::set< int64_t > &depconnectlist)
Builds the list of all connectivities related to the element including the connects pointed to by dep...
Definition: pzcompel.cpp:435
static void * ThreadWorkResidual(void *datavoid)
Contains declaration of TPZGeoNode class which defines a geometrical node.
virtual TPZCompMesh * Mesh() const
Access method for the mesh pointer.
void Filter(TPZVec< int64_t > &orig, TPZVec< int64_t > &dest) const
void AddFel(TPZFMatrix< TVar > &rhs, TPZVec< int64_t > &destination)
Performs a right hand side assemblage.
Definition: pzfmatrix.cpp:209
TPZVec< int64_t > fElBlocked
Vectors for mesh coloring.
virtual void Serial_Assemble(TPZMatrix< STATE > &mat, TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface)
Assemble the global system of equations into the matrix which has already been created.
TPZFNMatrix< 1000, STATE > fMat
Pointer to a blocked matrix object.
Definition: pzelmat.h:41
Contains declaration of TPZCompEl class which defines the interface of a computational element...
Templated vector implementation.
~ThreadData()
Destructor: Destroy the mutex semaphores and others.
int ClassId() const override
Define the class id associated with the class.
Structure to manipulate thread to solve system equations.
virtual void CalcStiff(TPZElementMatrix &ek, TPZElementMatrix &ef)
Computes the element stifness matrix and right hand side.
Definition: pzcompel.h:794
virtual TPZMatrix< STATE > * CreateAssemble(TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface, unsigned numthreads_assemble, unsigned numthreads_decompose)
Definition: pzstrmatrixot.h:60
void LeaveCriticalSection(pz_critical_section_t &cs)
static void ElementColoring(TPZCompMesh *cmesh, TPZVec< int64_t > &elSequence, TPZVec< int64_t > &elSequenceColor, TPZVec< int64_t > &elBlocked, TPZVec< int64_t > &NumelColors)
Create blocks of elements to parallel processing.
int64_t * fElementCompleted
All elements below or equal this index have been computed.
TPZEquationFilter fEquationFilter
Object which will determine which equations will be assembled.
Declarates the TPZBlock<REAL>class which implements block matrices.
int64_t NElements() const
Access method to query the number of elements of the vector.
Implements a chunk vector with free store administration. Utility.
Definition: TPZStream.h:39
static void * ThreadWork(void *threaddata)
The function which will compute the matrices.
#define MAX(a, b)
Gets maxime value between a and b.
Definition: pzreal.h:81
virtual int NSides() const =0
Returns the number of connectivities of the element.
int ClassId() const override
Define the class id associated with the class.
virtual void FilterEquations(TPZVec< int64_t > &origindex, TPZVec< int64_t > &destindex) const override
Filter out the equations which are out of the range.
void EnterCriticalSection(pz_critical_section_t &cs)
TPZManVector< int64_t > fDestinationIndex
Definition: pzelmat.h:53
void ComputeDestinationIndices()
Definition: pzelmat.cpp:126
Refines geometrical mesh (all the elements) num times.
Definition: pzstrmatrixot.h:44
static int64_t MinPassIndex(TPZStack< int64_t > &connectlist, TPZVec< int64_t > &elContribute, TPZVec< int64_t > &passIndex)
This abstract class defines the behaviour which each derived class needs to implement.
Definition: TPZMaterial.h:39
Contains declaration of TPZElementMatrix struct which associates an element matrix with the coeficien...
int64_t fElementCompleted
All elements below or equal this index have been computed.
virtual void CenterPoint(int side, TPZVec< REAL > &masscent) const =0
It returns the coordinates from the center of the side of the element in the element coordinate space...
TPZCompMesh * fMesh
Pointer to the computational mesh from which the matrix will be generated.
#define PZ_PTHREAD_JOIN(thread, val, fn)
Definition: pz_pthread.h:34
TPZVec< int64_t > fElSequenceColor
virtual TPZMaterial * Material() const
Identify the material object associated with the element.
Definition: pzcompel.cpp:959
virtual void MultiThread_Assemble(TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface)
Assemble the global right hand side.
void Print(std::ostream &out)
Definition: pzelmat.cpp:47
pthread_mutex_t fAccessElement
Mutexes (to choose which element is next)
int64_t size() const
Returns the number of elements of the vector.
Definition: pzvec.h:196
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Definition: pzvec.h:373
TPZCompEl * Element(int64_t iel)
Definition: pzcmesh.h:185
const std::set< int > & MaterialIds() override
Returns the material ids.
Contains declaration of TPZMesh class which defines a geometrical mesh and contains a corresponding l...
int64_t NActiveEquations() const
Retorna o numero de equacoes ativas do sistema.
int nthreads
Definition: numatst.cpp:315
#define LOGPZ_INFO(A, B)
Define log for informations.
Definition: pzlog.h:89
static RunStatsTable ass_rhs("-ass_rhs", "Assemble Stiffness")
std::string & processName()
Gets the process name (for reporting purposes).
Definition: TPZTimer.h:168
void start()
Turns the timer on.
Definition: TPZTimer.cpp:28
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
Defines the behaviour of all geometric elements. GeometryTPZGeoEl is the common denominator for all g...
Definition: pzgeoel.h:43
int64_t Index() const
Returns the index of the element within the element vector of the mesh.
Definition: pzgeoel.h:730
TVar Norm(const TPZFMatrix< TVar > &A)
Returns the norm of the matrix A.
Contains TPZMatrixclass which implements full matrix (using column major representation).
Implements a group of computational elements as a mesh and an element. Computational Mesh...
Definition: pzsubcmesh.h:36
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
friend struct ThreadData
Free store vector implementation.
TPZAutoPointer< TPZGuiInterface > fGuiInterface
Gui interface object.
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
virtual void AddKel(TPZFMatrix< TVar > &elmat, TPZVec< int64_t > &destinationindex)
Add a contribution of a stiffness matrix.
Definition: pzmatrix.cpp:506
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
static void AssembleColor(int64_t el, TPZStack< int64_t > &connectlist, TPZVec< int64_t > &elContribute)
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
#define PZ_PTHREAD_MUTEX_DESTROY(mutex, fn)
Definition: pz_pthread.h:73
int64_t NEqExpand() const
Retorna o numero de equacoes do sistema original.
TPZMatrix< STATE > * fGlobMatrix
Global matrix.
int64_t NConnects() const
Number of connects allocated including free nodes.
Definition: pzcmesh.h:163
TPZAdmChunkVector< TPZConnect > & ConnectVec()
Return a reference to the connect pointers vector.
Definition: pzcmesh.h:198
int64_t Index() const
Returns element index of the mesh fELementVec list.
Definition: pzcompel.h:821
Implements an interface to check the consistency of two implementations. Utility. ...
TPZManVector< int64_t > fSourceIndex
Definition: pzelmat.h:53
virtual void InitializeElementMatrix(TPZElementMatrix &ek, TPZElementMatrix &ef)
Initialize element matrix in which is computed CalcStiff.
std::set< int > fMaterialIds
Set of material ids to be considered. It is a private attribute.
static int64_t WhoBlockedMe(TPZStack< int64_t > &connectlist, TPZVec< int64_t > &elContribute, TPZVec< int64_t > &elSequenceColorInv)
#define LOGPZ_ERROR(A, B)
Define log for errors (cout)
Definition: pzlog.h:93
Contains declaration of TPZCompMesh class which is a repository for computational elements...
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
Definition: pzfmatrix.h:616
bool NeedsComputing(const std::set< int > &matids) override
Verifies if any element needs to be computed corresponding to the material ids.
int32_t Hash(std::string str)
Definition: TPZHash.cpp:10
virtual TPZStructMatrixOT * Clone() override
TPZVec< int64_t > * fComputedElements
vector indicating whether an element has been computed
This class associates an element matrix with the coeficients of its contribution in the global stiffn...
Definition: pzelmat.h:30
TPZFNMatrix< 1000, STATE > fConstrMat
Pointer to the constrained matrix object.
Definition: pzelmat.h:48
void ApplyConstraints()
Apply the constraints applied to the nodes by transforming the tangent matrix and right hand side...
Definition: pzelmat.cpp:186
Contains declaration of TPZSubCompMesh class which implements a group of computational elements as a ...
virtual int Dimension() const =0
Returns the dimension of the element.
TPZFMatrix< STATE > * fGlobRhs
Global rhs vector.
virtual void CalcResidual(TPZElementMatrix &ef)
Computes the element right hand side.
Definition: pzcompel.cpp:610
TPZGeoEl * Reference() const
Return a pointer to the corresponding geometric element if such exists, return 0 otherwise.
Definition: pzcompel.cpp:1137
virtual void X(TPZVec< REAL > &qsi, TPZVec< REAL > &result) const =0
Return the coordinate in real space of the point coordinate in the master element space...
void Read(TPZStream &buf, void *context) override
read objects from the stream
pthread_cond_t fCondition
static RunStatsTable ass_stiff("-ass_stiff", "Assemble Stiffness")
Implements computational mesh. Computational Mesh.
Definition: pzcmesh.h:47
TPZAdmChunkVector< TPZCompEl * > & ElementVec()
Returns a reference to the element pointers vector.
Definition: pzcmesh.h:183
#define PZ_PTHREAD_CREATE(thread, attr, routine, args, fn)
Definition: pz_pthread.h:31
virtual int GetNumThreads() const
Contains declaration of TPZInterpolatedElement class which implements computational element of the in...
int Id() const
Definition: TPZMaterial.h:170
void Fill(const T &copy, const int64_t from=0, const int64_t numelem=-1)
Will fill the elements of the vector with a copy object.
Definition: pzvec.h:460
int fThreadSeqNum
sequence number of the thread
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
pthread_mutex_t * fAccessElement
Mutexes (to choose which element is next)
virtual void Print(std::ostream &out) const
Definition: pzmatrix.h:253
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
void stop()
Turns the timer off, and computes the elapsed time.
Definition: TPZTimer.cpp:36
int64_t NElements() const
Returns the number of elements of the vector.
Definition: pzvec.h:190
virtual TPZMatrix< STATE > * Create() override
bool ShouldCompute(int matid) const override
Establish whether the element should be computed.
#define PZ_PTHREAD_MUTEX_INIT(mutex, attr, fn)
Definition: pz_pthread.h:70
static void OrderElement(TPZCompMesh *cmesh, TPZVec< int64_t > &ElementOrder)
Find the order to assemble the elements.
Defines the interface of a computational element. Computational Element.
Definition: pzcompel.h:59
virtual int HasDependency()
Returns 1 if the element has at least one dependent node. Returns 0 otherwise.
Definition: pzcompel.cpp:565
virtual void Assemble(TPZMatrix< STATE > &mat, TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface) override
Assemble the global system of equations into the matrix which has already been created.
bool HasDependency()
Returns true if the element has at least one dependent node. Returns false otherwise.
Definition: pzelmat.cpp:482
void Read(TPZStream &buf, void *context) override
read objects from the stream
Implements computational element based on an interpolation space. Computational Element.
Definition: pzintel.h:27
Implements an interface to register a class id and a restore function. Persistence.
Definition: TPZSavable.h:150
TPZVec< int64_t > fElementsComputed
vector of the size of the elements containing 0 or 1 if the element has been computed (in the order o...
Contains TPZSFMatrix class which implements a symmetric full matrix.
TPZStructMatrixOT * fStruct
Current structmatrix object.
virtual void Read(bool &val)
Definition: TPZStream.cpp:91