LifeV
RBFlocallyRescaledVectorial.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief A short description of the file content
30 
31  @author Davide Forti <forti@mathicsepc48.epfl.ch>
32  @date 14 Mar 2013
33 
34  A more detailed description of the file (if necessary)
35  */
36 
37 #ifndef RBFLOCALLYRESCALEDVECTORIAL_H
38 #define RBFLOCALLYRESCALEDVECTORIAL_H 1
39 
40 #include <lifev/core/interpolation/RBFInterpolation.hpp>
41 
42 namespace LifeV {
43 
44 template <typename mesh_Type>
46 {
47 public:
48 
50 
51  typedef VectorEpetra vector_Type;
53 
54  typedef MatrixEpetra<double> matrix_Type;
56 
57  typedef std::vector<int> flagContainer_Type;
58 
60 
63 
64  typedef GhostHandler<mesh_Type> neighboring_Type;
66 
67  typedef LifeV::Preconditioner basePrec_Type;
69 
70  typedef LifeV::PreconditionerIfpack prec_Type;
72 
74 
76 
77  virtual ~RBFlocallyRescaledVectorial();
78 
79  void setup ( meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags );
80 
81  void setupRBFData (vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList);
82 
83  void buildOperators();
84 
85  void interpolationOperator();
86 
87  void projectionOperator();
88 
89  void buildRhs();
90 
92 
93  void identifyNodes (meshPtr_Type LocalMesh, std::set<ID>& GID_nodes, vectorPtr_Type CheckVector);
94 
95  bool isInside (ID pointMarker, flagContainer_Type Flags);
96 
97  double computeRBFradius (meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID);
98 
99  double rbf (double x1, double y1, double z1, double x2, double y2, double z2, double radius);
100 
101  void interpolate();
102 
103  void solution (vectorPtr_Type& Solution);
104 
105  void solutionrbf (vectorPtr_Type& Solution_rbf);
106 
107  void updateRhs(const vectorPtr_Type& newRhs);
108 
109  void getInterpolationOperatorMap ( mapPtr_Type& map ) { map.reset(new map_Type(*M_interpolationOperatorMap) ); };
110 
111  void getprojectionOperatorMap (mapPtr_Type& map) { map.reset(new map_Type(*M_projectionOperatorMap)); };
112 
114 
115  // Methods added after changing the maps
116 
117  void buildKnownInterfaceMap();
118 
120 
122 
124 
125  void getKnownInterfaceMap(mapPtr_Type& map){ map.reset ( new map_Type(*M_knownInterfaceMap) ); };
126 
127  void getNumerationInterfaceKnown(vectorPtr_Type& vector){ vector.reset ( new vector_Type ( *M_numerationInterfaceKnown ) ); };
128 
129  void getSolutionOnGamma (vectorPtr_Type& GammaSolution) { GammaSolution.reset(new vector_Type ( *M_solutionOnGamma ) ); };
130 
131  void expandGammaToOmega_Known(const vectorPtr_Type& vectorOnGamma, vectorPtr_Type& vectorOnOmega);
132 
133  void restrictOmegaToGamma_Known(const vectorPtr_Type& vectorOnOmega, vectorPtr_Type& vectorOnGamma);
134 
135  void getVectorialInterpolationMap ( mapPtr_Type& map ) { map.reset ( new map_Type(*M_interpolationOperatorMapVectorial) ); };
136 
137 private:
138 
163 
166 
170 
171  // Added for maps
172 
179  int M_pid;
180 };
181 
182 template <typename mesh_Type>
184 {}
185 
186 template <typename mesh_Type>
188 {}
189 
190 template <typename mesh_Type>
191 void RBFlocallyRescaledVectorial<mesh_Type>::setup ( meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags )
192 {
193  M_fullMeshKnown = fullMeshKnown;
194  M_localMeshKnown = localMeshKnown;
195  M_fullMeshUnknown = fullMeshUnknown;
196  M_localMeshUnknown = localMeshUnknown;
197  M_flags = flags;
198 }
199 
200 template <typename mesh_Type>
201 void RBFlocallyRescaledVectorial<mesh_Type>::setupRBFData (vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList)
202 {
203  M_knownField.reset( new vector_Type ( *KnownField ) );
204  M_unknownField.reset( new vector_Type ( *UnknownField ) );
205  M_datafile = datafile;
206  M_belosList = belosList;
207  M_links = M_datafile("interpolation/n_links",1);
208 }
209 
210 template <typename Mesh>
212 {
213  this->interpolationOperator();
214  this->projectionOperator();
215  this->buildRhs();
216  this->interpolateCostantField();
217 }
218 
219 template <typename Mesh>
221 {
222  std::vector<int> dofKnown;
223  dofKnown.reserve ( M_GIdsKnownMesh.size() );
224 
225  std::set<ID>::const_iterator i;
226 
227  for (UInt dim = 0; dim < nDimensions; ++dim)
228  for ( i = M_GIdsKnownMesh.begin(); i != M_GIdsKnownMesh.end(); ++i )
229  {
230  dofKnown.push_back ( *i + dim * M_knownField->size()/nDimensions );
231  }
232 
233  int* pointerToDofs (0);
234  if (dofKnown.size() > 0)
235  {
236  pointerToDofs = &dofKnown[0];
237  }
238 
239  M_knownInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofKnown.size() ), pointerToDofs, M_knownField->mapPtr()->commPtr() ) );
240 }
241 
242 template <typename Mesh>
244 {
245  std::vector<int> dofUnknown;
246  dofUnknown.reserve ( M_GIdsUnknownMesh.size() );
247 
248  std::set<ID>::const_iterator i;
249 
250  for (UInt dim = 0; dim < nDimensions; ++dim)
251  for ( i = M_GIdsUnknownMesh.begin(); i != M_GIdsUnknownMesh.end(); ++i )
252  {
253  dofUnknown.push_back ( *i + dim * M_unknownField->size()/nDimensions );
254  }
255 
256  int* pointerToDofs (0);
257  if (dofUnknown.size() > 0)
258  {
259  pointerToDofs = &dofUnknown[0];
260  }
261 
262  M_unknownInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofUnknown.size() ), pointerToDofs, M_unknownField->mapPtr()->commPtr() ) );
263 }
264 
265 template <typename Mesh>
267 {
268  std::set<ID>::const_iterator ITrow;
269 
270  Int numtasks = M_knownField->mapPtr()->commPtr()->NumProc(); // Numero di processi
271  int* numInterfaceDof (new int[numtasks]); // vettore lungo tanti quanti sono i processi
272  int pid = M_knownField->mapPtr()->commPtr()->MyPID(); // ID processo
273  M_pid = pid;
274  int numMyElements;
275 
276  numMyElements = M_knownInterfaceMap->map (Unique)->NumMyElements(); // numero di elementi sul processo
277  numInterfaceDof[pid] = numMyElements; // Ogni processore mette nella propria posizione il numero di elementi di interfaccia che ha
278 
279  mapPtr_Type subMap;
280  subMap.reset ( new map_Type ( *M_knownInterfaceMap->map (Unique), (UInt) 0, M_knownField->size()/nDimensions) );
281 
282  M_numerationInterfaceKnown.reset (new VectorEpetra (*subMap, Unique) );
283 
284  for (int j = 0; j < numtasks; ++j)
285  {
286  M_knownField->mapPtr()->commPtr()->Broadcast ( &numInterfaceDof[j], 1, j);
287  }
288 
289  for (int j = numtasks - 1; j > 0 ; --j)
290  {
291  numInterfaceDof[j] = numInterfaceDof[j - 1];
292  }
293  numInterfaceDof[0] = 0;
294  for (int j = 1; j < numtasks ; ++j)
295  {
296  numInterfaceDof[j] += numInterfaceDof[j - 1];
297  }
298 
299  UInt l = 0;
300 
301  Real M_interface = (UInt) M_knownInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions; // Quanti dof ci sono nella mappa scalare di interfaccia
302  for (l = 0, ITrow = M_GIdsKnownMesh.begin(); ITrow != M_GIdsKnownMesh.end() ; ++ITrow)
303  {
304  if (M_knownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
305  {
306  (*M_numerationInterfaceKnown) [*ITrow ] = l + (int) (numInterfaceDof[pid] / nDimensions);
307  if ( (int) (*M_numerationInterfaceKnown) (*ITrow ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
308  {
309  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
310  }
311  ++l;
312  }
313  }
314 
315  M_numerationInterfaceKnownColumns.resize(numtasks);
316 
317  for (int j = 0; j < numtasks ; ++j)
318  (M_numerationInterfaceKnownColumns[j]).reset(new vector_Type ( *M_numerationInterfaceKnown, j ) );
319 
320  std::vector<int> couplingVector;
321  couplingVector.reserve ( (int) (M_knownInterfaceMap->map (Unique)->NumMyElements() ) );
322 
323  for ( ITrow = M_GIdsKnownMesh.begin(); ITrow != M_GIdsKnownMesh.end() ; ++ITrow)
324  {
325  if (M_knownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
326  {
327  couplingVector.push_back ( (*M_numerationInterfaceKnown) (*ITrow ) );
328  }
329  }
330 
331  M_interpolationOperatorMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_knownField->mapPtr()->commPtr() ) );
332 
333  M_interpolationOperatorMapVectorial.reset ( new MapEpetra ( *M_interpolationOperatorMap ) );
334  *M_interpolationOperatorMapVectorial += *M_interpolationOperatorMap;
335  *M_interpolationOperatorMapVectorial += *M_interpolationOperatorMap;
336 
337  delete [] numInterfaceDof;
338 }
339 
340 template <typename Mesh>
342 {
343  std::set<ID>::const_iterator ITrow;
344 
345  Int numtasks = M_unknownField->mapPtr()->commPtr()->NumProc(); // Numero di processi
346  int* numInterfaceDof (new int[numtasks]); // vettore lungo tanti quanti sono i processi
347  int pid = M_unknownField->mapPtr()->commPtr()->MyPID(); // ID processo
348  int numMyElements;
349 
350  numMyElements = M_unknownInterfaceMap->map (Unique)->NumMyElements(); // numero di elementi sul processo
351  numInterfaceDof[pid] = numMyElements; // Ogni processore mette nella propria posizione il numero di elementi di interfaccia che ha
352 
353  mapPtr_Type subMap;
354  subMap.reset ( new map_Type ( *M_unknownInterfaceMap->map (Unique), (UInt) 0, M_unknownField->size()/nDimensions) );
355 
356  M_numerationInterfaceUnknown.reset (new VectorEpetra (*subMap, Unique) );
357 
358  for (int j = 0; j < numtasks; ++j)
359  {
360  M_unknownField->mapPtr()->commPtr()->Broadcast ( &numInterfaceDof[j], 1, j);
361  }
362 
363  for (int j = numtasks - 1; j > 0 ; --j)
364  {
365  numInterfaceDof[j] = numInterfaceDof[j - 1];
366  }
367  numInterfaceDof[0] = 0;
368  for (int j = 1; j < numtasks ; ++j)
369  {
370  numInterfaceDof[j] += numInterfaceDof[j - 1];
371  }
372 
373  UInt l = 0;
374 
375  Real M_interface = (UInt) M_unknownInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions; // Quanti dof ci sono nella mappa scalare di interfaccia
376  for (l = 0, ITrow = M_GIdsUnknownMesh.begin(); ITrow != M_GIdsUnknownMesh.end() ; ++ITrow)
377  {
378  if (M_unknownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
379  {
380  (*M_numerationInterfaceUnknown) [*ITrow ] = l + (int) (numInterfaceDof[pid] / nDimensions);
381  if ( (int) (*M_numerationInterfaceUnknown) (*ITrow ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
382  {
383  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
384  }
385  ++l;
386  }
387  }
388 
389  std::vector<int> couplingVector;
390  couplingVector.reserve ( (int) (M_unknownInterfaceMap->map (Unique)->NumMyElements() ) );
391 
392  for ( ITrow = M_GIdsUnknownMesh.begin(); ITrow != M_GIdsUnknownMesh.end() ; ++ITrow)
393  {
394  if (M_unknownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
395  {
396  couplingVector.push_back ( (*M_numerationInterfaceUnknown) (*ITrow ) );
397  }
398  }
399 
400  M_projectionOperatorMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_unknownField->mapPtr()->commPtr() ) );
401 
402  M_projectionOperatorMapVectorial.reset ( new MapEpetra ( *M_projectionOperatorMap ) );
403  *M_projectionOperatorMapVectorial += *M_projectionOperatorMap;
404  *M_projectionOperatorMapVectorial += *M_projectionOperatorMap;
405 
406  delete [] numInterfaceDof;
407 }
408 
409 template <typename Mesh>
411 {
412  // Identifying dofs to be taken into account
413  this->identifyNodes (M_localMeshKnown, M_GIdsKnownMesh, M_knownField);
414 
415  // This map will be used to select dofs from the whole vector as right hand side
417 
418  // Building map that will be used to close the matrix, this map will be ordered from
419  // 1 to the number of DOFs at the interface
421 
422  // Object needed to find neighbors by mesh connectivity
423  M_neighbors.reset ( new neighboring_Type ( M_fullMeshKnown, M_localMeshKnown, M_knownField->mapPtr(), M_knownField->mapPtr()->commPtr() ) );
424  if (M_flags[0] == -1)
425  {
426  M_neighbors->setUpNeighbors ();
427  }
428  else
429  {
430  // List of neighbors, for each dof finding its neighbors
431  M_neighbors->createPointPointNeighborsList (M_flags);
432  }
433 
434  int LocalNodesNumber = M_GIdsKnownMesh.size();
435 
436  std::vector<double> RBF_radius (LocalNodesNumber);
437  std::vector<std::unordered_set<ID> > MatrixGraph (LocalNodesNumber);
438  int* GlobalID = new int[LocalNodesNumber];
439 
440  int k = 0;
441  int Max_entries = 0;
442 
443  for (std::set<ID>::iterator it = M_GIdsKnownMesh.begin(); it != M_GIdsKnownMesh.end(); ++it)
444  {
445  // Selecting each dof taken into account
446  GlobalID[k] = *it;
447 
448  // For each of them, identify the neighbors within a certain number of circles M_links
449  neighbors_Type Neighbors;
450  Neighbors = M_neighbors->circleNeighbors ( *it, M_links );
451  Neighbors.insert ( *it );
452  MatrixGraph[k] = Neighbors;
453 
454  RBF_radius[k] = computeRBFradius ( M_fullMeshKnown, M_fullMeshKnown, Neighbors, GlobalID[k]);
455  neighbors_Type NeighborsR;
456  NeighborsR = M_neighbors->neighborsWithinRadius ( GlobalID[k], RBF_radius[k] );
457  NeighborsR.insert ( GlobalID[k] );
458  MatrixGraph[k] = NeighborsR;
459 
460  ++k;
461  }
462 
463  // Matrix for interpolation operator
464  M_interpolationOperator.reset (new matrix_Type (*M_interpolationOperatorMap, 100) );
465  Real Values;
466 
467  M_interpolationOperator->zero();
468 
469  // Loop over all the dofs taken into account by the interpolation
470  for ( int i = 0 ; i < LocalNodesNumber; ++i )
471  {
472  // For each i-th dof, evaluate the rbf between the dof and its neighbors
473  for ( std::unordered_set<ID>::iterator it = MatrixGraph[i].begin(); it != MatrixGraph[i].end(); ++it)
474  {
475  Values = rbf ( M_fullMeshKnown->point (GlobalID[i]).x(),
476  M_fullMeshKnown->point (GlobalID[i]).y(),
477  M_fullMeshKnown->point (GlobalID[i]).z(),
478  M_fullMeshKnown->point (*it).x(),
479  M_fullMeshKnown->point (*it).y(),
480  M_fullMeshKnown->point (*it).z(),
481  RBF_radius[i] );
482 
483  M_interpolationOperator->addToCoefficient( (*M_numerationInterfaceKnown)( GlobalID[i] ),
484  (*(M_numerationInterfaceKnownColumns[M_pid]))(*it),
485  Values );
486  }
487  }
488 
489  M_interpolationOperator->globalAssemble();
490 
491  // M_interpolationOperator->exportToHDF5("InputField", "M_interpolationOperator", false);
492  delete[] GlobalID;
493 }
494 
495 template <typename mesh_Type>
497 {
498  // Identifying dofs to be taken into account
499  this->identifyNodes (M_localMeshUnknown, M_GIdsUnknownMesh, M_unknownField);
500 
502 
504 
505  // Total number of dofs taken into account
506  int LocalNodesNumber = M_GIdsUnknownMesh.size();
507 
508  std::vector<double> RBF_radius (LocalNodesNumber);
509  std::vector<std::unordered_set<ID> > MatrixGraph (LocalNodesNumber);
510  int* GlobalID = new int[LocalNodesNumber];
511  int k = 0;
512 
513  // I need to find the closest point in the "known mesh" to use its radius
514  double d;
515  double d_min;
516  int nearestPoint;
517 
518  for (std::set<ID>::iterator it = M_GIdsUnknownMesh.begin(); it != M_GIdsUnknownMesh.end(); ++it)
519  {
520  GlobalID[k] = *it;
521  d_min = 100;
522  for (int j = 0; j < M_fullMeshKnown->numVertices(); ++j)
523  {
524  if ( M_flags[0] == -1 || this->isInside (M_fullMeshKnown->point (j).markerID(), M_flags) )
525  {
526  d = std::sqrt ( ( M_fullMeshKnown->point (j).x() - M_fullMeshUnknown->point (GlobalID[k]).x() ) *
527  ( M_fullMeshKnown->point (j).x() - M_fullMeshUnknown->point (GlobalID[k]).x() ) +
528  ( M_fullMeshKnown->point (j).y() - M_fullMeshUnknown->point (GlobalID[k]).y() ) *
529  ( M_fullMeshKnown->point (j).y() - M_fullMeshUnknown->point (GlobalID[k]).y() ) +
530  ( M_fullMeshKnown->point (j).z() - M_fullMeshUnknown->point (GlobalID[k]).z() ) *
531  ( M_fullMeshKnown->point (j).z() - M_fullMeshUnknown->point (GlobalID[k]).z() ) );
532  if (d < d_min)
533  {
534  d_min = d;
535  nearestPoint = M_fullMeshKnown->point (j).id();
536  }
537  }
538  }
539 
540  // For each of them, identify the neighbors on the other mesh within a certain number of circles M_links
541  neighbors_Type Neighbors;
542  Neighbors = M_neighbors->circleNeighbors ( nearestPoint, M_links );
543  Neighbors.insert ( nearestPoint );
544 
545  RBF_radius[k] = computeRBFradius ( M_fullMeshKnown, M_fullMeshUnknown, Neighbors, GlobalID[k]);
546  neighbors_Type NeighborsR;
547  NeighborsR = M_neighbors->neighborsWithinRadius ( nearestPoint, RBF_radius[k] );
548  NeighborsR.insert ( nearestPoint );
549  MatrixGraph[k] = NeighborsR;
550  ++k;
551  }
552 
553  M_projectionOperator.reset (new matrix_Type (*M_projectionOperatorMap, 100) );
554 
555  Real Values;
556 
557  for ( int i = 0 ; i < LocalNodesNumber; ++i )
558  {
559  for ( std::unordered_set<ID>::iterator it = MatrixGraph[i].begin(); it != MatrixGraph[i].end(); ++it)
560  {
561  Values = rbf ( M_fullMeshUnknown->point (GlobalID[i]).x(),
562  M_fullMeshUnknown->point (GlobalID[i]).y(),
563  M_fullMeshUnknown->point (GlobalID[i]).z(),
564  M_fullMeshKnown->point (*it).x(),
565  M_fullMeshKnown->point (*it).y(),
566  M_fullMeshKnown->point (*it).z(),
567  RBF_radius[i]);
568 
569  M_projectionOperator->addToCoefficient( (*M_numerationInterfaceUnknown)( GlobalID[i] ),
570  (*(M_numerationInterfaceKnownColumns[M_pid]))(*it),
571  Values );
572  }
573  }
574  M_projectionOperator->globalAssemble (M_interpolationOperatorMap, M_projectionOperatorMap);
575 
576  delete[] GlobalID;
577 }
578 
579 template <typename mesh_Type>
580 inline double RBFlocallyRescaledVectorial<mesh_Type>::computeRBFradius (meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID)
581 {
582  double r = 0;
583  double r_max = 0;
584  for (idContainer_Type::iterator it = Neighbors.begin(); it != Neighbors.end(); ++it)
585  {
586  r = std::sqrt ( ( MeshGID->point ( GlobalID ).x() - MeshNeighbors->point ( *it ).x() ) *
587  ( MeshGID->point ( GlobalID ).x() - MeshNeighbors->point ( *it ).x() ) +
588  ( MeshGID->point ( GlobalID ).y() - MeshNeighbors->point ( *it ).y() ) *
589  ( MeshGID->point ( GlobalID ).y() - MeshNeighbors->point ( *it ).y() ) +
590  ( MeshGID->point ( GlobalID ).z() - MeshNeighbors->point ( *it ).z() ) *
591  ( MeshGID->point ( GlobalID ).z() - MeshNeighbors->point ( *it ).z() ) );
592  r_max = ( r > r_max ) ? r : r_max;
593  }
594  return r_max;
595 }
596 
597 template <typename mesh_Type>
599 {
600  M_RhsOne.reset (new vector_Type (*M_interpolationOperatorMap) );
601  *M_RhsOne += 1;
602 
603  M_RhsF1.reset (new vector_Type (*M_interpolationOperatorMap) );
604  M_RhsF2.reset (new vector_Type (*M_interpolationOperatorMap) );
605  M_RhsF3.reset (new vector_Type (*M_interpolationOperatorMap) );
606 
607  UInt offset = M_knownField->size()/3;
608 
609  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
610  {
611  (*M_RhsF1)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
612  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i));
613 
614  (*M_RhsF2)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
615  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
616 
617  (*M_RhsF3)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
618  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
619 
620 // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
621 // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
622  }
623 }
624 
625 template <typename mesh_Type>
627 {
628  vectorPtr_Type gamma_one;
629  gamma_one.reset (new vector_Type (*M_interpolationOperatorMap) );
630 
631  // Preconditioner
632  prec_Type* precRawPtr;
633  basePrecPtr_Type precPtr;
634  precRawPtr = new prec_Type;
635  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
636  precPtr.reset ( precRawPtr );
637 
638  LinearSolver solverOne;
639  solverOne.setCommunicator ( M_knownField->mapPtr()->commPtr() );
640  solverOne.setParameters ( *M_belosList );
641  solverOne.setPreconditioner ( precPtr );
642 
643  solverOne.setOperator (M_interpolationOperator);
644  solverOne.setRightHandSide ( M_RhsOne );
645  solverOne.solve ( gamma_one );
646 
647  M_rbf_one.reset (new vector_Type (*M_projectionOperatorMap) );
648  M_projectionOperator->multiply (false, *gamma_one, *M_rbf_one);
649 }
650 
651 template <typename mesh_Type>
653 {
654  vectorPtr_Type gamma_f1;
655  gamma_f1.reset (new vector_Type (*M_interpolationOperatorMap) );
656 
657  vectorPtr_Type gamma_f2;
658  gamma_f2.reset (new vector_Type (*M_interpolationOperatorMap) );
659 
660  vectorPtr_Type gamma_f3;
661  gamma_f3.reset (new vector_Type (*M_interpolationOperatorMap) );
662 
663  // Preconditioner
664  prec_Type* precRawPtr;
665  basePrecPtr_Type precPtr;
666  precRawPtr = new prec_Type;
667  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
668  precPtr.reset ( precRawPtr );
669 
670  // Solving for component x
671  LinearSolver solverRBF1;
672  solverRBF1.setCommunicator ( M_knownField->mapPtr()->commPtr() );
673  solverRBF1.setParameters ( *M_belosList );
674  solverRBF1.setPreconditioner ( precPtr );
675 
676  solverRBF1.setOperator (M_interpolationOperator);
677  solverRBF1.setRightHandSide (M_RhsF1);
678  solverRBF1.solve (gamma_f1);
679 
680  // Solving for component y
681  LinearSolver solverRBF2;
682  solverRBF2.setCommunicator ( M_knownField->mapPtr()->commPtr() );
683  solverRBF2.setParameters ( *M_belosList );
684  solverRBF2.setPreconditioner ( precPtr );
685 
686  solverRBF2.setOperator (M_interpolationOperator);
687  solverRBF2.setRightHandSide (M_RhsF2);
688  solverRBF2.solve (gamma_f2);
689 
690  // Solving for component z
691  LinearSolver solverRBF3;
692  solverRBF3.setCommunicator ( M_knownField->mapPtr()->commPtr() );
693  solverRBF3.setParameters ( *M_belosList );
694  solverRBF3.setPreconditioner ( precPtr );
695 
696  solverRBF3.setOperator (M_interpolationOperator);
697  solverRBF3.setRightHandSide (M_RhsF3);
698  solverRBF3.solve (gamma_f3);
699 
700  vectorPtr_Type rbf_f1;
701  rbf_f1.reset (new vector_Type (*M_projectionOperatorMap) );
702 
703  vectorPtr_Type solution1;
704  solution1.reset (new vector_Type (*M_projectionOperatorMap) );
705 
706  M_projectionOperator->multiply (false, *gamma_f1, *rbf_f1);
707 
708  // Rescaling component x
709  *solution1 = *rbf_f1;
710  *solution1 /= *M_rbf_one;
711 
712  vectorPtr_Type rbf_f2;
713  rbf_f2.reset (new vector_Type (*M_projectionOperatorMap) );
714 
715  vectorPtr_Type solution2;
716  solution2.reset (new vector_Type (*M_projectionOperatorMap) );
717 
718  M_projectionOperator->multiply (false, *gamma_f2, *rbf_f2);
719 
720  // Rescaling component y
721  *solution2 = *rbf_f2;
722  *solution2 /= *M_rbf_one;
723 
724  vectorPtr_Type rbf_f3;
725  rbf_f3.reset (new vector_Type (*M_projectionOperatorMap) );
726 
727  vectorPtr_Type solution3;
728  solution3.reset (new vector_Type (*M_projectionOperatorMap) );
729 
730  M_projectionOperator->multiply (false, *gamma_f3, *rbf_f3);
731 
732  // Rescaling component z
733  *solution3 = *rbf_f3;
734  *solution3 /= *M_rbf_one;
735 
736  // Solution of the interpolation problem
737 
738  UInt offset = M_unknownField->size()/3;
739 
740  for(int i = 0; i < M_numerationInterfaceUnknown->epetraVector().MyLength(); ++i)
741  {
742  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i)]
743  = (*solution1)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
744 
745  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i) + offset]
746  = (*solution2)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
747 
748  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i) + 2*offset]
749  = (*solution3)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
750 
751  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
752  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
753  }
754 
755  // Storing also the solution on gamma
756 
757  M_solutionOnGamma.reset ( new vector_Type ( *M_projectionOperatorMapVectorial ) );
758  M_solutionOnGamma->zero();
759 
760  UInt offsetScalar = M_solutionOnGamma->size()/3;
761 
762  M_solutionOnGamma->subset(*solution1, *M_projectionOperatorMap, 0, 0);
763  M_solutionOnGamma->subset(*solution2, *M_projectionOperatorMap, 0, offsetScalar );
764  M_solutionOnGamma->subset(*solution3, *M_projectionOperatorMap, 0, 2*offsetScalar);
765 
766 }
767 
768 template <typename mesh_Type>
770 {
771  /*
772  std::unordered_set<ID> GID_vectorial;
773  for ( UInt i = 0; i < M_localMeshUnknown->numVertices(); ++i )
774  if ( this->isInside (M_localMeshUnknown->point (i).markerID(), M_flags) )
775  if (M_unknownField->blockMap().LID ( static_cast<EpetraInt_Type> (M_localMeshUnknown->point (i).id()) ) != -1)
776  for(int nDim = 0; nDim < 3; ++nDim)
777  GID_vectorial.insert (M_localMeshUnknown->point (i).id() + nDim*M_fullMeshUnknown->numVertices());
778 
779  int LocalNodesNumber = GID_vectorial.size();
780  //std::cout << LocalNodesNumber << std::endl;
781  int* GlobalID = new int[LocalNodesNumber];
782  int k = 0;
783 
784  for (std::unordered_set<ID>::iterator it = GID_vectorial.begin(); it != GID_vectorial.end(); ++it)
785  {
786  GlobalID[k] = *it;
787  ++k;
788  }
789 
790  M_gammaMapUnknownVectorial.reset (new map_Type (-1, LocalNodesNumber, GlobalID, M_unknownField->mapPtr()->commPtr() ) );
791  delete GlobalID;
792  */
793 }
794 
795 
796 template <typename mesh_Type>
797 inline void RBFlocallyRescaledVectorial<mesh_Type>::identifyNodes (meshPtr_Type LocalMesh, std::set<ID>& GID_nodes, vectorPtr_Type CheckVector)
798 {
799  if (M_flags[0] == -1)
800  {
801  for ( UInt i = 0; i < LocalMesh->numVertices(); ++i )
802  if (CheckVector->blockMap().LID ( static_cast<EpetraInt_Type> ( LocalMesh->point (i).id() ) ) != -1)
803  {
804  GID_nodes.insert (LocalMesh->point (i).id() );
805  }
806  }
807  else
808  {
809  // Checking which points have to be considered.
810  // TODO: here the code could be otimized but currently it is
811  // not since we want to keep the code general, i.e., such
812  // that it works for mesh to mesh and also for interface to interface.
813  // In the case interface to interface we do not have to loop all over
814  // the vertices, but on the boundary faces.
815  // TODO: works just for P1 now since we ask for the markerID of the
816  // points.
817  for ( UInt i = 0; i < LocalMesh->numVertices(); ++i )
818  if ( this->isInside (LocalMesh->point (i).markerID(), M_flags) )
819  if (CheckVector->blockMap().LID ( static_cast<EpetraInt_Type> (LocalMesh->point (i).id()) ) != -1)
820  {
821  GID_nodes.insert (LocalMesh->point (i).id() );
822  }
823  }
824 }
825 
826 template <typename mesh_Type>
827 inline bool RBFlocallyRescaledVectorial<mesh_Type>::isInside (ID pointMarker, flagContainer_Type flags)
828 {
829  // Checking if the point with id number ID has to be considered
830  for (UInt i = 0; i < flags.size(); ++i)
831  if (pointMarker == flags[i])
832  {
833  return true;
834  }
835  return false;
836 }
837 
838 
839 template <typename mesh_Type>
840 inline double RBFlocallyRescaledVectorial<mesh_Type>::rbf (double x1, double y1, double z1, double x2, double y2, double z2, double radius)
841 {
842  double distance = std::sqrt ( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) + (z1 - z2)*(z1 - z2) );
843  return (1 - distance / radius) * (1 - distance / radius) * (1 - distance / radius) * (1 - distance / radius) * (4 * distance / radius + 1);
844 }
845 
846 template <typename mesh_Type>
847 void RBFlocallyRescaledVectorial<mesh_Type>::updateRhs(const vectorPtr_Type& newRhs)
848 {
849  M_RhsF1->zero();
850  M_RhsF2->zero();
851  M_RhsF3->zero();
852 
853  UInt offset = M_knownField->size()/3;
854 
855  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
856  {
857  (*M_RhsF1)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
858  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i));
859 
860  (*M_RhsF2)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
861  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
862 
863  (*M_RhsF3)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
864  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
865 
866  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
867  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
868  }
869 }
870 
871 template <typename mesh_Type>
872 void RBFlocallyRescaledVectorial<mesh_Type>::expandGammaToOmega_Known(const vectorPtr_Type& vectorOnGamma, vectorPtr_Type& vectorOnOmega)
873 {
874  vectorOnOmega.reset ( new vector_Type ( M_knownField->map() ) );
875  vectorOnOmega->zero();
876 
877  UInt offset = vectorOnOmega->size()/3;
878  UInt offsetGamma = vectorOnGamma->size()/3;
879 
880  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
881  {
882  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i)]
883  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]);
884 
885  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i) + offset]
886  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + offsetGamma );
887 
888  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset]
889  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + 2*offsetGamma);
890 
891  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
892  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
893  }
894 }
895 
896 template <typename mesh_Type>
897 void RBFlocallyRescaledVectorial<mesh_Type>::restrictOmegaToGamma_Known(const vectorPtr_Type& vectorOnOmega, vectorPtr_Type& vectorOnGamma)
898 {
899  vectorOnGamma.reset ( new vector_Type ( *M_interpolationOperatorMapVectorial ) );
900  vectorOnGamma->zero();
901 
902  UInt offset = vectorOnOmega->size()/3;
903  UInt offsetGamma = vectorOnGamma->size()/3;
904 
905  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
906  {
907  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
908  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i));
909 
910  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + offsetGamma ]
911  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
912 
913  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + 2*offsetGamma ]
914  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
915 
916  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
917  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
918  }
919 }
920 
921 
922 template <typename mesh_Type>
924 {
925  Solution->zero();
926  *Solution += *M_unknownField;
927 }
928 
929 template <typename mesh_Type>
931 {
932  /*
933  Solution_rbf = M_unknownField_rbf;
934  */
935 }
936 
937 //! Factory create function
938 template <typename mesh_Type>
940 {
941  return new RBFlocallyRescaledVectorial< mesh_Type > ();
942 }
943 namespace
944 {
947 }
948 
949 } // Namespace LifeV
950 
951 #endif /* RBFLOCALLYRESCALEDVECTORIAL_H */
std::vector< vectorPtr_Type > M_numerationInterfaceKnownColumns
std::shared_ptr< matrix_Type > matrixPtr_Type
void solutionrbf(vectorPtr_Type &Solution_rbf)
bool isInside(ID pointMarker, flagContainer_Type Flags)
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void identifyNodes(meshPtr_Type LocalMesh, std::set< ID > &GID_nodes, vectorPtr_Type CheckVector)
void setup(meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags)
Teuchos::RCP< Teuchos::ParameterList > parameterList_Type
std::shared_ptr< basePrec_Type > basePrecPtr_Type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
uint32_type ID
IDs.
Definition: LifeV.hpp:194
void expandGammaToOmega_Known(const vectorPtr_Type &vectorOnGamma, vectorPtr_Type &vectorOnOmega)
void getNumerationInterfaceKnown(vectorPtr_Type &vector)
double computeRBFradius(meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID)
std::shared_ptr< neighboring_Type > neighboringPtr_Type
void setupRBFData(vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList)
void getSolutionOnGamma(vectorPtr_Type &GammaSolution)
double Real
Generic real data.
Definition: LifeV.hpp:175
RBFInterpolation< mesh_Type > * createRBFlocallyRescaledVectorial()
Factory create function.
std::shared_ptr< vector_Type > vectorPtr_Type
double rbf(double x1, double y1, double z1, double x2, double y2, double z2, double radius)
void restrictOmegaToGamma_Known(const vectorPtr_Type &vectorOnOmega, vectorPtr_Type &vectorOnGamma)
void importFromHDF5(std::string const &fileName="ghostmap")
Import neighbor lists to an hdf5 file.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void updateRhs(const vectorPtr_Type &newRhs)