NeoPZ
pzstrmatrix.cpp
Go to the documentation of this file.
1 
6 #include "pzstrmatrix.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 "pzelementgroup.h"
19 #include "pzanalysis.h"
20 #include "pzsfulmat.h"
21 
22 #include "pzgnode.h"
23 #include "TPZTimer.h"
24 #include "TPZThreadTools.h"
25 
26 #include "pzcheckmesh.h"
27 #include "pzcheckconsistency.h"
28 #include "TPZMaterial.h"
29 #include "run_stats_table.h"
30 
31 using namespace std;
32 
33 #include "pzlog.h"
34 
35 #include "pz_pthread.h"
36 
37 #ifdef LOG4CXX
38 static LoggerPtr logger(Logger::getLogger("pz.strmatrix.TPZStructMatrixOR"));
39 static LoggerPtr loggerel(Logger::getLogger("pz.strmatrix.element"));
40 static LoggerPtr loggerel2(Logger::getLogger("pz.strmatrix.elementinterface"));
41 static LoggerPtr loggerelmat(Logger::getLogger("pz.strmatrix.elementmat"));
42 static LoggerPtr loggerCheck(Logger::getLogger("pz.strmatrix.checkconsistency"));
43 static LoggerPtr loggerGlobStiff(Logger::getLogger("pz.strmatrix.globalstiffness"));
44 #endif
45 
46 #ifdef CHECKCONSISTENCY
47 static TPZCheckConsistency stiffconsist("ElementStiff");
48 #endif
49 
51 }
52 
54 
55 }
56 
58 
59 }
60 
62 
63 }
64 
66  cout << "TPZStructMatrixOR::Create should never be called\n";
67  return 0;
68 }
69 
71  cout << "TPZStructMatrixOR::Clone should never be called\n";
72  DebugStop();
73  return 0;
74 }
75 
76 
77 static RunStatsTable ass_stiff("-ass_stiff", "Assemble Stiffness");
78 static RunStatsTable ass_rhs("-ass_rhs", "Assemble Stiffness");
79 
81  ass_stiff.start();
82  if (fEquationFilter.IsActive()) {
83  int64_t neqcondense = fEquationFilter.NActiveEquations();
84 #ifdef PZDEBUG
85  if (stiffness.Rows() != neqcondense) {
86  DebugStop();
87  }
88 #endif
89  TPZFMatrix<STATE> rhsloc(neqcondense, rhs.Cols(), 0.);
90  if (this->fNumThreads) {
91  this->MultiThread_Assemble(stiffness, rhsloc, guiInterface);
92  } else {
93  this->Serial_Assemble(stiffness, rhsloc, guiInterface);
94  }
95 
96  fEquationFilter.Scatter(rhsloc, rhs);
97  } else {
98  if (this->fNumThreads) {
99  this->MultiThread_Assemble(stiffness, rhs, guiInterface);
100  } else {
101  this->Serial_Assemble(stiffness, rhs, guiInterface);
102  }
103  }
104  ass_stiff.stop();
105 }
106 
108  ass_rhs.start();
109  if (fEquationFilter.IsActive()) {
110  int64_t neqcondense = fEquationFilter.NActiveEquations();
111  int64_t neqexpand = fEquationFilter.NEqExpand();
112  if (rhs.Rows() != neqexpand || Norm(rhs) != 0.) {
113  DebugStop();
114  }
115  TPZFMatrix<STATE> rhsloc(neqcondense, 1, 0.);
116  if (this->fNumThreads) {
117  this->MultiThread_Assemble(rhsloc, guiInterface);
118  } else {
119  this->Serial_Assemble(rhsloc, guiInterface);
120  }
121  fEquationFilter.Scatter(rhsloc, rhs);
122  } else {
123  if (this->fNumThreads) {
124  this->MultiThread_Assemble(rhs, guiInterface);
125  } else {
126  this->Serial_Assemble(rhs, guiInterface);
127  }
128  }
129  ass_rhs.stop();
130 }
131 
133 #ifdef PZDEBUG
134  TExceptionManager activateExceptions;
135 #endif
136  if (!fMesh) {
137  LOGPZ_ERROR(logger, "Serial_Assemble called without mesh")
138  DebugStop();
139  }
140 #ifdef LOG4CXX
141  if (loggerelmat->isDebugEnabled()) {
142  if (dynamic_cast<TPZSubCompMesh *> (fMesh)) {
143  std::stringstream sout;
144  sout << "AllEig = {};";
145  LOGPZ_DEBUG(loggerelmat, sout.str())
146  }
147  }
148 #endif
149 
150 #ifdef PZDEBUG
151  if (rhs.Rows() != fEquationFilter.NActiveEquations()) {
152  DebugStop();
153  }
154 #endif
155 
156  int64_t iel;
157  int64_t nelem = fMesh->NElements();
159 #ifdef LOG4CXX
160  bool globalresult = true;
161  bool writereadresult = true;
162 #endif
163  TPZTimer calcstiff("Computing the stiffness matrices");
164  TPZTimer assemble("Assembling the stiffness matrices");
166 
167  int64_t count = 0;
168  for (iel = 0; iel < nelem; iel++) {
169  TPZCompEl *el = elementvec[iel];
170  if (!el) continue;
171  int matid = 0;
172  TPZGeoEl *gel = el->Reference();
173  if (gel) {
174  matid = gel->MaterialId();
175  }
176  int matidsize = fMaterialIds.size();
177  if(matidsize){
178  if(!el->NeedsComputing(fMaterialIds)) continue;
179  }
180 
181  count++;
182  if (!(count % 1000)) {
183  std::cout << '*';
184  std::cout.flush();
185  }
186  if (!(count % 20000)) {
187  std::cout << "\n";
188  }
189  calcstiff.start();
190  ek.Reset();
191  ef.Reset();
192  el->CalcStiff(ek, ef);
193  if (guiInterface) if (guiInterface->AmIKilled()) {
194  return;
195  }
196 
197 #ifdef LOG4CXX
198  if (loggerelmat->isDebugEnabled()) {
199  if (dynamic_cast<TPZSubCompMesh *> (fMesh)) {
200  std::stringstream objname;
201  objname << "Element" << iel;
202  std::string name = objname.str();
203  objname << " = ";
204  std::stringstream sout;
205  ek.fMat.Print(objname.str().c_str(), sout, EMathematicaInput);
206  sout << "AppendTo[AllEig,Eigenvalues[" << name << "]];";
207 
208  LOGPZ_DEBUG(loggerelmat, sout.str())
209  /* if(iel == 133)
210  {
211  std::stringstream sout2;
212  el->Reference()->Print(sout2);
213  el->Print(sout2);
214  LOGPZ_DEBUG(logger,sout2.str())
215  }
216  */
217  }
218  }
219 #endif
220 
221 #ifdef CHECKCONSISTENCY
222  //extern TPZCheckConsistency stiffconsist("ElementStiff");
223  stiffconsist.SetOverWrite(true);
224  bool result;
225  result = stiffconsist.CheckObject(ek.fMat);
226  if (!result) {
227  globalresult = false;
228  std::stringstream sout;
229  sout << "element " << iel << " computed differently";
230  LOGPZ_ERROR(loggerCheck, sout.str())
231  }
232 
233 #endif
234 
235  calcstiff.stop();
236  assemble.start();
237 
238  if (!ek.HasDependency()) {
239  ek.ComputeDestinationIndices();
240  fEquationFilter.Filter(ek.fSourceIndex, ek.fDestinationIndex);
241  // TPZSFMatrix<STATE> test(stiffness);
242  // TPZFMatrix<STATE> test2(stiffness.Rows(),stiffness.Cols(),0.);
243  // stiffness.Print("before assembly",std::cout,EMathematicaInput);
244  stiffness.AddKel(ek.fMat, ek.fSourceIndex, ek.fDestinationIndex);
245 #ifdef PZDEBUG
246  REAL rhsnorm = Norm(ef.fMat);
247  REAL eknorm = Norm(ek.fMat);
248  if (std::isnan(rhsnorm) || std::isnan(eknorm)) {
249  std::cout << "element " << iel << " has norm " << rhsnorm << std::endl;
250  el->Print();
251  ek.fMat.Print("ek",std::cout);
252  ef.fMat.Print("ef",std::cout);
253  }
254 #endif
255  rhs.AddFel(ef.fMat, ek.fSourceIndex, ek.fDestinationIndex);
256  // stiffness.Print("stiffness after assembly STK = ",std::cout,EMathematicaInput);
257  // rhs.Print("rhs after assembly Rhs = ",std::cout,EMathematicaInput);
258  // test2.AddKel(ek.fMat,ek.fSourceIndex,ek.fDestinationIndex);
259  // test -= stiffness;
260  // test.Print("matriz de rigidez diference",std::cout);
261  // test2.Print("matriz de rigidez interface",std::cout);
262 #ifdef LOG4CXX
263  if (loggerel->isDebugEnabled()) {
264  std::stringstream sout;
265  TPZGeoEl *gel = el->Reference();
266  if (gel) {
267  TPZManVector<REAL> center(gel->Dimension()), xcenter(3, 0.);
268  gel->CenterPoint(gel->NSides() - 1, center);
269  gel->X(center, xcenter);
270  sout << "Stiffness for computational element index " << el->Index() << " material id " << gel->MaterialId() << std::endl;
271  sout << "Stiffness for geometric element " << gel->Index() << " center " << xcenter << std::endl;
272  } else {
273  sout << "Stiffness for computational element without associated geometric element index " << el->Index() << "\n";
274  }
275  ek.Print(sout);
276  ef.Print(sout);
277  LOGPZ_DEBUG(loggerel, sout.str())
278  }
279 #endif
280  } else {
281  // the element has dependent nodes
282  ek.ApplyConstraints();
283  ef.ApplyConstraints();
284  ek.ComputeDestinationIndices();
285  fEquationFilter.Filter(ek.fSourceIndex, ek.fDestinationIndex);
286  stiffness.AddKel(ek.fConstrMat, ek.fSourceIndex, ek.fDestinationIndex);
287  rhs.AddFel(ef.fConstrMat, ek.fSourceIndex, ek.fDestinationIndex);
288 
289 #ifdef LOG4CXX
290  if (loggerel->isDebugEnabled()) {
291  std::stringstream sout;
292  TPZGeoEl *gel = el->Reference();
293  // el->Print();
294  // int nc = el->NConnects();
295  // for (int ic=0; ic<nc; ic++) {
296  // std::cout << "Index " << el->ConnectIndex(ic) << " ";
297  // el->Connect(ic).Print(*fMesh);
298  // fMesh->ConnectVec()[ic].Print(*fMesh);
299  // }
300  if (gel) {
301  TPZManVector<REAL> center(gel->Dimension()), xcenter(3, 0.);
302  gel->CenterPoint(gel->NSides() - 1, center);
303  gel->X(center, xcenter);
304  sout << "Stiffness for geometric element " << gel->Index() << " center " << xcenter << std::endl;
305  } else {
306  sout << "Stiffness for computational element index " << iel << std::endl;
307  }
308  ek.Print(sout);
309  ef.Print(sout);
310  LOGPZ_DEBUG(loggerel, sout.str())
311  }
312 #endif
313  }
314  // tototototo
315  // GK.Multiply(Sol, GKSol);
316  // GKSol -= GF;
317  // GKSol.Transpose();
318  // {
319  // std::stringstream sout;
320  // sout << "Element " << iel << std::endl;
321  // std::stringstream str;
322  // str << "GKSol" << iel << " = ";
323  // GKSol.Print(str.str().c_str(),sout,EMathematicaInput);
324  // LOGPZ_DEBUG(logger, sout.str())
325  // }
326  // stiffness.Multiply(Sol, GKSol);
327  // GKSol -= rhs;
328  // GKSol.Transpose();
329  // {
330  // std::stringstream sout;
331  // sout << "Element " << iel << std::endl;
332  // std::stringstream str;
333  // str << "StiffSol" << iel << " = ";
334  // GKSol.Print(str.str().c_str(),sout,EMathematicaInput);
335  // LOGPZ_DEBUG(logger, sout.str())
336  // }
337  // {
338  // std::stringstream sout;
339  // sout << "Element " << iel << std::endl;
340  // std::stringstream str;
341  // str << "GK" << iel << " = ";
342  // GK.Print(str.str().c_str(),sout,EMathematicaInput);
343  // std::stringstream str2;
344  // str2 << "ST" << iel << " = ";
345  // stiffness.Print(str2.str().c_str(),sout,EMathematicaInput);
346  // sout << "GK-ST\n";
347  // LOGPZ_DEBUG(logger, sout.str())
348  // }
349  //
350  // stiffness.Zero();
351  // rhs.Zero();
352  assemble.stop();
353  }//fim for iel
354  if (count > 1000) std::cout << std::endl;
355 
356 #ifdef LOG4CXX
357  if (loggerCheck->isDebugEnabled()) {
358  std::stringstream sout;
359  sout << "The comparaison results are : consistency check " << globalresult << " write read check " << writereadresult;
360  LOGPZ_DEBUG(loggerCheck, sout.str())
361  }
362  if (loggerGlobStiff->isDebugEnabled())
363  {
364  std::stringstream sout;
365  stiffness.Print("GK = ",sout,EMathematicaInput);
366  rhs.Print("GR = ", sout,EMathematicaInput);
367  LOGPZ_DEBUG(loggerel,sout.str())
368  }
369 
370 #endif
371 
372 }
373 
375 
376  int64_t iel;
377  int64_t nelem = fMesh->NElements();
378 
379  TPZTimer calcresidual("Computing the residual vector");
380  TPZTimer assemble("Assembling the residual vector");
381 
383 
384  for (iel = 0; iel < nelem; iel++) {
385  TPZCompEl *el = elementvec[iel];
386  if (!el) continue;
387 
388  int matid = 0;
389  TPZGeoEl *gel = el->Reference();
390  if (gel) {
391  matid = gel->MaterialId();
392  }
393  int matidsize = fMaterialIds.size();
394  if(matidsize){
395  TPZMaterial * mat = el->Material();
396  TPZSubCompMesh *submesh = dynamic_cast<TPZSubCompMesh *> (el);
397  if (!mat)
398  {
399  if (!submesh) {
400  continue;
401  }
402  else if(submesh->NeedsComputing(fMaterialIds) == false) continue;
403  }
404  else
405  {
406  if (this->ShouldCompute(matid) == false) continue;
407  }
408  }
409 
411 
412  calcresidual.start();
413 
414  el->CalcResidual(ef);
415 
416  calcresidual.stop();
417 #ifdef LOG4CXX
418  if(loggerel->isDebugEnabled())
419  {
420  std::stringstream sout;
421  TPZGeoEl *gel = el->Reference();
422  if (gel) {
423  TPZManVector<REAL> center(gel->Dimension()), xcenter(3, 0.);
424  gel->CenterPoint(gel->NSides() - 1, center);
425  gel->X(center, xcenter);
426  sout << "Residual for computational element index " << el->Index() << " material id " << gel->MaterialId() << std::endl;
427  sout << "Residual for geometric element " << gel->Index() << " center " << xcenter << std::endl;
428  } else {
429  sout << "Residual for computational element without associated geometric element index " << el->Index() << "\n";
430  }
431  LOGPZ_DEBUG(loggerel, sout.str())
432  }
433 #endif
434  assemble.start();
435 
436  if (!ef.HasDependency()) {
439  rhs.AddFel(ef.fMat, ef.fSourceIndex, ef.fDestinationIndex);
440  } else {
441  // the element has dependent nodes
442  ef.ApplyConstraints();
446  }
447 #ifdef LOG4CXX
448  if(loggerel->isDebugEnabled())
449  {
450  std::stringstream sout;
451  ef.Print(sout);
452  LOGPZ_DEBUG(loggerel, sout.str())
453  }
454 #endif
455 
456  assemble.stop();
457 
458  }//fim for iel
459 #ifdef LOG4CXX
460  {
461  if (logger->isDebugEnabled()) {
462  std::stringstream sout;
463  sout << calcresidual.processName() << " " << calcresidual << std::endl;
464  sout << assemble.processName() << " " << assemble;
465  LOGPZ_DEBUG(logger, sout.str().c_str());
466  }
467  }
468 #endif
469  //std::cout << std::endl;
470 }
471 
473  ThreadData threaddata(this,mat,rhs,fMaterialIds,guiInterface);
474  const int numthreads = this->fNumThreads;
475  TPZVec<pthread_t> allthreads(numthreads);
476  int itr;
477  if (guiInterface) {
478  if (guiInterface->AmIKilled()) {
479  return;
480  }
481  }
482  for (itr = 0; itr < numthreads; itr++) {
483  PZ_PTHREAD_CREATE(&allthreads[itr], NULL, ThreadData::ThreadWork,
484  &threaddata, __FUNCTION__);
485  }
486 
487  ThreadData::ThreadAssembly(&threaddata);
488 
489  for (itr = 0; itr < numthreads; itr++) {
490  PZ_PTHREAD_JOIN(allthreads[itr], NULL, __FUNCTION__);
491  }
492 
493 #ifdef LOG4CXX2
494  if (loggerCheck->isDebugEnabled()) {
495  std::stringstream sout;
496  //stiffness.Print("Matriz de Rigidez: ",sout);
497  mat.Print("Matriz de Rigidez: ", sout, EMathematicaInput);
498  rhs.Print("Right Handside", sout, EMathematicaInput);
499  LOGPZ_DEBUG(loggerCheck, sout.str())
500  }
501 #endif
502 }
503 
505  ThreadData threaddata(this, rhs, fMaterialIds, guiInterface);
506  const int numthreads = this->fNumThreads;
507  TPZVec<pthread_t> allthreads(numthreads);
508  int itr;
509  if (guiInterface) {
510  if (guiInterface->AmIKilled()) {
511  return;
512  }
513  }
514 
515  for (itr = 0; itr < numthreads; itr++) {
516  PZ_PTHREAD_CREATE(&allthreads[itr], NULL, ThreadData::ThreadWork,
517  &threaddata, __FUNCTION__);
518  }
519 
520  ThreadData::ThreadAssembly(&threaddata);
521 
522  for (itr = 0; itr < numthreads; itr++) {
523  PZ_PTHREAD_JOIN(allthreads[itr], NULL, __FUNCTION__);
524  }
525 }
526 
528  TPZFMatrix<STATE> &rhs,
529  std::set<int> &MaterialIds,
530  TPZAutoPointer<TPZGuiInterface> guiInterface)
531 : fStruct(strmat), fGuiInterface(guiInterface), fGlobMatrix(&mat), fGlobRhs(&rhs), fNextElement(0) {
532 
533  PZ_PTHREAD_MUTEX_INIT(&fAccessElement, NULL, "TPZStructMatrixOR::ThreadData::ThreadData()");
534  /* sem_t *sem_open( ... );
535  int sem_close(sem_t *sem);
536  int sem_unlink(const char *name);
537  */
538  /*
539  #ifdef MACOSX
540  std::stringstream sout;
541  static int counter = 0;
542  sout << "AssemblySem" << counter++;
543  fAssembly = sem_open(sout.str().c_str(), O_CREAT,777,1);
544  if(fAssembly == SEM_FAILED)
545  {
546  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
547  DebugStop();
548  }
549  #else
550  int sem_result = sem_init(&fAssembly,0,0);
551  if(sem_result != 0)
552  {
553  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
554  }
555  #endif
556  */
557 }
558 
560  return Hash("TPZStructMatrixOR") ^ TPZStructMatrixBase::ClassId() << 1;
561 }
562 
563 void TPZStructMatrixOR::Read(TPZStream& buf, void* context) {
564  TPZStructMatrixBase::Read(buf,context);
565 }
566 
567 void TPZStructMatrixOR::Write(TPZStream& buf, int withclassid) const {
568  TPZStructMatrixBase::Write(buf,withclassid);
569 }
570 
571 
573  TPZFMatrix<STATE> &rhs,
574  std::set<int> &MaterialIds,
575  TPZAutoPointer<TPZGuiInterface> guiInterface)
576 : fStruct(strmat), fGuiInterface(guiInterface), fGlobMatrix(0), fGlobRhs(&rhs), fNextElement(0) {
577 
578  PZ_PTHREAD_MUTEX_INIT(&fAccessElement, NULL, "TPZStructMatrixOR::ThreadData::ThreadData()");
579  /* sem_t *sem_open( ... );
580  int sem_close(sem_t *sem);
581  int sem_unlink(const char *name);
582  */
583  /*
584  #ifdef MACOSX
585  std::stringstream sout;
586  static int counter = 0;
587  sout << "AssemblySem" << counter++;
588  fAssembly = sem_open(sout.str().c_str(), O_CREAT,777,1);
589  if(fAssembly == SEM_FAILED)
590  {
591  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
592  DebugStop();
593  }
594  #else
595  int sem_result = sem_init(&fAssembly,0,0);
596  if(sem_result != 0)
597  {
598  std::cout << __PRETTY_FUNCTION__ << " could not open the semaphore\n";
599  }
600  #endif
601  */
602 }
603 
605  PZ_PTHREAD_MUTEX_DESTROY(&fAccessElement, "TPZStructMatrixOR::ThreadData::~ThreadData()");
606  /*
607  #ifdef MACOSX
608  sem_close(fAssembly);
609  #else
610  sem_destroy(&fAssembly);
611  #endif
612  */
613 }
614 
615 //#define DRY_RUN
616 
618 #ifdef PZDEBUG
619  TExceptionManager activateExceptions;
620 #endif
621  ThreadData *data = (ThreadData *) datavoid;
622  // compute the next element (this method is threadsafe)
623  int64_t iel = data->NextElement();
624  TPZCompMesh *cmesh = data->fStruct->fMesh;
625  TPZAutoPointer<TPZGuiInterface> guiInterface = data->fGuiInterface;
626  int64_t nel = cmesh->NElements();
627  while (iel < nel) {
628 
631  if (data->fGlobMatrix) {
632  ek = new TPZElementMatrix(cmesh, TPZElementMatrix::EK);
633  } else {
634  ek = ef;
635  }
636 
637  TPZCompEl *el = cmesh->ElementVec()[iel];
638  TPZElementMatrix *ekp = ek.operator->();
639  TPZElementMatrix *efp = ef.operator->();
640  TPZElementMatrix &ekr = *ekp;
641  TPZElementMatrix &efr = *efp;
642 
643 #ifndef DRY_RUN
644  if (data->fGlobMatrix) {
645  el->CalcStiff(ekr, efr);
646  } else {
647  el->CalcResidual(efr);
648  }
649 #else
650  {
651  TPZInterpolatedElement *intel = dynamic_cast<TPZInterpolatedElement *> (el);
652  if (!intel) {
653  DebugStop();
654  }
655  if (data->fGlobMatrix) {
656  intel->InitializeElementMatrix(ekr, efr);
657  } else {
658  intel->InitializeElementMatrix(efr);
659  }
660  }
661 #endif
662 
663  if (guiInterface) if (guiInterface->AmIKilled()) {
664  break;
665  }
666 
667  if (!el->HasDependency()) {
669 
670  if (data->fStruct->HasRange()) {
672  }
673 #ifdef LOG4CXX
674  if (loggerel->isDebugEnabled()) {
675  std::stringstream sout;
676  sout << "Element index " << iel << std::endl;
677  ek->fMat.Print("Element stiffness matrix", sout);
678  ef->fMat.Print("Element right hand side", sout);
679  LOGPZ_DEBUG(loggerel, sout.str())
680  }
681 #endif
682  } else {
683  // the element has dependent nodes
684  if (data->fGlobMatrix) {
685  ek->ApplyConstraints();
686  }
687  ef->ApplyConstraints();
689  if (data->fStruct->HasRange()) {
691  }
692 #ifdef LOG4CXX
693  if (loggerel2->isDebugEnabled() && el->Reference() && el->Reference()->MaterialId() == 1 && el->IsInterface()) {
694  std::stringstream sout;
695  el->Reference()->Print(sout);
696  el->Print(sout);
697  ek->Print(sout);
698  // ef->Print(sout);
699  LOGPZ_DEBUG(loggerel2, sout.str())
700  }
701 #endif
702 #ifdef LOG4CXX
703  if (loggerel->isDebugEnabled()) {
704  std::stringstream sout;
705  sout << "Element index " << iel << std::endl;
706  ek->fConstrMat.Print("Element stiffness matrix", sout);
707  ef->fConstrMat.Print("Element right hand side", sout);
708  LOGPZ_DEBUG(loggerel, sout.str())
709  }
710 #endif
711  }
712 
713 
714  // put the elementmatrices on the stack to be assembled (threadsafe)
715  data->ComputedElementMatrix(iel, ek, ef);
716  // compute the next element (this method is threadsafe)
717  iel = data->NextElement();
718  }
719  PZ_PTHREAD_MUTEX_LOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadWork");
720  data->fAssembly.Post();
721  /*
722  #ifdef MACOSX
723  sem_post(data->fAssembly);
724  #else
725  sem_post(&data->fAssembly);
726  #endif
727  */
728  PZ_PTHREAD_MUTEX_UNLOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadWork");
729 
730  return 0;
731 }
732 
733 // The function which will compute the assembly
734 
736  ThreadData *data = (ThreadData *) threaddata;
737  TPZCompMesh *cmesh = data->fStruct->fMesh;
738  TPZAutoPointer<TPZGuiInterface> guiInterface = data->fGuiInterface;
739  int64_t nel = cmesh->NElements();
740  PZ_PTHREAD_MUTEX_LOCK(&(data->fAccessElement), "TPZStructMatrixOR::ThreadData::ThreadAssembly");
741  int64_t nextel = data->fNextElement;
742  int numprocessed = data->fProcessed.size();
743  while (nextel < nel || numprocessed) {
744  if (guiInterface) if (guiInterface->AmIKilled()) {
745  break;
746  }
747  std::map<int, std::pair< TPZAutoPointer<TPZElementMatrix>, TPZAutoPointer<TPZElementMatrix> > >::iterator itavail;
748  std::set<int>::iterator itprocess;
749  bool keeplooking = false;
750  if (data->fSubmitted.size() && data->fProcessed.size()) {
751  itavail = data->fSubmitted.begin();
752  itprocess = data->fProcessed.begin();
753  if (itavail->first == *itprocess) {
754  // make sure we come back to look for one more element
755  keeplooking = true;
756  // Get a hold of the data
757 #ifdef LOG4CXX
758  int iel = *itprocess;
759 #endif
760  data->fProcessed.erase(itprocess);
761  TPZAutoPointer<TPZElementMatrix> ek = itavail->second.first;
762  TPZAutoPointer<TPZElementMatrix> ef = itavail->second.second;
763  data->fSubmitted.erase(itavail);
764 #ifdef LOG4CXX
765  if (logger->isDebugEnabled()) {
766  std::stringstream sout;
767  sout << "Assembling element " << iel;
768  LOGPZ_DEBUG(logger, sout.str())
769  }
770 #endif
771 #ifdef CHECKCONSISTENCY
772  //static TPZCheckConsistency stiffconsist("ElementStiff");
773  stiffconsist.SetOverWrite(true);
774  bool result;
775  result = stiffconsist.CheckObject(ek->fMat);
776  if (!result) {
777  globalresult = false;
778  std::stringstream sout;
779  sout << "element " << iel << " computed differently";
780  LOGPZ_ERROR(loggerCheck, sout.str())
781  }
782 #endif
783 
784  // Release the mutex
785  PZ_PTHREAD_MUTEX_UNLOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadAssembly");
786 
787 #ifndef DRY_RUN
788  // Assemble the matrix
789  if (!ek->HasDependency()) {
790  if (data->fGlobMatrix) {
791  data->fGlobMatrix->AddKel(ek->fMat, ek->fSourceIndex, ek->fDestinationIndex);
792  }
793  data->fGlobRhs->AddFel(ef->fMat, ek->fSourceIndex, ek->fDestinationIndex);
794  } else {
795  if (data->fGlobMatrix) {
797  }
799  }
800 #endif
801  // acquire the mutex
802  PZ_PTHREAD_MUTEX_LOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadAssembly");
803  }
804  }
805  if (!keeplooking) {
806  PZ_PTHREAD_MUTEX_UNLOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadAssembly");
807 #ifdef LOG4CXX
808  if (logger->isDebugEnabled()) {
809  LOGPZ_DEBUG(logger, "Going to sleep within assembly")
810  }
811 #endif
812  // wait for a signal
813  data->fAssembly.Wait();
814  /*
815  #ifdef MACOSX
816  sem_wait(data->fAssembly);
817  #else
818  sem_wait(&data->fAssembly);
819  #endif
820  */
821 #ifdef LOG4CXX
822  if (logger->isDebugEnabled()) {
823  LOGPZ_DEBUG(logger, "Waking up for assembly")
824  }
825 #endif
826  PZ_PTHREAD_MUTEX_LOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadAssembly");
827  }
828  nextel = data->fNextElement;
829  numprocessed = data->fProcessed.size();
830 
831  }
832  // std::cout << std::endl;
833 #ifdef LOG4CXX
834  if (loggerCheck->isDebugEnabled()) {
835  std::stringstream sout;
836  sout << "nextel = " << nextel << " numprocessed = " << numprocessed << " submitted " << data->fSubmitted.size() << std::endl;
837  LOGPZ_DEBUG(loggerCheck, sout.str())
838  }
839 #endif
840 #ifdef LOG4CXX
841  if (loggerCheck->isDebugEnabled()) {
842  std::stringstream sout;
843  if (data->fGlobMatrix) {
844  data->fGlobMatrix->Print("Matriz de Rigidez: ", sout, EMathematicaInput);
845  }
846  data->fGlobRhs->Print("Right hand side", sout, EMathematicaInput);
847  LOGPZ_DEBUG(loggerCheck, sout.str())
848  }
849 #endif
850  PZ_PTHREAD_MUTEX_UNLOCK(&data->fAccessElement, "TPZStructMatrixOR::ThreadData::ThreadAssembly");
851  return 0;
852 }
853 
855  PZ_PTHREAD_MUTEX_LOCK(&fAccessElement, "TPZStructMatrixOR::ThreadData::NextElement()");
856  int64_t iel;
857  int64_t nextel = fNextElement;
858  TPZCompMesh *cmesh = fStruct->fMesh;
859  TPZAdmChunkVector<TPZCompEl *> &elementvec = cmesh->ElementVec();
860  int64_t nel = elementvec.NElements();
861  for (iel = fNextElement; iel < nel; iel++) {
862  TPZCompEl *el = elementvec[iel];
863  if (!el) continue;
864  if (fStruct->fMaterialIds.size() == 0) break;
865  if (el->NeedsComputing(fStruct->fMaterialIds)) break;
866  }
867  fNextElement = iel + 1;
868  nextel = iel;
869  if (iel < nel) fProcessed.insert(iel); //AQUIBORIN pelo que percebi, aqui tem que acontecer antes do unlock no caso sem Critical Section
870  PZ_PTHREAD_MUTEX_UNLOCK(&fAccessElement, "TPZStructMatrixOR::ThreadData::NextElement()");
871 #ifdef LOG4CXX
872  {
873  if (logger->isDebugEnabled()) {
874  std::stringstream sout;
875  sout << __PRETTY_FUNCTION__ << " returning " << nextel << " fNextElement " << fNextElement;
876  LOGPZ_DEBUG(logger, sout.str())
877  }
878  }
879 #endif
880  return nextel;
881 }
882 
883 
884 // put the computed element matrices in the map
885 
887  PZ_PTHREAD_MUTEX_LOCK(&fAccessElement, "TPZStructMatrixOR::ThreadData::ComputedElementMatrix()");
888  std::pair< TPZAutoPointer<TPZElementMatrix>, TPZAutoPointer<TPZElementMatrix> > el(ek, ef);
889  fSubmitted[iel] = el;
890  fAssembly.Post();
891  /*
892  #ifdef MACOSX
893  sem_post(fAssembly);
894  #else
895  sem_post(&fAssembly);
896  #endif
897  */
898  PZ_PTHREAD_MUTEX_UNLOCK(&fAccessElement, "TPZStructMatrixOR::ThreadData::ComputedElementMatrix()");
899 }
900 
int ClassId() const override
Define the class id associated with the class.
int64_t NElements() const
Number of computational elements allocated.
Definition: pzcmesh.h:169
static RunStatsTable ass_stiff("-ass_stiff", "Assemble Stiffness")
Contains a class to record running statistics on CSV tables.
int fNumThreads
Number of threads in Assemble process.
#define PZ_PTHREAD_MUTEX_UNLOCK(mutex, fn)
Definition: pz_pthread.h:79
TPZAutoPointer< TPZGuiInterface > fGuiInterface
Gui interface object.
Definition: pzstrmatrix.h:65
The timer class. Utility.
Definition: TPZTimer.h:46
Contains TPZAnalysis class which implements the sequence of actions to perform a finite element analy...
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
void Scatter(const TPZFMatrix< TVar > &vsmall, TPZFMatrix< TVar > &vexpand) const
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.
Structure to manipulate thread to solve system equations.
Definition: pzstrmatrix.h:40
int MaterialId() const
Returns the material index of the element.
Definition: pzgeoel.h:250
Timing class. Absolutely copied from GNU time. Take a look at
Contains declaration of TPZGeoNode class which defines a geometrical node.
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
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.
pthread_mutex_t fAccessElement
Mutexes (to choose which element is next)
Definition: pzstrmatrix.h:77
Contains the declaration of the TPZElementGroup class, which implements an computational element whic...
TPZFMatrix< STATE > * fGlobRhs
Global rhs vector.
Definition: pzstrmatrix.h:69
virtual bool NeedsComputing(const std::set< int > &materialids)
return true if the element has a variational statement associated with the material ids ...
Definition: pzcompel.h:170
virtual void CalcStiff(TPZElementMatrix &ek, TPZElementMatrix &ef)
Computes the element stifness matrix and right hand side.
Definition: pzcompel.h:794
~ThreadData()
Destructor: Destroy the mutex semaphores and others.
TPZEquationFilter fEquationFilter
Object which will determine which equations will be assembled.
Declarates the TPZBlock<REAL>class which implements block matrices.
This class implements a simple vector storage scheme for a templated class T. Utility.
Definition: pzgeopoint.h:19
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
std::map< int, std::pair< TPZAutoPointer< TPZElementMatrix >, TPZAutoPointer< TPZElementMatrix > > > fSubmitted
List of computed element matrices (autopointers?)
Definition: pzstrmatrix.h:71
virtual int NSides() const =0
Returns the number of connectivities of the element.
Contains the TPZStructMatrixOR class which responsible for a interface among Matrix and Finite Elemen...
int ClassId() const override
Define the class id associated with the class.
static void * ThreadWork(void *threaddata)
The function which will compute the matrices.
TPZManVector< int64_t > fDestinationIndex
Definition: pzelmat.h:53
void ComputeDestinationIndices()
Definition: pzelmat.cpp:126
virtual int IsInterface()
Definition: pzcompel.h:159
Refines geometrical mesh (all the elements) num times.
Definition: pzstrmatrix.h:35
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...
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
virtual const std::set< int > & MaterialIds()
Returns the material ids.
virtual TPZMaterial * Material() const
Identify the material object associated with the element.
Definition: pzcompel.cpp:959
virtual TPZStructMatrixOR * Clone() override
Definition: pzstrmatrix.cpp:70
void Print(std::ostream &out)
Definition: pzelmat.cpp:47
int64_t fNextElement
Current element.
Definition: pzstrmatrix.h:75
ThreadData(TPZStructMatrixOR *strmat, TPZMatrix< STATE > &mat, TPZFMatrix< STATE > &rhs, std::set< int > &MaterialIds, TPZAutoPointer< TPZGuiInterface > guiInterface)
Initialize the mutex semaphores and others.
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.
TPZStructMatrixOR * fStruct
Current structmatrix object.
Definition: pzstrmatrix.h:63
#define PZ_PTHREAD_MUTEX_LOCK(mutex, fn)
Definition: pz_pthread.h:76
std::string & processName()
Gets the process name (for reporting purposes).
Definition: TPZTimer.h:168
void start()
Turns the timer on.
Definition: TPZTimer.cpp:28
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
Free store vector implementation.
TPZMatrix< STATE > * fGlobMatrix
Global matrix.
Definition: pzstrmatrix.h:67
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
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.
int64_t NextElement()
Look for an element index which needs to be computed and put it on the stack.
virtual void MultiThread_Assemble(TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface)
Assemble the global right hand side.
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.
#define PZ_PTHREAD_MUTEX_DESTROY(mutex, fn)
Definition: pz_pthread.h:73
int64_t NEqExpand() const
Retorna o numero de equacoes do sistema original.
Contains declaration of TPZCheckMesh class which verifies the consistency of the datastructure of a T...
int64_t Index() const
Returns element index of the mesh fELementVec list.
Definition: pzcompel.h:821
virtual bool ShouldCompute(int matid) const
Establish whether the element should be computed.
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.
#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...
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.
Definition: pzstrmatrix.cpp:80
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
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
static RunStatsTable ass_rhs("-ass_rhs", "Assemble Stiffness")
void ApplyConstraints()
Apply the constraints applied to the nodes by transforming the tangent matrix and right hand side...
Definition: pzelmat.cpp:186
static void * ThreadAssembly(void *threaddata)
The function which will compute the assembly.
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.
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
std::set< int > fProcessed
Elements which are being processed.
Definition: pzstrmatrix.h:73
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...
TPZSemaphore fAssembly
Semaphore (to wake up assembly thread)
Definition: pzstrmatrix.h:79
void Reset(TPZCompMesh *mesh=NULL, MType type=Unknown)
Reset the data structure.
Definition: pzelmat.h:59
Implements computational mesh. Computational Mesh.
Definition: pzcmesh.h:47
TPZAdmChunkVector< TPZCompEl * > & ElementVec()
Returns a reference to the element pointers vector.
Definition: pzcmesh.h:183
virtual void Print(std::ostream &out=std::cout) const
Prints element data.
Definition: pzcompel.cpp:322
#define PZ_PTHREAD_CREATE(thread, attr, routine, args, fn)
Definition: pz_pthread.h:31
Contains declaration of TPZInterpolatedElement class which implements computational element of the in...
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
virtual void FilterEquations(TPZVec< int64_t > &origindex, TPZVec< int64_t > &destindex) const
Filter out the equations which are out of the range.
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
void Read(TPZStream &buf, void *context) override
read objects from the stream
#define PZ_PTHREAD_MUTEX_INIT(mutex, attr, fn)
Definition: pz_pthread.h:70
virtual void Print(std::ostream &out=std::cout)
Print all relevant data of the element to cout.
Definition: pzgeoel.cpp:238
void ComputedElementMatrix(int64_t iel, TPZAutoPointer< TPZElementMatrix > &ek, TPZAutoPointer< TPZElementMatrix > &ef)
Put the computed element matrices in the map.
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 bool HasRange() const
Verify if a range has been specified.
bool HasDependency()
Returns true if the element has at least one dependent node. Returns false otherwise.
Definition: pzelmat.cpp:482
virtual TPZMatrix< STATE > * Create() override
Definition: pzstrmatrix.cpp:65
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
Contains TPZSFMatrix class which implements a symmetric full matrix.