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.
energy_utilities.h
Go to the documentation of this file.
1 //
2 // Project Name: KratosSolidMechanicsApplication $
3 // Created by: $Author: MSantasusana $
4 // Last modified by: $Co-Author: $
5 // Date: $Date: March 2015 $
6 // Revision: $Revision: 0.0 $
7 //
8 //
9 
10 
11 #if !defined(KRATOS_ENERGY_UTILITIES_H_INCLUDED)
12 #define KRATOS_ENERGY_UTILITIES_H_INCLUDED
13 
14 
15 // System includes
16 //#include <cmath>
17 //#include <set>
18 
19 // #ifdef _OPENMP
20 // #include <omp.h>
21 // #endif
22 
23 // External includes
24 //#include "boost/smart_ptr.hpp"
25 #include "utilities/timer.h"
26 
27 // Project includes
28 //#include "includes/define.h"
29 #include "includes/variables.h"
30 #include "includes/model_part.h"
31 #include "utilities/openmp_utils.h"
32 #include "utilities/math_utils.h"
34 
35 namespace Kratos
36 {
37 
39 
44  {
45  public:
46 
49 
52 
56 
58  EnergyUtilities(){ mEchoLevel = 0; mParallel = true; };
59 
60  EnergyUtilities(bool Parallel){ mEchoLevel = 0; mParallel = Parallel; };
61 
62 
64  virtual ~EnergyUtilities(){};
65 
66 
70 
71 
75 
76 
77  //**************************************************************************
78  //**************************************************************************
79 
80 
81  double GetTotalKinematicEnergy(ModelPart& rModelPart)
82  {
84 
85  double KinematicEnergy = 0.0;
86 
88  double mass = 0.0;
89  double vel_arg = 0.0;
90 
91  ModelPart::NodesContainerType& pNodes = rModelPart.Nodes();
92 
93  #ifdef _OPENMP
94  int number_of_threads = omp_get_max_threads();
95  #else
96  int number_of_threads = 1;
97  #endif
98 
99  if( mParallel == false ){ number_of_threads = 1; }
100 
101  vector<unsigned int> node_partition;
102  OpenMPUtils::CreatePartition(number_of_threads, pNodes.size(), node_partition);
103 
104  std::vector<double> KinematicEnergyPartition(number_of_threads);
105  for(int i=0; i<number_of_threads; i++){
106  KinematicEnergyPartition[i] = 0.0;
107  }
108 
109  #pragma omp parallel private (KinematicEnergy, vel, mass, vel_arg)
110  {
111  int k = OpenMPUtils::ThisThread();
112  ModelPart::NodesContainerType::iterator NodeBegin = pNodes.begin() + node_partition[k];
113  ModelPart::NodesContainerType::iterator NodeEnd = pNodes.begin() + node_partition[k + 1];
114 
115 
116  for (ModelPart::NodesContainerType::const_iterator in = NodeBegin; in != NodeEnd; in++){
117 
118  mass = in->FastGetSolutionStepValue(NODAL_MASS);
119  vel = in->FastGetSolutionStepValue(VELOCITY);
120  vel_arg = MathUtils<double>::Norm3(vel);
121  KinematicEnergyPartition[k] += 0.5*vel_arg*vel_arg*mass;
122  }
123  }
124 
125  for(int i=0; i<number_of_threads; i++){
126  KinematicEnergy += KinematicEnergyPartition[i];
127 
128  }
129 
130  return KinematicEnergy;
131 
132 
133  KRATOS_CATCH( "" )
134  }
135 
136 
137 
138  double GetGravitationalEnergy(ModelPart& rModelPart)
139  {
140  KRATOS_TRY
141 
142  double PotentialEnergy = 0.0;
143  double gh = 0.0;
144 
145 
146  array_1d<double, 3> coord;
147  double mass = 0.0;
148  Vector VolumeAcceleration(3);
149  noalias(VolumeAcceleration) = ZeroVector(3);
150 
151  ModelPart::NodesContainerType& pNodes = rModelPart.Nodes();
152 
153  #ifdef _OPENMP
154  int number_of_threads = omp_get_max_threads();
155  #else
156  int number_of_threads = 1;
157  #endif
158 
159  if( mParallel == false ){ number_of_threads = 1; }
160 
161  vector<unsigned int> node_partition;
162  OpenMPUtils::CreatePartition(number_of_threads, pNodes.size(), node_partition);
163 
164  std::vector<double> PotentialEnergyPartition(number_of_threads);
165  for(int i=0; i<number_of_threads; i++){
166  PotentialEnergyPartition[i] = 0.0;
167  }
168 
169  #pragma omp parallel private (gh, VolumeAcceleration, mass, coord)
170  {
171  int k = OpenMPUtils::ThisThread();
172  ModelPart::NodesContainerType::iterator NodeBegin = pNodes.begin() + node_partition[k];
173  ModelPart::NodesContainerType::iterator NodeEnd = pNodes.begin() + node_partition[k + 1];
174 
175 
176  for (ModelPart::NodesContainerType::const_iterator in = NodeBegin; in != NodeEnd; in++)
177  {
178 
179  mass = in->FastGetSolutionStepValue(NODAL_MASS);
180  coord = in->Coordinates();
181 
182  gh = 0.0;
183  VolumeAcceleration = in->FastGetSolutionStepValue(VOLUME_ACCELERATION); //if( in->SolutionStepsDataHas(VOLUME_ACCELERATION) ){ //MSI:: should be checked once at the beginning only
184 
185  for (unsigned int i=0;i<3;i++){
186  gh += coord(i)*-VolumeAcceleration(i); //negative makes gravity introduce positive potential energy
187  }
188 
189  PotentialEnergyPartition[k] += mass*gh;
190 
191  }
192  }
193 
194  for(int i=0; i<number_of_threads; i++){
195  PotentialEnergy += PotentialEnergyPartition[i];
196 
197  }
198 
199  return PotentialEnergy;
200 
201 
202  KRATOS_CATCH( "" )
203  }
204 
205 
206  //Total Energy on initial configuration
207  double GetTotalStrainEnergy(ModelPart& rModelPart)
208  {
209 
210  KRATOS_TRY
211 
212  double StrainEnergy = 0.0;
213  ProcessInfo& rCurrentProcessInfo = rModelPart.GetProcessInfo();
214 
215  ModelPart::ElementsContainerType& pElements = rModelPart.Elements();
216 
217  #ifdef _OPENMP
218  int number_of_threads = omp_get_max_threads();
219  #else
220  int number_of_threads = 1;
221  #endif
222 
223  if( mParallel == false ){ number_of_threads = 1; }
224 
225  vector<unsigned int> element_partition;
226  OpenMPUtils::CreatePartition(number_of_threads, pElements.size(), element_partition);
227  std::vector<double> StrainEnergyPartition(number_of_threads);
228  for(int i=0; i<number_of_threads; i++){
229  StrainEnergyPartition[i] = 0.0;
230  }
231 
232  #pragma omp parallel
233  {
234  int k = OpenMPUtils::ThisThread();
235  ModelPart::ElementsContainerType::iterator ElemBegin = pElements.begin() + element_partition[k];
236  ModelPart::ElementsContainerType::iterator ElemEnd = pElements.begin() + element_partition[k + 1];
237 
238  for(ModelPart::ElementsContainerType::const_iterator ie = ElemBegin; ie != ElemEnd; ie++)
239  {
240  const GeometryType::IntegrationMethod IntegrationMethod = ie->GetGeometry().GetDefaultIntegrationMethod();
241  const GeometryType::IntegrationPointsArrayType& integration_points = ie->GetGeometry().IntegrationPoints( IntegrationMethod );
242 
243  std::vector<double> rOutput;
244  ie->CalculateOnIntegrationPoints(STRAIN_ENERGY,rOutput,rCurrentProcessInfo );
245 
246  for ( unsigned int PointNumber = 0; PointNumber < integration_points.size(); PointNumber++ )
247  {
248 
249  StrainEnergyPartition[k] += rOutput[PointNumber];
250 
251  }
252 
253  }
254 
255  }
256 
257  for(int i=0; i<number_of_threads; i++){
258  StrainEnergy += StrainEnergyPartition[i];
259 
260  }
261 
262  if(StrainEnergy==0){
263  std::cout<<" [ NO_STRAIN_ENERGY] "<<std::endl;
264  }
265 
266  return StrainEnergy;
267 
268 
269  KRATOS_CATCH( "" )
270  }
271 
272 
273 
275  {
276  KRATOS_TRY
277 
278  //work done by conditions...
279 
280  return 0.0;
281  KRATOS_CATCH( "" )
282  }
283 
285  {
286 
287  KRATOS_TRY
288  #ifdef _OPENMP
289  int number_of_threads = omp_get_max_threads();
290  #else
291  int number_of_threads = 1;
292  #endif
293 
294  vector<unsigned int> node_partition;
295  OpenMPUtils::CreatePartition(number_of_threads, pNodes.size(), node_partition);
296 
297  vector<unsigned int> element_partition;
298  OpenMPUtils::CreatePartition(number_of_threads, pElements.size(), element_partition);
299 
300 
301  #pragma omp parallel
302  {
303 
304  #pragma omp for
305 
306  for(int k=0; k<number_of_threads; k++)
307  {
308  ModelPart::NodesContainerType::iterator i_begin=pNodes.ptr_begin()+node_partition[k];
309  ModelPart::NodesContainerType::iterator i_end=pNodes.ptr_begin()+node_partition[k+1];
310 
311  for(ModelPart::NodeIterator i=i_begin; i!= i_end; ++i)
312  {
313  double& nodal_mass = i->FastGetSolutionStepValue(NODAL_MASS);
314  nodal_mass = 0.0;
315  }
316  }
317 
318  }
319 
320  //Calculate and assemble Mass Matrix on nodes
321 
322  unsigned int index = 0;
323 
324  #pragma omp parallel
325  {
326  int k = OpenMPUtils::ThisThread();
327  ModelPart::ElementsContainerType::iterator ElemBegin = pElements.begin() + element_partition[k];
328  ModelPart::ElementsContainerType::iterator ElemEnd = pElements.begin() + element_partition[k + 1];
329 
330  for (ModelPart::ElementsContainerType::iterator itElem = ElemBegin; itElem != ElemEnd; itElem++) //MSI: To be parallelized
331  {
332  Matrix MassMatrix;
333 
334  Element::GeometryType& geometry = itElem->GetGeometry();
335 
336  (itElem)->CalculateMassMatrix(MassMatrix, rCurrentProcessInfo); //already lumped.
337 
338  const unsigned int dimension = geometry.WorkingSpaceDimension();
339 
340  index = 0;
341  for (unsigned int i = 0; i <geometry.size(); i++)
342  {
343  index = i*dimension;
344 
345  geometry(i)->SetLock();
346  double& mass = geometry(i)->FastGetSolutionStepValue(NODAL_MASS);
347  mass += MassMatrix(index,index);
348  geometry(i)->UnSetLock();
349  }
350  }
351  }
352 
353  KRATOS_CATCH( "" )
354 
355  } //CalculateNodalMass
356 
357 
358 
359  //**************************************************************************
360  //**************************************************************************
361 
365  virtual void SetEchoLevel(int Level)
366  {
367  mEchoLevel = Level;
368  }
369 
371  {
372  return mEchoLevel;
373  }
374 
378 
379 
383 
384 
388 
392 
393 
395 
396 
397  protected:
400 
401 
405 
406 
410 
411 
415 
416 
420 
421 
425 
426 
430 
431 
433  private:
436 
437 
441  int mEchoLevel;
442 
443  bool mParallel;
444 
448 
452 
453  //************************************************************************************
454  //************************************************************************************
455 
456 
460 
461 
465 
466 
470 
472 
473 
474  }; // Class EnergyUtilities
475 
479 
480 
484 
486 
487 } // namespace Kratos.
488 
489 #endif // KRATOS_ENERGY_UTILITIES_H_INCLUDED defined
490 
491 
Short class definition.
Definition: energy_utilities.h:44
ModelPart::ElementsContainerType ElementsContainerType
Definition: energy_utilities.h:50
double GetTotalKinematicEnergy(ModelPart &rModelPart)
Definition: energy_utilities.h:81
double GetGravitationalEnergy(ModelPart &rModelPart)
Definition: energy_utilities.h:138
void CalculateNodalMass(ModelPart::NodesContainerType &pNodes, ModelPart::ElementsContainerType &pElements, ProcessInfo &rCurrentProcessInfo)
Definition: energy_utilities.h:284
virtual void SetEchoLevel(int Level)
Definition: energy_utilities.h:365
virtual ~EnergyUtilities()
Destructor.
Definition: energy_utilities.h:64
EnergyUtilities()
Default constructor.
Definition: energy_utilities.h:58
int GetEchoLevel()
Definition: energy_utilities.h:370
double GetExternallyAppliedEnergy(ModelPart &rModelPart)
Definition: energy_utilities.h:274
double GetTotalStrainEnergy(ModelPart &rModelPart)
Definition: energy_utilities.h:207
EnergyUtilities(bool Parallel)
Definition: energy_utilities.h:60
ModelPart::MeshType::GeometryType GeometryType
Definition: energy_utilities.h:51
IntegrationMethod
Definition: geometry_data.h:76
Geometry base class.
Definition: geometry.h:71
SizeType size() const
Definition: geometry.h:518
std::vector< IntegrationPointType > IntegrationPointsArrayType
Definition: geometry.h:161
SizeType WorkingSpaceDimension() const
Definition: geometry.h:1287
static double Norm3(const TVectorType &a)
Calculates the norm of vector "a" which is assumed to be of size 3.
Definition: math_utils.h:691
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
MeshType::ElementsContainerType ElementsContainerType
Element container. A vector set of Elements with their Id's as key.
Definition: model_part.h:168
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
MeshType::NodeIterator NodeIterator
Definition: model_part.h:134
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
MeshType::NodesContainerType NodesContainerType
Nodes container. Which is a vector set of nodes with their Id's as key.
Definition: model_part.h:128
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
static int ThisThread()
Wrapper for omp_get_thread_num().
Definition: openmp_utils.h:108
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
vel
Definition: pure_conduction.py:76
int k
Definition: quadrature.py:595
integer i
Definition: TensorModule.f:17