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.
calculate_curvature.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main author: Alex Jarauta
11 // Co-author : Elaf Mahrous
12 
13 
14 #if !defined(CALCULATE_CURVATURE_INCLUDED )
15 #define CALCULATE_CURVATURE_INCLUDED
16 
17 
18 
19 // System includes
20 #include <string>
21 #include <iostream>
22 #include <algorithm>
23 
24 // External includes
25 
26 
27 // Project includes
28 #include <pybind11/pybind11.h>
29 #include "includes/define.h"
30 #include "includes/define_python.h"
31 
32 #include "includes/model_part.h"
33 #include "includes/node.h"
34 #include "utilities/math_utils.h"
35 #include "utilities/geometry_utilities.h"
36 #include "utilities/openmp_utils.h"
37 #include "processes/process.h"
38 #include "includes/condition.h"
39 #include "includes/element.h"
40 #include "ULF_application.h"
41 
42 
43 
44 
45 namespace Kratos
46 {
47 
50 
54 
55 
59 
63 
67 
69 
80  : public Process
81  {
82  public:
83 
86 
89 
93 
96  {
97  }
98 
101  {
102  }
103 
104 
108 
109  // void operator()()
110  // {
111  // MergeParts();
112  // }
113 
114 
118 
119  void CalculateCurvature2D(ModelPart& ThisModelPart)
120  {
121  KRATOS_TRY
122 
123  double theta_eq = ThisModelPart.GetProcessInfo()[CONTACT_ANGLE_STATIC];
124  double pi = 3.14159265359;
125  double theta_w = theta_eq*pi/180.0;
126  double x0,y0,x1,y1,x2,y2;
127  int neighnum = 0;
128 
129  for(ModelPart::NodesContainerType::iterator im = ThisModelPart.NodesBegin() ; im != ThisModelPart.NodesEnd() ; ++im)
130  {
131  if (im->FastGetSolutionStepValue(IS_INTERFACE) != 0.0 && im->FastGetSolutionStepValue(IS_LAGRANGIAN_INLET) < 1e-15)
132  {
133  GlobalPointersVector< Node >& neighb = im->GetValue(NEIGHBOUR_NODES);
134  x0 = im->X();
135  y0 = im->Y();
136  neighnum = 0;
137 
138  for (unsigned int i = 0; i < neighb.size(); i++)
139  {
140  if (neighb[i].FastGetSolutionStepValue(IS_INTERFACE) != 0.0 || neighb[i].FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
141  {
142  if (neighb[i].X() != x0 || neighb[i].Y() != y0)
143  {
144  if (neighnum == 0)
145  //if (neighnum < 1e-15)
146  {
147  x1 = neighb[i].X();
148  y1 = neighb[i].Y();
149  }
150  if (neighnum == 1)
151  {
152  x2 = neighb[i].X();
153  y2 = neighb[i].Y();
154  }
155  neighnum++;
156  }
157  }
158  }
159  double curv = CalculateCurv(x0,y0,x1,y1,x2,y2);
160 
161  // Sign of the curvature
162  double sign_curv = 1.0;
163  double xc = 0.5*(x1 + x2);
164  double yc = 0.5*(y1 + y2);
165  int curv_pos = 0;
166  int struct_nodes = 0;
167  GlobalPointersVector< Element >& neighb_els = im->GetValue(NEIGHBOUR_ELEMENTS);
168  for (unsigned int i = 0; i < neighb_els.size(); i++)
169  {
170  int intf_nodes = 0;
171  for (unsigned int j = 0; j < 3; j++)
172  {
173  if (neighb_els[i].GetGeometry()[j].FastGetSolutionStepValue(IS_INTERFACE) != 0.0 || neighb_els[i].GetGeometry()[j].FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
174  intf_nodes++;
175  if (neighb_els[i].GetGeometry()[j].FastGetSolutionStepValue(IS_STRUCTURE) != 0.0)
176  struct_nodes++;
177  }
178  if (intf_nodes > 0)
179  neighb_els[i].GetValue(IS_WATER_ELEMENT) = 1.0;
180  //Calculate N at (xc,yc)
181  double x0_loc = neighb_els[i].GetGeometry()[0].X();
182  double y0_loc = neighb_els[i].GetGeometry()[0].Y();
183  double x1_loc = neighb_els[i].GetGeometry()[1].X();
184  double y1_loc = neighb_els[i].GetGeometry()[1].Y();
185  double x2_loc = neighb_els[i].GetGeometry()[2].X();
186  double y2_loc = neighb_els[i].GetGeometry()[2].Y();
187 
188  double x10 = x1_loc - x0_loc;
189  double y10 = y1_loc - y0_loc;
190 
191  double x20 = x2_loc - x0_loc;
192  double y20 = y2_loc - y0_loc;
193 
194  double detJ = x10 * y20-y10 * x20;
195  double totArea=0.5*detJ;
196 
198  N[0] = CalculateVol(x1_loc,y1_loc,x2_loc,y2_loc,xc,yc) / totArea;
199  N[1] = CalculateVol(x2_loc,y2_loc,x0_loc,y0_loc,xc,yc) / totArea;
200  N[2] = CalculateVol(x0_loc,y0_loc,x1_loc,y1_loc,xc,yc) / totArea;
201 
202  double eps_sign = -0.00000001;
203  if (N[0] >= eps_sign && N[1] >= eps_sign && N[2] >= eps_sign)
204  {
205  if (neighb_els[i].GetValue(IS_WATER_ELEMENT) == 1.0)
206  {
207  curv_pos++;
208  }
209  }
210  }
211  if (curv_pos == 0)
212  //if (curv_pos < 1e-15)
213  {
214  sign_curv = -1.0;
215  }
216 
217  im->FastGetSolutionStepValue(MEAN_CURVATURE_2D) = sign_curv*curv;
218 
219  }
220 
221  //20140923 Computing curvature at the triple point!
222  // Curvature at triple point must be equal to the rate of change of normal vector,
223  // using neighbor IS_FREE_SURFACE and n = nw*cos_theta + tw*sin_theta
224  if (im->FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
225  {
226  x0 = im->X();
227  y0 = im->Y();
228  double sin_t = sin(theta_w+0.5*pi);
229  double cos_t = cos(theta_w+0.5*pi);
232  array_1d<double,2> struct_dist = ZeroVector(2);
233  double dist_struct = 0.0;
234  GlobalPointersVector< Node >& neighb = im->GetValue(NEIGHBOUR_NODES);
235  for (unsigned int i = 0; i < neighb.size(); i++)
236  {
237  if (neighb[i].FastGetSolutionStepValue(IS_INTERFACE) != 0.0)
238  {
239  x1 = neighb[i].X();
240  y1 = neighb[i].Y();
241  n1[0] = neighb[i].FastGetSolutionStepValue(NORMAL_X);
242  n1[1] = neighb[i].FastGetSolutionStepValue(NORMAL_Y);
243 // n0[1] = cos_t;
244  n0[1] = sin_t;
245  if (n1[0] > 0.0)
246  n0[0] = -cos_t;
247 // n0[0] = sin_t;
248  else
249  n0[0] = cos_t;
250 // n0[0] = -sin_t;
251  }
252  if (neighb[i].FastGetSolutionStepValue(IS_STRUCTURE) != 0.0)
253  {
254  x2 = neighb[i].X();
255  y2 = neighb[i].Y();
256  Vector2D(x0,y0,x2,y2,struct_dist);
257  dist_struct = Norm2D(struct_dist);
258  if (dist_struct < 1.0e-5)
259  neighb[i].Set(TO_ERASE,true);
260  }
261  }
262  array_1d<double,2> ds_vec = ZeroVector(2);
263  Vector2D(x0,y0,x1,y1,ds_vec);
264  double ds = Norm2D(ds_vec);
267  dT[0] = n1[0] - n0[0];
268  dT[1] = n1[1] - n0[1];
269  double dT_norm = Norm2D(dT);
270  double curv_tp = dT_norm/ds;
271  // There is no need to compute curvature's sign: at triple point it's always positive!
272  im->FastGetSolutionStepValue(MEAN_CURVATURE_2D) = curv_tp;
273  }
274 
275  if(im->FastGetSolutionStepValue(IS_STRUCTURE) != 0.0 && im->FastGetSolutionStepValue(TRIPLE_POINT)*1.0E8 == 0.0)
276  //if(im->FastGetSolutionStepValue(IS_STRUCTURE) != 0.0 && im->FastGetSolutionStepValue(TRIPLE_POINT)*1.0E8 < 1e-15)
277  im->FastGetSolutionStepValue(MEAN_CURVATURE_2D) = 0.0;
278  }
279 
280  KRATOS_CATCH("")
281  }
282 
283  void CalculateCurvature3D(ModelPart& ThisModelPart)
284  {
285  KRATOS_TRY
286 
287  double pi = 3.14159265;
288  double hpi = 0.5*pi;
289  for(ModelPart::NodesContainerType::iterator im = ThisModelPart.NodesBegin() ;
290  im != ThisModelPart.NodesEnd() ; ++im)
291  {
292  if (im->FastGetSolutionStepValue(FLAG_VARIABLE) > 0.999)// || im->FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
293  {
295  // For node i, you find all its neighbor conditions. This is a set of triangles (faces)
296  // around node i. All the nodes surrounding node i are its 1-ring neighborhood.
297  // For every face, the two adjacent nodes are nodes j and k -> A_voronoi is obtained in
298  // every triangle and added to the total area.
300 
301  double xi = im->X();
302  double yi = im->Y();
303  double zi = im->Z();
304  double xj = 0.0;
305  double yj = 0.0;
306  double zj = 0.0;
307  double xk = 0.0;
308  double yk = 0.0;
309  double zk = 0.0;
310 
316  double norm_ij = 0.0;
317  double norm_ik = 0.0;
318  double norm_jk = 0.0;
319  array_1d<double,3> cross_prod_ijk = ZeroVector(3);
320 
321  double area_ijk = 0.0;
322  double alfa_ij = 0.0;
323  double beta_ij = 0.0;
324  double theta_kij = 0.0;
325  double theta_sum = 0.0;
326 
327  int neighnum = 0;
328  double A_mixed = 0.0;
329  array_1d<double,3> K_xi = ZeroVector(3);
330  double Delta_xi = 0.0;
331  double Sp = 0.0;
332 
333  GlobalPointersVector< Condition >& neighb_faces = im->GetValue(NEIGHBOUR_CONDITIONS);
334  //Loop over faces -> 1-ring neighborhood
335  for (unsigned int i = 0; i < neighb_faces.size(); i++)
336  {
337  int num_flag_var = 0;
338  num_flag_var += neighb_faces[i].GetGeometry()[0].FastGetSolutionStepValue(FLAG_VARIABLE);
339  num_flag_var += neighb_faces[i].GetGeometry()[1].FastGetSolutionStepValue(FLAG_VARIABLE);
340  num_flag_var += neighb_faces[i].GetGeometry()[2].FastGetSolutionStepValue(FLAG_VARIABLE);
341  if (num_flag_var > 2.999)
342  {
343  neighnum = 0;
344  for (unsigned int j = 0; j < neighb_faces[i].GetGeometry().size() ; j++)
345  {
346  if (neighb_faces[i].GetGeometry()[j].X() != xi ||
347  neighb_faces[i].GetGeometry()[j].Y() != yi || neighb_faces[i].GetGeometry()[j].Z() != zi)
348  {
349  if (neighnum == 0)
350  // if (neighnum < 1e-15)
351  {
352  xj = neighb_faces[i].GetGeometry()[j].X();
353  yj = neighb_faces[i].GetGeometry()[j].Y();
354  zj = neighb_faces[i].GetGeometry()[j].Z();
355  }
356  else
357  {
358  xk = neighb_faces[i].GetGeometry()[j].X();
359  yk = neighb_faces[i].GetGeometry()[j].Y();
360  zk = neighb_faces[i].GetGeometry()[j].Z();
361  }
362  neighnum++;
363  }
364  }
365 
366  Vector3D(xi,yi,zi,xj,yj,zj,rij);
367  Vector3D(xj,yj,zj,xi,yi,zi,rji);
368  Vector3D(xi,yi,zi,xk,yk,zk,rik);
369  Vector3D(xk,yk,zk,xi,yi,zi,rki);
370  Vector3D(xj,yj,zj,xk,yk,zk,rjk);
371  norm_ij = Norm3D(rij);
372  norm_ik = Norm3D(rik);
373  norm_jk = Norm3D(rjk);
374  alfa_ij = Angle2vecs3D(rji,rjk);
375  theta_kij = Angle2vecs3D(rij,rik);
376  beta_ij = pi - alfa_ij - theta_kij;
377  CrossProduct3D(rij, rik, cross_prod_ijk);
378  area_ijk = 0.5*Norm3D(cross_prod_ijk);
379  if (alfa_ij > hpi || beta_ij > hpi || theta_kij > hpi)
380  {
381  //Obtuse triangle!
382  if (theta_kij > hpi)
383  A_mixed += 0.5*area_ijk*1000.0;
384  else
385  A_mixed += 0.25*area_ijk*1000.0;
386  }
387  else
388  {
389  A_mixed += 0.125*cotan(alfa_ij)*norm_ik*norm_ik*1000.0;
390  A_mixed += 0.125*cotan(beta_ij)*norm_ij*norm_ij*1000.0;
391  }
392  //Mean curvature normal operator:
393  K_xi[0] += (cotan(alfa_ij)*rki[0] + cotan(beta_ij)*rji[0])*1000.0;
394  K_xi[1] += (cotan(alfa_ij)*rki[1] + cotan(beta_ij)*rji[1])*1000.0;
395  K_xi[2] += (cotan(alfa_ij)*rki[2] + cotan(beta_ij)*rji[2])*1000.0;
396  //Sum of angles in node i for gaussian curvature
397  theta_sum += theta_kij;
398  Sp += (0.5*area_ijk - 0.125*tan(hpi - theta_kij)*norm_jk*norm_jk);
399  }
400  }
401  double A_mixed_norm = sqrt(A_mixed*A_mixed);
402  if(A_mixed_norm < 1e-10)
403  {
404  K_xi[0] = 0.0;
405  K_xi[1] = 0.0;
406  K_xi[2] = 0.0;
407  }
408  else
409  {
410  //Now we have A_voronoi for node i.
411  K_xi[0] = (0.5/A_mixed)*K_xi[0];
412  K_xi[1] = (0.5/A_mixed)*K_xi[1];
413  K_xi[2] = (0.5/A_mixed)*K_xi[2];
414  }
415 // KRATOS_WATCH(A_mixed)
416 // double normKxi = Norm3D(K_xi);
417  array_1d<double,3> K_xi_norm = ZeroVector(3);
418  K_xi_norm[0] = K_xi[0];
419  K_xi_norm[1] = K_xi[1];
420  K_xi_norm[2] = K_xi[2];
421  NormalizeVec3D(K_xi_norm);
422  im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_X) = K_xi_norm[0];
423  im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_Y) = K_xi_norm[1];
424  im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_Z) = K_xi_norm[2];
425 
426  //Final step: kappa_H and kappa_G (mean curvature kappa_H is half the magnitude (norm) of K_xi vector)
427  im->FastGetSolutionStepValue(MEAN_CURVATURE_3D) = Norm3D(K_xi);
428  im->FastGetSolutionStepValue(GAUSSIAN_CURVATURE) = (2*pi - theta_sum)/Sp;
429 
430  //Principal curvatures, taking care of square root term:
431  Delta_xi = ((im->FastGetSolutionStepValue(MEAN_CURVATURE_3D))*(im->FastGetSolutionStepValue(MEAN_CURVATURE_3D)) - im->FastGetSolutionStepValue(GAUSSIAN_CURVATURE));
432  if(Delta_xi > 0.0)
433  {
434  im->FastGetSolutionStepValue(PRINCIPAL_CURVATURE_1) = im->FastGetSolutionStepValue(MEAN_CURVATURE_3D) + sqrt(Delta_xi);
435  im->FastGetSolutionStepValue(PRINCIPAL_CURVATURE_2) = im->FastGetSolutionStepValue(MEAN_CURVATURE_3D) - sqrt(Delta_xi);
436  }
437  else
438  {
439  im->FastGetSolutionStepValue(PRINCIPAL_CURVATURE_1) = im->FastGetSolutionStepValue(MEAN_CURVATURE_3D);
440  im->FastGetSolutionStepValue(PRINCIPAL_CURVATURE_2) = im->FastGetSolutionStepValue(MEAN_CURVATURE_3D);
441  }
442 
443  A_mixed = 0.0;
444  theta_sum = 0.0;
445  }
446 
447  //Now we correct curvature at triple points
448  if (im->FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
449  {
450  double neigh_fs = 0.0;
451  double mean_curv = 0.0;
452  GlobalPointersVector< Node >& neighb = im->GetValue(NEIGHBOUR_NODES);
453  for (unsigned int i = 0; i < neighb.size(); i++)
454  {
455  if (neighb[i].FastGetSolutionStepValue(IS_FREE_SURFACE) != 0.0)
456  {
457  neigh_fs++;
458  mean_curv += neighb[i].FastGetSolutionStepValue(MEAN_CURVATURE_3D);
459  }
460  }
461  if(neigh_fs != 0.0)
462  im->FastGetSolutionStepValue(MEAN_CURVATURE_3D) = mean_curv/neigh_fs;
463  }
464 
465  if ((im->FastGetSolutionStepValue(IS_STRUCTURE) != 0.0) && (im->FastGetSolutionStepValue(TRIPLE_POINT) == 0.0))
466  // if ((im->FastGetSolutionStepValue(IS_STRUCTURE) != 0.0) && (im->FastGetSolutionStepValue(TRIPLE_POINT) < 1e-15))
467  im->FastGetSolutionStepValue(MEAN_CURVATURE_3D) = 0.0;
468  }
469  KRATOS_CATCH("")
470  }
471 
473  {
474  KRATOS_TRY
475 
476  for(ModelPart::NodesContainerType::iterator im = ThisModelPart.NodesBegin() ;
477  im != ThisModelPart.NodesEnd() ; ++im)
478  {
479  if (im->FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
480  {
481  double xi = im->X();
482  double yi = im->Y();
483  double xj = 0.0;
484  double yj = 0.0;
485  double xk = 0.0;
486  double yk = 0.0;
487 
488  int neighnum = 0;
489  GlobalPointersVector< Node >& neighb = im->GetValue(NEIGHBOUR_NODES);
490  for (unsigned int i = 0; i < neighb.size(); i++)
491  {
492  if (neighb[i].FastGetSolutionStepValue(TRIPLE_POINT) != 0.0)
493  {
494  if (neighnum == 0)
495  //if (neighnum < 1e-15)
496  {
497  xj = neighb[i].X();
498  yj = neighb[i].Y();
499  }
500  else
501  {
502  xk = neighb[i].X();
503  yk = neighb[i].Y();
504  }
505  neighnum++;
506  }
507  }
508 
509  double curv = CalculateCurv(xi,yi,xj,yj,xk,yk);
510  if (neighnum > 2)
511  curv = 0.0;
512 
513  // Sign of the curvature
514  double sign_curv = 1.0;
515  double xc = 0.5*(xj + xk);
516  double yc = 0.5*(yj + yk);
518 
519  Vector2D(xi,yi,xc,yc,ric);
520 
522  ni[0] = im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_X);
523  ni[1] = im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_Y);
524  double alfa = DotProduct2D(ric,ni);
525 
526  if (alfa > 0.0)
527  sign_curv = -1.0;
528 
529  im->FastGetSolutionStepValue(MEAN_CURVATURE_2D) = sign_curv*curv;
530  }
531  }
532 
533  KRATOS_CATCH("")
534  }
535 
536 
538  {
539  KRATOS_TRY
540 
541  for(ModelPart::NodesContainerType::iterator im = ThisModelPart.NodesBegin() ;
542  im != ThisModelPart.NodesEnd() ; ++im)
543  {
544  if (im->FastGetSolutionStepValue(IS_FREE_SURFACE) != 0.0)
545  {
547  // THERE IS A FUNCTION CALLED "FIND_NODAL_NEIGHBOURS_SURFACE_PROCESS" THAT THEORETICALLY
548  // CAN OBTAIN NEIGHBOUR_NODES FROM NODES AT SURFACE. Now, for every node i in the surface,
549  // we found its tangent plane and we take first neighbour j to compute rij -> first basis vector
550  // Second basis vector is obtained by CrossProduct3D(n,rij)
551  // Then we solve system 2x2 to find coordinates of rij expressed in base (u,v). Next step
552  // is to solve 3x3 system of least squares and we obtain matrix B = (a b ; b c)
553  // Find eigenvectors using analytical solution, normalize them and these are principal directions!
555 
556  double xi = im->X();
557  double yi = im->Y();
558  double zi = im->Z();
559  double xj = 0.0;
560  double yj = 0.0;
561  double zj = 0.0;
562  double alfa = 0.0;
563  double beta = 0.0;
564  double kappaN_ij = 0.0;
565  //double M = 0.0;
566  //double N = 0.0;
567  //double L = 0.0;
568  array_1d<double,6> terms_func = ZeroVector(6);
569  array_1d<double,10> terms_func_der = ZeroVector(10);
570  GlobalPointersVector< Node >& neighb = im->GetValue(NEIGHBOUR_NODES);
572 
573  double kappa_H = im->FastGetSolutionStepValue(MEAN_CURVATURE_3D);
574  double kappa_G = im->FastGetSolutionStepValue(GAUSSIAN_CURVATURE);
575 
576  int option = 2; //choose 1 if you want to consider a + b = 2*kappa_H, choose 2 if a + c = 2*kappa_H
577 
578 // boost::numeric::ublas::bounded_matrix<double, 3, 3> LHSmat = ZeroMatrix(3,3);
579 // array_1d<double,3> RHSvec = ZeroVector(3);
580  boost::numeric::ublas::bounded_matrix<double, 2, 2> LHSmat = ZeroMatrix(2,2);
581  array_1d<double,2> RHSvec = ZeroVector(2);
582  boost::numeric::ublas::bounded_matrix<double, 2, 2> B = ZeroMatrix(2,2);
583 
584  //STEP 1: find (u,v) basis of tangent plane at node i
585  //Coordinates to create vector u (basis vector of tangent plane)
586  double xu = neighb[0].X();
587  double yu = neighb[0].Y();
588  double zu = neighb[0].Z();
589  array_1d<double,3> u_vec = ZeroVector(3);
590  array_1d<double,3> v_vec = ZeroVector(3);
591  array_1d<double,3> n_vec = ZeroVector(3);
592  array_1d<double,2> eigen1 = ZeroVector(2);
593  array_1d<double,2> eigen2 = ZeroVector(2);
594  array_1d<double,3> eigen1_xyz = ZeroVector(3);
595  array_1d<double,3> eigen2_xyz = ZeroVector(3);
596 
597  n_vec[0] = im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_X);
598  n_vec[1] = im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_Y);
599  n_vec[2] = im->FastGetSolutionStepValue(NORMAL_GEOMETRIC_Z);
600 
601  Vector3D(xi,yi,zi,xu,yu,zu,u_vec);
602  FindUnitTangent3D(u_vec,n_vec);
603 
604  //The other basis vector v is just cross product between n and u
605  CrossProduct3D(n_vec,u_vec,v_vec);
606  NormalizeVec3D(v_vec);
607 
608  //STEP 2: For each neighbour node, find components of dij in base (u,v) and add term to system matrix
609  int num_neighbs = 0;
610  for (unsigned j = 0; j < neighb.size(); j++)
611  {
612  num_neighbs++;
613  }
614 
615  for (unsigned j = 0; j < neighb.size(); j++)
616  {
617 
618  double xj;
619  double yj;
620  double zj;
621  //first find unit tanjent of edge i-j
622  xj = neighb[j].X();
623  yj = neighb[j].Y();
624  zj = neighb[j].Z();
625  Vector3D(xi,yi,zi,xj,yj,zj,dij);
626  FindUnitTangent3D(dij, n_vec);
627 
628  //now find components in (u,v) base
629  FindComponentsUV(alfa,beta,dij,u_vec,v_vec);
630 
631  //terms are added to global system matrix and RHSvec
632  kappaN_ij = NormalCurvature3D(xi,yi,zi,xj,yj,zj,n_vec);
633 // AddTermsToSys(kappaN_ij,kappa_H,alfa,beta,num_neighbs,LHSmat,RHSvec,option); //Includes versions depending on option below
634 // AddTermsToEq(kappaN_ij,kappa_H,alfa,beta,num_neighbs,M,N,L);
635  AddTermsToEq2(kappaN_ij,kappa_H,alfa,beta,num_neighbs,terms_func,terms_func_der);
636  }
637 
638  double a = 0.0;
639  double b = 0.0;
640  double c = 0.0;
641 
642  //STEP 3: global system matrix is full. Now we solve the system
643  if(option == 1)
644  {
645  //OPTION 1.1 - Meyer is right AND consider just first condition
646  SolveSys2x2(b,c,LHSmat,RHSvec);
647  a = 2.0*kappa_H - c;
648  }
649  else
650  {
651  //OPTION 2.1 - consider just first condition
652 // SolveSys3x3(a,b,c,LHSmat,RHSvec);
653 // SolveSys2x2(a,b,LHSmat,RHSvec);
654 // c = 2.0*kappa_H - a;
655 // b = sqrt(a*(2.0*kappa_H - a) - kappa_G);
656  //OPTION 2.2 - consider both conditions
657  NewtonMethod(terms_func,terms_func_der,a,kappa_H,kappa_G,kappaN_ij);
658  c = 2.0*kappa_H - a;
659  b = sqrt(a*(2.0*kappa_H - a) - kappa_G);
660  }
661 
662  //Regardless option choice, fill the curvature tensor
663  B(0,0) = a;
664  B(1,0) = b;
665  B(0,1) = b;
666  B(1,1) = c;
667  KRATOS_WATCH(option)
668  KRATOS_WATCH(a)
669  KRATOS_WATCH(b)
670  KRATOS_WATCH(c)
671 
672  double cond_sum = 0.0;
673  double cond_prod = a*c - b*b;
674  double eps_cond = 1e-5;
675  if (option == 1)
676  cond_sum = 0.5*(a + b);
677  else
678  cond_sum = 0.5*(a + c);
679  if ((cond_sum - kappa_H) > eps_cond || cond_prod != kappa_G)
680  {
681  KRATOS_WATCH("Not fulfilling this condition!!!!!!!!!!!!!!!!")
682  KRATOS_WATCH(cond_prod)
683  KRATOS_WATCH(kappa_G)
684  }
685 
686  //STEP 4: find eigenvectors of matrix B
687  double T = a + c;
688  double D = a*c - b*b;
689 
690  double lambda_1 = 0.5*T + sqrt(0.25*T*T - D);
691  double lambda_2 = 0.5*T - sqrt(0.25*T*T - D);
692 
693  if (b != 0.0)
694  {
695 // eigen1[0] = lambda_1 - c;
696 // eigen1[1] = b;
697 // eigen2[0] = lambda_2 - c;
698 // eigen2[1] = b;
699  //OR:
700  eigen1[0] = b;
701  eigen1[1] = lambda_1 - a;
702  eigen2[0] = b;
703  eigen2[1] = lambda_2 - a;
704  }
705  else
706  {
707  KRATOS_WATCH("b is zero")
708  eigen1[0] = 1.0;
709  eigen1[1] = 0.0;
710  eigen2[0] = 0.0;
711  eigen2[1] = 1.0;
712  }
713 
714  //Watch out! Eigenvectors are expressed in terms of base (u,v) -> transform to (x,y,z)
715  eigen1_xyz[0] = eigen1[0]*u_vec[0] + eigen1[1]*v_vec[0];
716  eigen1_xyz[1] = eigen1[0]*u_vec[1] + eigen1[1]*v_vec[1];
717  eigen1_xyz[2] = eigen1[0]*u_vec[2] + eigen1[1]*v_vec[2];
718  eigen2_xyz[0] = eigen2[0]*u_vec[0] + eigen2[1]*v_vec[0];
719  eigen2_xyz[1] = eigen2[0]*u_vec[1] + eigen2[1]*v_vec[1];
720  eigen2_xyz[2] = eigen2[0]*u_vec[2] + eigen2[1]*v_vec[2];
721  NormalizeVec3D(eigen1_xyz);
722  NormalizeVec3D(eigen2_xyz);
723  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_1_X) = eigen1_xyz[0];
724  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_1_Y) = eigen1_xyz[1];
725  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_1_Z) = eigen1_xyz[2];
726  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_2_X) = eigen2_xyz[0];
727  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_2_Y) = eigen2_xyz[1];
728  im->FastGetSolutionStepValue(PRINCIPAL_DIRECTION_2_Z) = eigen2_xyz[2];
729  }
730  }
731  KRATOS_CATCH("")
732  }
733 
734  double CalculateVol(const double x0, const double y0, const double x1, const double y1, const double x2, const double y2)
735  {
736  return 0.5*( (x1-x0)*(y2-y0)- (y1-y0)*(x2-x0) );
737  }
738 
739  double CalculateCurv(const double x0, const double y0, const double x1, const double y1, const double x2, const double y2)
740  {
742  array_1d<double,2> r20 = ZeroVector(2);
743  Vector2D(x1,y1,x0,y0,r01);
744  Vector2D(x0,y0,x2,y2,r20);
745  double norm01 = Norm2D(r01);
746  double norm20 = Norm2D(r20);
747  NormalizeVec2D(r01);
748  NormalizeVec2D(r20);
749  array_1d<double,2> r_diff = r01 - r20;
750  double norm_diff = Norm2D(r_diff);
751  return 2.0*norm_diff/(norm01 + norm20);
752  }
753 
754  void IsObtuse(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1,
755  const double x2, const double y2, const double z2, bool& isobt, bool& isobt_i, double& alfa)
756  {
760  Vector3D(x0,y0,z0,x1,y1,z1,r01);
761  Vector3D(x0,y0,z0,x2,y2,z2,r02);
762  Vector3D(x1,y1,z1,x2,y2,z2,r12);
763 
764  double hpi = 3.14159265*0.5;
765  double alfa0 = 0.0; //angle at node 0
766  double alfa1 = 0.0; //angle at node 1
767  double alfa2 = 0.0; //angle at node 2
768 
769  alfa0 = Angle2vecs3D(r01,r02);
770  r01[0] = -r01[0];
771  r01[1] = -r01[1];
772  r01[2] = -r01[2];
773  alfa1 = Angle2vecs3D(r01,r12); //minus sign because alfa1 is formed by vectors r10 and r12
774  alfa2 = Angle2vecs3D(r02,r12);
775 
776  alfa = alfa2;
777 
778  if (alfa0 > hpi || alfa1 > hpi || alfa2 > hpi)
779  isobt = true;
780  if (alfa0 > hpi)
781  isobt_i = true;
782  }
783 
784  void Vector2D(const double x0, const double y0, const double x1, const double y1, array_1d<double,2>& r01)
785  {
786  r01[0] = x1 - x0;
787  r01[1] = y1 - y0;
788  }
789 
790  void Vector3D(const double x0, const double y0, const double z0,
791  const double x1, const double y1, const double z1, array_1d<double,3>& r01)
792  {
793  r01[0] = x1 - x0;
794  r01[1] = y1 - y0;
795  r01[2] = z1 - z0;
796  }
797 
798  double Norm2D(const array_1d<double,2>& a)
799  {
800  return sqrt(a[0]*a[0] + a[1]*a[1]);
801  }
802 
803  double Norm3D(const array_1d<double,3>& a)
804  {
805  return sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
806  }
807 
809  {
810  return (a[0]*b[0] + a[1]*b[1]);
811  }
812 
814  {
815  return (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
816  }
817 
819  {
820  c[0] = a[1]*b[2] - a[2]*b[1];
821  c[1] = a[2]*b[0] - a[0]*b[2];
822  c[2] = a[0]*b[1] - a[1]*b[0];
823  }
824 
826  {
827  double norm_a = Norm2D(a);
828  double norm_b = Norm2D(b);
829  double temp = 0.0;
830  if (norm_a*norm_b > -1.0e-20 && norm_a*norm_b < 1.0e-20)
831  temp = 0.0;
832  else
833  temp = DotProduct2D(a,b)/(norm_a*norm_b);
834  return acos(temp);
835  }
836 
838  {
839  double norm_a = Norm3D(a);
840  double norm_b = Norm3D(b);
841  double temp = 0.0;
842 // if (norm_a*norm_b > -1.0e-20 && norm_a*norm_b < 1.0e-20)
843  if (norm_a*norm_b == 0.0)
844  //if (norm_a*norm_b < 1e-15)
845  temp = 0.0;
846  else
847  temp = DotProduct3D(a,b)/(norm_a*norm_b);
848  return acos(temp);
849  }
850 
851  double cotan(const double& alfa)
852  {
853  return cos(alfa)/sin(alfa);
854  }
855 
856  double NormalCurvature3D(const double xi, const double yi, const double zi,
857  const double xj, const double yj, const double zj, array_1d<double,3>& n)
858  {
859  double kappaN_ij = 0.0;
861  Vector3D(xj,yj,zj,xi,yi,zi,rji);
862  double norm_rji = Norm3D(rji);
863 
864  kappaN_ij = DotProduct3D(rji,n);
865  kappaN_ij = 2*kappaN_ij/(norm_rji*norm_rji);
866  return kappaN_ij;
867  }
868 
870  {
871  double dotprod = DotProduct3D(u_vec,n_vec);
872  u_vec[0] = (u_vec[0] - dotprod*n_vec[0]);
873  u_vec[1] = (u_vec[1] - dotprod*n_vec[1]);
874  u_vec[2] = (u_vec[2] - dotprod*n_vec[2]);
875  double norm_uvec = Norm3D(u_vec);
876  u_vec[0] /= norm_uvec;
877  u_vec[1] /= norm_uvec;
878  u_vec[2] /= norm_uvec;
879  }
880 
881  void FindComponentsUV(double& alfa, double& beta, array_1d<double,3>& dij, array_1d<double,3>& u_vec, array_1d<double,3>& v_vec)
882  {
883  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_syst;
884  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_dx;
885  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_dy;
886  int num_case = 0;
887  mat_syst(0,0) = u_vec[0];
888  mat_syst(1,0) = u_vec[1];
889  mat_syst(0,1) = v_vec[0];
890  mat_syst(1,1) = v_vec[1];
891  double det_matsys = Det2x2(mat_syst);
892  if (det_matsys*det_matsys < 0.00000001)
893  {
894  mat_syst(1,0) = u_vec[2];
895  mat_syst(1,1) = v_vec[2];
896  det_matsys = Det2x2(mat_syst);
897  num_case++;
898  if (det_matsys*det_matsys < 0.00000001)
899  {
900  mat_syst(0,0) = u_vec[1];
901  mat_syst(0,1) = v_vec[1];
902  num_case++;
903  }
904  }
905 
906  if (num_case == 0)
907  //if (num_case < 1e-15)
908  {
909  mat_dx(0,0) = dij[0];
910  mat_dx(1,0) = dij[1];
911  mat_dx(0,1) = v_vec[0];
912  mat_dx(1,1) = v_vec[1];
913  mat_dy(0,0) = u_vec[0];
914  mat_dy(1,0) = u_vec[1];
915  mat_dy(0,1) = dij[0];
916  mat_dy(1,1) = dij[1];
917  }
918  if (num_case == 1)
919  {
920  mat_dx(0,0) = dij[0];
921  mat_dx(1,0) = dij[2];
922  mat_dx(0,1) = v_vec[0];
923  mat_dx(1,1) = v_vec[2];
924  mat_dy(0,0) = u_vec[0];
925  mat_dy(1,0) = u_vec[2];
926  mat_dy(0,1) = dij[0];
927  mat_dy(1,1) = dij[2];
928  }
929  else
930  {
931  mat_dx(0,0) = dij[1];
932  mat_dx(1,0) = dij[2];
933  mat_dx(0,1) = v_vec[1];
934  mat_dx(1,1) = v_vec[2];
935  mat_dy(0,0) = u_vec[1];
936  mat_dy(1,0) = u_vec[2];
937  mat_dy(0,1) = dij[1];
938  mat_dy(1,1) = dij[2];
939  }
940 
941  double det_matdx = Det2x2(mat_dx);
942  double det_matdy = Det2x2(mat_dy);
943 
944  alfa = det_matdx/det_matsys;
945  beta = det_matdy/det_matsys;
946  }
947 
948  void SolveSys2x2(double& a, double& b,boost::numeric::ublas::bounded_matrix<double, 2, 2>& LHSmat,
949  array_1d<double,2>& RHSvec)
950  {
951  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_syst = ZeroMatrix(2,2);
952  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_dx = ZeroMatrix(2,2);
953  boost::numeric::ublas::bounded_matrix<double, 2, 2> mat_dy = ZeroMatrix(2,2);
954 
955  CopyMatrix2x2(LHSmat,mat_syst);
956  CopyMatrix2x2(LHSmat,mat_dx);
957  CopyMatrix2x2(LHSmat,mat_dy);
958  double det_matsys = Det2x2(mat_syst);
959  if (det_matsys > -0.000000001 && det_matsys < 0.000000001)
960  det_matsys = 0.000000001;
961 
962  mat_dx(0,0) = RHSvec[0];
963  mat_dx(1,0) = RHSvec[1];
964  mat_dy(0,1) = RHSvec[0];
965  mat_dy(1,1) = RHSvec[1];
966 
967  double det_matdx = Det2x2(mat_dx);
968  double det_matdy = Det2x2(mat_dy);
969 
970  a = det_matdx/det_matsys;
971  b = det_matdy/det_matsys;
972  }
973 
974  void SolveSys3x3(double& a, double& b, double& c,boost::numeric::ublas::bounded_matrix<double, 3, 3>& LHSmat,
975  array_1d<double,3>& RHSvec)
976  {
977  boost::numeric::ublas::bounded_matrix<double, 3, 3> mat_syst = ZeroMatrix(3,3);
978  boost::numeric::ublas::bounded_matrix<double, 3, 3> mat_dx = ZeroMatrix(3,3);
979  boost::numeric::ublas::bounded_matrix<double, 3, 3> mat_dy = ZeroMatrix(3,3);
980  boost::numeric::ublas::bounded_matrix<double, 3, 3> mat_dz = ZeroMatrix(3,3);
981 
982  CopyMatrix3x3(LHSmat,mat_syst);
983  CopyMatrix3x3(LHSmat,mat_dx);
984  CopyMatrix3x3(LHSmat,mat_dy);
985  CopyMatrix3x3(LHSmat,mat_dz);
986  double det_matsys = Det3x3(mat_syst);
987 
988  mat_dx(0,0) = RHSvec[0];
989  mat_dx(1,0) = RHSvec[1];
990  mat_dx(2,0) = RHSvec[2];
991  mat_dy(0,1) = RHSvec[0];
992  mat_dy(1,1) = RHSvec[1];
993  mat_dy(2,1) = RHSvec[2];
994  mat_dz(0,2) = RHSvec[0];
995  mat_dz(1,2) = RHSvec[1];
996  mat_dz(2,2) = RHSvec[2];
997 
998  double det_matdx = Det3x3(mat_dx);
999  double det_matdy = Det3x3(mat_dy);
1000  double det_matdz = Det3x3(mat_dz);
1001 
1002  a = det_matdx/det_matsys;
1003  b = det_matdy/det_matsys;
1004  c = det_matdz/det_matsys;
1005  }
1006 
1007 // void AddTermsToSys(double& kappaN_ij, double& alfa, double& beta, int& num_neighbs,
1008 // boost::numeric::ublas::bounded_matrix<double, 3, 3>& LHSmat, array_1d<double,3>& RHSvec)
1009  void AddTermsToSys(double& kappaN_ij, double& kappa_H, double& alfa, double& beta, int& num_neighbs,
1010  boost::numeric::ublas::bounded_matrix<double, 2, 2>& LHSmat, array_1d<double,2>& RHSvec, const int& option)
1011  {
1012  double weight = 1.0/num_neighbs;
1013  /*
1014  LHSmat(0,0) += weight*alfa*alfa*alfa*alfa;
1015  LHSmat(1,0) += weight*alfa*alfa*alfa*beta;
1016  LHSmat(2,0) += weight*alfa*alfa*beta*beta;
1017  LHSmat(0,1) += 2.0*weight*alfa*alfa*alfa*beta;
1018  LHSmat(1,1) += 2.0*weight*alfa*alfa*beta*beta;
1019  LHSmat(2,1) += 2.0*weight*alfa*beta*beta*beta;
1020  LHSmat(0,2) += weight*alfa*alfa*beta*beta;
1021  LHSmat(1,2) += weight*alfa*beta*beta*beta;
1022  LHSmat(2,2) += weight*beta*beta*beta*beta;
1023  RHSvec[0] += weight*kappaN_ij*alfa*alfa;
1024  RHSvec[1] += weight*kappaN_ij*alfa*beta;
1025  RHSvec[2] += weight*kappaN_ij*beta*beta;
1026  */
1027  /*
1028  LHSmat(0,0) += weight*(alfa*alfa - 2.0*alfa*beta)*(alfa*alfa - 2.0*alfa*beta);
1029  LHSmat(0,1) += weight*(alfa*alfa - 2.0*alfa*beta)*beta*beta;
1030  LHSmat(1,0) += weight*(alfa*alfa - 2.0*alfa*beta)*beta*beta;
1031  LHSmat(1,1) += weight*beta*beta*beta*beta;
1032  RHSvec[0] += weight*(kappaN_ij - 4.0*kappa_H*alfa*beta)*(alfa*alfa - 2.0*alfa*beta);
1033  RHSvec[1] += weight*(kappaN_ij - 4.0*kappa_H*alfa*beta)*beta*beta;
1034  */
1035  if(option == 1)
1036  {
1037  //OPTION 1.1 - Meyer is right
1038  LHSmat(0,0) += weight*(-alfa*alfa - 2.0*alfa*beta)*(-alfa*alfa - 2.0*alfa*beta);
1039  LHSmat(0,1) += weight*beta*beta*(-alfa*alfa - 2.0*alfa*beta);
1040  LHSmat(1,0) += weight*(-alfa*alfa - 2.0*alfa*beta)*beta*beta;
1041  LHSmat(1,1) += weight*beta*beta*beta*beta;
1042  RHSvec[0] += weight*(kappaN_ij - 2.0*kappa_H*alfa*alfa)*(-alfa*alfa - 2.0*alfa*beta);
1043  RHSvec[1] += weight*(kappaN_ij - 2.0*kappa_H*alfa*alfa)*beta*beta;
1044  }
1045  else
1046  {
1047  //OPTION 2.1 - Meyer is wrong
1048  LHSmat(0,0) += weight*(alfa*alfa - beta*beta)*(alfa*alfa - beta*beta);
1049  LHSmat(0,1) += 2.0*weight*alfa*beta*(alfa*alfa - beta*beta);
1050  LHSmat(1,0) += weight*alfa*beta*(alfa*alfa - beta*beta);
1051  LHSmat(1,1) += 2.0*weight*alfa*alfa*beta*beta;
1052  RHSvec[0] += weight*(kappaN_ij - 2.0*kappa_H*beta*beta)*(alfa*alfa - beta*beta);
1053  RHSvec[1] += weight*(kappaN_ij - 2.0*kappa_H*beta*beta)*alfa*beta;
1054  }
1055  }
1056  /*
1057  void AddTermsToEq(double& kappaN_ij, double& kappa_H, double& alfa, double& beta, int& num_neighbs,
1058  double& term_1, double& term_2, double& term_3, double& term_4, double& term_5, double& term_6)
1059  {
1060  double weight = 1.0/num_neighbs;
1061  M += weight*(alfa*alfa - beta*beta);
1062  N += weight*2.0*alfa*beta;
1063  L += weight*(kappaN_ij - 2.0*beta*beta*kappa_H);
1064  }
1065  */
1066  void AddTermsToEq2(double& kappaN_ij, double& kappa_H, double& alfa, double& beta, int& num_neighbs,
1067  array_1d<double,6>& terms_vec, array_1d<double,10>& terms_vec_der)
1068  {
1069  double weight = 1.0/num_neighbs;
1070  terms_vec[0] += weight*(alfa*alfa - beta*beta)*(alfa*alfa - beta*beta);
1071  terms_vec[1] += weight*alfa*beta*(alfa*alfa - beta*beta);
1072  terms_vec[2] += 2.0*weight*alfa*beta*(alfa*alfa - beta*beta);
1073  terms_vec[3] += 2.0*weight*alfa*alfa*beta*beta;
1074  terms_vec[4] += weight*(2.0*kappa_H*beta*beta - kappaN_ij)*(alfa*alfa - beta*beta);
1075  terms_vec[5] += weight*weight*(2.0*kappa_H*beta*beta - kappaN_ij)*alfa*beta;
1076 
1077  terms_vec_der[0] += weight*(alfa*alfa - beta*beta)*(alfa*alfa - beta*beta);
1078  terms_vec_der[1] += weight*(alfa*alfa - beta*beta)*(alfa*alfa - beta*beta);
1079  terms_vec_der[2] += 2.0*weight*alfa*beta*(alfa*alfa - beta*beta);
1080  terms_vec_der[3] += weight*alfa*beta*(alfa*alfa - beta*beta);
1081  terms_vec_der[4] += 0.5*weight*alfa*beta*(alfa*alfa - beta*beta);
1082  terms_vec_der[5] += 3.0*weight*alfa*beta*(alfa*alfa - beta*beta);
1083  terms_vec_der[6] += 4.0*weight*alfa*alfa*beta*beta;
1084  terms_vec_der[7] += 2.0*weight*alfa*alfa*beta*beta;
1085  terms_vec_der[8] += 0.5*weight*(2.0*kappa_H*beta*beta - kappaN_ij)*(alfa*alfa - beta*beta)*(alfa*alfa - beta*beta);
1086  terms_vec_der[9] += 2.0*weight*(2.0*kappa_H*beta*beta - kappaN_ij)*alfa*beta;
1087  }
1088 
1089  void SolveEq2ndDeg(double& A, double& B, double& C, double& a)
1090  {
1091  a = (-B - sqrt(B*B - 4.0*A*C))/(2.0*A);
1092  }
1093 
1094  void NewtonMethod(array_1d<double,6>& terms_vec, array_1d<double,10>& terms_vec_der, double& a,
1095  double& kappa_H, double& kappa_G, double& kappaN_ij)
1096  {
1097  double x0 = 1.0; //initial guess
1098  double x1 = 0.0; //next guess or solution
1099  double fx = 0.0; //function
1100  double dfx = 0.0; //function derivative
1101  double tol = 1.0e-7; //tolerance for the solution
1102  double epsi = 1.0e-10; //minimum value of function derivative
1103  unsigned int MaxIter = 20; //maximum number of iterations
1104  bool foundsol = false; //solution has been found
1105  for(unsigned int i = 0; i < MaxIter; i++)
1106  {
1107 
1108  double fx = 0.0;
1109  double dfx = 0.0;
1110 
1111  fx = func_Newton(x0,terms_vec,kappa_H,kappa_G,kappaN_ij);
1112  dfx = dxfunc_Newton(x0,terms_vec_der,kappa_H,kappa_G,kappaN_ij);
1113  if (abs(dfx) < epsi)
1114  x0 += 1.0;
1115  else
1116  x1 = x0 - fx/dfx;
1117 
1118  if(abs(x1-x0)/abs(x0) < tol)
1119  foundsol = true;
1120 
1121  x1 = x0;
1122  }
1123  if (foundsol == false)
1124  KRATOS_WATCH("did not converge!!!!!!!!!!!!!!!!!!!")
1125  }
1126 
1127  double func_Newton(double& x, array_1d<double,6>& terms_vec, double& kappa_H, double& kappa_G, double& kappaN_ij)
1128  {
1129  double f_x;
1130  f_x = terms_vec[0]*x*f_a(x,kappa_H,kappa_G) + terms_vec[1]*2.0*(kappa_H - x)*x*sqrt(f_a(x,kappa_H,kappa_G)) +
1131  terms_vec[2]*f_a(x,kappa_H,kappa_G)*sqrt(f_a(x,kappa_H,kappa_G)) + terms_vec[3]*f_a(x,kappa_H,kappa_G) +
1132  terms_vec[4]*sqrt(f_a(x,kappa_H,kappa_G)) + terms_vec[5]*2.0*(kappa_H - a);
1133  return f_x;
1134  }
1135 
1136  double dxfunc_Newton(double& x, array_1d<double,10>& tvder, double& kappa_H, double& kappa_G, double& kappaN_ij)
1137  {
1138  double df_x;
1139  df_x = tvder[0]*f_a(x,kappa_H,kappa_G) + tvder[1]*x*df_a(x,kappa_H) - tvder[2]*x*sqrt(f_a(x,kappa_H,kappa_G)) +
1140  tvder[3]*2.0*(kappa_H - x)*sqrt(f_a(x,kappa_H,kappa_G)) +
1141  tvder[4]*2.0*(kappa_H - x)*x*0.5*df_a(x,kappa_H)/sqrt(f_a(x,kappa_H,kappa_G)) +
1142  tvder[5]*df_a(x,kappa_H)*sqrt(f_a(x,kappa_H,kappa_G)) + tvder[6]*f_a(x,kappa_H,kappa_G) +
1143  tvder[7]*2.0*(kappa_H - x)*df_a(x,kappa_H) + tvder[8]*sqrt(f_a(x,kappa_H,kappa_G))*df_a(x,kappa_H) - tvder[9];
1144  return df_x;
1145  }
1146 
1147  double f_a(double& x, double& kappa_H, double& kappa_G)
1148  {
1149  return (x*(2.0*kappa_H - x) - kappa_G);
1150  }
1151 
1152  double df_a(double& x, double& kappa_H)
1153  {
1154  return (2.0*(kappa_H - x));
1155  }
1156 
1157  double Det2x2(boost::numeric::ublas::bounded_matrix<double, 2, 2>& input)
1158  {
1159  return (input(0,0)*input(1,1) - input(0,1)*input(1,0));
1160  }
1161 
1162  double Det3x3(boost::numeric::ublas::bounded_matrix<double, 3, 3>& input)
1163  {
1164  return (input(0,0)*input(1,1) - input(0,1)*input(1,0));
1165  }
1166 
1168  {
1169  double norm = Norm2D(input);
1170  if (norm != 0.0)
1171  {
1172  input[0] /= norm;
1173  input[1] /= norm;
1174  }
1175  }
1176 
1178  {
1179  double norm = Norm3D(input);
1180  if (norm != 0.0)
1181  {
1182  input[0] /= norm;
1183  input[1] /= norm;
1184  input[2] /= norm;
1185  }
1186  }
1187 
1188  void CopyMatrix3x3(boost::numeric::ublas::bounded_matrix<double, 3, 3>& input,
1189  boost::numeric::ublas::bounded_matrix<double, 3, 3>& output)
1190  {
1191  for (unsigned int i = 0; i < 3; i++)
1192  {
1193  for (unsigned int j = 0; j < 3; j++)
1194  {
1195  output(i,j) = input(i,j);
1196  }
1197  }
1198  }
1199 
1200  void CopyMatrix2x2(boost::numeric::ublas::bounded_matrix<double, 2, 2>& input,
1201  boost::numeric::ublas::bounded_matrix<double, 2, 2>& output)
1202  {
1203  for (unsigned int i = 0; i < 2; i++)
1204  {
1205  for (unsigned int j = 0; j < 2; j++)
1206  {
1207  output(i,j) = input(i,j);
1208  }
1209  }
1210  }
1211 
1212  bool GetNeighbours(array_1d<double,2> n_node,GlobalPointersVector< Node >& neighb,double& x1,double& y1,double& x2,double& y2, int& i_neck, int& neighnum)
1213  {
1214  bool neck = false;
1215  double theta = 0.0;
1216  array_1d<double,2> n_vec;
1217  for (unsigned int i = 0; i < neighb.size(); i++)
1218  {
1219  n_vec = neighb[i].FastGetSolutionStepValue(NORMAL);
1220  if (neighb[i].FastGetSolutionStepValue(IS_FREE_SURFACE) != 0.0)// || neighb[i].FastGetSolutionStepValue(TRIPLE_POINT) != 0.0 || neighb[i].FastGetSolutionStepValue(IS_STRUCTURE) != 0.0)
1221  {
1222  theta = Angle2vecs2D(n_node,n_vec);
1223  if (theta > 2.8 || theta < -2.8)
1224  {
1225  i_neck = i;
1226  neck = true;
1227  }
1228  else
1229  {
1230  if (neighnum == 0)
1231  //if (neighnum < 1e-15)
1232  {
1233  x1 = neighb[i].X();
1234  y1 = neighb[i].Y();
1235  }
1236  if (neighnum == 1)
1237  {
1238  x2 = neighb[i].X();
1239  y2 = neighb[i].Y();
1240  }
1241  neighnum++;
1242  }
1243  }
1244  }
1245  return neck;
1246  }
1247 
1251 
1252 
1256 
1257 
1261 
1263  virtual std::string Info() const
1264  {
1265  return "CalculateCurvature";
1266  }
1267 
1269  virtual void PrintInfo(std::ostream& rOStream) const
1270  {
1271  rOStream << "CalculateCurvature";
1272  }
1273 
1275  virtual void PrintData(std::ostream& rOStream) const
1276  {
1277  }
1278 
1279 
1283 
1284 
1286 
1287 protected:
1290 
1291 
1295 
1296 
1300 
1301 
1305 
1306 
1310 
1311 
1315 
1316 
1320 
1321 
1323 
1324 private:
1327 
1328 
1332 
1333 
1337 
1338 
1342 
1343 
1347 
1348 
1352 
1353 
1357 
1359 // CalculateCurvature& operator=(CalculateCurvature const& rOther);
1360 
1362 // CalculateCurvature(CalculateCurvature const& rOther);
1363 
1364 
1366 
1367 }; // Class CalculateCurvature
1368 
1370 
1373 
1374 
1378 
1379 
1381 inline std::istream& operator >> (std::istream& rIStream,
1382  CalculateCurvature& rThis);
1383 
1385 inline std::ostream& operator << (std::ostream& rOStream,
1386  const CalculateCurvature& rThis)
1387 {
1388  rThis.PrintInfo(rOStream);
1389  rOStream << std::endl;
1390  rThis.PrintData(rOStream);
1391 
1392  return rOStream;
1393 }
1395 
1396 
1397 
1398 } // namespace Kratos.
1399 
1400 
1401 #endif // KRATOS_CREATE_INTERFACE_CONDITIONS_PROCESS_INCLUDED defined
1402 
1403 
Short class definition.
Definition: calculate_curvature.h:81
void FindUnitTangent3D(array_1d< double, 3 > &u_vec, array_1d< double, 3 > &n_vec)
Definition: calculate_curvature.h:869
void IsObtuse(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, const double x2, const double y2, const double z2, bool &isobt, bool &isobt_i, double &alfa)
Definition: calculate_curvature.h:754
bool GetNeighbours(array_1d< double, 2 > n_node, GlobalPointersVector< Node > &neighb, double &x1, double &y1, double &x2, double &y2, int &i_neck, int &neighnum)
Definition: calculate_curvature.h:1212
double Angle2vecs2D(const array_1d< double, 2 > &a, const array_1d< double, 2 > &b)
Definition: calculate_curvature.h:825
void NormalizeVec2D(array_1d< double, 2 > &input)
Definition: calculate_curvature.h:1167
void SolveSys2x2(double &a, double &b, boost::numeric::ublas::bounded_matrix< double, 2, 2 > &LHSmat, array_1d< double, 2 > &RHSvec)
Definition: calculate_curvature.h:948
void CalculatePrincipalDirections3D(ModelPart &ThisModelPart)
Definition: calculate_curvature.h:537
void FindComponentsUV(double &alfa, double &beta, array_1d< double, 3 > &dij, array_1d< double, 3 > &u_vec, array_1d< double, 3 > &v_vec)
Definition: calculate_curvature.h:881
double DotProduct2D(const array_1d< double, 2 > &a, const array_1d< double, 2 > &b)
Definition: calculate_curvature.h:808
void CalculateCurvature3D(ModelPart &ThisModelPart)
Definition: calculate_curvature.h:283
void SolveEq2ndDeg(double &A, double &B, double &C, double &a)
Definition: calculate_curvature.h:1089
void AddTermsToSys(double &kappaN_ij, double &kappa_H, double &alfa, double &beta, int &num_neighbs, boost::numeric::ublas::bounded_matrix< double, 2, 2 > &LHSmat, array_1d< double, 2 > &RHSvec, const int &option)
Definition: calculate_curvature.h:1009
void NormalizeVec3D(array_1d< double, 3 > &input)
Definition: calculate_curvature.h:1177
double Det3x3(boost::numeric::ublas::bounded_matrix< double, 3, 3 > &input)
Definition: calculate_curvature.h:1162
void AddTermsToEq2(double &kappaN_ij, double &kappa_H, double &alfa, double &beta, int &num_neighbs, array_1d< double, 6 > &terms_vec, array_1d< double, 10 > &terms_vec_der)
Definition: calculate_curvature.h:1066
void SolveSys3x3(double &a, double &b, double &c, boost::numeric::ublas::bounded_matrix< double, 3, 3 > &LHSmat, array_1d< double, 3 > &RHSvec)
Definition: calculate_curvature.h:974
double Det2x2(boost::numeric::ublas::bounded_matrix< double, 2, 2 > &input)
Definition: calculate_curvature.h:1157
virtual void PrintInfo(std::ostream &rOStream) const
Print information about this object.
Definition: calculate_curvature.h:1269
double Angle2vecs3D(const array_1d< double, 3 > &a, const array_1d< double, 3 > &b)
Definition: calculate_curvature.h:837
void CopyMatrix2x2(boost::numeric::ublas::bounded_matrix< double, 2, 2 > &input, boost::numeric::ublas::bounded_matrix< double, 2, 2 > &output)
Definition: calculate_curvature.h:1200
CalculateCurvature()
Default constructor.
Definition: calculate_curvature.h:95
virtual std::string Info() const
Turn back information as a string.
Definition: calculate_curvature.h:1263
void NewtonMethod(array_1d< double, 6 > &terms_vec, array_1d< double, 10 > &terms_vec_der, double &a, double &kappa_H, double &kappa_G, double &kappaN_ij)
Definition: calculate_curvature.h:1094
void CrossProduct3D(const array_1d< double, 3 > &a, const array_1d< double, 3 > &b, array_1d< double, 3 > &c)
Definition: calculate_curvature.h:818
double cotan(const double &alfa)
Definition: calculate_curvature.h:851
void CopyMatrix3x3(boost::numeric::ublas::bounded_matrix< double, 3, 3 > &input, boost::numeric::ublas::bounded_matrix< double, 3, 3 > &output)
Definition: calculate_curvature.h:1188
virtual void PrintData(std::ostream &rOStream) const
Print object's data.
Definition: calculate_curvature.h:1275
void CalculateCurvature2D(ModelPart &ThisModelPart)
Definition: calculate_curvature.h:119
double f_a(double &x, double &kappa_H, double &kappa_G)
Definition: calculate_curvature.h:1147
double Norm2D(const array_1d< double, 2 > &a)
Definition: calculate_curvature.h:798
double Norm3D(const array_1d< double, 3 > &a)
Definition: calculate_curvature.h:803
double CalculateCurv(const double x0, const double y0, const double x1, const double y1, const double x2, const double y2)
Definition: calculate_curvature.h:739
virtual ~CalculateCurvature()
Destructor.
Definition: calculate_curvature.h:100
double df_a(double &x, double &kappa_H)
Definition: calculate_curvature.h:1152
double dxfunc_Newton(double &x, array_1d< double, 10 > &tvder, double &kappa_H, double &kappa_G, double &kappaN_ij)
Definition: calculate_curvature.h:1136
void Vector2D(const double x0, const double y0, const double x1, const double y1, array_1d< double, 2 > &r01)
Definition: calculate_curvature.h:784
void CalculateCurvatureContactLine(ModelPart &ThisModelPart)
Definition: calculate_curvature.h:472
double NormalCurvature3D(const double xi, const double yi, const double zi, const double xj, const double yj, const double zj, array_1d< double, 3 > &n)
Definition: calculate_curvature.h:856
KRATOS_CLASS_POINTER_DEFINITION(CalculateCurvature)
Pointer definition of PushStructureProcess.
double DotProduct3D(const array_1d< double, 3 > &a, const array_1d< double, 3 > &b)
Definition: calculate_curvature.h:813
double CalculateVol(const double x0, const double y0, const double x1, const double y1, const double x2, const double y2)
Definition: calculate_curvature.h:734
double func_Newton(double &x, array_1d< double, 6 > &terms_vec, double &kappa_H, double &kappa_G, double &kappaN_ij)
Definition: calculate_curvature.h:1127
void Vector3D(const double x0, const double y0, const double z0, const double x1, const double y1, const double z1, array_1d< double, 3 > &r01)
Definition: calculate_curvature.h:790
This class is a vector which stores global pointers.
Definition: global_pointers_vector.h:61
size_type size() const
Definition: global_pointers_vector.h:307
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
NodeIterator NodesEnd(IndexType ThisIndex=0)
Definition: model_part.h:497
The base class for all processes in Kratos.
Definition: process.h:49
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_WATCH(variable)
Definition: define.h:806
#define KRATOS_TRY
Definition: define.h:109
im
Definition: GenerateCN.py:100
Parameters GetValue(Parameters &rParameters, const std::string &rEntry)
Definition: add_kratos_parameters_to_python.cpp:53
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
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
output
Definition: generate_frictional_mortar_condition.py:444
input
Definition: generate_frictional_mortar_condition.py:435
x2
Definition: generate_frictional_mortar_condition.py:122
x1
Definition: generate_frictional_mortar_condition.py:121
int C
Definition: generate_hyper_elastic_simo_taylor_neo_hookean.py:27
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
int tol
Definition: hinsberg_optimization.py:138
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int j
Definition: quadrature.py:648
n1
Definition: read_stl.py:18
float temp
Definition: rotating_cone.py:85
float xc
Definition: rotating_cone.py:77
float yc
Definition: rotating_cone.py:78
A
Definition: sensitivityMatrix.py:70
N
Definition: sensitivityMatrix.py:29
x
Definition: sensitivityMatrix.py:49
B
Definition: sensitivityMatrix.py:76
integer i
Definition: TensorModule.f:17
double precision, public pi
Definition: TensorModule.f:16
e
Definition: run_cpp_mpi_tests.py:31