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.
monolithic_dem_coupled_weak.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3 Kratos
4 A General Purpose Software for Multi-Physics Finite Element Analysis
5 Version 1.0 (Released on march 05, 2007).
6 
7 Copyright 2007
8 Pooyan Dadvand, Riccardo Rossi
9 pooyan@cimne.upc.edu
10 rrossi@cimne.upc.edu
11 CIMNE (International Center for Numerical Methods in Engineering),
12 Gran Capita' s/n, 08034 Barcelona, Spain
13 
14 Permission is hereby granted, free of charge, to any person obtaining
15 a copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sublicense and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following condition:
21 
22 Distribution of this code for any commercial purpose is permissible
23 ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNER.
24 
25 The above copyright notice and this permission notice shall be
26 included in all copies or substantial portions of the Software.
27 
28 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
31 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
32 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
33 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
34 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 
36 ==============================================================================
37  */
38 
39 //
40 // Project Name: Kratos
41 // Last Modified by: $Author: gcasas $
42 // Date: $Date: 2010-10-09 10:34:00 $
43 // Revision: $Revision: 0.1 $
44 //
45 //
46 
47 
48 #ifndef MONOLITHIC_DEM_COUPLED_WEAK_H
49 #define MONOLITHIC_DEM_COUPLED_WEAK_H
50 
51 // System includes
52 #include <string>
53 #include <iostream>
54 
55 
56 // External includes
57 
58 
59 // Project includes
60 #include "containers/array_1d.h"
61 #include "includes/define.h"
62 #include "includes/element.h"
63 #include "includes/serializer.h"
64 #include "utilities/geometry_utilities.h"
65 
66 // Application includes
67 #include "includes/cfd_variables.h" //TODO: must be removed eventually
70 
71 namespace Kratos
72 {
73 
76 
79 
83 
87 
91 
95 
97 
135 template< unsigned int TDim,
136  unsigned int TNumNodes = TDim + 1 >
137 class KRATOS_API(SWIMMING_DEM_APPLICATION) MonolithicDEMCoupledWeak : public Element
138 {
139 public:
142 
145 
148 
150  typedef Node NodeType;
151 
157 
160 
163 
165 
167 
168  typedef std::size_t IndexType;
169 
170  typedef std::size_t SizeType;
171 
172  typedef std::vector<std::size_t> EquationIdVectorType;
173 
174  typedef std::vector< Dof<double>::Pointer > DofsVectorType;
175 
177 
178 //G
181 
184 
187 //Z
191 
192  //Constructors.
193 
195 
199  Element(NewId)
200  {}
201 
203 
208  Element(NewId, ThisNodes)
209  {}
210 
212 
216  MonolithicDEMCoupledWeak(IndexType NewId, GeometryType::Pointer pGeometry) :
217  Element(NewId, pGeometry)
218  {}
219 
221 
226  MonolithicDEMCoupledWeak(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties) :
227  Element(NewId, pGeometry, pProperties)
228  {}
229 
232  {}
233 
234 
238 
239 
243 
245 
252  Element::Pointer Create(IndexType NewId, NodesArrayType const& ThisNodes,
253  PropertiesType::Pointer pProperties) const override
254  {
255 
256  return Element::Pointer(new MonolithicDEMCoupledWeak(NewId, GetGeometry().Create(ThisNodes), pProperties));
257 
258  }
259 
261 
270  virtual void CalculateLocalSystem(MatrixType& rLeftHandSideMatrix,
271  VectorType& rRightHandSideVector,
272  const ProcessInfo& rCurrentProcessInfo) override
273  {
274  const unsigned int LocalSize = (TDim + 1) * TNumNodes;
275 
276  // Check sizes and initialize matrix
277  if (rLeftHandSideMatrix.size1() != LocalSize)
278  rLeftHandSideMatrix.resize(LocalSize, LocalSize, false);
279 
280  noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize, LocalSize);
281 
282  // Calculate RHS
283  this->CalculateRightHandSide(rRightHandSideVector, rCurrentProcessInfo);
284  }
285 
287 
291  virtual void CalculateLeftHandSide(MatrixType& rLeftHandSideMatrix, const ProcessInfo& rCurrentProcessInfo) override
292  {
293  const unsigned int LocalSize = (TDim + 1) * TNumNodes;
294 
295  if (rLeftHandSideMatrix.size1() != LocalSize)
296  rLeftHandSideMatrix.resize(LocalSize, LocalSize, false);
297 
298  noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize, LocalSize);
299  }
300 
302 
311  virtual void CalculateRightHandSide(VectorType& rRightHandSideVector,
312  const ProcessInfo& rCurrentProcessInfo) override
313  {
314  const unsigned int LocalSize = (TDim + 1) * TNumNodes;
315 
316  // Check sizes and initialize
317  if (rRightHandSideVector.size() != LocalSize)
318  rRightHandSideVector.resize(LocalSize, false);
319 
320  noalias(rRightHandSideVector) = ZeroVector(LocalSize);
321 
322  // Calculate this element's geometric parameters
323  double Area;
326  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
327 
328  // Calculate this element's fluid properties
329  double Density;
330  this->EvaluateInPoint(Density, DENSITY, N);
331 
332  // Calculate Momentum RHS contribution
333 //G
334  // Shape functions and integration points
335  MatrixType NContainer;
336  ShapeFunctionDerivativesArrayType DN_DXContainer;
337  VectorType GaussWeights;
338  this->CalculateWeights(DN_DXContainer, NContainer, GaussWeights);
339  const SizeType NumGauss = NContainer.size1();
340 
341  for (SizeType g = 0; g < NumGauss; g++)
342  {
343  const double GaussWeight = GaussWeights[g];
344  const ShapeFunctionsType& Ng = row(NContainer, g);
345  this->AddMomentumRHS(rRightHandSideVector, Density, Ng, GaussWeight);
346  }
347 
348  const double& DeltaTime = rCurrentProcessInfo[DELTA_TIME];
349  static const double arr[] = {0.5,0.5};
350  std::vector<double> SchemeWeights (arr, arr + sizeof(arr) / sizeof(arr[0]));
351 
352  this->AddOtherContributionsRHS(rRightHandSideVector, N, SchemeWeights, DeltaTime);
353 //Z
354 
355  // For OSS: Add projection of residuals to RHS
356  if (rCurrentProcessInfo[OSS_SWITCH] == 1)
357  {
358  array_1d<double, 3 > AdvVel;
359  this->GetAdvectiveVel(AdvVel, N);
360 
361  double KinViscosity;
362  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
363 
364  double Viscosity;
365  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
366 
367  // Calculate stabilization parameters
368  double TauOne, TauTwo;
369  this->CalculateTau(TauOne, TauTwo, AdvVel, Area,Density, Viscosity, rCurrentProcessInfo);
370 
371  this->AddProjectionToRHS(rRightHandSideVector, AdvVel, Density, TauOne, TauTwo, N, DN_DX, Area,rCurrentProcessInfo[DELTA_TIME]);
372  }
373  /*
374 // else if (this->GetValue(TRACK_SUBSCALES) == 1)// Experimental: Dynamic tracking of ASGS subscales (see Codina 2002 Stabilized finite element ... using orthogonal subscales)
375 // {
376 // * We want to evaluate v * d(u_subscale)/dt. This term is zero in OSS, due the orthogonality of the two terms. in ASGS, we approximate it as
377 // * d(u_s)/dt = u_s(last iteration) - u_s(previous time step) / DeltaTime where u_s(last iteration) = TauOne(MomResidual(last_iteration) + u_s(previous step)/DeltaTime)
378 // *
379 // array_1d<double, 3 > AdvVel;
380 // this->GetAdvectiveVel(AdvVel, N);
381 //
382 // double KinViscosity;
383 // this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
384 //
385 // double Viscosity;
386 // this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
387 //
388 // double StaticTauOne;
389 // this->CalculateStaticTau(StaticTauOne,AdvVel,Area,Viscosity);
390 //
391 // double TauOne,TauTwo;
392 // this->CalculateTau(TauOne,TauTwo,AdvVel,Area,Density,Viscosity,rCurrentProcessInfo);
393 //
394 // array_1d<double,3> ElemMomRes(3,0.0);
395 // this->ASGSMomResidual(AdvVel,Density,ElemMomRes,N,DN_DX,1.0);
396 //
397 // const array_1d<double,3>& rOldSubscale = this->GetValue(SUBSCALE_VELOCITY);
398 // const double DeltaTime = rCurrentProcessInfo[DELTA_TIME];
399 //
400 // // array_1d<double,3> Subscale = TauOne * (ElemMomRes + Density * rOldSubscale / DeltaTime);
401 // const double C1 = 1.0 - TauOne/StaticTauOne;
402 // const double C2 = TauOne / (StaticTauOne*DeltaTime);
403 //
404 // unsigned int LocalIndex = 0;
405 // for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
406 // {
407 // for(unsigned int d = 0; d < TDim; d++)
408 // rRightHandSideVector[LocalIndex++] -= N[iNode] * Area * ( C1 * ElemMomRes[d] - C2 * rOldSubscale[d] );
409 // // rRightHandSideVector[LocalIndex++] -= N[iNode] * Area * ( Subscale[d] - rOldSubscale[d] ) / DeltaTime;
410 // LocalIndex++; // Pressure Dof
411 // }
412 // }
413 */
414  }
415 
417 
424  virtual void CalculateMassMatrix(MatrixType& rMassMatrix, const ProcessInfo& rCurrentProcessInfo) override
425  {
426 // rMassMatrix.resize(0,0,false);
427  const unsigned int LocalSize = (TDim + 1) * TNumNodes;
428 
429  // Resize and set to zero
430  if (rMassMatrix.size1() != LocalSize)
431  rMassMatrix.resize(LocalSize, LocalSize, false);
432 
433  rMassMatrix = ZeroMatrix(LocalSize, LocalSize);
434 
435  // Get the element's geometric parameters
436  double Area;
439  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
440 
441  // Calculate this element's fluid properties
442  double Density;
443  this->EvaluateInPoint(Density, DENSITY, N);
444 
445  // Add 'classical' mass matrix (lumped)
446  //double Coeff = Density * Area / TNumNodes; //Optimize!
447 //GG
448  // Shape functions and integration points
449  MatrixType NContainer;
450  ShapeFunctionDerivativesArrayType DN_DXContainer;
451  VectorType GaussWeights;
452  this->CalculateWeights(DN_DXContainer, NContainer, GaussWeights);
453  const SizeType NumGauss = NContainer.size1();
454 
455  for (SizeType g = 0; g < NumGauss; g++)
456  {
457  const double GaussWeight = GaussWeights[g];
458  const ShapeFunctionsType& Ng = row(NContainer, g);
459  const ShapeFunctionDerivativesType& DN_DXg = DN_DXContainer[g];
460  AddConsistentMassMatrixContribution(rMassMatrix, Ng, Density, GaussWeight);
461 
462  if (rCurrentProcessInfo[OSS_SWITCH] != 1)
463  {
464  double KinViscosity;
465  this->EvaluateInPoint(KinViscosity, VISCOSITY, Ng);
466 
467  double Viscosity;
468  this->GetEffectiveViscosity(Density,KinViscosity, Ng, DN_DXg, Viscosity, rCurrentProcessInfo);
469 
470  // Get Advective velocity
471  array_1d<double, 3 > AdvVel;
472 
473  this->GetAdvectiveVel(AdvVel, Ng);
474 
475  // Calculate stabilization parameters
476  double TauOne, TauTwo;
477  this->CalculateTau(TauOne, TauTwo, AdvVel, Area, Density, Viscosity, rCurrentProcessInfo);
478 
479  // Add dynamic stabilization terms ( all terms involving a delta(u) )
480  this->AddMassStabTerms(rMassMatrix, Density, AdvVel, TauOne, Ng, DN_DXg, GaussWeight);
481  }
482  }
483 /*
484  //this->CalculateLumpedMassMatrix(rMassMatrix, Coeff);
485 
486 
487  For ASGS: add dynamic stabilization terms.
488  These terms are not used in OSS, as they belong to the finite element
489  space and cancel out with their projections.
490  //
491  if (rCurrentProcessInfo[OSS_SWITCH] != 1)
492  {
493  double KinViscosity;
494  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
495 
496  double Viscosity;
497  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
498 
499  // Get Advective velocity
500  array_1d<double, 3 > AdvVel;
501 
502  this->GetAdvectiveVel(AdvVel, N);
503 
504  // Calculate stabilization parameters
505  double TauOne, TauTwo;
506  this->CalculateTau(TauOne, TauTwo, AdvVel, Area, Density, Viscosity, rCurrentProcessInfo);
507 
508  // Add dynamic stabilization terms ( all terms involving a delta(u) )
509  this->AddMassStabTerms(rMassMatrix, Density, AdvVel, TauOne, N, DN_DX, Area);
510  }
511 
512 */
513 //ZZ
514  }
515 
517 
525  virtual void CalculateLocalVelocityContribution(MatrixType& rDampingMatrix,
526  VectorType& rRightHandSideVector,
527  const ProcessInfo& rCurrentProcessInfo) override
528  {
529  const unsigned int LocalSize = (TDim + 1) * TNumNodes;
530 
531  // Resize and set to zero the matrix
532  // Note that we don't clean the RHS because it will already contain body force (and stabilization) contributions
533  if (rDampingMatrix.size1() != LocalSize)
534  rDampingMatrix.resize(LocalSize, LocalSize, false);
535 
536  noalias(rDampingMatrix) = ZeroMatrix(LocalSize, LocalSize);
537 
538  // Get this element's geometric properties
539  double Area;
542  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
543 
544  // Calculate this element's fluid properties
545  double Density, KinViscosity;
546  this->EvaluateInPoint(Density, DENSITY, N);
547  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
548 
549  double Viscosity;
550  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
551 
552  // Get Advective velocity
553  array_1d<double, 3 > AdvVel;
554  this->GetAdvectiveVel(AdvVel, N);
555 
556  // Calculate stabilization parameters
557  double TauOne, TauTwo;
558  this->CalculateTau(TauOne, TauTwo, AdvVel, Area, Density, Viscosity, rCurrentProcessInfo);
559 
560  /* if(this->GetValue(TRACK_SUBSCALES)==1)
561  {
562  const double DeltaTime = rCurrentProcessInfo[DELTA_TIME];
563  this->AddIntegrationPointVelocityContribution(rDampingMatrix, rRightHandSideVector, Density, Viscosity, AdvVel, TauOne, TauTwo, N, DN_DX, Area,DeltaTime);
564  }
565  else
566  {*/
567 //GG
568  // Shape functions and integration points
569  MatrixType NContainer;
570  ShapeFunctionDerivativesArrayType DN_DXContainer;
571  VectorType GaussWeights;
572  this->CalculateWeights(DN_DXContainer, NContainer, GaussWeights);
573  const SizeType NumGauss = NContainer.size1();
574 
575  for (SizeType g = 0; g < NumGauss; g++)
576  {
577  const double GaussWeight = GaussWeights[g];
578  const ShapeFunctionsType& Ng = row(NContainer, g);
579  const ShapeFunctionDerivativesType& DN_DXg = DN_DXContainer[g];
580  this->GetAdvectiveVel(AdvVel, Ng);
581  this->AddIntegrationPointVelocityContribution(rDampingMatrix, rRightHandSideVector, Density, Viscosity, AdvVel, TauOne, TauTwo, Ng, DN_DXg, GaussWeight);
582  }
583 
584  //this->AddIntegrationPointVelocityContribution(rDampingMatrix, rRightHandSideVector, Density, Viscosity, AdvVel, TauOne, TauTwo, N, DN_DX, Area);
585 //ZZ
586 
587 // this->ModulatedGradientDiffusion(rDampingMatrix,DN_DX,Density*Area);
588 // }
589 
590  // Now calculate an additional contribution to the residual: r -= rDampingMatrix * (u,p)
591  VectorType U = ZeroVector(LocalSize);
592  int LocalIndex = 0;
593 
594  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
595  {
596  array_1d< double, 3 > & rVel = this->GetGeometry()[iNode].FastGetSolutionStepValue(VELOCITY);
597  for (unsigned int d = 0; d < TDim; ++d) // Velocity Dofs
598  {
599  U[LocalIndex] = rVel[d];
600  ++LocalIndex;
601  }
602  U[LocalIndex] = this->GetGeometry()[iNode].FastGetSolutionStepValue(PRESSURE); // Pressure Dof
603  ++LocalIndex;
604  }
605 
606  noalias(rRightHandSideVector) -= prod(rDampingMatrix, U);
607  }
608 
609  virtual void FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override
610  {
611 // if(this->GetValue(TRACK_SUBSCALES) == 1)
612 // {
613 // // Get this element's geometric properties
614 // double Area;
615 // array_1d<double, TNumNodes> N;
616 // BoundedMatrix<double, TNumNodes, TDim> DN_DX;
617 // GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
618 //
619 // // Calculate this element's fluid properties
620 // double Density, KinViscosity;
621 // this->EvaluateInPoint(Density, DENSITY, N);
622 // this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
623 //
624 // double Viscosity;
625 // this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
626 //
627 // // Get Advective velocity
628 // array_1d<double, 3 > AdvVel;
629 // this->GetAdvectiveVel(AdvVel, N);
630 //
631 // // Calculate stabilization parameters
632 // double StaticTauOne;
633 // this->CalculateStaticTau(StaticTauOne,AdvVel,Area,Viscosity);
634 //
635 // array_1d<double,3> ElementalMomRes(3,0.0);
636 //
637 // if ( rCurrentProcessInfo[OSS_SWITCH] != 1 ) // ASGS
638 // {
639 // this->ASGSMomResidual(AdvVel,Density,ElementalMomRes,N,DN_DX,1.0);
640 // }
641 // else // OSS
642 // {
643 // this->OSSMomResidual(AdvVel,Density,ElementalMomRes,N,DN_DX,1.0);;
644 // }
645 //
646 // // Update subscale term
647 // const double DeltaTime = rCurrentProcessInfo.GetValue(DELTA_TIME);
648 // array_1d<double,3>& OldSubscaleVel = this->GetValue(SUBSCALE_VELOCITY);
649 // array_1d<double,3> Tmp = ( 1.0/( 1.0/DeltaTime + 1.0/StaticTauOne)) * (Density*OldSubscaleVel/DeltaTime + ElementalMomRes);
650 // OldSubscaleVel = Tmp;
651 // }
652  }
653 
655 
667  virtual void Calculate(const Variable<double>& rVariable,
668  double& rOutput,
669  const ProcessInfo& rCurrentProcessInfo) override
670  {
671  if (rVariable == ERROR_RATIO)
672  {
673  // Get the element's geometric parameters
674  double Area;
677  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
678 
679  // Calculate this element's fluid properties
680  double Density, KinViscosity;
681  this->EvaluateInPoint(Density, DENSITY, N);
682  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
683 
684  double Viscosity;
685  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
686 
687  // Get Advective velocity
688  array_1d<double, 3 > AdvVel;
689  this->GetAdvectiveVel(AdvVel, N);
690 
691  // Output container
692  array_1d< double, 3 > ElementalMomRes(3, 0.0);
693 
694  // Calculate stabilization parameter. Note that to estimate the subscale velocity, the dynamic coefficient in TauOne is assumed zero.
695  double TauOne;
696  this->CalculateStaticTau(TauOne, AdvVel, Area,Density, Viscosity);
697 
698  if ( rCurrentProcessInfo[OSS_SWITCH] != 1 ) // ASGS
699  {
700  this->ASGSMomResidual(AdvVel,Density,ElementalMomRes,N,DN_DX,1.0);
701  ElementalMomRes *= TauOne;
702  }
703  else // OSS
704  {
705  this->OSSMomResidual(AdvVel,Density,ElementalMomRes,N,DN_DX,1.0);;
706  ElementalMomRes *= TauOne;
707  }
708 
709  // Error estimation ( ||U'|| / ||Uh_gauss|| ), taking ||U'|| = TauOne ||MomRes||
710  double ErrorRatio(0.0);//, UNorm(0.0);
711 // array_1d< double, 3 > UGauss(3, 0.0);
712 // this->AddPointContribution(UGauss, VELOCITY, N);
713 
714  for (unsigned int i = 0; i < TDim; ++i)
715  {
716  ErrorRatio += ElementalMomRes[i] * ElementalMomRes[i];
717 // UNorm += UGauss[i] * UGauss[i];
718  }
719  ErrorRatio = sqrt(ErrorRatio); // / UNorm);
720  ErrorRatio /= Density;
721  this->SetValue(ERROR_RATIO, ErrorRatio);
722  rOutput = ErrorRatio;
723  }
724  else if (rVariable == NODAL_AREA)
725  {
726  // Get the element's geometric parameters
727  double Area;
730  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
731 
732  // Carefully write results to nodal variables, to avoid parallelism problems
733  for (unsigned int i = 0; i < TNumNodes; ++i)
734  {
735  this->GetGeometry()[i].SetLock(); // So it is safe to write in the node in OpenMP
736  this->GetGeometry()[i].FastGetSolutionStepValue(NODAL_AREA) += Area * N[i];
737  this->GetGeometry()[i].UnSetLock(); // Free the node for other threads
738  }
739  }
740  }
741 
743 
754  virtual void Calculate(const Variable<array_1d<double, 3 > >& rVariable,
755  array_1d<double, 3 > & rOutput,
756  const ProcessInfo& rCurrentProcessInfo) override
757  {
758  if (rVariable == ADVPROJ) // Compute residual projections for OSS
759  {
760  // Get the element's geometric parameters
761  double Area;
764  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
765 
766  // Calculate this element's fluid properties
767  double Density;
768  this->EvaluateInPoint(Density, DENSITY, N);
769 
770  // Get Advective velocity
771  array_1d<double, 3 > AdvVel;
772  this->GetAdvectiveVel(AdvVel, N);
773 
774  // Output containers
775  array_1d< double, 3 > ElementalMomRes(3, 0.0);
776  double ElementalMassRes(0);
777 
778  this->AddProjectionResidualContribution(AdvVel, Density, ElementalMomRes, ElementalMassRes, N, DN_DX, Area);
779 
780  if (rCurrentProcessInfo[OSS_SWITCH] == 1)
781  {
782  // Carefully write results to nodal variables, to avoid parallelism problems
783  for (unsigned int i = 0; i < TNumNodes; ++i)
784  {
785  this->GetGeometry()[i].SetLock(); // So it is safe to write in the node in OpenMP
786  array_1d< double, 3 > & rAdvProj = this->GetGeometry()[i].FastGetSolutionStepValue(ADVPROJ);
787  for (unsigned int d = 0; d < TDim; ++d)
788  rAdvProj[d] += N[i] * ElementalMomRes[d];
789 
790  this->GetGeometry()[i].FastGetSolutionStepValue(DIVPROJ) += N[i] * ElementalMassRes;
791  this->GetGeometry()[i].FastGetSolutionStepValue(NODAL_AREA) += Area * N[i];
792  this->GetGeometry()[i].UnSetLock(); // Free the node for other threads
793  }
794  }
795 
797  rOutput = ElementalMomRes;
798  }
799  else if (rVariable == SUBSCALE_VELOCITY)
800  {
801  // Get the element's geometric parameters
802  double Area;
805  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
806 
807  // Calculate this element's fluid properties
808  double Density;
809  this->EvaluateInPoint(Density, DENSITY, N);
810 
811  // Get Advective velocity
812  array_1d<double, 3 > AdvVel;
813  this->GetAdvectiveVel(AdvVel, N);
814 
815  // Output containers
816  array_1d< double, 3 > ElementalMomRes(3,0.0);
817  double ElementalMassRes(0.0);
818 
819  this->AddProjectionResidualContribution(AdvVel, Density, ElementalMomRes, ElementalMassRes, N, DN_DX, Area);
820 
821  if (rCurrentProcessInfo[OSS_SWITCH] == 1)
822  {
823  /* Projections of the elemental residual are computed with
824  * Newton-Raphson iterations of type M(lumped) dx = ElemRes - M(consistent) * x
825  */
826  const double Weight = ConsistentMassCoef(Area); // Consistent mass matrix is Weigth * ( Ones(TNumNodes,TNumNodes) + Identity(TNumNodes,TNumNodes) )
827  // Carefully write results to nodal variables, to avoid parallelism problems
828  for (unsigned int i = 0; i < TNumNodes; ++i)
829  {
830  this->GetGeometry()[i].SetLock(); // So it is safe to write in the node in OpenMP
831 
832  // Add elemental residual to RHS
833  array_1d< double, 3 > & rMomRHS = this->GetGeometry()[i].GetValue(ADVPROJ);
834  double& rMassRHS = this->GetGeometry()[i].GetValue(DIVPROJ);
835  for (unsigned int d = 0; d < TDim; ++d)
836  rMomRHS[d] += N[i] * ElementalMomRes[d];
837 
838  rMassRHS += N[i] * ElementalMassRes;
839 
840  // Write nodal area
841  this->GetGeometry()[i].FastGetSolutionStepValue(NODAL_AREA) += Area * N[i];
842 
843  // Substract M(consistent)*x(i-1) from RHS
844  for(unsigned int j = 0; j < TNumNodes; ++j) // RHS -= Weigth * Ones(TNumNodes,TNumNodes) * x(i-1)
845  {
846  for(unsigned int d = 0; d < TDim; ++d)
847  rMomRHS[d] -= Weight * this->GetGeometry()[j].FastGetSolutionStepValue(ADVPROJ)[d];
848  rMassRHS -= Weight * this->GetGeometry()[j].FastGetSolutionStepValue(DIVPROJ);
849  }
850  for(unsigned int d = 0; d < TDim; ++d) // RHS -= Weigth * Identity(TNumNodes,TNumNodes) * x(i-1)
851  rMomRHS[d] -= Weight * this->GetGeometry()[i].FastGetSolutionStepValue(ADVPROJ)[d];
852  rMassRHS -= Weight * this->GetGeometry()[i].FastGetSolutionStepValue(DIVPROJ);
853 
854  this->GetGeometry()[i].UnSetLock(); // Free the node for other threads
855  }
856  }
857 
859  rOutput = ElementalMomRes;
860  }
861  }
862 
863  // The following methods have different implementations depending on TDim
865 
871  virtual void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override;
872 
874 
878  virtual void GetDofList(DofsVectorType& rElementalDofList, const ProcessInfo& rCurrentProcessInfo) const override;
879 
881 
885  virtual void GetFirstDerivativesVector(Vector& Values, int Step = 0) const override;
886 
888 
892  virtual void GetSecondDerivativesVector(Vector& Values, int Step = 0) const override;
893 
895 
905  std::vector<array_1d<double, 3 > >& rOutput,
906  const ProcessInfo& rCurrentProcessInfo) override;
907 
909 
920  virtual void CalculateOnIntegrationPoints(const Variable<double>& rVariable,
921  std::vector<double>& rValues,
922  const ProcessInfo& rCurrentProcessInfo) override
923  {
924  if (rVariable == TAUONE || rVariable == TAUTWO || rVariable == MU)
925  {
926  double TauOne, TauTwo;
927  double Area;
930  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
931 
932  array_1d<double, 3 > AdvVel;
933  this->GetAdvectiveVel(AdvVel, N);
934 
935  double Density,KinViscosity;
936  this->EvaluateInPoint(Density, DENSITY, N);
937  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
938 
939  double Viscosity;
940  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
941 
942  this->CalculateTau(TauOne, TauTwo, AdvVel, Area, Density, Viscosity, rCurrentProcessInfo);
943 
944  rValues.resize(1, false);
945  if (rVariable == TAUONE)
946  {
947  rValues[0] = TauOne;
948  }
949  else if (rVariable == TAUTWO)
950  {
951  rValues[0] = TauTwo;
952  }
953  else if (rVariable == MU)
954  {
955  rValues[0] = Density * Viscosity;
956  }
957  }
958  else if(rVariable == SUBSCALE_PRESSURE)
959  {
960  double TauOne, TauTwo;
961  double Area;
964  GeometryUtils::CalculateGeometryData(this->GetGeometry(), DN_DX, N, Area);
965 
966  array_1d<double, 3 > AdvVel;
967  this->GetAdvectiveVel(AdvVel, N);
968 
969  double Density,KinViscosity;
970  this->EvaluateInPoint(Density, DENSITY, N);
971  this->EvaluateInPoint(KinViscosity, VISCOSITY, N);
972 
973  double Viscosity;
974  this->GetEffectiveViscosity(Density,KinViscosity, N, DN_DX, Viscosity, rCurrentProcessInfo);
975 
976  this->CalculateTau(TauOne, TauTwo, AdvVel, Area, Density, Viscosity, rCurrentProcessInfo);
977 
978  double DivU = 0.0;
979  for(unsigned int i=0; i < TNumNodes; i++)
980  {
981  for(unsigned int d = 0; d < TDim; d++)
982  DivU -= DN_DX(i,d) * this->GetGeometry()[i].FastGetSolutionStepValue(VELOCITY)[d];
983  }
984 
985  rValues.resize(1, false);
986 
987  rValues[0] = TauTwo * DivU;// *Density?? decide on criteria and use the same for SUBSCALE_VELOCITY
988 
989  if(rCurrentProcessInfo[OSS_SWITCH]==1)
990  {
991  double Proj = 0.0;
992  for(unsigned int i=0; i < TNumNodes; i++)
993  {
994  Proj += N[i]*this->GetGeometry()[i].FastGetSolutionStepValue(DIVPROJ);
995  }
996  rValues[0] -= TauTwo*Proj;
997  }
998  }
999  else if (rVariable == NODAL_AREA && TDim == 3)
1000  {
1001  MatrixType J = ZeroMatrix(3,3);
1002  const array_1d<double,3>& X0 = this->GetGeometry()[0].Coordinates();
1003  const array_1d<double,3>& X1 = this->GetGeometry()[1].Coordinates();
1004  const array_1d<double,3>& X2 = this->GetGeometry()[2].Coordinates();
1005  const array_1d<double,3>& X3 = this->GetGeometry()[3].Coordinates();
1006 
1007  J(0,0) = X1[0]-X0[0];
1008  J(0,1) = X2[0]-X0[0];
1009  J(0,2) = X3[0]-X0[0];
1010  J(1,0) = X1[1]-X0[1];
1011  J(1,1) = X2[1]-X0[1];
1012  J(1,2) = X3[1]-X0[1];
1013  J(2,0) = X1[2]-X0[2];
1014  J(2,1) = X2[2]-X0[2];
1015  J(2,2) = X3[2]-X0[2];
1016 
1017  double DetJ = J(0,0)*( J(1,1)*J(2,2) - J(1,2)*J(2,1) ) + J(0,1)*( J(1,2)*J(2,0) - J(1,0)*J(2,2) ) + J(0,2)*( J(1,0)*J(2,1) - J(1,1)*J(2,0) );
1018  rValues.resize(1, false);
1019  rValues[0] = DetJ;
1020  }
1021  else // Default behaviour (returns elemental data)
1022  {
1023  rValues.resize(1, false);
1024  /*
1025  The cast is done to avoid modification of the element's data. Data modification
1026  would happen if rVariable is not stored now (would initialize a pointer to &rVariable
1027  with associated value of 0.0). This is catastrophic if the variable referenced
1028  goes out of scope.
1029  */
1030  const MonolithicDEMCoupledWeak<TDim, TNumNodes>* const_this = static_cast<const MonolithicDEMCoupledWeak<TDim, TNumNodes>*> (this);
1031  rValues[0] = const_this->GetValue(rVariable);
1032  }
1033  }
1034 
1036  std::vector<array_1d<double, 6 > >& rValues,
1037  const ProcessInfo& rCurrentProcessInfo) override
1038  {}
1039 
1040  virtual void CalculateOnIntegrationPoints(const Variable<Vector>& rVariable,
1041  std::vector<Vector>& rValues,
1042  const ProcessInfo& rCurrentProcessInfo) override
1043  {}
1044 
1045  virtual void CalculateOnIntegrationPoints(const Variable<Matrix>& rVariable,
1046  std::vector<Matrix>& rValues,
1047  const ProcessInfo& rCurrentProcessInfo) override
1048  {}
1049 
1053 
1057 
1059 
1067  virtual int Check(const ProcessInfo& rCurrentProcessInfo) const override
1068  {
1069  KRATOS_TRY
1070 
1071  // Perform basic element checks
1072  int ErrorCode = Kratos::Element::Check(rCurrentProcessInfo);
1073  if(ErrorCode != 0) return ErrorCode;
1074 
1075  // Additional variables, only required to print results:
1076  // SUBSCALE_VELOCITY, SUBSCALE_PRESSURE, TAUONE, TAUTWO, MU, VORTICITY.
1077 
1078  // Checks on nodes
1079 
1080  // Check that the element's nodes contain all required SolutionStepData and Degrees of freedom
1081  for(unsigned int i=0; i<this->GetGeometry().size(); ++i) {
1082  KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(VELOCITY, this->GetGeometry()[i])
1083  KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(PRESSURE, this->GetGeometry()[i])
1084  KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(MESH_VELOCITY, this->GetGeometry()[i])
1085  KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(ACCELERATION, this->GetGeometry()[i])
1086 
1087  KRATOS_CHECK_DOF_IN_NODE(VELOCITY_X, this->GetGeometry()[i])
1088  KRATOS_CHECK_DOF_IN_NODE(VELOCITY_Y, this->GetGeometry()[i])
1089  KRATOS_CHECK_DOF_IN_NODE(VELOCITY_Z, this->GetGeometry()[i])
1090  KRATOS_CHECK_DOF_IN_NODE(PRESSURE, this->GetGeometry()[i])
1091  }
1092  // Not checking OSS related variables NODAL_AREA, ADVPROJ, DIVPROJ, which are only required as SolutionStepData if OSS_SWITCH == 1
1093 
1094  // If this is a 2D problem, check that nodes are in XY plane
1095  if (this->GetGeometry().WorkingSpaceDimension() == 2) {
1096  for (unsigned int i=0; i<this->GetGeometry().size(); ++i) {
1097  KRATOS_ERROR_IF(this->GetGeometry()[i].Z() != 0.0) << "Node with non-zero Z coordinate found. Id: "<< this->GetGeometry()[i].Id() << std::endl;
1098  }
1099  }
1100 
1101  return 0;
1102 
1103  KRATOS_CATCH("");
1104  }
1105 
1109 
1110 
1114 
1116  virtual std::string Info() const override
1117  {
1118  std::stringstream buffer;
1119  buffer << "MonolithicDEMCoupledWeak #" << Id();
1120  return buffer.str();
1121  }
1122 
1124  virtual void PrintInfo(std::ostream& rOStream) const override
1125  {
1126  rOStream << "MonolithicDEMCoupledWeak" << TDim << "D";
1127  }
1128 
1129 // /// Print object's data.
1130 // virtual void PrintData(std::ostream& rOStream) const;
1131 
1135 
1136 
1138 
1139 protected:
1142 
1143 //GG
1145  void CalculateWeights(ShapeFunctionDerivativesArrayType& rDN_DX, Matrix& rNContainer, Vector& rGaussWeights);
1146 //ZZ
1147 
1151 
1152 
1156 
1157 
1161 
1163 
1175  virtual void CalculateTau(double& TauOne,
1176  double& TauTwo,
1177  const array_1d< double, 3 > & rAdvVel,
1178  const double Area,
1179  const double Density,
1180  const double KinViscosity,
1181  const ProcessInfo& rCurrentProcessInfo)
1182  {
1183  // Compute mean advective velocity norm
1184  double AdvVelNorm = 0.0;
1185  for (unsigned int d = 0; d < TDim; ++d)
1186  AdvVelNorm += rAdvVel[d] * rAdvVel[d];
1187 
1188  AdvVelNorm = sqrt(AdvVelNorm);
1189 
1190 //GG
1191  // const double Element_Diam = sqrt(this->FilterWidth());
1192 //ZZ
1193  const double Element_Size = this->ElementSize(Area);
1194 
1195 //G
1196  // TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 4 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1197 //GG
1198  // TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 5.6666666666 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1199  double L0 = 0.015; // 0.1 * (volumen probeta) ^(1/3)
1200  double lp = sqrt(L0 * Element_Size);
1201  double lu = lp;
1202  double c2u = 2;
1203  double c2p = c2u;
1204  double sigma = 0.0;
1205  //this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1206  if (sigma > 0.00001){
1207  TauOne = Element_Size * Element_Size / (c2u * sigma * lu * lu);
1208  TauTwo = lp * lp * sigma * c2p;
1209  }
1210  else{
1211  TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 5.6666666666 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1212  TauTwo = Density * (KinViscosity + 0.5 * Element_Size * AdvVelNorm);
1213  }
1214 //ZZ
1215 //Z
1216 
1217 //GG
1218  // TauTwo = Density * (KinViscosity + 0.5 * Element_Size * AdvVelNorm);
1219 
1220 //ZZ
1221  //TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 12.0 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1222  //TauTwo = Density * (KinViscosity + Element_Size * AdvVelNorm / 6.0);
1223 
1224 
1225  }
1226 
1228 
1238  virtual void CalculateStaticTau(double& TauOne,
1239  const array_1d< double, 3 > & rAdvVel,
1240  const double Area,
1241  const double Density,
1242  const double KinViscosity)
1243  {
1244  // Compute mean advective velocity norm
1245  double AdvVelNorm = 0.0;
1246  for (unsigned int d = 0; d < TDim; ++d)
1247  AdvVelNorm += rAdvVel[d] * rAdvVel[d];
1248 
1249  AdvVelNorm = sqrt(AdvVelNorm);
1250 
1251 //GG
1252  // const double Element_Diam = sqrt(this->FilterWidth());
1253 //ZZ
1254  const double Element_Size = this->ElementSize(Area);
1255 
1256  TauOne = 1.0 / (Density*(4.0 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size));
1257 //G
1258  // TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 4 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1259 //GG
1260  // TauOne = 1.0 / (Density * ( rCurrentProcessInfo[DYNAMIC_TAU] / rCurrentProcessInfo[DELTA_TIME] + 5.6666666666 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size) );
1261  double L0 = 0.015;
1262  double lp = sqrt(L0 * Element_Size);
1263  double lu = lp;
1264  double c2u = 2;
1265  double sigma = 0.0;
1266  //this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1267 
1268  if (sigma > 0.00001){
1269  TauOne = Element_Size * Element_Size / (c2u * sigma * lu * lu);
1270  }
1271  else{
1272  TauOne = 1.0 / (Density*(4.0 * KinViscosity / (Element_Size * Element_Size) + 2.0 * AdvVelNorm / Element_Size));
1273  }
1274 //ZZ
1275  }
1276 
1278  virtual void AddMomentumRHS(VectorType& F,
1279  const double Density,
1280  const array_1d<double, TNumNodes>& rShapeFunc,
1281  const double Weight)
1282  {
1283  double Coef = Density * Weight;
1284 
1285  array_1d<double, 3 > BodyForce(3, 0.0);
1286  this->EvaluateInPoint(BodyForce, BODY_FORCE, rShapeFunc);
1287 
1288  // Add the results to the velocity components (Local Dofs are vx, vy, [vz,] p for each node)
1289  int LocalIndex = 0;
1290 
1291  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
1292  {
1293  for (unsigned int d = 0; d < TDim; ++d)
1294  {
1295  F[LocalIndex++] += Coef * rShapeFunc[iNode] * BodyForce[d];
1296  }
1297  ++LocalIndex; // Skip pressure Dof
1298  }
1299  }
1300 //G
1302  const array_1d<double, TNumNodes>& rShapeFunc,
1303  const std::vector<double>& TimeSchemeWeights,
1304  const double& DeltaTime)
1305  {
1306 
1307  double FluidFractionRate;
1308  this->EvaluateTimeDerivativeInPoint(FluidFractionRate, FLUID_FRACTION_RATE, rShapeFunc, DeltaTime, TimeSchemeWeights);
1309 
1310  // Add the results to the velocity components (Local Dofs are vx, vy, [vz,] p for each node)
1311  int LocalIndex = 0;
1312 
1313  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode){
1314 
1315  for (unsigned int d = 0; d < TDim; ++d){
1316  F[LocalIndex++] -= FluidFractionRate;
1317  }
1318 
1319  ++LocalIndex; // Skip pressure Dof
1320  }
1321 
1322  }
1323 //Z
1324 
1326  virtual void AddProjectionToRHS(VectorType& RHS,
1327  const array_1d<double, 3 > & rAdvVel,
1328  const double Density,
1329  const double TauOne,
1330  const double TauTwo,
1331  const array_1d<double, TNumNodes>& rShapeFunc,
1332  const BoundedMatrix<double, TNumNodes, TDim>& rShapeDeriv,
1333  const double Weight,
1334  const double DeltaTime = 1.0)
1335  {
1336  const unsigned int BlockSize = TDim + 1;
1337 
1339  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1340 //GG
1341  for (int i = 0; i != TNumNodes; ++i){
1342  AGradN[i] = 0.0;
1343  }
1344 
1345  double sigma = 0.0;
1346  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1347 //ZZ
1348  array_1d<double,3> MomProj(3,0.0);
1349  double DivProj = 0.0;
1350  this->EvaluateInPoint(MomProj,ADVPROJ,rShapeFunc);
1351  this->EvaluateInPoint(DivProj,DIVPROJ,rShapeFunc);
1352 
1353  MomProj *= TauOne;
1354  DivProj *= TauTwo;
1355 
1356  unsigned int FirstRow = 0;
1357 
1358  for (unsigned int i = 0; i < TNumNodes; i++)
1359  {
1360 //G
1361  double FluidFraction = this->GetGeometry()[i].FastGetSolutionStepValue(FLUID_FRACTION);
1362  array_1d<double,3> FluidFractionGradient(3,0.0);
1363  FluidFractionGradient[0] += rShapeDeriv(i, 0) * FluidFraction;
1364  FluidFractionGradient[1] += rShapeDeriv(i, 1) * FluidFraction;
1365  FluidFractionGradient[2] += rShapeDeriv(i, 2) * FluidFraction;
1366 //Z
1367 
1368  for (unsigned int d = 0; d < TDim; d++)
1369  {
1370 //G
1371 // RHS[FirstRow+d] -= Weight * (Density * AGradN[i] * MomProj[d] + rShapeDeriv(i,d) * DivProj); // TauOne * ( a * Grad(v) ) * MomProjection + TauTwo * Div(v) * MassProjection
1372 //GG
1373  // RHS[FirstRow+d] -= Weight * (Density * AGradN[i] * MomProj[d] + (FluidFraction * rShapeDeriv(i,d) + FluidFractionGradient[d] * rShapeFunc[i]) * DivProj); // TauOne * (a * Grad(v)) * MomProjection + TauTwo * Div(v) * MassProjection
1374  RHS[FirstRow+d] -= Weight * ((Density * AGradN[i] - sigma * rShapeFunc[i]) * MomProj[d] + (FluidFraction * rShapeDeriv(i,d) + FluidFractionGradient[d] * rShapeFunc[i]) * DivProj); // TauOne * (a * Grad(v)) * MomProjection + TauTwo * Div(v) * MassProjection
1375 //ZZ
1376 //Z
1377  RHS[FirstRow+TDim] -= Weight * rShapeDeriv(i,d) * MomProj[d]; // TauOne * Grad(q) * MomProjection
1378  }
1379  FirstRow += BlockSize;
1380  }
1381  }
1382 
1384 
1391  const double Mass)
1392  {
1393  unsigned int DofIndex = 0;
1394  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
1395  {
1396  for (unsigned int d = 0; d < TDim; ++d)
1397  {
1398  rLHSMatrix(DofIndex, DofIndex) += Mass;
1399  ++DofIndex;
1400  }
1401  ++DofIndex; // Skip pressure Dof
1402  }
1403  }
1404 
1406  const array_1d<double,TNumNodes>& rShapeFunc,
1407  const double Density,
1408  const double Weight)
1409  {
1410  const unsigned int BlockSize = TDim + 1;
1411 
1412  double Coef = Density * Weight;
1413  unsigned int FirstRow(0), FirstCol(0);
1414  double K; // Temporary results
1415 
1416  // Note: Dof order is (vx,vy,[vz,]p) for each node
1417  for (unsigned int i = 0; i < TNumNodes; ++i)
1418  {
1419  // Loop over columns
1420  for (unsigned int j = 0; j < TNumNodes; ++j)
1421  {
1422  // Delta(u) * TauOne * [ AdvVel * Grad(v) ] in velocity block
1423  K = Coef * rShapeFunc[i] * rShapeFunc[j];
1424 
1425  for (unsigned int d = 0; d < TDim; ++d) // iterate over dimensions for velocity Dofs in this node combination
1426  {
1427  rLHSMatrix(FirstRow + d, FirstCol + d) += K;
1428  }
1429  // Update column index
1430  FirstCol += BlockSize;
1431  }
1432  // Update matrix indices
1433  FirstRow += BlockSize;
1434  FirstCol = 0;
1435  }
1436  }
1437 
1438 
1440 
1452  void AddMassStabTerms(MatrixType& rLHSMatrix,
1453  const double Density,
1454  const array_1d<double, 3 > & rAdvVel,
1455  const double TauOne,
1456  const array_1d<double, TNumNodes>& rShapeFunc,
1457  const BoundedMatrix<double, TNumNodes, TDim>& rShapeDeriv,
1458  const double Weight)
1459  {
1460  const unsigned int BlockSize = TDim + 1;
1461 
1462  double Coef = Weight * TauOne;
1463  unsigned int FirstRow(0), FirstCol(0);
1464  double K; // Temporary results
1465 
1466  // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1468  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1469 //G
1470  double FluidFraction;
1471  array_1d<double,3> FluidFractionGradient(3,0.0);
1472  this->EvaluateInPoint(FluidFraction, FLUID_FRACTION, rShapeFunc);
1473  this->EvaluateGradientOfScalarInPoint(FluidFractionGradient, FLUID_FRACTION, rShapeDeriv);
1474 
1475  for (unsigned int i = 0; i < TNumNodes; ++i) {
1476  this->GetGeometry()[i].FastGetSolutionStepValue(FLUID_FRACTION_GRADIENT) = FluidFractionGradient;
1477  }
1478 //GG
1479  for (int i = 0; i != TNumNodes; ++i){
1480  AGradN[i] = 0.0;
1481  }
1482  double sigma = 0.0;
1483  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1484 //ZZ
1485 //Z
1486 
1487  // Note: Dof order is (vx,vy,[vz,]p) for each node
1488  for (unsigned int i = 0; i < TNumNodes; ++i)
1489  {
1490  // Loop over columns
1491  for (unsigned int j = 0; j < TNumNodes; ++j)
1492  {
1493  // Delta(u) * TauOne * [ AdvVel * Grad(v) ] in velocity block
1494  K = Coef * Density * AGradN[i] * Density * rShapeFunc[j];
1495  // K -= Coef * sigma * rShapeFunc[i] * rShapeFunc[j];
1496 
1497  for (unsigned int d = 0; d < TDim; ++d) // iterate over dimensions for velocity Dofs in this node combination
1498  {
1499  rLHSMatrix(FirstRow + d, FirstCol + d) += K;
1500  // Delta(u) * TauOne * Grad(q) in q * Div(u) block
1501 //G
1502  // rLHSMatrix(FirstRow + TDim, FirstCol + d) += Coef * Density * rShapeDeriv(i, d) * rShapeFunc[j];
1503  rLHSMatrix(FirstRow + TDim, FirstCol + d) += Coef * Density * (FluidFraction * rShapeDeriv(i, d) + FluidFractionGradient[d] * rShapeFunc[i]) * rShapeFunc[j];
1504 //Z
1505  }
1506  // Update column index
1507  FirstCol += BlockSize;
1508  }
1509  // Update matrix indices
1510  FirstRow += BlockSize;
1511  FirstCol = 0;
1512  }
1513  }
1514 
1517  VectorType& rDampRHS,
1518  const double Density,
1519  const double Viscosity,
1520  const array_1d< double, 3 > & rAdvVel,
1521  const double TauOne,
1522  const double TauTwo,
1523  const array_1d< double, TNumNodes >& rShapeFunc,
1524  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1525  const double Weight)
1526  {
1527  const unsigned int BlockSize = TDim + 1;
1528 
1529  // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1531  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1532 //GG
1533  for (int i = 0; i != TNumNodes; ++i){
1534  AGradN[i] = 0.0;
1535  }
1536  double sigma = 0.0;
1537  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1538 //ZZ
1539  // Build the local matrix and RHS
1540  unsigned int FirstRow(0), FirstCol(0); // position of the first term of the local matrix that corresponds to each node combination
1541  double K, G, PDivV, L, qF; // Temporary results
1542 
1543  array_1d<double,3> BodyForce(3,0.0);
1544  this->EvaluateInPoint(BodyForce,BODY_FORCE,rShapeFunc);
1545  BodyForce *= Density;
1546 //G
1547  double DivPEpsilon, GEps, FluidFraction;
1548  array_1d<double,3> FluidFractionGradient(3,0.0);
1549  this->EvaluateInPoint(FluidFraction, FLUID_FRACTION, rShapeFunc);
1550  this->EvaluateGradientOfScalarInPoint(FluidFractionGradient, FLUID_FRACTION, rShapeDeriv);
1551 //GG
1552  // Lumped version for 1 integration point of the sigma u*v terms
1553 // unsigned int DofIndex = 0;
1554 // for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
1555 // {
1556 // for (unsigned int d = 0; d < TDim; ++d)
1557 // {
1558 // rDampingMatrix(DofIndex, DofIndex) += Weight * (sigma - TauOne * sigma * sigma) * rShapeFunc[iNode]; // lumped version of sigma * u * v + Stabilization (- sigma * v * TauOne * sigma * u)
1559 // ++DofIndex;
1560 // }
1561 // ++DofIndex; // Skip pressure Dof
1562 // }
1563 //ZZ
1564 //Z
1565 
1566  for (unsigned int i = 0; i < TNumNodes; ++i) // iterate over rows
1567  {
1568  for (unsigned int j = 0; j < TNumNodes; ++j) // iterate over columns
1569  {
1570  // Calculate the part of the contributions that is constant for each node combination
1571 
1572  // Velocity block
1573  K = Density * rShapeFunc[i] * AGradN[j]; // Convective term: v * ( a * Grad(u) )
1574 
1575  //K = 0.5 * Density * (rShapeFunc[i] * AGradN[j] - AGradN[i] * rShapeFunc[j]); // Skew-symmetric convective term 1/2( v*grad(u)*u - grad(v) uu )
1576  K += TauOne * Density * AGradN[i] * Density * AGradN[j]; // Stabilization: (a * Grad(v)) * TauOne * (a * Grad(u))
1577 //GG
1578  K += (sigma - TauOne * sigma * sigma) * rShapeFunc[i] * rShapeFunc[j]; // sigma * u * v + Stabilization (- sigma * v * TauOne * sigma * u)
1579 //ZZ
1580  K *= Weight;
1581  // q-p stabilization block (reset result)
1582  L = 0;
1583 
1584  for (unsigned int m = 0; m < TDim; ++m) // iterate over v components (vx,vy[,vz])
1585  {
1586  // Velocity block
1587  //K += Weight * Density * Viscosity * rShapeDeriv(i, m) * rShapeDeriv(j, m); // Diffusive term: Viscosity * Grad(v) * Grad(u)
1588 
1589  // v * Grad(p) block
1590 
1591  G = TauOne * Density * AGradN[i] * rShapeDeriv(j, m); // Stabilization: (a * Grad(v)) * TauOne * Grad(p)
1592 //GG
1593  G -= TauOne * sigma * rShapeFunc[i] * rShapeDeriv(j, m); // Stabilization: (- sigma * v * TauOne * Grad(p)
1594 //ZZ
1595 //G
1596  GEps = TauOne * Density * AGradN[i] * (FluidFraction * rShapeDeriv(j, m) + FluidFractionGradient[m] * rShapeFunc[j]); // Stabilization: (a * Grad(u)) * TauOne * (eps * Grad(q) - q * Grad(eps))
1597 //GG
1598  GEps += TauOne * sigma * rShapeFunc[i] * (FluidFraction * rShapeDeriv(j, m) + FluidFractionGradient[m] * rShapeFunc[j]); // Stabilization: sigma * u * TauOne * (eps * Grad(q) - q * Grad(eps))
1599 //ZZ
1600  DivPEpsilon = (FluidFraction * rShapeDeriv(i, m) + FluidFractionGradient[m] * rShapeFunc[i]) * rShapeFunc[j]; // eps * q * Div(v) + q * Grad(eps) * u
1601 //Z
1602  PDivV = rShapeDeriv(i, m) * rShapeFunc[j]; // Div(v) * p
1603 
1604  // Write v * Grad(p) component
1605  rDampingMatrix(FirstRow + m, FirstCol + TDim) += Weight * (G - PDivV);
1606  // Use symmetry to write the q * Div(u) component
1607 //G
1608  // rDampingMatrix(FirstCol + TDim, FirstRow + m) += Weight * (G + PDivV);
1609  rDampingMatrix(FirstCol + TDim, FirstRow + m) += Weight * (GEps + DivPEpsilon);
1610 
1611  // q-p stabilization block
1612  // L += rShapeDeriv(i, m) * rShapeDeriv(j, m); // Stabilization: Grad(q) * TauOne * Grad(p)
1613  L += (FluidFraction * rShapeDeriv(i, m) + FluidFractionGradient[m] * rShapeFunc[i]) * rShapeDeriv(j, m); // Stabilization: (eps * Grad(q) + q * Grad(eps)) * TauOne * Grad(p)
1614 //Z
1615  for (unsigned int n = 0; n < TDim; ++n) // iterate over u components (ux,uy[,uz])
1616  {
1617  // Velocity block
1618 //G
1619  // rDampingMatrix(FirstRow + m, FirstCol + n) += Weight * TauTwo * rShapeDeriv(i, m) * rShapeDeriv(j, n); // Stabilization: Div(v) * TauTwo * Div(u)
1620  rDampingMatrix(FirstRow + m, FirstCol + n) += Weight * TauTwo * rShapeDeriv(i, m) * (FluidFraction * rShapeDeriv(j, n) + FluidFractionGradient[n] * rShapeFunc[j]); // Stabilization: Div(v) * TauTwo * (eps * Div(u) + Grad(eps) * u)
1621 //Z
1622  }
1623 
1624  }
1625 
1626  // Write remaining terms to velocity block
1627  for (unsigned int d = 0; d < TDim; ++d)
1628  rDampingMatrix(FirstRow + d, FirstCol + d) += K;
1629 
1630  // Write q-p stabilization block
1631  rDampingMatrix(FirstRow + TDim, FirstCol + TDim) += Weight * TauOne * L;
1632 
1633 
1634  // Update reference column index for next iteration
1635  FirstCol += BlockSize;
1636  }
1637 
1638  // Operate on RHS
1639  qF = 0.0;
1640  for (unsigned int d = 0; d < TDim; ++d)
1641  {
1642 //G
1643 //GG
1644  // rDampRHS[FirstRow + d] += Weight * TauOne * Density * AGradN[i] * BodyForce[d]; // ( a * Grad(v) ) * TauOne * (Density * BodyForce)
1645  rDampRHS[FirstRow + d] += Weight * TauOne * (Density * AGradN[i] - sigma * rShapeFunc[i]) * BodyForce[d];
1646 //ZZ
1647  // qF += rShapeDeriv(i, d) * BodyForce[d];
1648  qF += (FluidFraction * rShapeDeriv(i, d) + FluidFractionGradient[d] * rShapeFunc[i]) * BodyForce[d];
1649 
1650 //Z
1651  }
1652 
1653  rDampRHS[FirstRow + TDim] += Weight * TauOne * qF; // Grad(q) * TauOne * (Density * BodyForce)
1654 
1655  // Update reference indices
1656  FirstRow += BlockSize;
1657  FirstCol = 0;
1658  }
1659 
1660 // this->AddBTransCB(rDampingMatrix,rShapeDeriv,Viscosity*Coef);
1661 
1662  this->AddViscousTerm(rDampingMatrix,rShapeDeriv,Viscosity*Density*Weight);
1663  }
1664 /*
1666 // void AddIntegrationPointVelocityContribution(MatrixType& rDampingMatrix,
1667 // VectorType& rDampRHS,
1668 // const double Density,
1669 // const double Viscosity,
1670 // const array_1d< double, 3 > & rAdvVel,
1671 // const double TauOne,
1672 // const double TauTwo,
1673 // const array_1d< double, TNumNodes >& rShapeFunc,
1674 // const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1675 // const double Weight,
1676 // const double DeltaTime)
1677 // {
1678 // const unsigned int BlockSize = TDim + 1;
1679 //
1680 // const double TauCoef = TauOne*TauTwo / DeltaTime;
1681 //
1682 // // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1683 // array_1d<double, TNumNodes> AGradN;
1684 // this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1685 //
1686 // // Build the local matrix and RHS
1687 // unsigned int FirstRow(0), FirstCol(0); // position of the first term of the local matrix that corresponds to each node combination
1688 // double K, G, PDivV, L; // Temporary results
1689 // double Coef = Density * Weight;
1690 //
1691 // // Note that we iterate first over columns, then over rows to read the Body Force only once per node
1692 // for (unsigned int j = 0; j < TNumNodes; ++j) // iterate over colums
1693 // {
1694 // // Get Body Force
1695 // const array_1d<double, 3 > & rBodyForce = this->GetGeometry()[j].FastGetSolutionStepValue(BODY_FORCE);
1696 //
1697 // const array_1d<double,3>& OldVelocity = this->GetGeometry()[j].FastGetSolutionStepValue(VELOCITY,1);
1698 //
1699 // for (unsigned int i = 0; i < TNumNodes; ++i) // iterate over rows
1700 // {
1701 // // Calculate the part of the contributions that is constant for each node combination
1702 //
1703 // // Velocity block
1704 // K = rShapeFunc[i] * AGradN[j]; // Convective term: v * ( a * Grad(u) )
1705 // K += TauOne * AGradN[i] * AGradN[j]; // Stabilization: (a * Grad(v)) * TauOne * (a * Grad(u))
1706 //
1707 // // q-p stabilization block (reset result)
1708 // L = 0;
1709 //
1710 // for (unsigned int m = 0; m < TDim; ++m) // iterate over v components (vx,vy[,vz])
1711 // {
1712 // // Velocity block
1713 // // K += Viscosity * rShapeDeriv(i, m) * rShapeDeriv(j, m); // Diffusive term: Viscosity * Grad(v) * Grad(u)
1714 // // Note that we are usig kinematic viscosity, as we will multiply it by density later
1715 //
1716 // // v * Grad(p) block
1717 // G = TauOne * AGradN[i] * rShapeDeriv(j, m); // Stabilization: (a * Grad(v)) * TauOne * Grad(p)
1718 // PDivV = rShapeDeriv(i, m) * rShapeFunc[j]; // Div(v) * p
1719 //
1720 // // Write v * Grad(p) component
1721 // rDampingMatrix(FirstRow + m, FirstCol + TDim) += Weight * (G - PDivV);
1722 // // Use symmetry to write the q * rho * Div(u) component
1723 // rDampingMatrix(FirstCol + TDim, FirstRow + m) += Coef * (G + PDivV);
1724 //
1725 // // q-p stabilization block
1726 // L += rShapeDeriv(i, m) * rShapeDeriv(j, m); // Stabilization: Grad(q) * TauOne * Grad(p)
1727 //
1728 // for (unsigned int n = 0; n < TDim; ++n) // iterate over u components (ux,uy[,uz])
1729 // {
1730 // // Velocity block
1731 // rDampingMatrix(FirstRow + m, FirstCol + n) += Coef * (TauTwo + TauCoef) * rShapeDeriv(i, m) * rShapeDeriv(j, n); // Stabilization: Div(v) * TauTwo *( 1+TauOne/Dt) * Div(u)
1732 // rDampRHS[FirstRow + m] -= Coef * TauCoef * rShapeDeriv(i, m) * rShapeDeriv(j, n) * OldVelocity[n]; // Stabilization: Div(v) * TauTwo*TauOne/Dt * Div(u_old)
1733 // }
1734 //
1735 // }
1736 //
1737 // // Write remaining terms to velocity block
1738 // K *= Coef; // Weight by nodal area and density
1739 // for (unsigned int d = 0; d < TDim; ++d)
1740 // rDampingMatrix(FirstRow + d, FirstCol + d) += K;
1741 //
1742 // // Write q-p stabilization block
1743 // rDampingMatrix(FirstRow + TDim, FirstCol + TDim) += Weight * TauOne * L;
1744 //
1745 // // Operate on RHS
1746 // L = 0; // We reuse one of the temporary variables for the pressure RHS
1747 //
1748 // for (unsigned int d = 0; d < TDim; ++d)
1749 // {
1750 // rDampRHS[FirstRow + d] += Coef * TauOne * AGradN[i] * rShapeFunc[j] * rBodyForce[d]; // ( a * Grad(v) ) * TauOne * (Density * BodyForce)
1751 // L += rShapeDeriv(i, d) * rShapeFunc[j] * rBodyForce[d];
1752 // }
1753 // rDampRHS[FirstRow + TDim] += Coef * TauOne * L; // Grad(q) * TauOne * (Density * BodyForce)
1754 //
1755 // // Update reference row index for next iteration
1756 // FirstRow += BlockSize;
1757 // }
1758 //
1759 // // Update reference indices
1760 // FirstRow = 0;
1761 // FirstCol += BlockSize;
1762 // }
1763 //
1764 // // this->AddBTransCB(rDampingMatrix,rShapeDeriv,Viscosity*Coef);
1765 // this->AddViscousTerm(rDampingMatrix,rShapeDeriv,Viscosity*Coef);
1766 // }
1767  */
1769 
1774  const double Density,
1775  array_1d< double, 3 > & rElementalMomRes,
1776  double& rElementalMassRes,
1777  const array_1d< double, TNumNodes >& rShapeFunc,
1778  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1779  const double Weight)
1780  {
1781  // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1783  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1784 //GG
1785  for (int i = 0; i != TNumNodes; ++i){
1786  AGradN[i] = 0.0;
1787  }
1788  double sigma = 0.0;
1789  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1790 //ZZ
1791 //G
1792  double FluidFraction;
1793  array_1d<double,3> FluidFractionGradient(3,0.0);
1794  this->EvaluateInPoint(FluidFraction, FLUID_FRACTION, rShapeFunc);
1795  this->EvaluateGradientOfScalarInPoint(FluidFractionGradient, FLUID_FRACTION, rShapeDeriv);
1796 //Z
1797  // Compute contribution to Kij * Uj, with Kij = Ni * Residual(Nj); Uj = (v,p)Node_j (column vector)
1798  for (unsigned int i = 0; i < TNumNodes; ++i) // Iterate over element nodes
1799  {
1800 
1801  // Variable references
1802  const array_1d< double, 3 > & rVelocity = this->GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
1803  const array_1d< double, 3 > & rBodyForce = this->GetGeometry()[i].FastGetSolutionStepValue(BODY_FORCE);
1804  const double& rPressure = this->GetGeometry()[i].FastGetSolutionStepValue(PRESSURE);
1805 
1806  // Compute this node's contribution to the residual (evaluated at inegration point)
1807  for (unsigned int d = 0; d < TDim; ++d)
1808  {
1809 //GG
1810  // rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * rBodyForce[d] - AGradN[i] * rVelocity[d]) - rShapeDeriv(i, d) * rPressure);
1811  rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * rBodyForce[d] - AGradN[i] * rVelocity[d]) - sigma * rShapeFunc[i] * rVelocity[d] - rShapeDeriv(i, d) * rPressure);
1812 //ZZ
1813 //G
1814  // rElementalMassRes -= Weight * rShapeDeriv(i, d) * rVelocity[d];
1815  rElementalMassRes -= Weight * (FluidFraction * rShapeDeriv(i, d) * rVelocity[d] + FluidFractionGradient[d] * rVelocity[d]);
1816  }
1817 
1818  rElementalMassRes += Weight * this->GetGeometry()[i].FastGetSolutionStepValue(FLUID_FRACTION_RATE);
1819 //Z
1820 
1821  }
1822  }
1823 
1825 
1835  const double Density,
1836  array_1d< double, 3 > & rElementalMomRes,
1837  const array_1d< double, TNumNodes >& rShapeFunc,
1838  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1839  const double Weight)
1840  {
1841  // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1843  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1844 //GG
1845  for (int i = 0; i != TNumNodes; ++i){
1846  AGradN[i] = 0.0;
1847  }
1848  double sigma = 0.0;
1849  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1850 //ZZ
1851  // Compute contribution to Kij * Uj, with Kij = Ni * Residual(Nj); Uj = (v,p)Node_j (column vector)
1852  for (unsigned int i = 0; i < TNumNodes; ++i) // Iterate over element nodes
1853  {
1854 
1855  // Variable references
1856  const array_1d< double, 3 > & rVelocity = this->GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
1857  const array_1d< double, 3 > & rAcceleration = this->GetGeometry()[i].FastGetSolutionStepValue(ACCELERATION);
1858  const array_1d< double, 3 > & rBodyForce = this->GetGeometry()[i].FastGetSolutionStepValue(BODY_FORCE);
1859  const double& rPressure = this->GetGeometry()[i].FastGetSolutionStepValue(PRESSURE);
1860 
1861  // Compute this node's contribution to the residual (evaluated at inegration point)
1862  for (unsigned int d = 0; d < TDim; ++d)
1863  {
1864 //GG
1865  // rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * (rBodyForce[d] - rAcceleration[d]) - AGradN[i] * rVelocity[d]) - rShapeDeriv(i, d) * rPressure);
1866  rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * (rBodyForce[d] - rAcceleration[d]) - AGradN[i] * rVelocity[d]) - sigma * rShapeFunc[i] * rVelocity[d] - rShapeDeriv(i, d) * rPressure);
1867 //ZZ
1868  }
1869  }
1870  }
1871 
1873 
1883  const double Density,
1884  array_1d< double, 3 > & rElementalMomRes,
1885  const array_1d< double, TNumNodes >& rShapeFunc,
1886  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1887  const double Weight)
1888  {
1889  // If we want to use more than one Gauss point to integrate the convective term, this has to be evaluated once per integration point
1891  this->GetConvectionOperator(AGradN, rAdvVel, rShapeDeriv); // Get a * grad(Ni)
1892 //GG
1893  for (int i = 0; i != TNumNodes; ++i){
1894  AGradN[i] = 0.0;
1895  }
1896  double sigma = 0.0;
1897  this->EvaluateInPoint(sigma,PERMEABILITY_1_DAY,rShapeFunc);
1898 //ZZ
1899  // Compute contribution to Kij * Uj, with Kij = Ni * Residual(Nj); Uj = (v,p)Node_j (column vector)
1900  for (unsigned int i = 0; i < TNumNodes; ++i) // Iterate over element nodes
1901  {
1902 
1903  // Variable references
1904  const array_1d< double, 3 > & rVelocity = this->GetGeometry()[i].FastGetSolutionStepValue(VELOCITY);
1905  const array_1d< double, 3 > & rBodyForce = this->GetGeometry()[i].FastGetSolutionStepValue(BODY_FORCE);
1906  const array_1d< double, 3 > & rProjection = this->GetGeometry()[i].FastGetSolutionStepValue(ADVPROJ);
1907  const double& rPressure = this->GetGeometry()[i].FastGetSolutionStepValue(PRESSURE);
1908 
1909  // Compute this node's contribution to the residual (evaluated at inegration point)
1910  for (unsigned int d = 0; d < TDim; ++d)
1911  {
1912 //GG
1913  // rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * rBodyForce[d] - AGradN[i] * rVelocity[d]) - rShapeDeriv(i, d) * rPressure);
1914  rElementalMomRes[d] += Weight * (Density * (rShapeFunc[i] * rBodyForce[d] - AGradN[i] * rVelocity[d]) - sigma * rShapeFunc[i] * rVelocity[d] - rShapeDeriv(i, d) * rPressure);
1915 //ZZ
1916  rElementalMomRes[d] -= Weight * rShapeFunc[i] * rProjection[d];
1917 
1918  }
1919  }
1920  }
1921 
1922 
1924 
1932  virtual void GetEffectiveViscosity(const double Density,
1933  const double MolecularViscosity,
1934  const array_1d<double, TNumNodes>& rShapeFunc,
1935  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
1936  double& TotalViscosity,
1937  const ProcessInfo& rCurrentProcessInfo)
1938  {
1939  const double C = this->GetValue(C_SMAGORINSKY);
1940 
1941  TotalViscosity = MolecularViscosity;
1942  if (C != 0.0 )
1943  {
1944  // The filter width in Smagorinsky is typically the element size h. We will store the square of h, as the final formula involves the squared filter width
1945  const double FilterWidth = this->FilterWidth(rShapeDeriv);
1946 
1947  const double NormS = this->SymmetricGradientNorm(rShapeDeriv);
1948 
1949  // Total Viscosity
1950  TotalViscosity += 2.0 * C * C * FilterWidth * NormS;
1951  }
1952  }
1953 
1955 
1961  virtual void GetAdvectiveVel(array_1d< double, 3 > & rAdvVel,
1962  const array_1d< double, TNumNodes >& rShapeFunc)
1963  {
1964  // Compute the weighted value of the advective velocity in the (Gauss) Point
1965  rAdvVel = rShapeFunc[0] * (this->GetGeometry()[0].FastGetSolutionStepValue(VELOCITY) - this->GetGeometry()[0].FastGetSolutionStepValue(MESH_VELOCITY));
1966  for (unsigned int iNode = 1; iNode < TNumNodes; ++iNode)
1967  rAdvVel += rShapeFunc[iNode] * (this->GetGeometry()[iNode].FastGetSolutionStepValue(VELOCITY) - this->GetGeometry()[iNode].FastGetSolutionStepValue(MESH_VELOCITY));
1968  }
1969 
1971 
1978  virtual void GetAdvectiveVel(array_1d< double, 3 > & rAdvVel,
1979  const array_1d< double, TNumNodes >& rShapeFunc,
1980  const std::size_t Step)
1981  {
1982  // Compute the weighted value of the advective velocity in the (Gauss) Point
1983  rAdvVel = rShapeFunc[0] * (this->GetGeometry()[0].FastGetSolutionStepValue(VELOCITY, Step) - this->GetGeometry()[0].FastGetSolutionStepValue(MESH_VELOCITY, Step));
1984  for (unsigned int iNode = 1; iNode < TNumNodes; ++iNode)
1985  rAdvVel += rShapeFunc[iNode] * (this->GetGeometry()[iNode].FastGetSolutionStepValue(VELOCITY, Step) - this->GetGeometry()[iNode].FastGetSolutionStepValue(MESH_VELOCITY, Step));
1986  }
1987 
1989 
1997  const array_1d< double, 3 > & rVelocity,
1998  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv)
1999  {
2000  // Evaluate (and weight) the a * Grad(Ni) operator in the integration point, for each node i
2001  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode) // Loop over nodes
2002  {
2003  // Initialize result
2004  rResult[iNode] = rVelocity[0] * rShapeDeriv(iNode, 0);
2005  for (unsigned int d = 1; d < TDim; ++d) // loop over components
2006  rResult[iNode] += rVelocity[d] * rShapeDeriv(iNode, d);
2007  }
2008  }
2009 
2011 
2022  virtual void AddPointContribution(double& rResult,
2023  const Variable< double >& rVariable,
2024  const array_1d< double, TNumNodes >& rShapeFunc,
2025  const double Weight = 1.0)
2026  {
2027  // Compute the weighted value of the nodal variable in the (Gauss) Point
2028  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
2029  rResult += Weight * rShapeFunc[iNode] * this->GetGeometry()[iNode].FastGetSolutionStepValue(rVariable);
2030  }
2031 
2033 
2042  virtual void EvaluateInPoint(double& rResult,
2043  const Variable< double >& rVariable,
2044  const array_1d< double, TNumNodes >& rShapeFunc)
2045  {
2046  // Compute the weighted value of the nodal variable in the (Gauss) Point
2047  rResult = rShapeFunc[0] * this->GetGeometry()[0].FastGetSolutionStepValue(rVariable);
2048  for (unsigned int iNode = 1; iNode < TNumNodes; ++iNode)
2049  rResult += rShapeFunc[iNode] * this->GetGeometry()[iNode].FastGetSolutionStepValue(rVariable);
2050  }
2051 
2052 //G
2053 
2055  const Variable< double >& rVariable,
2056  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv)
2057  {
2058 
2059  for (unsigned int i = 0; i < TNumNodes; ++i) {
2060  double& scalar = this->GetGeometry()[i].FastGetSolutionStepValue(rVariable);
2061 
2062  for (unsigned int d = 0; d < TDim; ++d){
2063  rResult[d] += rShapeDeriv(i, d) * scalar;
2064  }
2065  }
2066  }
2067 
2068  virtual void EvaluateTimeDerivativeInPoint(double& rResult,
2069  const Variable< double >& rVariable,
2070  const array_1d< double, TNumNodes >& rShapeFunc,
2071  const double& DeltaTime,
2072  const std::vector<double>& rSchemeWeigths)
2073  {
2074  // Compute the time derivative of a nodal variable as a liner contribution of weighted value of the nodal variable in the (Gauss) Point
2075 
2076  if (rVariable == FLUID_FRACTION_RATE){
2077  rResult = 0.0;
2078 
2079  for (unsigned int iWeight = 0; iWeight < rSchemeWeigths.size(); ++iWeight){
2080 
2081  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode){
2082  rResult += rSchemeWeigths[iWeight] * rShapeFunc[iNode] * this->GetGeometry()[iNode].FastGetSolutionStepValue(rVariable, iWeight);
2083  }
2084 
2085  }
2086 
2087  rResult /= DeltaTime;
2088  }
2089  }
2090 //Z
2091 
2093 
2104  const Variable< array_1d< double, 3 > >& rVariable,
2105  const array_1d< double, TNumNodes>& rShapeFunc,
2106  const double Weight = 1.0)
2107  {
2108  // Compute the weighted value of the nodal variable in the (Gauss) Point
2109  for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode)
2110  rResult += Weight * rShapeFunc[iNode] * this->GetGeometry()[iNode].FastGetSolutionStepValue(rVariable);
2111  }
2112 
2114 
2122  virtual void EvaluateInPoint(array_1d< double, 3 > & rResult,
2123  const Variable< array_1d< double, 3 > >& rVariable,
2124  const array_1d< double, TNumNodes >& rShapeFunc)
2125  {
2126  // Compute the weighted value of the nodal variable in the (Gauss) Point
2127  rResult = rShapeFunc[0] * this->GetGeometry()[0].FastGetSolutionStepValue(rVariable);
2128  for (unsigned int iNode = 1; iNode < TNumNodes; ++iNode)
2129  rResult += rShapeFunc[iNode] * this->GetGeometry()[iNode].FastGetSolutionStepValue(rVariable);
2130  }
2131 
2133 
2140  double ElementSize(const double);
2141 
2143  double FilterWidth();
2144 
2147 
2149 
2154  {
2155  const unsigned int GradientSize = (TDim*(TDim+1))/2; // Number of different terms in the symmetric gradient matrix
2156  array_1d<double,GradientSize> GradientVector( GradientSize, 0.0 );
2157  unsigned int Index;
2158 
2159  // Compute Symmetric Grad(u). Note that only the lower half of the matrix is calculated
2160  for (unsigned int k = 0; k < TNumNodes; ++k)
2161  {
2162  const array_1d< double, 3 > & rNodeVel = this->GetGeometry()[k].FastGetSolutionStepValue(VELOCITY);
2163  Index = 0;
2164  for (unsigned int i = 0; i < TDim; ++i)
2165  {
2166  for (unsigned int j = 0; j < i; ++j) // Off-diagonal
2167  GradientVector[Index++] += 0.5 * (rShapeDeriv(k, j) * rNodeVel[i] + rShapeDeriv(k, i) * rNodeVel[j]);
2168  GradientVector[Index++] += rShapeDeriv(k, i) * rNodeVel[i]; // Diagonal
2169  }
2170  }
2171 
2172  // Norm[ Symmetric Grad(u) ] = ( 2 * Sij * Sij )^(1/2)
2173  Index = 0;
2174  double NormS(0.0);
2175  for (unsigned int i = 0; i < TDim; ++i)
2176  {
2177  for (unsigned int j = 0; j < i; ++j)
2178  {
2179  NormS += 2.0 * GradientVector[Index] * GradientVector[Index]; // Using symmetry, lower half terms of the matrix are added twice
2180  ++Index;
2181  }
2182  NormS += GradientVector[Index] * GradientVector[Index]; // Diagonal terms
2183  ++Index; // Diagonal terms
2184  }
2185 
2186  NormS = sqrt( 2.0 * NormS );
2187  return NormS;
2188  }
2189 
2191 
2197  virtual void AddViscousTerm(MatrixType& rDampingMatrix,
2198  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
2199  const double Weight);
2200 
2202 
2212  void AddBTransCB(MatrixType& rDampingMatrix,
2213  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv,
2214  const double Weight)
2215  {
2216  BoundedMatrix<double, (TDim * TNumNodes)/2, TDim*TNumNodes > B;
2217  BoundedMatrix<double, (TDim * TNumNodes)/2, (TDim*TNumNodes)/2 > C;
2218  this->CalculateB(B,rShapeDeriv);
2219  this->CalculateC(C,Weight);
2220 
2221  const unsigned int BlockSize = TDim + 1;
2222  const unsigned int StrainSize = (TDim*TNumNodes)/2;
2223 
2224  DenseVector<unsigned int> aux(TDim*TNumNodes);
2225  for(unsigned int i=0; i<TNumNodes; i++)
2226  {
2227  int base_index = TDim*i;
2228  int aux_index = BlockSize*i;
2229  for(unsigned int j=0; j<TDim; j++)
2230  {
2231  aux[base_index+j] = aux_index+j;
2232  }
2233  }
2234 
2235  for(unsigned int k=0; k< StrainSize; k++)
2236  {
2237  for(unsigned int l=0; l< StrainSize; l++)
2238  {
2239  const double Ckl = C(k,l);
2240  for (unsigned int i = 0; i < TDim*TNumNodes; ++i) // iterate over v components (vx,vy[,vz])
2241  {
2242  const double Bki=B(k,i);
2243  for (unsigned int j = 0; j < TDim*TNumNodes; ++j) // iterate over u components (ux,uy[,uz])
2244  {
2245  rDampingMatrix(aux[i],aux[j]) += Bki*Ckl*B(l,j);
2246  }
2247 
2248  }
2249 
2250  }
2251  }
2252  }
2253 
2256  const double Weight)
2257  {
2258  const GeometryType& rGeom = this->GetGeometry();
2259 
2260  // Velocity gradient
2261  MatrixType GradU = ZeroMatrix(TDim,TDim);
2262  for (unsigned int n = 0; n < TNumNodes; n++)
2263  {
2264  const array_1d<double,3>& rVel = this->GetGeometry()[n].FastGetSolutionStepValue(VELOCITY);
2265  for (unsigned int i = 0; i < TDim; i++)
2266  for (unsigned int j = 0; j < TDim; j++)
2267  GradU(i,j) += rDN_DX(n,j)*rVel[i];
2268  }
2269 
2270  // Element lengths
2271  array_1d<double,3> Delta(3,0.0);
2272  Delta[0] = fabs(rGeom[TNumNodes-1].X()-rGeom[0].X());
2273  Delta[1] = fabs(rGeom[TNumNodes-1].Y()-rGeom[0].Y());
2274  Delta[2] = fabs(rGeom[TNumNodes-1].Z()-rGeom[0].Z());
2275 
2276  for (unsigned int n = 1; n < TNumNodes; n++)
2277  {
2278  double hx = fabs(rGeom[n].X()-rGeom[n-1].X());
2279  if (hx > Delta[0]) Delta[0] = hx;
2280  double hy = fabs(rGeom[n].Y()-rGeom[n-1].Y());
2281  if (hy > Delta[1]) Delta[1] = hy;
2282  double hz = fabs(rGeom[n].Z()-rGeom[n-1].Z());
2283  if (hz > Delta[2]) Delta[2] = hz;
2284  }
2285 
2286  double AvgDeltaSq = Delta[0];
2287  for (unsigned int d = 1; d < TDim; d++)
2288  AvgDeltaSq *= Delta[d];
2289  AvgDeltaSq = std::pow(AvgDeltaSq,2./TDim);
2290 
2291  Delta[0] = Delta[0]*Delta[0]/12.0;
2292  Delta[1] = Delta[1]*Delta[1]/12.0;
2293  Delta[2] = Delta[2]*Delta[2]/12.0;
2294 
2295  // Gij
2296  MatrixType G = ZeroMatrix(TDim,TDim);
2297  for (unsigned int i = 0; i < TDim; i++)
2298  for (unsigned int j = 0; j < TDim; j++)
2299  for (unsigned int d = 0; d < TDim; d++)
2300  G(i,j) += Delta[d]*GradU(i,d)*GradU(j,d);
2301 
2302  // Gij:Sij
2303  double GijSij = 0.0;
2304  for (unsigned int i = 0; i < TDim; i++)
2305  for (unsigned int j = 0; j < TDim; j++)
2306  GijSij += 0.5*G(i,j)*( GradU(i,j) + GradU(j,i) );
2307 
2308  if (GijSij < 0.0) // Otherwise model term is clipped
2309  {
2310  // Gkk
2311  double Gkk = G(0,0);
2312  for (unsigned int d = 1; d < TDim; d++)
2313  Gkk += G(d,d);
2314 
2315  // C_epsilon
2316  const double Ce = 1.0;
2317 
2318  // ksgs
2319  double ksgs = -4*AvgDeltaSq*GijSij/(Ce*Ce*Gkk);
2320 
2321  // Assembly of model term
2322  unsigned int RowIndex = 0;
2323  unsigned int ColIndex = 0;
2324 
2325  for (unsigned int i = 0; i < TNumNodes; i++)
2326  {
2327  for (unsigned int j = 0; j < TNumNodes; j++)
2328  {
2329  for (unsigned int d = 0; d < TDim; d++)
2330  {
2331  double Aux = rDN_DX(i,d) * Delta[0] * G(d,0)*rDN_DX(j,0);
2332  for (unsigned int k = 1; k < TDim; k++)
2333  Aux += rDN_DX(i,d) *Delta[k] * G(d,k)*rDN_DX(j,k);
2334  rDampingMatrix(RowIndex+d,ColIndex+d) += Weight * 2.0*ksgs * Aux;
2335  }
2336 
2337  ColIndex += TDim;
2338  }
2339  RowIndex += TDim;
2340  ColIndex = 0;
2341  }
2342  }
2343 
2344  }
2345 
2347 
2352  void CalculateB( BoundedMatrix<double, (TDim * TNumNodes) / 2, TDim * TNumNodes >& rB,
2353  const BoundedMatrix<double, TNumNodes, TDim >& rShapeDeriv);
2354 
2356 
2363  virtual void CalculateC( BoundedMatrix<double, (TDim * TNumNodes) / 2, (TDim * TNumNodes) / 2 >& rC,
2364  const double Viscosity);
2365 
2366  double ConsistentMassCoef(const double Area);
2367 
2371 
2372 
2376 
2377 
2381 
2382 
2384 
2385 private:
2388 
2389 
2393 
2397 
2398  friend class Serializer;
2399 
2400  virtual void save(Serializer& rSerializer) const override
2401  {
2403  }
2404 
2405  virtual void load(Serializer& rSerializer) override
2406  {
2408  }
2409 
2413 
2414 
2418 
2419 
2423 
2424 
2428 
2429 
2433 
2435  MonolithicDEMCoupledWeak & operator=(MonolithicDEMCoupledWeak const& rOther);
2436 
2438  MonolithicDEMCoupledWeak(MonolithicDEMCoupledWeak const& rOther);
2439 
2441 
2442 }; // Class MonolithicDEMCoupledWeak
2443 
2445 
2448 
2449 
2453 
2454 
2456 template< unsigned int TDim,
2457  unsigned int TNumNodes >
2458 inline std::istream& operator >>(std::istream& rIStream,
2460 {
2461  return rIStream;
2462 }
2463 
2465 template< unsigned int TDim,
2466  unsigned int TNumNodes >
2467 inline std::ostream& operator <<(std::ostream& rOStream,
2469 {
2470  rThis.PrintInfo(rOStream);
2471  rOStream << std::endl;
2472  rThis.PrintData(rOStream);
2473 
2474  return rOStream;
2475 }
2477 
2479 
2480 } // namespace Kratos.
2481 
2482 #endif // MONOLITHIC_DEM_COUPLED_WEAK_H
PeriodicInterfaceProcess & operator=(const PeriodicInterfaceProcess &)=delete
Base class for all Elements.
Definition: element.h:60
std::size_t SizeType
Definition: element.h:94
std::vector< DofType::Pointer > DofsVectorType
Definition: element.h:100
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: element.h:1135
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:904
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
std::size_t IndexType
Definition: flags.h:74
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: geometrical_object.h:248
Geometry base class.
Definition: geometry.h:71
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 object defines an indexed object.
Definition: indexed_object.h:54
void resize(std::size_t NewSize1, std::size_t NewSize2, bool preserve=0)
Definition: amatrix_interface.h:224
A stabilized element for the incompressible Navier-Stokes equations.
Definition: monolithic_dem_coupled_weak.h:138
MonolithicDEMCoupledWeak(IndexType NewId, const NodesArrayType &ThisNodes)
Constructor using an array of nodes.
Definition: monolithic_dem_coupled_weak.h:207
PointerVectorSet< Dof< double >, IndexedObject > DofsArrayType
Definition: monolithic_dem_coupled_weak.h:176
virtual void EvaluateTimeDerivativeInPoint(double &rResult, const Variable< double > &rVariable, const array_1d< double, TNumNodes > &rShapeFunc, const double &DeltaTime, const std::vector< double > &rSchemeWeigths)
Definition: monolithic_dem_coupled_weak.h:2068
Vector VectorType
Definition: monolithic_dem_coupled_weak.h:164
virtual void GetSecondDerivativesVector(Vector &Values, int Step=0) const override
Returns ACCELERATION_X, ACCELERATION_Y, (ACCELERATION_Z,) 0 for each node.
Matrix MatrixType
Definition: monolithic_dem_coupled_weak.h:166
std::size_t IndexType
Definition: monolithic_dem_coupled_weak.h:168
void CalculateLumpedMassMatrix(MatrixType &rLHSMatrix, const double Mass)
Add lumped mass matrix.
Definition: monolithic_dem_coupled_weak.h:1390
void ModulatedGradientDiffusion(MatrixType &rDampingMatrix, const BoundedMatrix< double, TNumNodes, TDim > &rDN_DX, const double Weight)
Definition: monolithic_dem_coupled_weak.h:2254
virtual void GetFirstDerivativesVector(Vector &Values, int Step=0) const override
Returns VELOCITY_X, VELOCITY_Y, (VELOCITY_Z,) PRESSURE for each node.
std::size_t SizeType
Definition: monolithic_dem_coupled_weak.h:170
virtual void EvaluateInPoint(array_1d< double, 3 > &rResult, const Variable< array_1d< double, 3 > > &rVariable, const array_1d< double, TNumNodes > &rShapeFunc)
Write the value of a variable at a point inside the element to a double.
Definition: monolithic_dem_coupled_weak.h:2122
MonolithicDEMCoupledWeak(IndexType NewId=0)
Default constuctor.
Definition: monolithic_dem_coupled_weak.h:198
void AddMassStabTerms(MatrixType &rLHSMatrix, const double Density, const array_1d< double, 3 > &rAdvVel, const double TauOne, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Add mass-like stabilization terms to LHS.
Definition: monolithic_dem_coupled_weak.h:1452
virtual void EvaluateInPoint(double &rResult, const Variable< double > &rVariable, const array_1d< double, TNumNodes > &rShapeFunc)
Write the value of a variable at a point inside the element to a double.
Definition: monolithic_dem_coupled_weak.h:2042
virtual void CalculateOnIntegrationPoints(const Variable< array_1d< double, 6 > > &rVariable, std::vector< array_1d< double, 6 > > &rValues, const ProcessInfo &rCurrentProcessInfo) override
Definition: monolithic_dem_coupled_weak.h:1035
virtual void EvaluateGradientOfScalarInPoint(array_1d< double, 3 > &rResult, const Variable< double > &rVariable, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv)
Definition: monolithic_dem_coupled_weak.h:2054
virtual void GetAdvectiveVel(array_1d< double, 3 > &rAdvVel, const array_1d< double, TNumNodes > &rShapeFunc, const std::size_t Step)
Write the advective velocity evaluated at this point to an array.
Definition: monolithic_dem_coupled_weak.h:1978
std::vector< Dof< double >::Pointer > DofsVectorType
Definition: monolithic_dem_coupled_weak.h:174
virtual void CalculateOnIntegrationPoints(const Variable< Matrix > &rVariable, std::vector< Matrix > &rValues, const ProcessInfo &rCurrentProcessInfo) override
Definition: monolithic_dem_coupled_weak.h:1045
virtual void FinalizeNonLinearIteration(const ProcessInfo &rCurrentProcessInfo) override
Definition: monolithic_dem_coupled_weak.h:609
virtual void GetEffectiveViscosity(const double Density, const double MolecularViscosity, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, double &TotalViscosity, const ProcessInfo &rCurrentProcessInfo)
Add the contribution from Smagorinsky model to the (kinematic) viscosity.
Definition: monolithic_dem_coupled_weak.h:1932
virtual ~MonolithicDEMCoupledWeak()
Destructor.
Definition: monolithic_dem_coupled_weak.h:231
virtual void CalculateOnIntegrationPoints(const Variable< array_1d< double, 3 > > &rVariable, std::vector< array_1d< double, 3 > > &rOutput, const ProcessInfo &rCurrentProcessInfo) override
Obtain an array_1d<double,3> elemental variable, evaluated on gauss points.
Geometry< NodeType >::PointsArrayType NodesArrayType
definition of nodes container type, redefined from GeometryType
Definition: monolithic_dem_coupled_weak.h:162
std::vector< std::size_t > EquationIdVectorType
Definition: monolithic_dem_coupled_weak.h:172
void CalculateWeights(ShapeFunctionDerivativesArrayType &rDN_DX, Matrix &rNContainer, Vector &rGaussWeights)
Determine integration point weights and shape funcition derivatives from the element's geometry.
KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(MonolithicDEMCoupledWeak)
Pointer definition of MonolithicDEMCoupledWeak.
virtual void GetDofList(DofsVectorType &rElementalDofList, const ProcessInfo &rCurrentProcessInfo) const override
Returns a list of the element's Dofs.
void AddProjectionResidualContribution(const array_1d< double, 3 > &rAdvVel, const double Density, array_1d< double, 3 > &rElementalMomRes, double &rElementalMassRes, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Assemble the contribution from an integration point to the element's residual.
Definition: monolithic_dem_coupled_weak.h:1773
double FilterWidth(const BoundedMatrix< double, TNumNodes, TDim > &DN_DX)
Return the filter width for the smagorinsky model (Delta squared)
double ElementSize(const double)
Return an estimate for the element size h, used to calculate the stabilization parameters.
virtual void Calculate(const Variable< double > &rVariable, double &rOutput, const ProcessInfo &rCurrentProcessInfo) override
Implementation of Calculate to compute an error estimate.
Definition: monolithic_dem_coupled_weak.h:667
virtual void CalculateLocalSystem(MatrixType &rLeftHandSideMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Provides local contributions from body forces and OSS projection terms.
Definition: monolithic_dem_coupled_weak.h:270
MonolithicDEMCoupledWeak(IndexType NewId, GeometryType::Pointer pGeometry)
Constructor using a geometry object.
Definition: monolithic_dem_coupled_weak.h:216
virtual void AddViscousTerm(MatrixType &rDampingMatrix, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Adds the contribution of the viscous term to the momentum equation.
double FilterWidth()
Return the filter width for the smagorinsky model (Delta squared)
Kratos::Vector ShapeFunctionsType
Type for shape function values container.
Definition: monolithic_dem_coupled_weak.h:180
void OSSMomResidual(const array_1d< double, 3 > &rAdvVel, const double Density, array_1d< double, 3 > &rElementalMomRes, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Assemble the contribution from an integration point to the element's residual.
Definition: monolithic_dem_coupled_weak.h:1882
void GetConvectionOperator(array_1d< double, TNumNodes > &rResult, const array_1d< double, 3 > &rVelocity, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv)
Write the convective operator evaluated at this point (for each nodal funciton) to an array.
Definition: monolithic_dem_coupled_weak.h:1996
MonolithicDEMCoupledWeak(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties)
Constuctor using geometry and properties.
Definition: monolithic_dem_coupled_weak.h:226
virtual void CalculateOnIntegrationPoints(const Variable< Vector > &rVariable, std::vector< Vector > &rValues, const ProcessInfo &rCurrentProcessInfo) override
Definition: monolithic_dem_coupled_weak.h:1040
virtual void AddPointContribution(array_1d< double, 3 > &rResult, const Variable< array_1d< double, 3 > > &rVariable, const array_1d< double, TNumNodes > &rShapeFunc, const double Weight=1.0)
Add the weighted value of a variable at a point inside the element to a vector.
Definition: monolithic_dem_coupled_weak.h:2103
void AddBTransCB(MatrixType &rDampingMatrix, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Adds the contribution of the viscous term to the momentum equation (alternate).
Definition: monolithic_dem_coupled_weak.h:2212
virtual void CalculateTau(double &TauOne, double &TauTwo, const array_1d< double, 3 > &rAdvVel, const double Area, const double Density, const double KinViscosity, const ProcessInfo &rCurrentProcessInfo)
Calculate Stabilization parameters.
Definition: monolithic_dem_coupled_weak.h:1175
void AddConsistentMassMatrixContribution(MatrixType &rLHSMatrix, const array_1d< double, TNumNodes > &rShapeFunc, const double Density, const double Weight)
Definition: monolithic_dem_coupled_weak.h:1405
virtual void CalculateLocalVelocityContribution(MatrixType &rDampingMatrix, VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Computes the local contribution associated to 'new' velocity and pressure values.
Definition: monolithic_dem_coupled_weak.h:525
Element::Pointer Create(IndexType NewId, NodesArrayType const &ThisNodes, PropertiesType::Pointer pProperties) const override
Create a new element of this type.
Definition: monolithic_dem_coupled_weak.h:252
virtual void Calculate(const Variable< array_1d< double, 3 > > &rVariable, array_1d< double, 3 > &rOutput, const ProcessInfo &rCurrentProcessInfo) override
Implementation of Calculate to compute the local OSS projections.
Definition: monolithic_dem_coupled_weak.h:754
virtual void CalculateC(BoundedMatrix< double,(TDim *TNumNodes)/2,(TDim *TNumNodes)/2 > &rC, const double Viscosity)
Calculate a matrix that provides the stress given the strain rate.
virtual void CalculateStaticTau(double &TauOne, const array_1d< double, 3 > &rAdvVel, const double Area, const double Density, const double KinViscosity)
Calculate momentum stabilization parameter (without time term).
Definition: monolithic_dem_coupled_weak.h:1238
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: monolithic_dem_coupled_weak.h:159
virtual int Check(const ProcessInfo &rCurrentProcessInfo) const override
Checks the input and that all required Kratos variables have been registered.
Definition: monolithic_dem_coupled_weak.h:1067
Node NodeType
definition of node type (default is: Node)
Definition: monolithic_dem_coupled_weak.h:150
void CalculateB(BoundedMatrix< double,(TDim *TNumNodes)/2, TDim *TNumNodes > &rB, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv)
Calculate the strain rate matrix.
double ConsistentMassCoef(const double Area)
double SymmetricGradientNorm(const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv)
Compute the norm of the symmetric gradient of velocity.
Definition: monolithic_dem_coupled_weak.h:2153
GeometryType::ShapeFunctionsGradientsType ShapeFunctionDerivativesArrayType
Type for an array of shape function gradient matrices.
Definition: monolithic_dem_coupled_weak.h:186
virtual void CalculateRightHandSide(VectorType &rRightHandSideVector, const ProcessInfo &rCurrentProcessInfo) override
Provides local contributions from body forces and projections to the RHS.
Definition: monolithic_dem_coupled_weak.h:311
virtual void AddMomentumRHS(VectorType &F, const double Density, const array_1d< double, TNumNodes > &rShapeFunc, const double Weight)
Add the momentum equation contribution to the RHS (body forces)
Definition: monolithic_dem_coupled_weak.h:1278
virtual void CalculateMassMatrix(MatrixType &rMassMatrix, const ProcessInfo &rCurrentProcessInfo) override
Computes local contributions to the mass matrix.
Definition: monolithic_dem_coupled_weak.h:424
virtual void AddProjectionToRHS(VectorType &RHS, const array_1d< double, 3 > &rAdvVel, const double Density, const double TauOne, const double TauTwo, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight, const double DeltaTime=1.0)
Add OSS projection terms to the RHS.
Definition: monolithic_dem_coupled_weak.h:1326
virtual void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: monolithic_dem_coupled_weak.h:1124
IndexedObject BaseType
base type: an IndexedObject that automatically has a unique number
Definition: monolithic_dem_coupled_weak.h:147
virtual void GetAdvectiveVel(array_1d< double, 3 > &rAdvVel, const array_1d< double, TNumNodes > &rShapeFunc)
Write the advective velocity evaluated at this point to an array.
Definition: monolithic_dem_coupled_weak.h:1961
void ASGSMomResidual(const array_1d< double, 3 > &rAdvVel, const double Density, array_1d< double, 3 > &rElementalMomRes, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Assemble the contribution from an integration point to the element's residual.
Definition: monolithic_dem_coupled_weak.h:1834
virtual void AddPointContribution(double &rResult, const Variable< double > &rVariable, const array_1d< double, TNumNodes > &rShapeFunc, const double Weight=1.0)
Add the weighted value of a variable at a point inside the element to a double.
Definition: monolithic_dem_coupled_weak.h:2022
virtual void CalculateOnIntegrationPoints(const Variable< double > &rVariable, std::vector< double > &rValues, const ProcessInfo &rCurrentProcessInfo) override
Obtain a double elemental variable, evaluated on gauss points.
Definition: monolithic_dem_coupled_weak.h:920
virtual void AddOtherContributionsRHS(VectorType &F, const array_1d< double, TNumNodes > &rShapeFunc, const std::vector< double > &TimeSchemeWeights, const double &DeltaTime)
Definition: monolithic_dem_coupled_weak.h:1301
virtual void CalculateLeftHandSide(MatrixType &rLeftHandSideMatrix, const ProcessInfo &rCurrentProcessInfo) override
Returns a zero matrix of appropiate size (provided for compatibility with scheme)
Definition: monolithic_dem_coupled_weak.h:291
void AddIntegrationPointVelocityContribution(MatrixType &rDampingMatrix, VectorType &rDampRHS, const double Density, const double Viscosity, const array_1d< double, 3 > &rAdvVel, const double TauOne, const double TauTwo, const array_1d< double, TNumNodes > &rShapeFunc, const BoundedMatrix< double, TNumNodes, TDim > &rShapeDeriv, const double Weight)
Add a the contribution from a single integration point to the velocity contribution.
Definition: monolithic_dem_coupled_weak.h:1516
Properties PropertiesType
Definition: monolithic_dem_coupled_weak.h:156
Kratos::Matrix ShapeFunctionDerivativesType
Type for a matrix containing the shape function gradients.
Definition: monolithic_dem_coupled_weak.h:183
virtual std::string Info() const override
Turn back information as a string.
Definition: monolithic_dem_coupled_weak.h:1116
virtual void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const override
Provides the global indices for each one of this element's local rows.
This class defines the node.
Definition: node.h:65
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
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
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
The serialization consists in storing the state of an object into a storage format like data file or ...
Definition: serializer.h:123
#define KRATOS_SERIALIZE_SAVE_BASE_CLASS(Serializer, BaseType)
Definition: define.h:812
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_SERIALIZE_LOAD_BASE_CLASS(Serializer, BaseType)
Definition: define.h:815
#define KRATOS_CHECK_DOF_IN_NODE(TheVariable, TheNode)
Definition: checks.h:176
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(TheVariable, TheNode)
Definition: checks.h:171
Modeler::Pointer Create(const std::string &ModelerName, Model &rModel, const Parameters ModelParameters)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:30
Parameters GetValue(Parameters &rParameters, const std::string &rEntry)
Definition: add_kratos_parameters_to_python.cpp:53
void CalculateB(const GeometricalObject &rElement, const TMatrixType1 &rDN_DX, TMatrixType2 &rB)
This method computes the deformation tensor B (for small deformation solid elements)
Definition: structural_mechanics_element_utilities.h:105
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
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
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
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
def SetValue(entity, variable, value)
Definition: coupling_interface_data.py:256
X2
Definition: generate_frictional_mortar_condition.py:120
X1
Definition: generate_frictional_mortar_condition.py:119
int C
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:27
def Index()
Definition: hdf5_io_tools.py:38
F
Definition: hinsberg_optimization.py:144
def load(f)
Definition: ode_solve.py:307
int L
Definition: ode_solve.py:390
int d
Definition: ode_solve.py:397
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
float sigma
Definition: rotating_cone.py:79
int m
Definition: run_marine_rain_substepping.py:8
J
Definition: sensitivityMatrix.py:58
N
Definition: sensitivityMatrix.py:29
K
Definition: sensitivityMatrix.py:73
B
Definition: sensitivityMatrix.py:76
integer i
Definition: TensorModule.f:17
integer l
Definition: TensorModule.f:17