LifeV
RBFlocallyRescaledScalar.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 13 Mar 2013
33 
34  A more detailed description of the file (if necessary)
35  */
36 
37 #ifndef RBFLOCALLYRESCALEDSCALAR_H
38 #define RBFLOCALLYRESCALEDSCALAR_H 1
39 
40 #include <lifev/core/interpolation/RBFInterpolation.hpp>
41 
42 namespace LifeV
43 {
44 
45 template <typename mesh_Type>
47 {
48 public:
49 
51 
52  typedef VectorEpetra vector_Type;
54 
55  typedef MatrixEpetra<double> matrix_Type;
57 
58  typedef std::vector<int> flagContainer_Type;
59 
61 
64 
65  typedef GhostHandler<mesh_Type> neighbors_Type;
67 
68  typedef LifeV::Preconditioner basePrec_Type;
70 
71  typedef LifeV::PreconditionerIfpack prec_Type;
73 
75 
77 
78  virtual ~RBFlocallyRescaledScalar();
79 
80  void setup ( meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags );
81 
82  void setupRBFData (vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList);
83 
84  void buildOperators();
85 
86  void interpolationOperator();
87 
88  void projectionOperator();
89 
90  void buildRhs();
91 
93 
94  void identifyNodes (meshPtr_Type LocalMesh, std::unordered_set<ID>& GID_nodes, vectorPtr_Type CheckVector);
95 
96  bool isInside (ID pointMarker, flagContainer_Type Flags);
97 
98  double computeRBFradius (meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID);
99 
100  double rbf (double x1, double y1, double z1, double x2, double y2, double z2, double radius);
101 
102  void interpolate();
103 
104  void solution (vectorPtr_Type& Solution);
105 
106  void solutionrbf (vectorPtr_Type& Solution_rbf);
107 
108  void updateRhs(vectorPtr_Type newRhs);
109 
110  void setRadius ( double radius );
111 
112  void getinterpolationOperatorMap(mapPtr_Type& map){ map.reset(new map_Type(*M_interpolationOperatorMap)); }
113 
114  void getprojectionOperatorMap(mapPtr_Type& map){ map.reset(new map_Type(*M_projectionOperatorMap)); }
115 
116 private:
117 
138  double M_radius;
139 
140  std::vector<double> M_kx;
141  std::vector<double> M_ky;
142  std::vector<double> M_kz;
143 
144  std::vector<double> M_ukx;
145  std::vector<double> M_uky;
146  std::vector<double> M_ukz;
147 };
148 
149 template <typename mesh_Type>
151 {}
152 
153 template <typename mesh_Type>
155 {}
156 
157 template <typename mesh_Type>
158 void RBFlocallyRescaledScalar<mesh_Type>::setup ( meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags )
159 {
160  M_fullMeshKnown = fullMeshKnown;
161  M_localMeshKnown = localMeshKnown;
162  M_fullMeshUnknown = fullMeshUnknown;
163  M_localMeshUnknown = localMeshUnknown;
164  M_flags = flags;
165 
166  M_kx.resize(M_fullMeshKnown->numVertices());
167  M_ky.resize(M_fullMeshKnown->numVertices());
168  M_kz.resize(M_fullMeshKnown->numVertices());
169 
170  for (int j = 0; j < M_fullMeshKnown->numVertices(); ++j)
171  {
172  M_kx[j] = M_fullMeshKnown->point(j).x();
173  M_ky[j] = M_fullMeshKnown->point(j).y();
174  M_kz[j] = M_fullMeshKnown->point(j).z();
175  }
176 
177  M_ukx.resize(M_fullMeshUnknown->numVertices());
178  M_uky.resize(M_fullMeshUnknown->numVertices());
179  M_ukz.resize(M_fullMeshUnknown->numVertices());
180 
181  for (int j = 0; j < M_fullMeshUnknown->numVertices(); ++j)
182  {
183  M_ukx[j] = M_fullMeshUnknown->point(j).x();
184  M_uky[j] = M_fullMeshUnknown->point(j).y();
185  M_ukz[j] = M_fullMeshUnknown->point(j).z();
186  }
187 
188 }
189 
190 template <typename mesh_Type>
191 void RBFlocallyRescaledScalar<mesh_Type>::setupRBFData (vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList)
192 {
193  M_knownField = KnownField;
194  M_unknownField = UnknownField;
195  M_datafile = datafile;
196  M_belosList = belosList;
197 }
198 
199 template <typename mesh_Type>
200 void RBFlocallyRescaledScalar<mesh_Type>::setRadius ( double radius )
201 {
202  M_radius = radius;
203 }
204 
205 template <typename Mesh>
207 {
208  LifeChrono TimeBuilding;
209  TimeBuilding.start();
210  this->interpolationOperator();
211  this->projectionOperator();
212  TimeBuilding.stop();
213  if(M_knownField->mapPtr()->commPtr()->MyPID()==0)
214  std::cout << "Time to assembly operators = " << TimeBuilding.diff() << std::endl;
215 
216  this->buildRhs();
217  this->interpolateCostantField();
218 }
219 
220 template <typename Mesh>
222 {
223  this->identifyNodes (M_localMeshKnown, M_GIdsKnownMesh, M_knownField);
224  M_neighbors.reset ( new neighbors_Type ( M_fullMeshKnown, M_localMeshKnown, M_knownField->mapPtr(), M_knownField->mapPtr()->commPtr() ) );
225  if (M_flags[0] == -1)
226  {
227  M_neighbors->setUpNeighbors();
228  }
229  else
230  {
231  M_neighbors->createPointPointNeighborsList (M_flags);
232  }
233 
234  int LocalNodesNumber = M_GIdsKnownMesh.size();
235 
236  std::vector<double> RBF_radius (LocalNodesNumber);
237  std::vector<std::unordered_set<ID> > MatrixGraph (LocalNodesNumber);
238  int* ElementsPerRow = new int[LocalNodesNumber];
239  int* GlobalID = new int[LocalNodesNumber];
240  int k = 0;
241  int Max_entries = 0;
242 
243  for (std::unordered_set<ID>::iterator it = M_GIdsKnownMesh.begin(); it != M_GIdsKnownMesh.end(); ++it)
244  {
245  GlobalID[k] = *it;
246  MatrixGraph[k] = M_neighbors->pointPointNeighborsList() [GlobalID[k]];
247  MatrixGraph[k].insert (GlobalID[k]);
248  RBF_radius[k] = computeRBFradius ( M_fullMeshKnown, M_fullMeshKnown, MatrixGraph[k], GlobalID[k]);
249  ElementsPerRow[k] = MatrixGraph[k].size();
250  if (ElementsPerRow[k] > Max_entries)
251  {
252  Max_entries = ElementsPerRow[k];
253  }
254  ++k;
255  }
256 
257  M_interpolationOperatorMap.reset (new map_Type (-1, LocalNodesNumber, GlobalID, M_knownField->mapPtr()->commPtr() ) );
258  M_interpolationOperator.reset (new matrix_Type (*M_interpolationOperatorMap, ElementsPerRow) );
259 
260  int* Indices = new int[Max_entries];
261  double* Values = new double[Max_entries];
262 
263  for ( int i = 0 ; i < LocalNodesNumber; ++i )
264  {
265  k = 0;
266  for ( std::unordered_set<ID>::iterator it = MatrixGraph[i].begin(); it != MatrixGraph[i].end(); ++it)
267  {
268  Indices[k] = *it;
269  Values[k] = rbf ( M_kx[GlobalID[i]], M_ky[GlobalID[i]], M_kz[GlobalID[i]],
270  M_kx[*it], M_ky[*it], M_kz[*it],
271  RBF_radius[i]);
272  ++k;
273  }
274  M_interpolationOperator->matrixPtr()->InsertGlobalValues (GlobalID[i], k, Values, Indices);
275  }
276  M_interpolationOperator->globalAssemble();
277  delete[] Indices;
278  delete[] Values;
279  delete[] ElementsPerRow;
280  delete[] GlobalID;
281 }
282 
283 template <typename mesh_Type>
285 {
286 
287  this->identifyNodes (M_localMeshUnknown, M_GIdsUnknownMesh, M_unknownField);
288 
289  int LocalNodesNumber = M_GIdsUnknownMesh.size();
290 
291  std::vector<double> RBF_radius (LocalNodesNumber);
292  std::vector<std::unordered_set<ID> > MatrixGraph (LocalNodesNumber);
293  int* ElementsPerRow = new int[LocalNodesNumber];
294  int* GlobalID = new int[LocalNodesNumber];
295  int k = 0;
296  int Max_entries = 0;
297  double d;
298  double d_min;
299  int nearestPoint;
300 
301  for (std::unordered_set<ID>::iterator it = M_GIdsUnknownMesh.begin(); it != M_GIdsUnknownMesh.end(); ++it)
302  {
303  GlobalID[k] = *it;
304  d_min = 100;
305  for (int j = 0; j < M_fullMeshKnown->numVertices(); ++j)
306  {
307  if ( M_flags[0] == -1 || this->isInside (M_fullMeshKnown->point (j).markerID(), M_flags) )
308  {
309  d = std::sqrt ( std::pow (M_kx[j] - M_ukx[GlobalID[k]], 2)
310  + std::pow (M_ky[j] - M_uky[GlobalID[k]], 2)
311  + std::pow (M_kz[j] - M_ukz[GlobalID[k]], 2) );
312  if (d < d_min)
313  {
314  d_min = d;
315  nearestPoint = M_fullMeshKnown->point (j).id();
316  }
317  }
318  }
319  MatrixGraph[k] = M_neighbors->pointPointNeighborsList() [nearestPoint];
320  MatrixGraph[k].insert (nearestPoint);
321  RBF_radius[k] = computeRBFradius ( M_fullMeshKnown, M_fullMeshUnknown, MatrixGraph[k], GlobalID[k]);
322  ElementsPerRow[k] = MatrixGraph[k].size();
323  if (ElementsPerRow[k] > Max_entries)
324  {
325  Max_entries = ElementsPerRow[k];
326  }
327  ++k;
328  }
329 
330  M_projectionOperatorMap.reset (new map_Type (-1, LocalNodesNumber, GlobalID, M_unknownField->mapPtr()->commPtr() ) );
331  M_projectionOperator.reset (new matrix_Type (*M_projectionOperatorMap, ElementsPerRow) );
332 
333  int* Indices = new int[Max_entries];
334  double* Values = new double[Max_entries];
335 
336  for ( int i = 0 ; i < LocalNodesNumber; ++i )
337  {
338  k = 0;
339  for ( std::unordered_set<ID>::iterator it = MatrixGraph[i].begin(); it != MatrixGraph[i].end(); ++it)
340  {
341  Indices[k] = *it;
342  Values[k] = rbf ( M_ukx[GlobalID[i]], M_uky[GlobalID[i]], M_ukz[GlobalID[i]],
343  M_kx[*it], M_ky[*it], M_kz[*it], RBF_radius[i]);
344  ++k;
345  }
346  M_projectionOperator->matrixPtr()->InsertGlobalValues (GlobalID[i], k, Values, Indices);
347  }
348  M_projectionOperator->globalAssemble (M_interpolationOperatorMap, M_projectionOperatorMap);
349  delete[] Indices;
350  delete[] Values;
351  delete[] ElementsPerRow;
352  delete[] GlobalID;
353 }
354 
355 template <typename mesh_Type>
356 double RBFlocallyRescaledScalar<mesh_Type>::computeRBFradius (meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID)
357 {
358  double r = 0;
359  double r_max = 0;
360  for (idContainer_Type::iterator it = Neighbors.begin(); it != Neighbors.end(); ++it)
361  {
362  r = std::sqrt ( std::pow ( MeshGID->point ( GlobalID ).x() - MeshNeighbors->point ( *it ).x(), 2 )
363  + std::pow ( MeshGID->point ( GlobalID ).y() - MeshNeighbors->point ( *it ).y(), 2 )
364  + std::pow ( MeshGID->point ( GlobalID ).z() - MeshNeighbors->point ( *it ).z(), 2 ) );
365  r_max = ( r > r_max ) ? r : r_max;
366  }
367  return r_max;
368 }
369 
370 template <typename mesh_Type>
372 {
373  M_RhsF.reset (new vector_Type (*M_interpolationOperatorMap) );
374  M_RhsOne.reset (new vector_Type (*M_interpolationOperatorMap) );
375 
376  M_RhsF->subset (*M_knownField, *M_interpolationOperatorMap, 0, 0);
377  *M_RhsOne += 1;
378 }
379 
380 template <typename mesh_Type>
382 {
383  vectorPtr_Type gamma_one;
384  gamma_one.reset (new vector_Type (*M_interpolationOperatorMap) );
385 
386  // Preconditioner
387  prec_Type* precRawPtr;
388  basePrecPtr_Type precPtr;
389  precRawPtr = new prec_Type;
390  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
391  precPtr.reset ( precRawPtr );
392 
393  LinearSolver solverOne;
394  solverOne.setCommunicator ( M_knownField->mapPtr()->commPtr() );
395  solverOne.setParameters ( *M_belosList );
396  solverOne.setPreconditioner ( precPtr );
397 
398  solverOne.setOperator (M_interpolationOperator);
399  solverOne.setRightHandSide ( M_RhsOne );
400  solverOne.solve ( gamma_one );
401 
402  M_rbf_one.reset (new vector_Type (*M_projectionOperatorMap) );
403  M_projectionOperator->multiply (false, *gamma_one, *M_rbf_one);
404 }
405 
406 template <typename mesh_Type>
408 {
409  vectorPtr_Type gamma_f;
410  gamma_f.reset (new vector_Type (*M_interpolationOperatorMap) );
411 
412  // Preconditioner
413  prec_Type* precRawPtr;
414  basePrecPtr_Type precPtr;
415  precRawPtr = new prec_Type;
416  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
417  precPtr.reset ( precRawPtr );
418 
419  LinearSolver solverRBF;
420  solverRBF.setCommunicator ( M_knownField->mapPtr()->commPtr() );
421  solverRBF.setParameters ( *M_belosList );
422  solverRBF.setPreconditioner ( precPtr );
423 
424  solverRBF.setOperator (M_interpolationOperator);
425  solverRBF.setRightHandSide (M_RhsF);
426  solverRBF.solve (gamma_f);
427 
428  vectorPtr_Type rbf_f;
429  rbf_f.reset (new vector_Type (*M_projectionOperatorMap) );
430 
431  vectorPtr_Type solution;
432  solution.reset (new vector_Type (*M_projectionOperatorMap) );
433 
434  M_projectionOperator->multiply (false, *gamma_f, *rbf_f);
435 
436  *solution = *rbf_f;
437  *solution /= *M_rbf_one;
438 
439  M_unknownField_rbf.reset (new vector_Type (M_unknownField->map() ) );
440  M_unknownField_rbf->subset (*rbf_f, *M_projectionOperatorMap, 0, 0);
441 
442  M_unknownField->subset (*solution, *M_projectionOperatorMap, 0, 0);
443 }
444 
445 template <typename mesh_Type>
446 void RBFlocallyRescaledScalar<mesh_Type>::identifyNodes (meshPtr_Type LocalMesh, std::unordered_set<ID>& GID_nodes, vectorPtr_Type CheckVector)
447 {
448  if (M_flags[0] == -1)
449  {
450  for ( UInt i = 0; i < LocalMesh->numVertices(); ++i )
451  if (CheckVector->blockMap().LID ( static_cast<EpetraInt_Type> (LocalMesh->point (i).id()) ) != -1)
452  {
453  GID_nodes.insert (LocalMesh->point (i).id() );
454  }
455  }
456  else
457  {
458  for ( UInt i = 0; i < LocalMesh->numVertices(); ++i )
459  if ( this->isInside (LocalMesh->point (i).markerID(), M_flags) )
460  if (CheckVector->blockMap().LID ( static_cast<EpetraInt_Type> (LocalMesh->point (i).id()) ) != -1)
461  {
462  GID_nodes.insert (LocalMesh->point (i).id() );
463  }
464  }
465 }
466 
467 template <typename mesh_Type>
468 bool RBFlocallyRescaledScalar<mesh_Type>::isInside (ID pointMarker, flagContainer_Type flags)
469 {
470  int check = 0;
471  for (UInt i = 0; i < flags.size(); ++i)
472  if (pointMarker == flags[i])
473  {
474  ++check;
475  }
476  return (check > 0) ? true : false;
477 }
478 
479 
480 template <typename mesh_Type>
481 double RBFlocallyRescaledScalar<mesh_Type>::rbf (double x1, double y1, double z1, double x2, double y2, double z2, double radius)
482 {
483  double distance = std::sqrt ( std::pow (x1 - x2, 2) + std::pow (y1 - y2, 2) + std::pow (z1 - z2, 2) );
484  return std::pow (1 - distance / radius, 4) * (4 * distance / radius + 1);
485 }
486 
487 template <typename mesh_Type>
489 {
490  *M_RhsF *= 0;
491  *M_RhsF = *newRhs;
492 }
493 
494 template <typename mesh_Type>
496 {
497  Solution = M_unknownField;
498 }
499 
500 template <typename mesh_Type>
501 void RBFlocallyRescaledScalar<mesh_Type>::solutionrbf (vectorPtr_Type& Solution_rbf)
502 {
503  Solution_rbf = M_unknownField_rbf;
504 }
505 
506 //! Factory create function
507 template <typename mesh_Type>
509 {
510  return new RBFlocallyRescaledScalar< mesh_Type > ();
511 }
512 namespace
513 {
516 }
517 
518 } // Namespace LifeV
519 
520 #endif /* RBFLOCALLYRESCALEDSCALAR_H */
void setup(meshPtr_Type fullMeshKnown, meshPtr_Type localMeshKnown, meshPtr_Type fullMeshUnknown, meshPtr_Type localMeshUnknown, flagContainer_Type flags)
std::shared_ptr< mesh_Type > meshPtr_Type
bool isInside(ID pointMarker, flagContainer_Type Flags)
void start()
Start the timer.
Definition: LifeChrono.hpp:93
double computeRBFradius(meshPtr_Type MeshNeighbors, meshPtr_Type MeshGID, idContainer_Type Neighbors, ID GlobalID)
std::shared_ptr< basePrec_Type > basePrecPtr_Type
GhostHandler< mesh_Type > neighbors_Type
void solution(vectorPtr_Type &Solution)
std::shared_ptr< vector_Type > vectorPtr_Type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double rbf(double x1, double y1, double z1, double x2, double y2, double z2, double radius)
LifeV::PreconditionerIfpack prec_Type
std::shared_ptr< matrix_Type > matrixPtr_Type
std::shared_ptr< prec_Type > precPtr_Type
void stop()
Stop the timer.
Definition: LifeChrono.hpp:100
Teuchos::RCP< Teuchos::ParameterList > parameterList_Type
void solutionrbf(vectorPtr_Type &Solution_rbf)
void getinterpolationOperatorMap(mapPtr_Type &map)
void setupRBFData(vectorPtr_Type KnownField, vectorPtr_Type UnknownField, GetPot datafile, parameterList_Type belosList)
void identifyNodes(meshPtr_Type LocalMesh, std::unordered_set< ID > &GID_nodes, vectorPtr_Type CheckVector)
RBFInterpolation< mesh_Type > * createRBFlocallyRescaledScalar()
Factory create function.
std::shared_ptr< MapEpetra > mapPtr_Type
void importFromHDF5(std::string const &fileName="ghostmap")
Import neighbor lists to an hdf5 file.
std::shared_ptr< neighbors_Type > neighborsPtr_Type