KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
residualbased_elimination_quasiincompresible_builder_and_solver.h
Go to the documentation of this file.
1 /* *********************************************************
2 *
3 * Last Modified by: $Author: anonymous $
4 * Date: $Date: 2009-01-15 14:50:24 $
5 * Revision: $Revision: 1.12 $
6 *
7 * ***********************************************************/
8 
9 
10 #if !defined(KRATOS_RESIDUAL_BASED_ELIMINATION_QUASI_INCOMPRESSIBLE_BUILDER_AND_SOLVER )
11 #define KRATOS_RESIDUAL_BASED_ELIMINATION_QUASI_INCOMPRESSIBLE_BUILDER_AND_SOLVER
12 
13 
14 /* System includes */
15 #include <set>
16 
17 #ifdef _OPENMP
18 #include <omp.h>
19 #endif
20 
21 /* External includes */
22 // #include "boost/smart_ptr.hpp"
23 #include <pybind11/pybind11.h>
24 #include "includes/define.h"
25 #include "includes/define_python.h"
26 
27 /* Project includes */
28 #include "includes/define.h"
29 #include "ULF_application.h"
31 #include "utilities/geometry_utilities.h"
32 
33 #include "boost/smart_ptr.hpp"
34 #include "utilities/timer.h"
35 
36 namespace Kratos
37 {
38 
87 template
88 <
89 class TSparseSpace,
90  class TDenseSpace ,
91  class TLinearSolver,
92  int TDim
93  >
95  : public BuilderAndSolver< TSparseSpace,TDenseSpace,TLinearSolver >
96 {
97 public:
101 
103 
105  typedef typename BaseType::TDataType TDataType;
106 
108 
110 
112 
114 
118 
120 
124 
126 
135  typename TLinearSolver::Pointer pNewLinearSystemSolver)
136  : BuilderAndSolver< TSparseSpace,TDenseSpace,TLinearSolver >(pNewLinearSystemSolver)
137  {
138  }
139 
140 
144 
145 
153  //**************************************************************************
154  //**************************************************************************
156  typename TSchemeType::Pointer pScheme,
157  ModelPart& r_model_part,
159  TSystemVectorType& Dx,
161  {
162  KRATOS_TRY
163 
164  KRATOS_THROW_ERROR(std::runtime_error, "For the quasi incompressible builder and solver this fct doesnt exist!", "");
165 
166  KRATOS_CATCH("")
167  }
168 
170  ModelPart& r_model_part,
172  TSystemVectorType& Dx,
174  {
175  KRATOS_TRY
176  //KRATOS_WATCH("Initialize Solution Step::: EMPTY FUNCTION FOR THIS SOLVER")
177  KRATOS_CATCH("")
178  }
179 
181  ModelPart& r_model_part,
183  TSystemVectorType& Dx,
185  {
186  KRATOS_TRY
187  //KRATOS_WATCH("Finalize Solution Step:::EMPTY FUNCTION FOR THIS SOLVER")
188  KRATOS_CATCH("")
189  }
190 
191  //**************************************************************************
192  //**************************************************************************
193  //this is done in a purely nodal way taking advantage of the neighbour relatinoships
194  //which are assumed to be calculated separately
195  //HERE we store the displacements variables in a list
197  typename TSchemeType::Pointer pScheme,
198  ModelPart& r_model_part
199  )
200  {
201  KRATOS_TRY
202 
203  //KRATOS_WATCH("ENTERED SETUP DOFSET OF BUILDER AND SOLVER OF ULF")
204  mActiveNodes.clear();
205  mActiveNodes.reserve(r_model_part.Nodes().size() );
206 
207  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
208  {
209  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
210  {
211  mActiveNodes.push_back(*(it.base() ));
212  }
213  }
214 
215  //getting the dof position
216  //unsigned int dof_position = (mActiveNodes.begin())->GetDofPosition(PRESSURE);
217 
218  //fills the DofList and give a unique progressive tag to each node
220  BaseType::mDofSet.reserve(mActiveNodes.size()*TDim );
221 
222  for(GlobalPointersVector< Node >::iterator iii = mActiveNodes.begin(); iii!=mActiveNodes.end(); iii++)
223  {
224 
225  BaseType::mDofSet.push_back( iii->pGetDof(DISPLACEMENT_X).get());
226  BaseType::mDofSet.push_back( iii->pGetDof(DISPLACEMENT_Y).get());
227  //BaseType::mDofSet.push_back( iii->pGetDof(DISPLACEMENT_Y));
228  if constexpr (TDim==3)
229  BaseType::mDofSet.push_back( iii->pGetDof(DISPLACEMENT_Z).get());
230  }
231 
232 
234 
235  if (BaseType::mDofSet.size()==0)
236  KRATOS_THROW_ERROR(std::logic_error, "No degrees of freedom!", "");
237 
239 
240  //KRATOS_WATCH("FINISHED SETUP DOFSET OF BUILDER AND SOLVER OF ULF")
241 
242  //BELOW IS THE OLD VERSION
243  /*
244  //count dofs
245  mnumber_of_active_nodes = 0;
246  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
247  {
248  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
249  {
250  mnumber_of_active_nodes += 1;
251  }
252  }
253 
254  //getting the dof position
255  //unsigned int dof_position = r_model_part.NodesBegin()->GetDofPosition(PRESSURE);
256 
257  //fills the DofList
258  BaseType::mDofSet.clear();
259  BaseType::mDofSet.reserve( mnumber_of_active_nodes * TDim );
260  int FractionalStepNumber = r_model_part.GetProcessInfo()[FRACTIONAL_STEP];
261  KRATOS_WATCH(FractionalStepNumber);
262  if constexpr (TDim == 2)
263  {
264  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
265  {
266  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
267  {
268  BaseType::mDofSet.push_back( it->pGetDof(DISPLACEMENT_X) );
269  BaseType::mDofSet.push_back( it->pGetDof(DISPLACEMENT_Y) );
270  }
271  }
272 
273  }
274  else if constexpr (TDim == 3)
275  {
276  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
277  {
278  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
279  {
280  BaseType::mDofSet.push_back( it->pGetDof(DISPLACEMENT_X) );
281  BaseType::mDofSet.push_back( it->pGetDof(DISPLACEMENT_Y) );
282  BaseType::mDofSet.push_back( it->pGetDof(DISPLACEMENT_Z) );
283  }
284  }
285  }
286  //before it was like that:
287  //this->mEquationSystemSize = rDofSet.size();
288 
289 
290 
291  this->mEquationSystemSize = BaseType::mDofSet.size();
292 
293  //throws an execption if there are no Degrees of freedom involved in the analysis
294  if (BaseType::mDofSet.size()==0)
295  KRATOS_THROW_ERROR(std::logic_error, "No degrees of freedom!", "");
296 
297  BaseType::mDofSetIsInitialized = true;
298  */
299 
300  KRATOS_CATCH("")
301  }
302 
303  //**************************************************************************
304  //**************************************************************************
305  //this function numbers the DOFS - from 1 onwards... (note, that only DISPLACEMENT DOFs are stored, PRESSURE is not!!!!)
307  ModelPart& r_model_part
308  )
309  {
310  KRATOS_TRY
311 
312  //assing id to the nodes
313  unsigned int index = 0;
314  for(typename DofsArrayType::iterator i_dof = BaseType::mDofSet.begin() ; i_dof != BaseType::mDofSet.end() ; ++i_dof)
315  {
316  //i_dof->EquationId() = index;
317  i_dof->SetEquationId(index) ;
318  index++;
319  }
320  KRATOS_CATCH("");
321  }
322 
323  //**************************************************************************
324  //**************************************************************************
325  //
326 
327 
328  void ResizeAndInitializeVectors( typename TSchemeType::Pointer pScheme,
331  TSystemVectorType& Dx,
335  ModelPart& rModelPart
336  )
337  {
338  KRATOS_TRY
339 
340 
341  //resizing the system vectors and matrix
342  if (A.size1() == 0 || this->GetReshapeMatrixFlag() == true) //if the matrix is not initialized
343  {
344  A.resize(this->mEquationSystemSize,this->mEquationSystemSize,false);
345  //ConstructMatrixStructure(A);
346  }
347  if(Dx.size() != this->mEquationSystemSize)
348  Dx.resize(this->mEquationSystemSize,false);
349  if(b.size() != this->mEquationSystemSize)
350  b.resize(this->mEquationSystemSize,false);
351 
352  if(BaseType::mpReactionsVector == NULL) //if the pointer is not initialized initialize it to an empty matrix
353  {
355  BaseType::mpReactionsVector.swap(pNewReactionsVector);
356  }
357 
358  //resize auxiliaries
359  unsigned int reduced_dim = this->mEquationSystemSize / TDim;
360  if(mD.size1() != reduced_dim)
361  mD.resize(reduced_dim,this->mEquationSystemSize,false);
362 
363  if(mMconsistent.size1() != reduced_dim)
364  mMconsistent.resize(reduced_dim,reduced_dim,false);
365 
366  if(mMdiagInv.size() != reduced_dim )
367  mMdiagInv.resize(reduced_dim,false);
368  KRATOS_CATCH("")
369 
370  }
371 
372  void Build(
373  typename TSchemeType::Pointer pScheme,
374  ModelPart& r_model_part,
377  {
378  KRATOS_TRY
379  if(!pScheme)
380  KRATOS_THROW_ERROR(std::runtime_error, "No scheme provided!", "");
381 
382  //getting the elements from the model
383  ElementsArrayType& pElements = r_model_part.Elements();
384 
385  //getting the array of the conditions
386  ConditionsArrayType& ConditionsArray = r_model_part.Conditions();
387 
388  //resetting to zero the vector of reactions
389  TSparseSpace::SetToZero( *(BaseType::mpReactionsVector) );
390 #ifndef _OPENMP
391  //contributions to the system
392  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0,0);
393  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
394 
395  //vector containing the localization in the system of the different
396  //terms
398 
399 
400  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
401 
402  // assemble all elements
403  for (typename ElementsArrayType::ptr_iterator it=pElements.ptr_begin(); it!=pElements.ptr_end(); ++it)
404  {
405 
406  //calculate elemental contribution
407  pScheme->CalculateSystemContributions(*it,LHS_Contribution,RHS_Contribution,EquationId,CurrentProcessInfo);
408 
409  //assemble the elemental contribution
410  AssembleLHS(A,LHS_Contribution,EquationId);
411  AssembleRHS(b,RHS_Contribution,EquationId);
412  }
413  LHS_Contribution.resize(0,0,false);
414 
415  RHS_Contribution.resize(0,false);
416 
417  // assemble all conditions
418  for (typename ConditionsArrayType::ptr_iterator it=ConditionsArray.ptr_begin(); it!=ConditionsArray.ptr_end(); ++it)
419  {
420  //calculate elemental contribution
421  pScheme->Condition_CalculateSystemContributions(*it,LHS_Contribution,RHS_Contribution,EquationId,CurrentProcessInfo);
422 
423  //assemble the elemental contribution
424  AssembleLHS(A,LHS_Contribution,EquationId);
425  AssembleRHS(b,RHS_Contribution,EquationId);
426  }
427 #else
428  //creating an array of lock variables of the size of the system matrix
429  std::vector< omp_lock_t > lock_array(A.size1());
430 
431  int A_size = A.size1();
432  for (int i = 0; i < A_size; i++)
433  omp_init_lock(&lock_array[i]);
434 
435  //create a partition of the element array
436  int number_of_threads = omp_get_max_threads();
437 
438  vector<unsigned int> element_partition;
439  CreatePartition(number_of_threads, pElements.size(), element_partition);
440  //KRATOS_WATCH(number_of_threads);
441  //KRATOS_WATCH(element_partition);
442 
443 
444  double start_prod = omp_get_wtime();
445 
446  #pragma omp parallel for
447  for (int k = 0; k < number_of_threads; k++)
448  {
449  //contributions to the system
450  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0, 0);
451  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
452 
453  //vector containing the localization in the system of the different
454  //terms
456  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
457  typename ElementsArrayType::ptr_iterator it_begin = pElements.ptr_begin() + element_partition[k];
458  typename ElementsArrayType::ptr_iterator it_end = pElements.ptr_begin() + element_partition[k + 1];
459 
460  // assemble all elements
461  for (typename ElementsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
462  {
463 
464  //calculate elemental contribution
465  pScheme->CalculateSystemContributions(*it, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
466 
467  //assemble the elemental contribution
468  Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId, lock_array);
469  /*
470  double aaaa = TSparseSpace::TwoNorm(b);
471  if (TSparseSpace::TwoNorm(b) == aaaa + 1000000000000000000.0)
472  {
473  KRATOS_WATCH((*it)->Id())
474  KRATOS_THROW_ERROR(std::logic_error, "Something is wrong: fluid element cannot have all 3 nodes at the FSI boundary " , "");
475 
476  }
477  */
478 
479  // #pragma omp critical
480  // {
481  // //assemble the elemental contribution
482  // AssembleLHS(A,LHS_Contribution,EquationId);
483  // AssembleRHS(b,RHS_Contribution,EquationId);
484  // }
485  }
486  }
487  //KRATOS_WATCH("Finished assembling of builder and solver")
488  vector<unsigned int> condition_partition;
489  CreatePartition(number_of_threads, ConditionsArray.size(), condition_partition);
490 
491  #pragma omp parallel for
492  for (int k = 0; k < number_of_threads; k++)
493  {
494  //contributions to the system
495  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0, 0);
496  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
497 
499 
500  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
501 
502  typename ConditionsArrayType::ptr_iterator it_begin = ConditionsArray.ptr_begin() + condition_partition[k];
503  typename ConditionsArrayType::ptr_iterator it_end = ConditionsArray.ptr_begin() + condition_partition[k + 1];
504 
505  // assemble all elements
506  for (typename ConditionsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
507  {
508  //calculate elemental contribution
509  pScheme->Condition_CalculateSystemContributions(*it, LHS_Contribution, RHS_Contribution, EquationId, CurrentProcessInfo);
510 
511  //assemble the elemental contribution
512  Assemble(A, b, LHS_Contribution, RHS_Contribution, EquationId, lock_array);
513 
514  // #pragma omp critical
515  // {
516  // //assemble the elemental contribution
517  // AssembleLHS(A,LHS_Contribution,EquationId);
518  // AssembleRHS(b,RHS_Contribution,EquationId);
519  // }
520  }
521  }
522 
523 
524 
525  double stop_prod = omp_get_wtime();
526  std::cout << "time: " << stop_prod - start_prod << std::endl;
527 
528  for (int i = 0; i < A_size; i++)
529  omp_destroy_lock(&lock_array[i]);
530  //KRATOS_WATCH("finished parallel building");
531 
532  // //ensure that all the threads are syncronized here
533  // #pragma omp barrier
534 #endif
535 
536  KRATOS_CATCH("")
537 
538  }
539 
562 protected:
603 public:
618 
619 //private:
621 
627  // GlobalPointersVector<Node > mActiveNodes;
628 
633  //**************************************************************************
634 
635  inline void CreatePartition(unsigned int number_of_threads, const int number_of_rows, vector<unsigned int>& partitions)
636  {
637  partitions.resize(number_of_threads + 1);
638  int partition_size = number_of_rows / number_of_threads;
639  partitions[0] = 0;
640  partitions[number_of_threads] = number_of_rows;
641  for (unsigned int i = 1; i < number_of_threads; i++)
642  partitions[i] = partitions[i - 1] + partition_size;
643  }
644 
645 #ifdef _OPENMP
646 
647  void Assemble(
650  const LocalSystemMatrixType& LHS_Contribution,
651  const LocalSystemVectorType& RHS_Contribution,
652  Element::EquationIdVectorType& EquationId,
653  std::vector< omp_lock_t >& lock_array
654  )
655  {
656  unsigned int local_size = LHS_Contribution.size1();
657 
658  for (unsigned int i_local = 0; i_local < local_size; i_local++)
659  {
660  unsigned int i_global = EquationId[i_local];
661 
662  if (i_global < BaseType::mEquationSystemSize)
663  {
664  omp_set_lock(&lock_array[i_global]);
665 
666  b[i_global] += RHS_Contribution(i_local);
667  for (unsigned int j_local = 0; j_local < local_size; j_local++)
668  {
669  unsigned int j_global = EquationId[j_local];
670  if (j_global < BaseType::mEquationSystemSize)
671  {
672  A(i_global, j_global) += LHS_Contribution(i_local, j_local);
673  }
674  }
675 
676  omp_unset_lock(&lock_array[i_global]);
677 
678 
679  }
680  //note that computation of reactions is not performed here!
681  }
682  }
683  void AssembleRHS_parallel(
685  const LocalSystemVectorType& RHS_Contribution,
686  Element::EquationIdVectorType& EquationId,
687  std::vector< omp_lock_t >& lock_array
688  )
689  {
690  unsigned int local_size = RHS_Contribution.size();
691 
692  for (unsigned int i_local = 0; i_local < local_size; i_local++)
693  {
694  unsigned int i_global = EquationId[i_local];
695 
696  if (i_global < BaseType::mEquationSystemSize)
697  {
698  omp_set_lock(&lock_array[i_global]);
699 
700  b[i_global] += RHS_Contribution(i_local);
701 
702  omp_unset_lock(&lock_array[i_global]);
703 
704 
705  }
706  //note that computation of reactions is not performed here!
707  }
708  }
709 #endif
710 
711  //**************************************************************************
714  LocalSystemMatrixType& LHS_Contribution,
716  )
717  {
718  unsigned int local_size = LHS_Contribution.size1();
719 
720  for (unsigned int i_local=0; i_local<local_size; i_local++)
721  {
722  unsigned int i_global=EquationId[i_local];
723  if ( i_global < BaseType::mEquationSystemSize )
724  {
725  for (unsigned int j_local=0; j_local<local_size; j_local++)
726  {
727  unsigned int j_global=EquationId[j_local];
728  if ( j_global < BaseType::mEquationSystemSize )
729  A(i_global,j_global) += LHS_Contribution(i_local,j_local);
730  }
731  }
732  }
733  }
734 
735 
736 
737  //**************************************************************************
740  LocalSystemVectorType& RHS_Contribution,
742  )
743  {
744  unsigned int local_size = RHS_Contribution.size();
745 
746  for (unsigned int i_local=0; i_local<local_size; i_local++)
747  {
748  unsigned int i_global=EquationId[i_local];
749  if ( i_global < BaseType::mEquationSystemSize ) //on all DOFS
750  {
751  // ASSEMBLING THE SYSTEM VECTOR
752  b[i_global] += RHS_Contribution[i_local];
753  }
754  }
755 
756  }
757  //**************************************************************************
758  //**************************************************************************
760  typename TSchemeType::Pointer pScheme,
761  ModelPart& r_model_part,
763  TSystemVectorType& Dx,
765  {
766  //KRATOS_WATCH(b);
767  TSparseSpace::SetToZero(b);
768  //KRATOS_WATCH("Calculating REACTIONSSSSSSSS")
769  //reset the reactions to zero in all the nodes
770  for (typename NodesArrayType::iterator node_iterator =r_model_part.NodesBegin(); node_iterator !=r_model_part.NodesEnd(); ++node_iterator)
771  {
772  node_iterator->FastGetSolutionStepValue(REACTION_X)=0.0;
773  node_iterator->FastGetSolutionStepValue(REACTION_Y)=0.0;
774  node_iterator->FastGetSolutionStepValue(REACTION_Z)=0.0;
775  }
776 
777  //refresh RHS to have the correct reactions
778 
779  BuildRHS(pScheme,r_model_part,b);
780 
781  //KRATOS_WATCH(b)
782  /*
783  for (typename NodesArrayType::iterator node_iterator =r_model_part.NodesBegin(); node_iterator !=r_model_part.NodesEnd(); ++node_iterator)
784  {
785 
786  //not adding thelonely nodes:
787  if( node_iterator->FastGetSolutionStepValue(IS_INTERFACE)==1.0 )
788  {
789  //we add one because we have to account for the contribution of the node itself
790  unsigned int eq_id=(node_iterator->GetDof(DISPLACEMENT_X)).EquationId();
791  node_iterator->FastGetSolutionStepValue(REACTION_X)=b[eq_id];
792  eq_id=(node_iterator->GetDof(DISPLACEMENT_Y)).EquationId();
793  node_iterator->FastGetSolutionStepValue(REACTION_Y)=b[eq_id];
794  }
795  }
796  */
797 
798  //array_1d<double, 3> ReactionsVec;
799  typename DofsArrayType::ptr_iterator it2;
800  for (it2=BaseType::mDofSet.ptr_begin(); it2 != BaseType::mDofSet.ptr_end(); ++it2)
801  {
802 
803 
804 
805  //JUST FOR ONE EXAMPLE - Turek (otherwise the below is correct)
806  if ( (*it2)->IsFixed() )
807  {
808  unsigned int eq_id=(*it2)->EquationId();
809 
810  //KRATOS_WATCH(eq_id)
811  //KRATOS_WATCH(b[eq_id])
812  (*it2)->GetSolutionStepReactionValue() = b[eq_id];
813  //KRATOS_WATCH((*it2)->GetSolutionStepReactionValue())
814  }
815  //
816  }
817 
818  }
819 
820  //**************************************************************************
821  //**************************************************************************
822  void BuildRHS(
823  typename TSchemeType::Pointer pScheme,
824  ModelPart& r_model_part,
826  {
827  KRATOS_TRY
828 
829  //Getting the Elements
830  ElementsArrayType& pElements = r_model_part.Elements();
831 
832  //getting the array of the conditions
833  ConditionsArrayType& ConditionsArray = r_model_part.Conditions();
834 
835 #ifndef _OPENMP
836  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
837 
838  //resetting to zero the vector of reactions
839  TSparseSpace::SetToZero( *(BaseType::mpReactionsVector) );
840 
841  //contributions to the system
842  LocalSystemMatrixType LHS_Contribution = LocalSystemMatrixType(0,0);
843  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
844 
845  //vector containing the localization in the system of the different
846  //terms
848 
849  // assemble all elements
850  for (typename ElementsArrayType::ptr_iterator it=pElements.ptr_begin(); it!=pElements.ptr_end(); ++it)
851  {
852  //calculate elemental Right Hand Side Contribution
853  pScheme->Calculate_RHS_Contribution(*it,RHS_Contribution,EquationId,CurrentProcessInfo);
854 
855  //assemble the elemental contribution
856  AssembleRHS(b,RHS_Contribution,EquationId);
857  }
858 
859  LHS_Contribution.resize(0,0,false);
860  RHS_Contribution.resize(0,false);
861 
862  // assemble all conditions
863  for (typename ConditionsArrayType::ptr_iterator it=ConditionsArray.ptr_begin(); it!=ConditionsArray.ptr_end(); ++it)
864  {
865  //calculate elemental contribution
866  pScheme->Condition_Calculate_RHS_Contribution(*it,RHS_Contribution,EquationId,CurrentProcessInfo);
867 
868  //assemble the elemental contribution
869  AssembleRHS(b,RHS_Contribution,EquationId);
870  }
871 #else
872  //creating an array of lock variables of the size of the system matrix
873  std::vector< omp_lock_t > lock_array(b.size());
874 
875  int b_size = b.size();
876  for (int i = 0; i < b_size; i++)
877  omp_init_lock(&lock_array[i]);
878 
879  //create a partition of the element array
880  int number_of_threads = omp_get_max_threads();
881 
882  vector<unsigned int> element_partition;
883  CreatePartition(number_of_threads, pElements.size(), element_partition);
884  //KRATOS_WATCH(number_of_threads);
885  //KRATOS_WATCH(element_partition);
886 
887 
888  double start_prod = omp_get_wtime();
889 
890  #pragma omp parallel for
891  for (int k = 0; k < number_of_threads; k++)
892  {
893  //contributions to the system
894  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
895 
896  //vector containing the localization in the system of the different
897  //terms
899  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
900  typename ElementsArrayType::ptr_iterator it_begin = pElements.ptr_begin() + element_partition[k];
901  typename ElementsArrayType::ptr_iterator it_end = pElements.ptr_begin() + element_partition[k + 1];
902 
903  // assemble all elements
904  for (typename ElementsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
905  {
906 
907  //calculate elemental contribution
908  pScheme->Calculate_RHS_Contribution(*it,RHS_Contribution,EquationId,CurrentProcessInfo);
909 
910  //assemble the elemental contribution
911  AssembleRHS_parallel(b, RHS_Contribution, EquationId, lock_array);
912  /*
913  double aaaa = TSparseSpace::TwoNorm(b);
914  if (TSparseSpace::TwoNorm(b) == aaaa + 1000000000000000000.0)
915  {
916  KRATOS_WATCH((*it)->Id())
917  KRATOS_THROW_ERROR(std::logic_error, "Something is wrong: fluid element cannot have all 3 nodes at the FSI boundary " , "");
918 
919  }
920  */
921 
922  // #pragma omp critical
923  // {
924  // //assemble the elemental contribution
925  // AssembleLHS(A,LHS_Contribution,EquationId);
926  // AssembleRHS(b,RHS_Contribution,EquationId);
927  // }
928  }
929  }
930  //KRATOS_WATCH("Finished assembling of builder and solver")
931  vector<unsigned int> condition_partition;
932  CreatePartition(number_of_threads, ConditionsArray.size(), condition_partition);
933 
934  #pragma omp parallel for
935  for (int k = 0; k < number_of_threads; k++)
936  {
937  //contributions to the system
938 
939  LocalSystemVectorType RHS_Contribution = LocalSystemVectorType(0);
940 
942 
943  ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
944 
945  typename ConditionsArrayType::ptr_iterator it_begin = ConditionsArray.ptr_begin() + condition_partition[k];
946  typename ConditionsArrayType::ptr_iterator it_end = ConditionsArray.ptr_begin() + condition_partition[k + 1];
947 
948  // assemble all elements
949  for (typename ConditionsArrayType::ptr_iterator it = it_begin; it != it_end; ++it)
950  {
951  //calculate elemental contribution
952  pScheme->Condition_Calculate_RHS_Contribution(*it,RHS_Contribution,EquationId,CurrentProcessInfo);
953  //assemble the elemental contribution
954 
955  AssembleRHS_parallel(b, RHS_Contribution, EquationId, lock_array);
956 
957  // #pragma omp critical
958  // {
959  // //assemble the elemental contribution
960  // AssembleLHS(A,LHS_Contribution,EquationId);
961  // AssembleRHS(b,RHS_Contribution,EquationId);
962  // }
963  }
964  }
965 
966 
967 
968  double stop_prod = omp_get_wtime();
969  std::cout << "time: " << stop_prod - start_prod << std::endl;
970 
971  for (int i = 0; i < b_size; i++)
972  omp_destroy_lock(&lock_array[i]);
973  //KRATOS_WATCH("finished parallel building");
974 
975  // //ensure that all the threads are syncronized here
976  // #pragma omp barrier
977 #endif
978 
979  KRATOS_CATCH("")
980 
981  }
982  //**************************************************************************
983  //**************************************************************************
985  TSystemMatrixType& A, ModelPart& r_model_part
986  )
987  {
988  KRATOS_TRY
989  //KRATOS_WATCH("Started constructing MAT STRUC")
990  std::vector<int> indices;
991  indices.reserve(1000);
992 
993  //count non zeros
994  int total_nnz = 0;
995  for (typename NodesArrayType::iterator node_iterator =r_model_part.NodesBegin(); node_iterator !=r_model_part.NodesEnd(); ++node_iterator)
996  {
997 
998  //not adding thelonely nodes:
999  if( (node_iterator->GetValue(NEIGHBOUR_NODES)).size() != 0 )
1000  {
1001  //we add one because we have to account for the contribution of the node itself
1002  total_nnz +=1+(node_iterator->GetValue(NEIGHBOUR_NODES)).size();
1003  }
1004  }
1005 
1006  //reserve space in the matrix
1007  A.reserve(total_nnz* TDim * TDim,false);
1008 
1009  unsigned int row_index;
1010 
1011  //fill the matrix row by row
1012  unsigned int dof_position = r_model_part.NodesBegin()->GetDofPosition(DISPLACEMENT_X);
1013  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
1014  {
1015  GlobalPointersVector< Node >& neighb_nodes = it->GetValue(NEIGHBOUR_NODES);
1016  if( neighb_nodes.size() != 0 )
1017  {
1018  //first row in the block
1019  row_index = it->GetDof(DISPLACEMENT_X,dof_position).EquationId();
1020 
1021  //add id of the current node
1022  //NOTE: here and in the following we ASSUME that the ids of DISPLACEMENT_X _Y and _Z are sequential
1023  for(unsigned int kk = 0; kk<TDim; kk++)
1024  {
1025  indices.push_back(row_index + kk);
1026  }
1027 
1028  //filling and order the first neighbours list
1029  for( GlobalPointersVector< Node >::iterator i = neighb_nodes.begin();
1030  i != neighb_nodes.end(); i++)
1031  {
1032  unsigned int tmp = (i->GetDof(DISPLACEMENT_X,dof_position)).EquationId();
1033  for(unsigned int kk = 0; kk<TDim; kk++)
1034  {
1035  indices.push_back(tmp + kk);
1036  }
1037  }
1038  std::sort(indices.begin(),indices.end());
1039 
1040  //fill in the system matrix A
1041  for(unsigned int kk = 0; kk<TDim; kk++)
1042  {
1043  for(unsigned int j=0; j<indices.size(); j++)
1044  {
1045  A.push_back(row_index + kk,indices[j] , 0.00);
1046  }
1047  }
1048 
1049  //clean the indices (it is a work array)
1050  indices.erase(indices.begin(),indices.end());
1051  }
1052  }
1053  //KRATOS_WATCH("FINISHED constructing MAT STRUC")
1054  KRATOS_CATCH("")
1055  }
1056 
1057  //**************************************************************************
1058  //**************************************************************************
1060  TSystemMatrixType& Mconsistent, ModelPart& r_model_part)
1061  {
1062  KRATOS_TRY
1063  //KRATOS_WATCH("Started constructing MAT STRUC M CONSISTENT")
1064  std::vector<int> indices;
1065  indices.reserve(1000);
1066 
1067  //KRATOS_WATCH("contruct matrix structure Mconsistent 0")
1068 
1069  int total_nnz = 0;
1070  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
1071  {
1072  //not to do include lonely nodes in the system
1073  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
1074  {
1075  //we add one because we have to account for the contribution of the node itself
1076  total_nnz += 1+(it->GetValue(NEIGHBOUR_NODES)).size();
1077  }
1078  }
1079 
1080  Mconsistent.reserve(total_nnz,false);
1081 
1082  unsigned int row_index;
1083  //fill the matrix row by row
1084  unsigned int dof_position = r_model_part.NodesBegin()->GetDofPosition(DISPLACEMENT_X);
1085 
1086  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
1087  {
1088  GlobalPointersVector< Node >& neighb_nodes = it->GetValue(NEIGHBOUR_NODES);
1089  if( neighb_nodes.size() != 0 )
1090  {
1091  //first row in the block
1092  row_index = it->GetDof(DISPLACEMENT_X,dof_position).EquationId();
1093 
1094  //add id of the current node
1095  //NOTE: here and in the following we ASSUME that the ids of DISPLACEMENT_X _Y and _Z are sequential
1096 
1097  //we store in the array of indices the column numbers of the pressure index of the respective node, which coincides
1098  //with the index of DISP_X, divided by TDim (pressure is scalar - no need to store 2 more indices, as it was in
1099  //the case of vector (displ)
1100 
1101  //CHECK THIS!!!
1102  //indices.push_back(row_index/3.0);
1103  indices.push_back(row_index/TDim);
1104 
1105  //filling and order the first neighbours list
1106  for( GlobalPointersVector< Node >::iterator i = neighb_nodes.begin();
1107  i != neighb_nodes.end(); i++)
1108  {
1109  unsigned int tmp = (i->GetDof(DISPLACEMENT_X,dof_position)).EquationId();
1110  indices.push_back(tmp/TDim);
1111 
1112  }
1113  std::sort(indices.begin(),indices.end());
1114 
1115  //fill M (the consistent mass matrix)-note that the "pressure index" is assumed to concide the DISPLACEMENT_X index divided by 3
1116  for(unsigned int j=0; j<indices.size(); j++)
1117  {
1118  Mconsistent.push_back(row_index/TDim, indices[j] , 0.00);
1119  //KRATOS_WATCH(Mconsistent)
1120  }
1121  //clean the indices (it is a work array)
1122  indices.erase(indices.begin(),indices.end());
1123  }
1124  }
1125  //KRATOS_WATCH("FInished constructing MAT STRUC M CONSISTENT")
1126  KRATOS_CATCH("")
1127  }
1128 
1129 
1130  //**************************************************************************
1131  //**************************************************************************
1133  TSystemMatrixType& mD, ModelPart& r_model_part)
1134  {
1135  KRATOS_TRY
1136  //KRATOS_WATCH("Started constructing MAT STRUC Divergence Matrix")
1137  std::vector<int> indices;
1138  indices.reserve(1000);
1139 
1140  //count non zeros
1141  int total_nnz = 0;
1142  for (typename NodesContainerType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
1143  {
1144  //not to add lonely nodes to the system
1145  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0 )
1146  {
1147  //we add one because we have to account for the contribution of the node itself
1148  total_nnz += 1 + (it->GetValue(NEIGHBOUR_NODES)).size();
1149  }
1150  }
1151 
1152  mD.reserve(total_nnz* TDim,false);
1153 
1154  unsigned int row_index;
1155  //fill the matrix row by row
1156  unsigned int dof_position = r_model_part.NodesBegin()->GetDofPosition(DISPLACEMENT_X);
1157 
1158  for (typename NodesArrayType::iterator it=r_model_part.NodesBegin(); it!=r_model_part.NodesEnd(); ++it)
1159  {
1160  GlobalPointersVector< Node >& neighb_nodes = it->GetValue(NEIGHBOUR_NODES);
1161  if( neighb_nodes.size() != 0 )
1162  {
1163  //first row in the block
1164  row_index = it->GetDof(DISPLACEMENT_X,dof_position).EquationId();
1165 
1166  //add id of the current node
1167  //NOTE: here and in the following we ASSUME that the ids of DISPLACEMENT_X _Y and _Z are sequential
1168  for(unsigned int kk = 0; kk<TDim; kk++)
1169  {
1170  indices.push_back(row_index + kk);
1171  }
1172 
1173  //filling and order the first neighbours list
1174  for( GlobalPointersVector< Node >::iterator i = neighb_nodes.begin();
1175  i != neighb_nodes.end(); i++)
1176  {
1177  unsigned int tmp = (i->GetDof(DISPLACEMENT_X,dof_position)).EquationId();
1178  for(unsigned int kk = 0; kk<TDim; kk++)
1179  {
1180  indices.push_back(tmp + kk);
1181  }
1182  }
1183  std::sort(indices.begin(),indices.end());
1184 
1185 
1186  //fill D (the divergence matrix) - note that the "pressure index" is assumed to concide the DISPLACEMENT_X index divided by 3
1187  for(unsigned int j=0; j<indices.size(); j++)
1188  {
1189  mD.push_back(row_index/TDim, indices[j] , 0.00);
1190  }
1191 
1192  //clean the indices (it is a work array)
1193  indices.erase(indices.begin(),indices.end());
1194  }
1195  }
1196  //KRATOS_WATCH("FSI D")
1197  //KRATOS_WATCH(mD)
1198  //KRATOS_WATCH("Finished constructing MAT STRUC Divergence Matrix")
1199  KRATOS_CATCH("")
1200 
1201  }
1202 
1203  //**************************************************************************
1204  //**************************************************************************
1207  ModelPart& r_model_part)
1208  {
1209  KRATOS_TRY
1210  //KRATOS_WATCH("BUILDING AUXILIARY MATRIX D")
1211 
1212 
1213 
1214  //array_1d<double,TDim+1> rhs_contribution;
1215 
1216 #ifndef _OPENMP
1217 // BoundedMatrix::BoundedMatrix<double,TDim+1,TDim> DN_DX;
1220  array_1d<unsigned int ,TDim+1> local_indices;
1221  double Volume;
1222  double temp;
1223 
1224 
1225  //getting the dof position
1226  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
1227 
1228  double aaa = 1.0/(TDim+1.0);
1229  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1230  for(ModelPart::ElementsContainerType::iterator i = r_model_part.ElementsBegin();
1231  i!=r_model_part.ElementsEnd(); i++)
1232  {
1233 
1234 
1235  Geometry< Node >& geom = i->GetGeometry();
1236  //counting the n-r of structure nodes
1237  unsigned int str_nr=0;
1238 
1239  //for (int k = 0;k<TDim+1;k++)
1240  for (unsigned int k = 0; k<geom.size(); k++)
1241  {
1242  str_nr+=(unsigned int)(i->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1243  }
1245  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1246  // that means, that the entries corresponding to the structural elements are zero
1248  if (geom.size()!=str_nr)
1249  {
1250  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1251  if (Volume<0)
1252  Volume*=-1.0;
1253 
1254  //finiding local indices
1255  //for(int ii = 0; ii<TDim+1; ii++)
1256  for(unsigned int ii = 0; ii<geom.size(); ii++)
1257  {
1258  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1259  }
1260  //building matrix D (transpose of the gradient integrated by parts)
1261 
1262  temp = Volume*aaa;
1263 
1264 
1265  for(unsigned int row = 0; row<TDim+1; row++)
1266  {
1267  unsigned int row_index = local_indices[row] / (TDim); //ATTENTION! here i am doing a dangerous op
1268  //KRATOS_WATCH(row_index)
1269  //first write the lumped mass matrix
1270  mMdiagInv[row_index] += temp;
1271  for(unsigned int col = 0; col<TDim+1; col++)
1272  {
1273 
1274  for(unsigned int kkk = 0; kkk<TDim; kkk++)
1275  {
1276  //check if the below is correct (copied it from Mass matrix)
1277  unsigned int col_index = local_indices[col]+kkk;
1278 
1279  //unsigned int col_index = col + kkk;
1280  //FIRST THE DIVERGENCE MATRIX
1281  mD(row_index,col_index) += temp * DN_DX(col,kkk);
1282  //And now the consistent mass matrix
1283  if (row_index==col_index)
1284  {
1285  //Mconsistent(row_index,col_index) += temp * 2.0;
1286  if constexpr (TDim==2)
1287  Mconsistent(row_index,col_index) += 0.25*temp * 2.0;
1288  else if constexpr (TDim==3)
1289  Mconsistent(row_index,col_index) += 0.2*temp * 2.0*2.5;
1290  }
1291  else
1292  {
1293  //Mconsistent(row_index,col_index) += temp ;
1294  if constexpr (TDim==2)
1295  Mconsistent(row_index,col_index) += 0.25*temp ;
1296  else if constexpr (TDim==3)
1297  Mconsistent(row_index,col_index) += 0.2*temp*0.0 ;
1298  }
1299 
1300  }
1301  }
1302 
1303 
1304  }
1305  }
1306 
1307  }
1308 
1309 
1310 #else
1311  //creating an array of lock variables of the size of the system matrix
1312  std::vector< omp_lock_t > lock_array(mD.size1());
1313 
1314  int D_size = mD.size1();
1315  for (int i = 0; i < D_size; i++)
1316  omp_init_lock(&lock_array[i]);
1317 
1318  //create a partition of the element array
1319  int number_of_threads = omp_get_max_threads();
1320 
1321  vector<unsigned int> element_partition;
1322  CreatePartition(number_of_threads, r_model_part.Elements().size(), element_partition);
1323  //KRATOS_WATCH(number_of_threads);
1324  //KRATOS_WATCH(element_partition);
1325 
1326 
1327  double start_prod = omp_get_wtime();
1328 
1329 
1330 //#pragma omp parallel for private (DN_DX, N, local_indices, Volume, temp, aaa, dof_position)
1331  #pragma omp parallel for
1332  for (int k = 0; k < number_of_threads; k++)
1333  {
1336  array_1d<unsigned int ,TDim+1> local_indices;
1337  //array_1d<double,TDim+1> rhs_contribution;
1338  double Volume;
1339  double temp;
1340 
1341 
1342  //getting the dof position
1343  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
1344 
1345  double aaa = 1.0/(TDim+1.0);
1346 
1347 
1348 
1349  //Element::EquationIdVectorType EquationId;
1350  //ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
1351  typename ElementsArrayType::ptr_iterator it_begin = r_model_part.Elements().ptr_begin() + element_partition[k];
1352  typename ElementsArrayType::ptr_iterator it_end = r_model_part.Elements().ptr_begin() + element_partition[k + 1];
1353 
1354 
1355 
1356  // assemble all elements
1357  for (typename ElementsArrayType::ptr_iterator i = it_begin; i != it_end; ++i)
1358  {
1359 
1360  Geometry< Node >& geom = (*i)->GetGeometry();
1361  //counting the n-r of structure nodes
1362  unsigned int str_nr=0;
1363 
1364  //for (int k = 0;k<TDim+1;k++)
1365  for (unsigned int k = 0; k<geom.size(); k++)
1366  {
1367  str_nr+=(unsigned int)((*i)->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1368  }
1370  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1371  // that means, that the entries corresponding to the structural elements are zero
1373  if (geom.size()!=str_nr)
1374  {
1375  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1376  if (Volume<0)
1377  Volume*=-1.0;
1378 
1379  //finiding local indices
1380  //for(int ii = 0; ii<TDim+1; ii++)
1381  for(unsigned int ii = 0; ii<geom.size(); ii++)
1382  {
1383  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1384  }
1385  //building matrix D (transpose of the gradient integrated by parts)
1386 
1387  temp = Volume*aaa;
1388 
1389 
1390  for(unsigned int row = 0; row<TDim+1; row++)
1391  {
1392  unsigned int row_index = local_indices[row] / (TDim); //ATTENTION! here i am doing a dangerous op
1393  mMdiagInv[row_index] += temp;
1394  omp_set_lock(&lock_array[row_index]);
1395  //first write the lumped mass matrix
1396 
1397  //KRATOS_WATCH(row_index)
1398  for(unsigned int col = 0; col<TDim+1; col++)
1399  {
1400  unsigned int col_index = local_indices[col] /(TDim);
1401  if (row_index==col_index)
1402  {
1403  //Mconsistent(row_index,col_index) += temp * 2.0;
1404  if constexpr (TDim==2)
1405  Mconsistent(row_index,col_index) += 0.25*temp * 2.0;
1406  else if constexpr (TDim==3)
1407  Mconsistent(row_index,col_index) += 0.2*temp * 2.0;
1408  }
1409  else
1410  {
1411  //Mconsistent(row_index,col_index) += temp ;
1412  if constexpr (TDim==2)
1413  Mconsistent(row_index,col_index) += 0.25*temp ;
1414  else if constexpr (TDim==3)
1415  Mconsistent(row_index,col_index) += 0.2*temp ;
1416  }
1417 
1418 
1419  for(unsigned int kkk = 0; kkk<TDim; kkk++)
1420  {
1421  //check if the below is correct (copied it from Mass matrix)
1422  unsigned int col_index = local_indices[col]+kkk;
1423 
1424  //unsigned int col_index = col + kkk;
1425  //FIRST THE DIVERGENCE MATRIX
1426  mD(row_index,col_index) += temp * DN_DX(col,kkk);
1427  //And now the consistent mass matrix
1428 
1429 
1430  }
1431  }
1432  omp_unset_lock(&lock_array[row_index]);
1433 
1434 
1435  }
1436  }
1437  }
1438  }
1439 
1440  double stop_prod = omp_get_wtime();
1441  std::cout << "time: " << stop_prod - start_prod << std::endl;
1442 
1443  for (int i = 0; i < D_size; i++)
1444  omp_destroy_lock(&lock_array[i]);
1445 #endif
1446 
1447  //this will be done sequentially in any case
1448  //inverting the lumped mass matrix
1449  for(unsigned int i = 0; i<TSparseSpace::Size(mMdiagInv); i++)
1450  {
1451  if (mMdiagInv[i]>1e-26)
1452  mMdiagInv[i] = 1.0/mMdiagInv[i];
1453  else //if (mMdiagInv[i]==0.0)
1454  {
1455 
1456  //KRATOS_WATCH(mMdiagInv[i])
1457  //KRATOS_THROW_ERROR(std::logic_error,"something is wrong with the mass matrix entry - ZERO!!!","")
1458  mMdiagInv[i] = 1000000000000.0;
1459 
1460  //KRATOS_WATCH(mMdiagInv[i])
1461  //KRATOS_THROW_ERROR(std::logic_error,"Zero ELEMENT VOLUMEE!!!!!!!!!!!!!!","")
1462  //mMdiagInv[i] = 0.0;
1463 
1464  }
1465  }
1466 
1467  //KRATOS_WATCH("FINISHED BUILDING AUXILIARY MATRIX D")
1468  KRATOS_CATCH (" ")
1469  }
1470  /*
1471  void BuildAuxiliaries(
1472  TSystemMatrixType& mD,
1473  ModelPart& r_model_part)
1474  {
1475  KRATOS_TRY
1476  //KRATOS_WATCH("BUILDING AUXILIARY MATRIX D")
1477 
1478 
1479  boost::numeric::ublas::bounded_matrix<double,TDim+1,TDim> DN_DX;
1480  array_1d<double,TDim+1> N;
1481  array_1d<unsigned int ,TDim+1> local_indices;
1482  //array_1d<double,TDim+1> rhs_contribution;
1483  double Volume;
1484  double temp;
1485 
1486 
1487  //getting the dof position
1488  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
1489 
1490  double aaa = 1.0/(TDim+1.0);
1491  #ifndef _OPENMP
1492  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1493  for(ModelPart::ElementsContainerType::iterator i = r_model_part.ElementsBegin();
1494  i!=r_model_part.ElementsEnd(); i++)
1495  {
1496 
1497 
1498  Geometry< Node >& geom = i->GetGeometry();
1499  //counting the n-r of structure nodes
1500  unsigned int str_nr=0;
1501 
1502  //for (int k = 0;k<TDim+1;k++)
1503  for (unsigned int k = 0;k<geom.size();k++)
1504  {
1505  str_nr+=(unsigned int)(i->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1506  }
1508  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1509  // that means, that the entries corresponding to the structural elements are zero
1511  if (geom.size()!=str_nr)
1512  {
1513  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1514  if (Volume<0)
1515  Volume*=-1.0;
1516 
1517  //finiding local indices
1518  //for(int ii = 0; ii<TDim+1; ii++)
1519  for(unsigned int ii = 0; ii<geom.size(); ii++)
1520  {
1521  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1522  }
1523  //building matrix D (transpose of the gradient integrated by parts)
1524 
1525  temp = Volume*aaa;
1526 
1527 
1528  for(unsigned int row = 0; row<TDim+1; row++)
1529  {
1530  unsigned int row_index = local_indices[row] / (TDim); //ATTENTION! here i am doing a dangerous op
1531  //KRATOS_WATCH(row_index)
1532 
1533  for(unsigned int col = 0; col<TDim+1; col++)
1534  {
1535  for(unsigned int kkk = 0; kkk<TDim; kkk++)
1536  {
1537  //check if the below is correct (copied it from Mass matrix)
1538  unsigned int col_index = local_indices[col]+kkk;
1539  //unsigned int col_index = col + kkk;
1540  mD(row_index,col_index) += temp * DN_DX(col,kkk);
1541  }
1542  }
1543 
1544 
1545  }
1546  }
1547 
1548  }
1549  #else
1550  //creating an array of lock variables of the size of the system matrix
1551  std::vector< omp_lock_t > lock_array(mD.size1());
1552 
1553  int D_size = mD.size1();
1554  for (int i = 0; i < D_size; i++)
1555  omp_init_lock(&lock_array[i]);
1556 
1557  //create a partition of the element array
1558  int number_of_threads = omp_get_max_threads();
1559 
1560  vector<unsigned int> element_partition;
1561  CreatePartition(number_of_threads, r_model_part.Elements().size(), element_partition);
1562  KRATOS_WATCH(number_of_threads);
1563  KRATOS_WATCH(element_partition);
1564 
1565 
1566  double start_prod = omp_get_wtime();
1567 
1568 
1569  //#pragma omp parallel for private (DN_DX, N, local_indices, Volume, temp, aaa, dof_position)
1570  #pragma omp parallel for
1571  for (int k = 0; k < number_of_threads; k++)
1572  {
1573  boost::numeric::ublas::bounded_matrix<double,TDim+1,TDim> DN_DX;
1574  array_1d<double,TDim+1> N;
1575  array_1d<unsigned int ,TDim+1> local_indices;
1576  //array_1d<double,TDim+1> rhs_contribution;
1577  double Volume;
1578  double temp;
1579 
1580 
1581  //getting the dof position
1582  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
1583 
1584  double aaa = 1.0/(TDim+1.0);
1585 
1586 
1587 
1588  //Element::EquationIdVectorType EquationId;
1589  //ProcessInfo& CurrentProcessInfo = r_model_part.GetProcessInfo();
1590  typename ElementsArrayType::ptr_iterator it_begin = r_model_part.Elements().ptr_begin() + element_partition[k];
1591  typename ElementsArrayType::ptr_iterator it_end = r_model_part.Elements().ptr_begin() + element_partition[k + 1];
1592 
1593 
1594 
1595  // assemble all elements
1596  for (typename ElementsArrayType::ptr_iterator i = it_begin; i != it_end; ++i)
1597  {
1598 
1599  Geometry< Node >& geom = (*i)->GetGeometry();
1600  //counting the n-r of structure nodes
1601  unsigned int str_nr=0;
1602 
1603  //for (int k = 0;k<TDim+1;k++)
1604  for (unsigned int k = 0;k<geom.size();k++)
1605  {
1606  str_nr+=(unsigned int)((*i)->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1607  }
1609  //if the element is not having all the nodes IS_STRUCTURE, assemble it, otherwise do nothing
1610  // that means, that the entries corresponding to the structural elements are zero
1612  if (geom.size()!=str_nr)
1613  {
1614  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1615  if (Volume<0)
1616  Volume*=-1.0;
1617 
1618  //finiding local indices
1619  //for(int ii = 0; ii<TDim+1; ii++)
1620  for(unsigned int ii = 0; ii<geom.size(); ii++)
1621  {
1622  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1623  }
1624  //building matrix D (transpose of the gradient integrated by parts)
1625 
1626  temp = Volume*aaa;
1627 
1628 
1629  for(unsigned int row = 0; row<TDim+1; row++)
1630  {
1631  unsigned int row_index = local_indices[row] / (TDim); //ATTENTION! here i am doing a dangerous op
1632  omp_set_lock(&lock_array[row_index]);
1633  //KRATOS_WATCH(row_index)
1634  for(unsigned int col = 0; col<TDim+1; col++)
1635  {
1636  for(unsigned int kkk = 0; kkk<TDim; kkk++)
1637  {
1638  //check if the below is correct (copied it from Mass matrix)
1639  unsigned int col_index = local_indices[col]+kkk;
1640  //unsigned int col_index = col + kkk;
1641  mD(row_index,col_index) += temp * DN_DX(col,kkk);
1642  }
1643  }
1644  omp_unset_lock(&lock_array[row_index]);
1645 
1646 
1647  }
1648  }
1649  }
1650  }
1651 
1652  double stop_prod = omp_get_wtime();
1653  std::cout << "time: " << stop_prod - start_prod << std::endl;
1654 
1655  for (int i = 0; i < D_size; i++)
1656  omp_destroy_lock(&lock_array[i]);
1657  #endif
1658 
1659  //KRATOS_WATCH("FINISHED BUILDING AUXILIARY MATRIX D")
1660  KRATOS_CATCH (" ")
1661  }
1662 
1663  */
1664 
1665  //**************************************************************************
1666  //**************************************************************************
1667  //
1668  //assembles consistent and lumped mass matrices
1670  {
1671  //first we assemble the diagonal mass matrix
1672  KRATOS_TRY
1673  //KRATOS_WATCH("BUILDING MASS MATRICES ")
1676  array_1d<unsigned int ,TDim+1> local_indices;
1677  //array_1d<double,TDim+1> rhs_contribution;
1678  double Volume;
1679  double temp;
1680  //getting the dof position
1681  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
1682 
1683  double aaa = 1.0/(TDim+1.0);
1684 
1685  for(ModelPart::ElementsContainerType::iterator i = r_model_part.ElementsBegin();
1686  i!=r_model_part.ElementsEnd(); i++)
1687  {
1688 
1689  Geometry< Node >& geom = i->GetGeometry();
1690  //counting number of structural nodes
1691  unsigned int str_nr=0;
1692  //for (int k = 0;k<TDim+1;k++)
1693  for (unsigned int k = 0; k<geom.size(); k++)
1694  {
1695  str_nr+=int(i->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1696  }
1697  //we do not do anything for the elements of the structure (all nodes are IS_STR)
1698  if (geom.size()!=str_nr)
1699  {
1700 
1701  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1702  if (Volume<0)
1703  Volume*=-1.0;
1704 
1705  //finiding local indices
1706  //for(int ii = 0; ii<TDim+1; ii++)
1707  for(unsigned int ii = 0; ii<geom.size(); ii++)
1708  {
1709  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1710  }
1711 
1712  temp = Volume*aaa;
1713  for(unsigned int row = 0; row<TDim+1; row++)
1714  {
1715  unsigned int row_index = local_indices[row] / (TDim);
1716  mMdiagInv[row_index] += temp;
1717  }
1718  }
1719 
1720  }
1721  //KRATOS_WATCH(mMdiagInv)
1722  //inverting the mass matrix
1723  for(unsigned int i = 0; i<TSparseSpace::Size(mMdiagInv); i++)
1724  {
1725  if (mMdiagInv[i]>1e-26)
1726  mMdiagInv[i] = 1.0/mMdiagInv[i];
1727  else //if (mMdiagInv[i]==0.0)
1728  {
1729 
1730  //KRATOS_WATCH(mMdiagInv[i])
1731  //KRATOS_THROW_ERROR(std::logic_error,"something is wrong with the mass matrix entry - ZERO!!!","")
1732  mMdiagInv[i] = 1000000000000.0;
1733 
1734  //KRATOS_WATCH(mMdiagInv[i])
1735  //KRATOS_THROW_ERROR(std::logic_error,"Zero ELEMENT VOLUMEE!!!!!!!!!!!!!!","")
1736  //mMdiagInv[i] = 0.0;
1737 
1738  }
1739  }
1740 
1741 
1742  //KRATOS_WATCH(mMdiagInv)
1743  //AND NOW WE BUILD THE CONSISTENT MASS MATRIX
1744 
1745  for(ModelPart::ElementsContainerType::iterator i = r_model_part.ElementsBegin();
1746  i!=r_model_part.ElementsEnd(); i++)
1747  {
1748 
1749  Geometry< Node >& geom = i->GetGeometry();
1750  unsigned int str_nr=0;
1751  for (unsigned int k = 0; k<i->GetGeometry().size(); k++)
1752  {
1753  str_nr+=(unsigned int)(i->GetGeometry()[k].FastGetSolutionStepValue(IS_STRUCTURE));
1754  }
1755 
1756  if (geom.size()!=str_nr)
1757  {
1758 
1759 
1760 
1761  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
1762  if (Volume<0)
1763  Volume*=-1.0;
1764  //finiding local indices
1765  //for(int ii = 0; ii<TDim+1; ii++)
1766  for(unsigned int ii = 0; ii<geom.size(); ii++)
1767  {
1768  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
1769  }
1770 
1771  temp = Volume*aaa;
1772  //element mass matrix has a shape:
1773  // 2 1 1
1774  // A/12.0* 1 2 1 in 2D
1775  // 1 1 2
1776  //
1777  // and
1778  //
1779  // 2 1 1 1
1780  // V/20.0* 1 2 1 1 in 3D
1781  // 1 1 2 1
1782  // 1 1 1 2
1783 
1784  //nothing should be added in case of membrane
1785  for(unsigned int row = 0; row<TDim+1; row++)
1786  {
1787  unsigned int row_index = local_indices[row] / (TDim); //pressure is a scalar=>matrix size is Tdim times smaller than for vector
1788  for(unsigned int col = 0; col<TDim+1; col++)
1789  {
1790  unsigned int col_index = local_indices[col] /(TDim);
1791  if (row_index==col_index)
1792  {
1793  //Mconsistent(row_index,col_index) += temp * 2.0;
1794  if constexpr (TDim==2)
1795  Mconsistent(row_index,col_index) += 0.25*temp * 2.0;
1796  else if constexpr (TDim==3)
1797  Mconsistent(row_index,col_index) += 0.2*temp * 2.0;
1798  }
1799  else
1800  {
1801 
1802  //Mconsistent(row_index,col_index) += temp ;
1803  if constexpr (TDim==2)
1804  Mconsistent(row_index,col_index) += 0.25*temp ;
1805  else if constexpr (TDim==3)
1806  Mconsistent(row_index,col_index) += 0.2*temp;
1807 
1808  }
1809  }
1810 
1811 
1812  }
1813  }
1814  }
1815 
1816  // KRATOS_WATCH("FINISHED BUILDING MASS MATRICES ")
1817  KRATOS_CATCH("")
1818 
1819  }
1820 
1821 
1822  //output += trans(input)*input
1823  //
1825  TSystemVectorType& precond,
1826  TSystemVectorType& result)
1827  {
1828  KRATOS_TRY
1829 
1830  if ( precond.size()!=vec.size() )
1831  KRATOS_THROW_ERROR(std::logic_error,"preconditioner size is wrong","")
1832  if ( precond.size()!=result.size() )
1833  KRATOS_THROW_ERROR(std::logic_error,"preconditioner size is wrong","")
1834  TSparseSpace::SetToZero(result);
1835 
1836  //typedef unsigned int size_type;
1837  //typedef double value_type;
1838  //KRATOS_WATCH(precond)
1839  #pragma omp parallel for
1840  for (int i=0; i<static_cast<int>(precond.size()); i++)
1841  {
1842  result[i]=precond[i]*vec[i];
1843  }
1844  KRATOS_CATCH("");
1845  }
1846 
1847 
1849  TSystemVectorType& Minv,
1851 
1852  TSystemVectorType& WorkArray,
1853  TSystemVectorType& destination)
1854  {
1855  KRATOS_TRY
1856  //KRATOS_WATCH("COMPUTING GM-1D")
1857  //typedef unsigned int size_type;
1858  //typedef double value_type;
1859 
1860  TSparseSpace::SetToZero(WorkArray);
1861  //TSparseSpace::SetToZero(destination);
1862 
1863  //WorkArray = D * x
1864  TSparseSpace::Mult(mD, x, WorkArray);
1865 
1866  //KRATOS_WATCH(WorkArray)
1867 
1868  //WorkArray = Minv * WorkArray
1869  #pragma omp parallel for
1870  for(int i=0; i<static_cast<int>(WorkArray.size()); i++)
1871  {
1872  WorkArray[i] *= Minv[i];
1873  }
1874 
1875  //destination = trans(D) * WorkArray
1876 
1877 
1878 
1879  //TSparseSpace::TransposeMult(D, x, WorkArray);
1880  TSparseSpace::TransposeMult(mD, WorkArray, destination);
1881  //KRATOS_WATCH(destination)
1882  //KRATOS_WATCH("FINISHED COMPUTING GM-1D")
1883  KRATOS_CATCH("");
1884  }
1885 
1886 
1887  //*************************************************************************************************
1888  //*************************************************************************************************
1890  {
1891  KRATOS_TRY
1892  //TSparseSpace::SetToZero(Dx);
1893 
1894  if ( Dx.size()!=xi.size() )
1895  KRATOS_THROW_ERROR(std::logic_error,"Dx and xi sizes mismatch","")
1896 
1897  Dx=xi;
1898  KRATOS_CATCH("");
1899  }
1900 
1901 
1902  //*************************************************************************************************
1903  //*************************************************************************************************
1904 
1906  const TSystemVectorType& Minv,
1907  const TSystemMatrixType& A,
1908  TSystemVectorType& preconditioner)
1909  {
1910  KRATOS_TRY
1911  //KRATOS_WATCH("COMPUTING preconditioner")
1912  typedef unsigned int size_type;
1913  typedef double value_type;
1914 
1915 
1916 
1917  TSparseSpace::SetToZero(preconditioner);
1918 
1919 
1920 
1921  if ( preconditioner.size()!=A.size1() )
1922  KRATOS_THROW_ERROR(std::logic_error,"preconditioner size is wrong","")
1923 
1924  //get diagonal of matrix A
1925  for(unsigned int i = 0; i<A.size1(); i++)
1926  {
1927  preconditioner[i] = A(i,i);
1928  }
1929 
1930  //TSparseSpace::SetToZero(preconditioner);
1931 
1932  //calculate and add diagonal of G*Minv*D
1933  //using that G*Minv*D(i,i) = D_k
1934 
1935 
1936  for (size_type k = 0; k < D.size1 (); ++ k)
1937  {
1938  size_type begin = D.index1_data () [k];
1939  size_type end = D.index1_data () [k + 1];
1940 
1941 
1942  for (size_type i = begin; i < end; ++ i)
1943  {
1944  unsigned int index_i = D.index2_data () [i];
1945  value_type data_i = D.value_data()[i];
1946  preconditioner[index_i] += Minv[k]*data_i*data_i;
1947  }
1948  }
1949 
1950 
1951  //KRATOS_WATCH(preconditioner)
1952  //invert the preconditioner matrix
1953  for(unsigned int i = 0; i<A.size1(); i++)
1954  {
1955 
1956 
1957 
1958  if (fabs(preconditioner[i])>1e-26)
1959  //preconditioner[i] = 1.00/preconditioner[i];
1960  preconditioner[i] = 1.00/preconditioner[i];
1961  else
1962  preconditioner[i] = 1000000000000000000.0;
1963 
1964  if (preconditioner[i]<0.0)
1965  preconditioner[i]*=-10000000000000000000.0;
1966  //preconditioner[i]*=1000000000000000000.0;
1967  /*
1968  if (preconditioner[i]<0.0)
1969  {
1970  //preconditioner[i]=1.0;
1971  KRATOS_THROW_ERROR(std::logic_error,"NEGATIVE PRECONDITIONER","")
1972  }
1973  */
1974 
1975 
1976  }
1977  //KRATOS_WATCH("Finished COMPUTING preconditioner")
1978  KRATOS_CATCH("");
1979 
1980  }
1981 
1982  //*************************************************************************************************
1983  //*************************************************************************************************
1984 
1985  bool ConvergenceCheck (TSystemVectorType& residual, TSystemVectorType& b, const double& tolerance, const int& iter_number, const int& max_iter_number)
1986  {
1987  //const DataType abs_toll = DataType(1e-15);
1988  //
1989  //absolute tolerance = 1e-15
1990  //
1991  if (iter_number>max_iter_number)
1992  KRATOS_THROW_ERROR(std::logic_error,"MAX NUMBER OF ITERATIONS EXCEEDED, UR CG DIDNT CONVERGE","")
1993 
1994  if (TSparseSpace::TwoNorm(residual)<1e-15)
1995  return true;
1996 
1997 
1998  else
1999  {
2000  const double& ratio = TSparseSpace::TwoNorm(residual)/TSparseSpace::TwoNorm(b);
2001  //KRATOS_WATCH(ratio)
2002  return( (ratio) < tolerance);
2003  }
2004 
2005  }
2006 
2007  //*************************************************************************************************
2008  //*************************************************************************************************
2009 
2011  {
2012  KRATOS_TRY
2013 
2014  double large_number = 1e20;
2015  for(typename DofsArrayType::iterator i_dof = BaseType::mDofSet.begin() ; i_dof != BaseType::mDofSet.end() ; ++i_dof)
2016  {
2017  if(i_dof->IsFixed() == true)
2018  {
2019  unsigned int eq_id = i_dof->EquationId();
2020 
2021  A(eq_id,eq_id) += large_number;
2022  //b[eq_id] = 0.0001;
2023  }
2024  }
2025 
2026  KRATOS_CATCH("");
2027  }
2029  {
2030  KRATOS_TRY
2031 
2032  int i=0;
2033  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
2034  const int size = TSparseSpace::Size(mMdiagInv);
2035 
2036  TSystemVectorType p(size);
2037  TSystemVectorType f_p(3*size);
2038  i=0;
2039  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2040  {
2041  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0)// && in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2042  {
2043  i=in->GetDof(DISPLACEMENT_X,dof_position).EquationId()/TDim;
2044  p[i]=in->FastGetSolutionStepValue(PRESSURE);
2045  }
2046 
2047  }
2048 
2050 
2051 
2052  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2053  {
2054  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0)// && in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2055  {
2056 
2057 
2058  in->FastGetSolutionStepValue(FORCE_X)=f_p[in->GetDof(DISPLACEMENT_X,dof_position).EquationId()];
2059  in->FastGetSolutionStepValue(FORCE_Y)=f_p[in->GetDof(DISPLACEMENT_Y,dof_position).EquationId()];
2060  in->FastGetSolutionStepValue(FORCE_Z)=f_p[in->GetDof(DISPLACEMENT_Z,dof_position).EquationId()];
2061 
2062  }
2063  }
2064 
2065  KRATOS_CATCH("");
2066  }
2067 
2068  void ComputePressureAtFreeSurface (ModelPart& r_model_part, double bulk_modulus, double density)
2069  {
2070  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2071  {
2072  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0)// && in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2073  {
2074  if (in->FastGetSolutionStepValue(IS_FLUID)==1.0 && in->FastGetSolutionStepValue(IS_FREE_SURFACE)==1.0)
2075  {
2076  //KRATOS_WATCH("Computing pressure at a free surface node")
2077  in->FastGetSolutionStepValue(PRESSURE)=bulk_modulus*density*(in->FastGetSolutionStepValue(NODAL_AREA) - in->FastGetSolutionStepValue(NODAL_AREA,1))/(in->FastGetSolutionStepValue(NODAL_AREA));
2078 //=in->FastGetSolutionStepValue(PRESSURE,1)+bulk_modulus*density*(in->FastGetSolutionStepValue(NODAL_AREA) - in->FastGetSolutionStepValue(NODAL_AREA,1))/(in->FastGetSolutionStepValue(NODAL_AREA));
2079 
2080  }
2081  }
2082 
2083  }
2084 
2085  }
2087  /*
2088  void CalculateLupmedMass(ModelPart& model_part)
2089  {
2090  KRATOS_TRY
2091  double dummy=0.0;
2092  ProcessInfo& proc_info = model_part.GetProcessInfo();
2093  for (typename ModelPart::ElementsContainerType::iterator im=model_part.ElementsBegin(); im!=model_part.ElementsEnd(); ++im)
2094  {
2095  im->Calculate(NODAL_MASS, dummy, proc_info);
2096  }
2097  KRATOS_CATCH("");
2098  }
2099  */
2101  {
2102  KRATOS_TRY
2103  double pres=0.0;
2104  for (typename ModelPart::NodesContainerType::iterator it=model_part.NodesBegin(); it!=model_part.NodesEnd(); ++it)
2105  {
2106  pres=it->FastGetSolutionStepValue(PRESSURE);
2107  it->FastGetSolutionStepValue(PRESSURE_OLD_IT)=pres;
2108  }
2109  KRATOS_CATCH("");
2110  }
2112  void FractionalStepProjection(ModelPart& model_part, double alpha_bossak)
2113  {
2114  KRATOS_TRY
2115 // double aaa=0.0;
2116  double dt = model_part.GetProcessInfo()[DELTA_TIME];
2119  array_1d<double,3> aux0, aux1, aux2; //this are sized to 3 even in 2D!!
2120 
2121  //reset the auxilliary vector
2122 
2123  for (typename ModelPart::NodesContainerType::iterator it=model_part.NodesBegin(); it!=model_part.NodesEnd(); ++it)
2124  {
2125  it->FastGetSolutionStepValue(VAUX)=ZeroVector(3);
2126  }
2127 
2128  //calculate the velocity correction and store it in VAUX
2129 
2130  for (typename ModelPart::ElementsContainerType::iterator im=model_part.ElementsBegin(); im!=model_part.ElementsEnd(); ++im)
2131  {
2132  //get the list of nodes of the element
2133  Geometry< Node >& geom = im->GetGeometry();
2134 
2135  double volume;
2137 
2138  array_1d<double,3> pres_inc;
2139  //pres_inc[0] = geom[0].FastGetSolutionStepValue(PRESSURE,1)-geom[0].FastGetSolutionStepValue(PRESSURE);
2140  //pres_inc[1] = geom[1].FastGetSolutionStepValue(PRESSURE,1)-geom[1].FastGetSolutionStepValue(PRESSURE);
2141  //pres_inc[2] = geom[2].FastGetSolutionStepValue(PRESSURE,1)-geom[2].FastGetSolutionStepValue(PRESSURE);
2142 
2143 
2144  pres_inc[0] = geom[0].FastGetSolutionStepValue(PRESSURE_OLD_IT)-geom[0].FastGetSolutionStepValue(PRESSURE);
2145  pres_inc[1] = geom[1].FastGetSolutionStepValue(PRESSURE_OLD_IT)-geom[1].FastGetSolutionStepValue(PRESSURE);
2146  pres_inc[2] = geom[2].FastGetSolutionStepValue(PRESSURE_OLD_IT)-geom[2].FastGetSolutionStepValue(PRESSURE);
2147 
2148  //KRATOS_WATCH(pres_inc[0])
2149  //KRATOS_WATCH(pres_inc[1])
2150  //KRATOS_WATCH(pres_inc[2])
2151 
2152  //Riccardo's modification: multiply the G(p_n+1-p_n) by 1/2
2153  //pres_inc*=0.5;
2154 
2155  //Gradient operator G:
2156  BoundedMatrix<double,6,2> shape_func = ZeroMatrix(6, 2);
2158  for (int ii = 0; ii< 3; ii++)
2159  {
2160  int column = ii*2;
2161  shape_func(column,0) = N[ii];
2162  shape_func(column + 1, 1) = shape_func(column,0);
2163  }
2164  noalias(G)=prod(shape_func, trans(DN_DX));
2165  G*=volume;
2166 
2167  array_1d<double,6> aaa;
2168  noalias(aaa) = prod(G,pres_inc);
2169 
2170  array_1d<double,3> aux;
2171 
2172  aux[0]=aaa[0];
2173  aux[1]=aaa[1];
2174  //z-component is zero
2175  aux[2]=0.0;
2176  geom[0].FastGetSolutionStepValue(VAUX) += aux;
2177 
2178  //reusing aux for the second node
2179  aux[0]=aaa[2];
2180  aux[1]=aaa[3];
2181  //z-component is zero
2182 
2183  geom[1].FastGetSolutionStepValue(VAUX) += aux;
2184  //reusing aux for the third node
2185  aux[0]=aaa[4];
2186  aux[1]=aaa[5];
2187 
2188  geom[2].FastGetSolutionStepValue(VAUX) += aux;
2189  }
2190 
2191  //double beta_newm=0.25*(1.0-alpha_bossak)*(1.0-alpha_bossak);
2192  alpha_bossak=-0.3;
2193  double coef=0.25*(1.0-alpha_bossak);
2194 
2195  //double beta_newm=coef*(1.0-alpha_bossak);
2196 
2197 
2198  for (typename ModelPart::NodesContainerType::iterator it=model_part.NodesBegin(); it!=model_part.NodesEnd(); ++it)
2199  {
2200  if( (it->GetValue(NEIGHBOUR_NODES)).size() != 0)
2201  {
2202  //VELOCITY = VELOCITY + dt * Minv * VAUX
2203  if (it->FastGetSolutionStepValue(NODAL_MASS)>0.0000000001)
2204  //KRATOS_THROW_ERROR(std::logic_error, "You have not computed the nodal mass!", "");
2205  {
2206 
2207  double dt_sq_Minv =coef*dt*dt / it->FastGetSolutionStepValue(NODAL_MASS);
2208 
2209  array_1d<double,3>& temp = it->FastGetSolutionStepValue(VAUX);
2210 
2211  if(!it->IsFixed(DISPLACEMENT_X))
2212  {
2213  it->FastGetSolutionStepValue(DISPLACEMENT_X)+=dt_sq_Minv*temp[0];
2214  }
2215  if(!it->IsFixed(DISPLACEMENT_Y))
2216  {
2217  it->FastGetSolutionStepValue(DISPLACEMENT_Y)+=dt_sq_Minv*temp[1];
2218  }
2219  }
2220  }
2221  }
2222  KRATOS_CATCH("");
2223  }
2225  void UpdateAfterProjection( ModelPart& model_part, double alpha_bossak)
2226  {
2227  KRATOS_TRY
2228  //updating time derivatives (nodally for efficiency)
2229  double dt = model_part.GetProcessInfo()[DELTA_TIME];
2230  array_1d<double,3> DeltaDisp;
2231  double beta_newmark = 0.25*pow((1.00-alpha_bossak),2);
2232 
2233  double gamma_newmark = 0.5-alpha_bossak;
2234 
2235  /*
2236  ma0 = 1.0/(mBetaNewmark*pow(DeltaTime,2));
2237  ma1 = mGammaNewmark / (mBetaNewmark*DeltaTime);
2238  ma2 = 1.0/(mBetaNewmark*DeltaTime);
2239  ma3 = 1.0/(2.0*mBetaNewmark) - 1.0;
2240  ma4 = mGammaNewmark/mBetaNewmark - 1.0;
2241  */
2242 
2243  double ma0=1.0/(beta_newmark*pow(dt,2));
2244  double ma1=gamma_newmark/(beta_newmark*dt);
2245  double ma2=1.0/(beta_newmark*dt);
2246  double ma3=(1.0/(2.0*beta_newmark))-1.0;
2247  double ma4=(gamma_newmark/beta_newmark)-1.0;
2248  double ma5=dt*0.5*((gamma_newmark/beta_newmark)-2.0);
2249 
2250  for(ModelPart::NodeIterator i = model_part.NodesBegin() ; i != model_part.NodesEnd() ; ++i)
2251  {
2252  noalias(DeltaDisp) = (i)->FastGetSolutionStepValue(DISPLACEMENT) - (i)->FastGetSolutionStepValue(DISPLACEMENT,1);
2253  array_1d<double,3>& CurrentVelocity = (i)->FastGetSolutionStepValue(VELOCITY,0);
2254  array_1d<double,3>& OldVelocity = (i)->FastGetSolutionStepValue(VELOCITY,1);
2255 
2256  array_1d<double,3>& CurrentAcceleration = (i)->FastGetSolutionStepValue(ACCELERATION,0);
2257  array_1d<double,3>& OldAcceleration = (i)->FastGetSolutionStepValue(ACCELERATION,1);
2258 
2259  UpdateVelocity(CurrentVelocity,DeltaDisp,OldVelocity,OldAcceleration, ma1, ma4, ma5);
2260  UpdateAcceleration(CurrentAcceleration,DeltaDisp,OldVelocity,OldAcceleration, ma0, ma2, ma3);
2261  }
2262  KRATOS_CATCH("");
2263  }
2265  inline void UpdateVelocity(array_1d<double, 3>& CurrentVelocity, const array_1d<double, 3>& DeltaDisp,
2266  const array_1d<double, 3>& OldVelocity,
2267  const array_1d<double, 3>& OldAcceleration, double& ma1, double& ma4, double & ma5)
2268  {
2269  noalias(CurrentVelocity) = ma1*DeltaDisp - ma4*OldVelocity - ma5*OldAcceleration;
2270  }
2272  inline void UpdateAcceleration(array_1d<double, 3>& CurrentAcceleration, const array_1d<double, 3>& DeltaDisp,
2273  const array_1d<double, 3>& OldVelocity,
2274  const array_1d<double, 3>& OldAcceleration, double& ma0, double& ma2, double & ma3)
2275  {
2276  noalias(CurrentAcceleration) = ma0*DeltaDisp - ma2*OldVelocity - ma3*OldAcceleration;
2277  }
2278 
2280  {
2281  KRATOS_TRY
2282  //getting the dof position
2283  unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
2284 // const double dt = r_model_part.GetProcessInfo()[DELTA_TIME];
2285 
2287  //resetting the pressures to zero
2288  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2289  {
2290  in->FastGetSolutionStepValue(PRESSURE)=0.0;
2291  }
2292  //for pressure vectors
2293  const int size = TSparseSpace::Size(mMdiagInv);
2294 
2295  TSystemVectorType p_n(size);
2296  //TSystemMatrixType aux(size,size);
2297  //aux=ZeroMatrix(size,size);
2298  TSystemVectorType temp(size);
2299  TSystemVectorType history(size);
2300 
2301  //TSparseSpace::SetToZero(p_n1);
2302  TSparseSpace::SetToZero(p_n);
2303  TSparseSpace::SetToZero(history);
2304 
2305 
2306 
2307 
2308 
2309 
2310  //assuming that the bulk modulus is the same for all nodes in the model part
2311  //p_n is the history, d_a - change_of_nodal_area/current_nodal_area
2312  int i=0;
2313  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2314  {
2315  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0 )// && in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2316  {
2317  i=in->GetDof(DISPLACEMENT_X,dof_position).EquationId()/TDim;
2318  p_n[i]=in->FastGetSolutionStepValue(PRESSURE,1);
2319 
2320  }
2321 
2322 
2323  }
2324  //KRATOS_WATCH(p_n)
2325 
2326  //history (multiplied by the consistent mass matrix) and then by the inverse lumped mass matrix
2327  TSparseSpace::Mult(mMconsistent, p_n, history);
2328 
2329  //KRATOS_WATCH(history)
2330  int aa=0;
2331 
2332  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2333  {
2334  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0)// && in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2335  {
2336  aa=in->GetDof(DISPLACEMENT_X,dof_position).EquationId()/TDim;
2337  if (in->FastGetSolutionStepValue(IS_FLUID)==1.0)
2338  {
2339  //+temp[aa]/density
2340  in->FastGetSolutionStepValue(PRESSURE)=(mMdiagInv[aa]*history[aa])+bulk_modulus*density*(in->FastGetSolutionStepValue(NODAL_AREA) - in->FastGetSolutionStepValue(NODAL_AREA,1))/(in->FastGetSolutionStepValue(NODAL_AREA));
2341 
2342  //this one is without mass matrix difference stab, just the laplacian
2343  //in->FastGetSolutionStepValue(PRESSURE)=p_n[aa]+temp[aa]/density+bulk_modulus*density*(in->FastGetSolutionStepValue(NODAL_AREA) - in->FastGetSolutionStepValue(NODAL_AREA,1))/(in->FastGetSolutionStepValue(NODAL_AREA));
2344  }
2345  }
2346 
2347  }
2348 
2349 
2350  KRATOS_CATCH("");
2351  }
2352  //this function updates pressure after the Dx is obtained at every step of N-R procedure
2355  {
2356  KRATOS_TRY
2357  //getting the dof position
2358 // unsigned int dof_position = (r_model_part.NodesBegin())->GetDofPosition(DISPLACEMENT_X);
2359 // const double dt = r_model_part.GetProcessInfo()[DELTA_TIME];
2360 
2362 
2363  //for pressure vectors
2364  const int size = TSparseSpace::Size(mMdiagInv);
2365  //for displacement vectors
2366  const int size_disp = TDim*TSparseSpace::Size(mMdiagInv);
2367 
2368  TSystemVectorType p_n(size);
2369  TSystemVectorType dp(size);
2370  TSystemVectorType p_n1(size);
2371  TSystemVectorType history(size);
2372  //TSystemVectorType temp1(size);
2373  //TSystemVectorType temp2(size);
2374 
2375  TSparseSpace::SetToZero(p_n);
2376  TSparseSpace::SetToZero(dp);
2377  TSparseSpace::SetToZero(p_n1);
2378  TSparseSpace::SetToZero(history);
2379  //TSparseSpace::SetToZero(temp1);
2380  //TSparseSpace::SetToZero(temp2);
2381 
2382  TSystemMatrixType aux(size,size);
2383  TSystemVectorType temp(size);
2384 
2385 
2386  TSystemVectorType displ(size_disp);
2387  /*
2388  TSystemMatrixType GlobLapl (size,size);
2389  TSystemMatrixType LocLapl (TDim+1,TDim+1);
2390 
2391  for (typename ElementsArrayType::iterator im=r_model_part.ElementsBegin(); im!=r_model_part.ElementsEnd(); ++im)
2392  {
2393  boost::numeric::ublas::bounded_matrix<double,TDim+1,TDim> DN_DX;
2394  array_1d<double,TDim+1> N;
2395  array_1d<unsigned int ,TDim+1> local_indices;
2396 
2397  Geometry< Node >& geom = im->GetGeometry();
2398  //calculating elemental values
2399  double Volume;
2400  GeometryUtils::CalculateGeometryData(geom, DN_DX, N, Volume);
2401 
2402  array_1d<double,3> ms_vel_gauss = ZeroVector(3);
2403 
2404  const array_1d<double,3>& fv0 = geom[0].FastGetSolutionStepValue(VELOCITY);
2405  const array_1d<double,3>& fv1 = geom[1].FastGetSolutionStepValue(VELOCITY);
2406  const array_1d<double,3>& fv2 = geom[2].FastGetSolutionStepValue(VELOCITY);
2407  array_1d<double,3> fv3 = ZeroVector(3);
2408  if constexpr (TDim==3)
2409  fv3 = geom[3].FastGetSolutionStepValue(VELOCITY);
2410 
2411 
2412  double nu = geom[0].FastGetSolutionStepValue(VISCOSITY)+
2413  geom[1].FastGetSolutionStepValue(VISCOSITY) +
2414  geom[2].FastGetSolutionStepValue(VISCOSITY);
2415 
2416  double density = geom[0].FastGetSolutionStepValue(DENSITY)+
2417  geom[1].FastGetSolutionStepValue(DENSITY) +
2418  geom[2].FastGetSolutionStepValue(DENSITY);
2419 
2420  ms_vel_gauss=fv0+fv1+fv2;
2421  if constexpr (TDim==2)
2422  {
2423  nu*=0.33333333333;
2424  density*=0.33333333333;
2425  ms_vel_gauss*=0.33333333333;
2426  }
2427 
2428 
2429 
2430  if constexpr (TDim==3)
2431  {
2432  ms_vel_gauss+=fv3;
2433  nu+=geom[3].FastGetSolutionStepValue(VISCOSITY);
2434  density+=geom[3].FastGetSolutionStepValue(DENSITY);
2435  ms_vel_gauss*=0.25;
2436  nu*=0.25;
2437  density*=0.25;
2438  }
2439 
2440 
2441  //finiding local indices
2442  //for(int ii = 0; ii<TDim+1; ii++)
2443  for(unsigned int ii = 0; ii<geom.size(); ii++)
2444  {
2445  local_indices[ii] = geom[ii].GetDof(DISPLACEMENT_X,dof_position).EquationId();
2446  }
2447 
2448 
2449  //the structural elements should not contribute to the Laplacian
2450  int str_nr=0;
2451  for (unsigned int k = 0;k<geom.size();k++)
2452  {
2453  str_nr+=(unsigned int)(geom[k].FastGetSolutionStepValue(IS_STRUCTURE));
2454  }
2455  int switch_var=0;
2456  //set to zero the entries of the str. elements
2457  if (str_nr==TDim+1)
2458  switch_var=0;
2459  else
2460  switch_var =1;
2461 
2462  //ms_vel_gauss[i] = msN[0]*(fv0[i]) + msN[1]*(fv1[i]) + msN[2]*(fv2[i]);
2463  //but with one integration N=0.333333333
2464  double norm_u;
2465  double h;
2466  if constexpr (TDim==2)
2467  {
2468  ms_vel_gauss[0] = 0.33333333333333*(fv0[0]+fv1[0]+fv2[0]);
2469  ms_vel_gauss[1] = 0.33333333333333*(fv0[1]+fv1[1]+fv2[1]);
2470  ms_vel_gauss[2] = 0.0;
2471 
2472  //calculating parameter tau (saved internally to each element)
2473  h = sqrt(2.00*Volume);
2474  norm_u = ms_vel_gauss[0]*ms_vel_gauss[0] + ms_vel_gauss[1]*ms_vel_gauss[1];
2475  norm_u = sqrt(norm_u);
2476  }
2477  if constexpr (TDim==3)
2478  {
2479  ms_vel_gauss[0] = 0.25*(fv0[0]+fv1[0]+fv2[0]+fv3[0]);
2480  ms_vel_gauss[1] = 0.25*(fv0[1]+fv1[1]+fv2[1]+fv3[1]);
2481  ms_vel_gauss[2] = 0.25*(fv0[2]+fv1[2]+fv2[2]+fv3[2]);
2482 
2483  //calculating parameter tau (saved internally to each element)
2484  h = sqrt(2.00*Volume);
2485  norm_u = ms_vel_gauss[0]*ms_vel_gauss[0] + ms_vel_gauss[1]*ms_vel_gauss[1] + ms_vel_gauss[2]*ms_vel_gauss[2];
2486  norm_u = sqrt(norm_u);
2487  }
2488  //- 4.0/(bulk_modulus*h*h)
2489  //double tau = 1.00 / ( 4.00*nu/(h*h) - bulk_modulus*dt/h+2.00*norm_u/h);
2490  //double tau=(bulk_modulus)*dt*h/(norm_u+nu/h);
2491  //double tau=(bulk_modulus)*dt*dt;//h/(norm_u+*nu/h);
2492  //my last proposal
2493  double tau = (bulk_modulus)*dt*nu/(norm_u*norm_u+(nu/dt));
2494  //Ric's proposal - doesnt work - checked with 2d-splash
2495  //double tau = (bulk_modulus)*dt*1.0/((1.0/dt)+(nu/h*h));
2496 
2497  //SWITCHED OFF THE STABILIZATION!
2498  switch_var=0;
2499 
2500 
2501  noalias(LocLapl)=switch_var*prod(DN_DX,trans(DN_DX));
2502 
2503 
2504 
2505 
2506 
2507 
2508 
2509  for(unsigned int row = 0; row<TDim+1; row++)
2510  {
2511  unsigned int row_index = local_indices[row] / (TDim);
2512  for(unsigned int col = 0; col<TDim+1; col++)
2513  {
2514  unsigned int col_index = local_indices[col] /(TDim);
2515 
2516  GlobLapl(row_index, col_index)+=tau*Volume*LocLapl(row,col);
2517  }
2518  }
2519  //end of the loop over elements
2520  }
2521 
2522  for (int i=0;i<mMdiagInv.size(); i++)
2523  {
2524  aux(i,i)=GlobLapl(i,i)*mMdiagInv(i);
2525  }
2526  */
2527  //assuming that the bulk modulus is the same for all nodes in the model part
2528  //
2529  //additionally here we update densities, simply by implyimg: ro_0xV_0=ro_1xV_1
2530  int i=0;
2531  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2532  {
2533  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0 )
2534  {
2535  //in pn we save old pressures
2536  if (i<size)
2537  p_n[i]=in->FastGetSolutionStepValue(PRESSURE,1);
2538  i++;
2539  //here we update densities
2540  //if (in->FastGetSolutionStepValue(NODAL_AREA)!=0.0)
2541  // in->FastGetSolutionStepValue(DENSITY)=in->FastGetSolutionStepValue(DENSITY,1)*in->FastGetSolutionStepValue(NODAL_AREA,1)/in->FastGetSolutionStepValue(NODAL_AREA);
2542 
2543  }
2544  }
2545  //temp = prod(aux, p_n);
2546  //history (multiplied by the consistent mass matrix)
2547  TSparseSpace::Mult(mMconsistent, p_n, history);
2548 
2549  //now we compute the pressure increment
2550  //first we save in the p_n1 the current deltap = KDd //Dx is denoted by d
2551  //
2552  //we store displacements in one big vector
2553 
2554  for(typename DofsArrayType::iterator i_dof = BaseType::mDofSet.begin() ; i_dof != BaseType::mDofSet.end() ; ++i_dof)
2555 
2556  {
2557 
2558  displ[i_dof->EquationId()]=i_dof->GetSolutionStepValue()-i_dof->GetSolutionStepValue(1);
2559  }
2560 
2561 
2562  TSparseSpace::Mult(mD, displ, dp);
2563  //KRATOS_WATCH(bulk_modulus)
2564 
2565  dp*=(bulk_modulus*density);
2566 
2567 
2568  //now we add the history (multiplied by the consistent mass matrix)
2569  //adding: mMconsistent*p_n + KDdipsl
2570 
2571 
2572  //p_n1=(temp+dp);
2573 
2574  //and now we multiply the result with the inverse of the lumped mass matrix
2575  //we reutilize the auxilliary matrix temp
2576 
2577  for (int ii=0; ii<size; ii++)
2578  {
2579  //temp1[ii]=mMdiagInv[ii]*p_n1[ii];
2580  p_n1[ii]=mMdiagInv[ii]*(history[ii]+dp[ii]);
2581  }
2582 
2583 
2584  //this is just to check
2585  //for (int ii=0; ii<size;ii++)
2586  //{
2587  //temp2[ii]=(mMdiagInv[ii]*dp[ii])+p_n[ii];
2588  //}
2589 
2590  //resetting the pressures to zero
2591  //
2592  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2593  {
2594  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0 )
2595  {
2596  in->FastGetSolutionStepValue(PRESSURE)=0.0;
2597  }
2598  }
2599 
2600  int aa=0;
2601  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2602  {
2603  if( (in->GetValue(NEIGHBOUR_NODES)).size() != 0 )
2604  {
2605  //not to add the "lonely" nodes , that are not part of the model (e.g. structure walls)
2606  if (aa<size)
2607  in->FastGetSolutionStepValue(PRESSURE)=p_n1[aa];//+temp[aa]/density;
2608  //in->FastGetSolutionStepValue(PRESSURE)=temp2[aa];
2609  aa++;
2610  }
2611  }
2612 
2613  //KRATOS_WATCH("PRESSURE UPDATE FUNCTION INSIDE BULDER AND SOLVER")
2614  /*
2615  for (typename NodesArrayType::iterator in=r_model_part.NodesBegin(); in!=r_model_part.NodesEnd(); ++in)
2616  {
2617  KRATOS_WATCH(in->FastGetSolutionStepValue(PRESSURE));
2618  }
2619  */
2620  KRATOS_CATCH("");
2621  }
2622 
2623  //**************************************************************************
2624  //**************************************************************************
2625  /*
2626  void SystemSolve(
2627  const TSystemMatrixType& A,
2628  const TSystemMatrixType& D,
2629  const TSystemVectorType& mMass_inverse,
2630  const TSystemVectorType& mpreconditioner,
2631  TSystemVectorType& x,
2632  const TSystemVectorType& b
2633  )
2634  {
2635  KRATOS_TRY
2636 
2637  const int size = TSparseSpaceType::Size(rX);
2638 
2639  unsigned int IterationsNumber = 0;
2640 
2641  TSystemVectorType r(size);
2642  TSystemVectorType q(size);
2643 
2644 
2645 
2646  PreconditionedMult(rA,rX,r);
2647  TSparseSpaceType::ScaleAndAdd(1.00, rB, -1.00, r);
2648 
2649  BaseType::mBNorm = TSparseSpaceType::TwoNorm(rB);
2650 
2651  VectorType p(r);
2652  VectorType q(size);
2653 
2654  double roh0 = TSparseSpaceType::Dot(r, r);
2655  double roh1 = roh0;
2656  double beta = 0;
2657 
2658  if(fabs(roh0) < 1.0e-30) //modification by Riccardo
2659  // if(roh0 == 0.00)
2660  return false;
2661 
2662  do
2663  {
2664  PreconditionedMult(rA,p,q);
2665 
2666  double pq = TSparseSpaceType::Dot(p,q);
2667 
2668  //if(pq == 0.00)
2669  if(fabs(pq) <= 1.0e-30)
2670  break;
2671 
2672  double alpha = roh0 / pq;
2673 
2674  TSparseSpaceType::ScaleAndAdd(alpha, p, 1.00, rX);
2675  TSparseSpaceType::ScaleAndAdd(-alpha, q, 1.00, r);
2676 
2677  roh1 = TSparseSpaceType::Dot(r,r);
2678 
2679  beta = (roh1 / roh0);
2680  TSparseSpaceType::ScaleAndAdd(1.00, r, beta, p);
2681 
2682  roh0 = roh1;
2683 
2684  BaseType::mResidualNorm = sqrt(roh1);
2685  BaseType::mIterationsNumber++;
2686  } while(BaseType::IterationNeeded() && (fabs(roh0) > 1.0e-30)
2687 
2688 
2689  KRATOS_CATCH("");
2690  }
2691  */
2692 
2710 }; /* Class ResidualBasedEliminationDiscreteLaplacianBuilderAndSolver */
2711 
2720 } /* namespace Kratos.*/
2721 
2722 #endif /* KRATOS_RESIDUAL_BASED_ELIMINATION_QUASI_INCOMPRESSIBLE_BUILDER_AND_SOLVER defined */
2723 
2724 
Current class provides an implementation for the base builder and solving operations.
Definition: builder_and_solver.h:64
bool mDofSetIsInitialized
If the matrix is reshaped each step.
Definition: builder_and_solver.h:743
TSparseSpace::VectorType TSystemVectorType
Definition of the vector size.
Definition: builder_and_solver.h:85
ModelPart::NodesContainerType NodesArrayType
The containers of the entities.
Definition: builder_and_solver.h:109
TSparseSpace::MatrixType TSystemMatrixType
Definition of the sparse matrix.
Definition: builder_and_solver.h:82
ModelPart::ConditionsContainerType ConditionsArrayType
Definition: builder_and_solver.h:111
TSystemVectorPointerType mpReactionsVector
Definition: builder_and_solver.h:751
TDenseSpace::MatrixType LocalSystemMatrixType
The local matrix definition.
Definition: builder_and_solver.h:94
TSparseSpace::VectorPointerType TSystemVectorPointerType
Definition of the pointer to the vector.
Definition: builder_and_solver.h:91
TSparseSpace::DataType TDataType
Definition of the data type.
Definition: builder_and_solver.h:79
DofsArrayType mDofSet
Pointer to the linear solver.
Definition: builder_and_solver.h:739
TDenseSpace::VectorType LocalSystemVectorType
The local vector definition.
Definition: builder_and_solver.h:97
TSparseSpace::MatrixPointerType TSystemMatrixPointerType
Definition of the pointer to the sparse matrix.
Definition: builder_and_solver.h:88
unsigned int mEquationSystemSize
Flag taking in account if it is needed or not to calculate the reactions.
Definition: builder_and_solver.h:747
ModelPart::ElementsContainerType ElementsArrayType
Definition: builder_and_solver.h:110
std::vector< std::size_t > EquationIdVectorType
Definition: condition.h:98
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
static void CalculateGeometryData(const GeometryType &rGeometry, BoundedMatrix< double, 4, 3 > &rDN_DX, array_1d< double, 4 > &rN, double &rVolume)
This function is designed to compute the shape function derivatives, shape functions and volume in 3D...
Definition: geometry_utilities.h:176
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
void push_back(TPointerType x)
Definition: global_pointers_vector.h:322
iterator begin()
Definition: global_pointers_vector.h:221
size_type size() const
Definition: global_pointers_vector.h:307
iterator end()
Definition: global_pointers_vector.h:229
Definition: amatrix_interface.h:41
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ElementIterator ElementsBegin(IndexType ThisIndex=0)
Definition: model_part.h:1169
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
MeshType::NodeIterator NodeIterator
Definition: model_part.h:134
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
ElementIterator ElementsEnd(IndexType ThisIndex=0)
Definition: model_part.h:1179
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
ptr_iterator ptr_end()
Returns an iterator pointing to the end of the underlying data container.
Definition: pointer_vector_set.h:404
void clear()
Clear the set, removing all elements.
Definition: pointer_vector_set.h:663
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: pointer_vector_set.h:95
ptr_iterator ptr_begin()
Returns an iterator pointing to the beginning of the underlying data container.
Definition: pointer_vector_set.h:386
size_type size() const
Returns the number of elements in the container.
Definition: pointer_vector_set.h:502
void push_back(TPointerType x)
Adds a pointer to the end of the set.
Definition: pointer_vector_set.h:544
void reserve(int reservedsize)
Reserves memory for a specified number of elements.
Definition: pointer_vector_set.h:733
iterator end()
Returns an iterator pointing to the end of the container.
Definition: pointer_vector_set.h:314
typename TContainerType::iterator ptr_iterator
Definition: pointer_vector_set.h:104
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:96
void CalculatePreconditionerDiagonalMatrix(const TSystemMatrixType &D, const TSystemVectorType &Minv, const TSystemMatrixType &A, TSystemVectorType &preconditioner)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1905
TSystemVectorType mMdiagInv
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:614
BaseType::NodesArrayType NodesArrayType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:121
void BuildAndSolve(typename TSchemeType::Pointer pScheme, ModelPart &r_model_part, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b)
Function to perform the building and solving phase at the same time.
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:155
void BuildRHS(typename TSchemeType::Pointer pScheme, ModelPart &r_model_part, TSystemVectorType &b)
Function to perform the build of the RHS. The vector could be sized as the total number of dofs or as...
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:822
void ReturnDx(TSystemVectorType &Dx, TSystemVectorType &xi)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1889
BaseType::TSystemMatrixPointerType TSystemMatrixPointerType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:116
BaseType::TSchemeType TSchemeType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:104
void FractionalStepProjection(ModelPart &model_part, double alpha_bossak)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2112
void CalculateNodalPressureForce(TSystemMatrixType &mD, TSystemVectorType &mMdiagInv, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2028
void UpdateAfterProjection(ModelPart &model_part, double alpha_bossak)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2225
BuilderAndSolver< TSparseSpace, TDenseSpace, TLinearSolver > BaseType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:102
BaseType::ElementsContainerType ElementsContainerType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:125
void Build(typename TSchemeType::Pointer pScheme, ModelPart &r_model_part, TSystemMatrixType &A, TSystemVectorType &b)
equivalent (but generally faster) then performing BuildLHS and BuildRHS
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:372
void InitializeSolutionStep(ModelPart &r_model_part, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b)
It applies certain operations at the system of equations at the beginning of the solution step.
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:169
BaseType::TDataType TDataType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:105
~ResidualBasedEliminationQuasiIncompressibleBuilderAndSolver() override
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:143
KRATOS_CLASS_POINTER_DEFINITION(ResidualBasedEliminationQuasiIncompressibleBuilderAndSolver)
void ComputePressureAtFreeSurface(ModelPart &r_model_part, double bulk_modulus, double density)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2068
TSystemMatrixType mD
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:612
void CreatePartition(unsigned int number_of_threads, const int number_of_rows, vector< unsigned int > &partitions)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:635
BaseType::LocalSystemMatrixType LocalSystemMatrixType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:115
void UpdateVelocity(array_1d< double, 3 > &CurrentVelocity, const array_1d< double, 3 > &DeltaDisp, const array_1d< double, 3 > &OldVelocity, const array_1d< double, 3 > &OldAcceleration, double &ma1, double &ma4, double &ma5)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2265
void UpdatePressuresNew(TSystemMatrixType &mMconsistent, TSystemVectorType &mMdiagInv, ModelPart &r_model_part, double bulk_modulus, double density)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2279
BaseType::ElementsArrayType ElementsArrayType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:122
void AssembleRHS(TSystemVectorType &b, LocalSystemVectorType &RHS_Contribution, Element::EquationIdVectorType &EquationId)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:738
TSystemMatrixType mMconsistent
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:613
bool ConvergenceCheck(TSystemVectorType &residual, TSystemVectorType &b, const double &tolerance, const int &iter_number, const int &max_iter_number)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1985
BaseType::NodesArrayType NodesContainerType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:119
BaseType::TSystemMatrixType TSystemMatrixType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:109
void AssembleLHS(TSystemMatrixType &A, LocalSystemMatrixType &LHS_Contribution, Element::EquationIdVectorType &EquationId)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:712
void CalculateReactions(typename TSchemeType::Pointer pScheme, ModelPart &r_model_part, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b)
It computes the reactions of the system.
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:759
BaseType::DofsArrayType DofsArrayType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:107
void calc_GMinvD_prod(TSystemMatrixType &mD, TSystemVectorType &Minv, TSystemVectorType &x, TSystemVectorType &WorkArray, TSystemVectorType &destination)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1848
unsigned int mnumber_of_active_nodes
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:616
void SetUpSystem(ModelPart &r_model_part)
It organises the dofset in order to speed up the building phase.
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:306
void calc_prod_precond_vec(TSystemVectorType &vec, TSystemVectorType &precond, TSystemVectorType &result)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1824
void ConstructMatrixStructure(TSystemMatrixType &A, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:984
void SetUpDofSet(typename TSchemeType::Pointer pScheme, ModelPart &r_model_part)
Builds the list of the DofSets involved in the problem by "asking" to each element and condition its ...
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:196
void UpdatePressures(TSystemMatrixType &mD, TSystemMatrixType &mMconsistent, TSystemVectorType &mMdiagInv, ModelPart &r_model_part, double bulk_modulus, double density)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2353
void SavePressureIteration(ModelPart &model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2100
BaseType::LocalSystemVectorType LocalSystemVectorType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:113
void ConstructMatrixStructure_Mconsistent(TSystemMatrixType &Mconsistent, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1059
GlobalPointersVector< Node > mActiveNodes
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:617
void ConstructMatrixStructure_DivergenceMatrixD(TSystemMatrixType &mD, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1132
void FinalizeSolutionStep(ModelPart &r_model_part, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b)
It applies certain operations at the system of equations at the end of the solution step.
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:180
void UpdateAcceleration(array_1d< double, 3 > &CurrentAcceleration, const array_1d< double, 3 > &DeltaDisp, const array_1d< double, 3 > &OldVelocity, const array_1d< double, 3 > &OldAcceleration, double &ma0, double &ma2, double &ma3)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2272
BaseType::ConditionsArrayType ConditionsArrayType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:123
BaseType::TSystemVectorPointerType TSystemVectorPointerType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:117
void AssembleMassMatrices(TSystemMatrixType &Mconsistent, TSystemVectorType &mMdiagInv, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1669
TSystemVectorType mpreconditioner
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:615
ResidualBasedEliminationQuasiIncompressibleBuilderAndSolver(typename TLinearSolver::Pointer pNewLinearSystemSolver)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:134
BaseType::TSystemVectorType TSystemVectorType
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:111
void ModifyForDirichlet(TSystemMatrixType &A, TSystemVectorType &b)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:2010
void BuildAuxiliaries(TSystemMatrixType &mD, TSystemMatrixType &Mconsistent, TSystemVectorType &mMdiagInv, ModelPart &r_model_part)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:1205
void ResizeAndInitializeVectors(typename TSchemeType::Pointer pScheme, TSystemMatrixType &A, TSystemMatrixType &mD, TSystemVectorType &Dx, TSystemVectorType &b, TSystemMatrixType &mMconsistent, TSystemVectorType &mMdiagInv, ModelPart &rModelPart)
Definition: residualbased_elimination_quasiincompresible_builder_and_solver.h:328
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
#define KRATOS_THROW_ERROR(ExceptionType, ErrorMessage, MoreInfo)
Definition: define.h:77
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
dt
Definition: DEM_benchmarks.py:173
end
Definition: DEM_benchmarks.py:180
im
Definition: GenerateCN.py:100
void TransposeMult(SparseSpaceType &dummy, SparseSpaceType::MatrixType &rA, SparseSpaceType::VectorType &rX, SparseSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:104
double TwoNorm(SparseSpaceType &dummy, SparseSpaceType::VectorType &x)
Definition: add_strategies_to_python.cpp:164
TSpaceType::IndexType Size(TSpaceType &dummy, typename TSpaceType::VectorType const &rV)
Definition: add_strategies_to_python.cpp:111
void Mult(TSpaceType &dummy, typename TSpaceType::MatrixType &rA, typename TSpaceType::VectorType &rX, typename TSpaceType::VectorType &rY)
Definition: add_strategies_to_python.cpp:98
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
AMatrix::MatrixRow< const TExpressionType > row(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t RowIndex)
Definition: amatrix_interface.h:649
AMatrix::TransposeMatrix< const T > trans(const T &TheMatrix)
Definition: amatrix_interface.h:486
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
AMatrix::MatrixColumn< const TExpressionType > column(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression, std::size_t ColumnIndex)
Definition: amatrix_interface.h:637
model_part
Definition: face_heat.py:14
float density
Definition: face_heat.py:56
int local_size
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:17
tuple tmp
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:98
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
residual
Definition: hinsberg_optimization_4.py:433
float aux2
Definition: isotropic_damage_automatic_differentiation.py:240
float aux1
Definition: isotropic_damage_automatic_differentiation.py:239
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
float temp
Definition: rotating_cone.py:85
bulk_modulus
Definition: script.py:97
A
Definition: sensitivityMatrix.py:70
p
Definition: sensitivityMatrix.py:52
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
volume
Definition: sp_statistics.py:15
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31