LifeV
Interpolation.cpp
Go to the documentation of this file.
1 #include <lifev/core/interpolation/Interpolation.hpp>
2 
3 namespace LifeV
4 {
5 
7  M_precBuilt ( false )
8 {
9 }
10 
12 {}
13 
14 void
15 Interpolation::setup( const GetPot& datafile, parameterList_Type belosList )
16 {
17  M_datafile = datafile;
18  M_belosList = belosList;
19 }
20 
21 double
22 Interpolation::rbf (double x1, double y1, double z1, double x2, double y2, double z2, double radius)
23 {
24  double distance = std::sqrt ( (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) + (z1 - z2)*(z1 - z2) );
25  return (1 - distance / radius) * (1 - distance / radius) * (1 - distance / radius) * (1 - distance / radius) * (4 * distance / radius + 1);
26 }
27 
28 void
29 Interpolation::setVectors (const vectorPtr_Type& KnownField, const vectorPtr_Type& UnknownField )
30 {
31  M_knownField.reset( new vector_Type ( *KnownField ) );
32  M_unknownField.reset( new vector_Type ( *UnknownField ) );
33 }
34 
35 void
37 {
40  buildRhs();
42  free_space ();
43 }
44 
45 void
47 {
49 
50  // Total number of dofs taken into account
51  int LocalNodesNumber = M_GIdsUnknownMesh.size();
52 
53  std::vector<std::vector<int>> MatrixGraph (LocalNodesNumber);
54  int* GlobalID = new int[LocalNodesNumber];
55  int k = 0;
56 
57  // I need to find the closest point in the "known mesh" to use its radius
58  double d;
59  double d_min;
60  int nearestPoint;
61 
62  for (std::set<ID>::iterator it = M_GIdsUnknownMesh.begin(); it != M_GIdsUnknownMesh.end(); ++it)
63  {
64  GlobalID[k] = *it;
65  d_min = 100;
66  for (int j = 0; j < M_xcoord_known.size(); ++j)
67  {
68  if ( M_marker_known[j] == M_flag )
69  {
70  d = std::sqrt ( ( M_xcoord_known[j] - M_xcoord_unknown[*it] ) * ( M_xcoord_known[j] - M_xcoord_unknown[*it] ) +
71  ( M_ycoord_known[j] - M_ycoord_unknown[*it] ) * ( M_ycoord_known[j] - M_ycoord_unknown[*it] ) +
72  ( M_zcoord_known[j] - M_zcoord_unknown[*it] ) * ( M_zcoord_known[j] - M_zcoord_unknown[*it] ) );
73  if (d < d_min)
74  {
75  d_min = d;
76  nearestPoint = j;
77  }
78  }
79  }
80 
81  // For each of them, identify the neighbors on the other mesh within a certain number of circles M_links
82  MatrixGraph[k] = M_dof_connectivity_known[nearestPoint];
83  // RBF_radius[k] = computeRBFradius_unknown ( *it, MatrixGraph[k]);
84  ++k;
85  }
86  M_projectionOperator.reset (new matrix_Type (*M_projectionOperatorMap, 100) );
87 
88  Real Values;
89 
90  for ( int i = 0 ; i < LocalNodesNumber; ++i )
91  {
92  for ( int it = 0; it < MatrixGraph[i].size(); ++it )
93  {
94  Values = rbf ( M_xcoord_unknown[GlobalID[i]],
95  M_ycoord_unknown[GlobalID[i]],
96  M_zcoord_unknown[GlobalID[i]],
97  M_xcoord_known[MatrixGraph[i][it]],
98  M_ycoord_known[MatrixGraph[i][it]],
99  M_zcoord_known[MatrixGraph[i][it]],
100  M_links /*RBF_radius[i]*/ );
101 
102  M_projectionOperator->addToCoefficient( (*M_numerationInterfaceUnknown)( GlobalID[i] ),
103  (*(M_numerationInterfaceKnownColumns[M_pid]))(MatrixGraph[i][it]),
104  Values );
105  }
106  }
107  M_projectionOperator->globalAssemble (M_interpolationOperatorMap, M_projectionOperatorMap);
108  delete[] GlobalID;
109 }
110 
111 double
112 Interpolation::computeRBFradius_known ( const ID& index, std::vector<int> indexes )
113 {
114  double r = 0;
115  double r_max = 0;
116  for ( int i = 0; i < indexes.size(); ++i )
117  {
118  r = std::sqrt ( ( M_xcoord_known[index] - M_xcoord_known[indexes[i]] ) * ( M_xcoord_known[index] - M_xcoord_known[indexes[i]] ) +
119  ( M_ycoord_known[index] - M_ycoord_known[indexes[i]] ) * ( M_ycoord_known[index] - M_ycoord_known[indexes[i]] ) +
120  ( M_zcoord_known[index] - M_zcoord_known[indexes[i]] ) * ( M_zcoord_known[index] - M_zcoord_known[indexes[i]] ) );
121  r_max = ( r > r_max ) ? r : r_max;
122  }
123  return r_max;
124 }
125 
126 double
127 Interpolation::computeRBFradius_unknown ( const ID& index, std::vector<int> indexes )
128 {
129  double r = 0;
130  double r_max = 0;
131  for ( int i = 0; i < indexes.size(); ++i )
132  {
133  r = std::sqrt ( ( M_xcoord_unknown[index] - M_xcoord_known[indexes[i]] ) * ( M_xcoord_unknown[index] - M_xcoord_known[indexes[i]] ) +
134  ( M_ycoord_unknown[index] - M_ycoord_known[indexes[i]] ) * ( M_ycoord_unknown[index] - M_ycoord_known[indexes[i]] ) +
135  ( M_zcoord_unknown[index] - M_zcoord_known[indexes[i]] ) * ( M_zcoord_unknown[index] - M_zcoord_known[indexes[i]] ) );
136  r_max = ( r > r_max ) ? r : r_max;
137  }
138  return r_max;
139 }
140 
141 void
143 {
145 
146  int LocalNodesNumber = M_GIdsKnownMesh.size();
147 
148  std::vector<double> RBF_radius (LocalNodesNumber);
149  std::vector<std::vector<int>> MatrixGraph (LocalNodesNumber);
150  int* GlobalID = new int[LocalNodesNumber];
151 
152  int k = 0;
153  int Max_entries = 0;
154 
155  for (std::set<ID>::iterator it = M_GIdsKnownMesh.begin(); it != M_GIdsKnownMesh.end(); ++it)
156  {
157  GlobalID[k] = *it;
158  MatrixGraph[k] = M_dof_connectivity_known[*it];
159  //RBF_radius[k] = computeRBFradius_known ( *it, MatrixGraph[k] );
160  // std::cout << "DOF " << *it << " has radius " << RBF_radius[k] << std::endl;
161  ++k;
162  }
163 
164  // Matrix for interpolation operator
165  M_interpolationOperator.reset (new matrix_Type (*M_interpolationOperatorMap, 100) );
166 
167  Real Values;
168 
169  M_interpolationOperator->zero();
170 
171  // Loop over all the dofs taken into account by the interpolation
172  for ( int i = 0 ; i < LocalNodesNumber; ++i )
173  {
174  // For each i-th dof, evaluate the rbf between the dof and its neighbors
175  for ( int it = 0; it < MatrixGraph[i].size(); ++it)
176  {
177  Values = rbf ( M_xcoord_known[GlobalID[i]],
178  M_ycoord_known[GlobalID[i]],
179  M_zcoord_known[GlobalID[i]],
180  M_xcoord_known[MatrixGraph[i][it]],
181  M_ycoord_known[MatrixGraph[i][it]],
182  M_zcoord_known[MatrixGraph[i][it]],
183  M_links /*RBF_radius[i]*/ );
184 
185  M_interpolationOperator->addToCoefficient( (*M_numerationInterfaceKnown)( GlobalID[i] ),
186  (*(M_numerationInterfaceKnownColumns[M_pid]))(MatrixGraph[i][it]),
187  Values );
188  }
189  }
190 
191  M_interpolationOperator->globalAssemble();
192 
193  delete[] GlobalID;
194 }
195 
196 
197 void
199 {
200  CurrentFEManifold feBd1 ( fespace->refFE().boundaryFE(), getGeometricMap ( *fespace->mesh() ).boundaryMap() );
201 
202  int numBFaces = fespace->mesh()->numBFaces();
203  int numTotalDof = fespace->dof().numTotalDof();
204 
205  std::vector< std::vector<int> > dof_element_connectivity(numTotalDof);
206 
207  M_marker_known.resize(numTotalDof);
208  M_xcoord_known.resize(numTotalDof);
209  M_ycoord_known.resize(numTotalDof);
210  M_zcoord_known.resize(numTotalDof);
211 
212  for ( int i = 0; i < numBFaces; ++i )
213  {
214  if ( fespace->mesh()->boundaryFacet ( i ).markerID() == M_flag )
215  {
216  feBd1.update ( fespace->mesh()->boundaryFacet ( i ), UPDATE_ONLY_CELL_NODES ); // Updating facet information on mesh1
217  std::vector<ID> localToGlobalMapOnBFacet1 = fespace->dof().localToGlobalMapOnBdFacet (i);
218 
219  // devo riempire vettore con marker di ogni dof
220  VectorSmall<6> FaceDof;
221  FaceDof *= 0;
222 
223  for (ID lDof1 = 0; lDof1 < localToGlobalMapOnBFacet1.size(); lDof1++)
224  {
225  dof_element_connectivity[localToGlobalMapOnBFacet1[lDof1]].push_back(i);
226 
227  feBd1.coorMap ( M_xcoord_known[localToGlobalMapOnBFacet1[lDof1]],
228  M_ycoord_known[localToGlobalMapOnBFacet1[lDof1]],
229  M_zcoord_known[localToGlobalMapOnBFacet1[lDof1]],
230  feBd1.refFE().xi ( lDof1 ),
231  feBd1.refFE().eta ( lDof1 ) );
232 
233  if ( lDof1 < 3 )
234  FaceDof[lDof1] = fespace->mesh()->boundaryFacet ( i ).point ( lDof1 ).markerID ();
235 
236  }
237 
238  if ( localToGlobalMapOnBFacet1.size() > 3 )
239  {
240  // a p2 dof that was not in the mesh, so a dof the we inserted, has flag 1439 (random number) or it inherits the flag of the edge
241  FaceDof[3] = ( FaceDof[0] == FaceDof[1] ) ? FaceDof[0] : M_flag;
242  FaceDof[4] = ( FaceDof[1] == FaceDof[2] ) ? FaceDof[1] : M_flag;
243  FaceDof[5] = ( FaceDof[0] == FaceDof[2] ) ? FaceDof[0] : M_flag;
244  }
245 
246  for (ID lDof1 = 0; lDof1 < localToGlobalMapOnBFacet1.size(); lDof1++)
247  {
248  M_marker_known[localToGlobalMapOnBFacet1[lDof1]] = FaceDof[lDof1];
249  if ( FaceDof[lDof1] == M_flag )
250  M_GIdsKnownMesh_common.insert(localToGlobalMapOnBFacet1[lDof1]);
251  }
252  }
253  }
254 
255  M_dof_connectivity_known.resize(numTotalDof);
256 
257  for ( int i = 0; i < numTotalDof; ++i )
258  {
259  if ( M_marker_known[i] == M_flag)
260  {
261  for ( int j = 0; j < numTotalDof; ++j )
262  {
263  if ( M_marker_known[j] == M_flag)
264  {
265  Real distance = std::sqrt( (M_xcoord_known[i] - M_xcoord_known[j])*(M_xcoord_known[i] - M_xcoord_known[j]) +
266  (M_ycoord_known[i] - M_ycoord_known[j])*(M_ycoord_known[i] - M_ycoord_known[j]) +
267  (M_zcoord_known[i] - M_zcoord_known[j])*(M_zcoord_known[i] - M_zcoord_known[j]) );
268  if ( distance < M_links )
269  {
270  M_dof_connectivity_known[i].push_back(j);
271  }
272  }
273  }
274  }
275  }
276 
277  /*
278  for ( int i = 0; i < numTotalDof; ++i )
279  {
280  if ( M_marker_known[i] == M_flag)
281  {
282  std::cout << "GID " << i;
283  for ( int k = 0; k < M_dof_connectivity_known[i].size(); ++k )
284  {
285  std::cout << " " << M_dof_connectivity_known[i][k];
286  }
287  std::cout << "\n";
288  }
289  }
290  */
291 
292  /*
293  for ( int i = 0; i < numTotalDof; ++i )
294  {
295  for ( int k = 0; k < dof_element_connectivity[i].size(); ++k )
296  {
297  feBd1.update ( fespace->mesh()->boundaryFacet ( dof_element_connectivity[i][k] ), UPDATE_ONLY_CELL_NODES );
298  std::vector<ID> localToGlobalMapOnBFacet1 = fespace->dof().localToGlobalMapOnBdFacet ( dof_element_connectivity[i][k] );
299  for (ID lDof1 = 0; lDof1 < localToGlobalMapOnBFacet1.size(); lDof1++)
300  {
301  M_dof_connectivity_known[i].push_back(localToGlobalMapOnBFacet1[lDof1]);
302  }
303  }
304  std::sort( M_dof_connectivity_known[i].begin(), M_dof_connectivity_known[i].end() );
305  M_dof_connectivity_known[i].erase( unique( M_dof_connectivity_known[i].begin(), M_dof_connectivity_known[i].end() ), M_dof_connectivity_known[i].end() );
306  }
307  */
308 
309 
310  /*
311  // stampa coordinate
312  if ( fespace->map().commPtr()->MyPID() == 0 )
313  for ( int i = 0 ; i < M_xcoord_known.size(); ++i )
314  std::cout << "GID " << i << ", x = " << M_xcoord_known[i] << ", y = " << M_ycoord_known[i] << ", z = " << M_zcoord_known[i] << std::endl;
315  */
316 
317  /*
318  // stampa connettivita tra dof
319  if ( fespace->map().commPtr()->MyPID() == 0 )
320  {
321  for ( int i = 0 ; i < M_dof_connectivity_known.size(); ++i )
322  {
323  std::cout << "GID " << i << " ha " << M_dof_connectivity_known[i].size() << " vicini\n";
324  for ( int j = 0 ; j < M_dof_connectivity_known[i].size(); ++j )
325  {
326  std::cout << " " << M_dof_connectivity_known[i][j];
327  }
328  std::cout << "\n";
329  }
330  }
331  */
332 
333  /*
334  // stampa flag di ogni dof
335  if ( fespace->map().commPtr()->MyPID() == 0 )
336  {
337  for ( int i = 0 ; i < M_marker_known.size(); ++i )
338  std::cout << "DOF " << i << " has flag " << M_marker_known[i] << std::endl;
339  }
340  */
341 }
342 
343 void
345 {
346  M_marker_unknown.clear();
347  M_xcoord_unknown.clear();
348  M_ycoord_unknown.clear();
349  M_zcoord_unknown.clear();
350  M_marker_known.clear();
351  M_xcoord_known.clear();
352  M_ycoord_known.clear();
353  M_zcoord_known.clear();
354  M_GIdsUnknownMesh_common.clear();
355  M_GIdsKnownMesh_common.clear();
356  M_GIdsKnownMesh.clear();
357  M_GIdsUnknownMesh.clear();
358 }
359 
360 void
362 {
363  CurrentFEManifold feBd1 ( fespace->refFE().boundaryFE(), getGeometricMap ( *fespace->mesh() ).boundaryMap() );
364 
365  int numBFaces = fespace->mesh()->numBFaces();
366  int numTotalDof = fespace->dof().numTotalDof();
367 
368  std::vector< std::vector<int> > dof_element_connectivity(numTotalDof);
369 
370  M_marker_unknown.resize(numTotalDof);
371  M_xcoord_unknown.resize(numTotalDof);
372  M_ycoord_unknown.resize(numTotalDof);
373  M_zcoord_unknown.resize(numTotalDof);
374 
375  for ( int i = 0; i < numBFaces; ++i )
376  {
377  if ( fespace->mesh()->boundaryFacet ( i ).markerID() == M_flag )
378  {
379  feBd1.update ( fespace->mesh()->boundaryFacet ( i ), UPDATE_ONLY_CELL_NODES ); // Updating facet information on mesh1
380  std::vector<ID> localToGlobalMapOnBFacet1 = fespace->dof().localToGlobalMapOnBdFacet (i);
381 
382  // devo riempire vettore con marker di ogni dof
383  VectorSmall<6> FaceDof;
384  FaceDof *= 0;
385 
386  for (ID lDof1 = 0; lDof1 < localToGlobalMapOnBFacet1.size(); lDof1++)
387  {
388  dof_element_connectivity[localToGlobalMapOnBFacet1[lDof1]].push_back(i);
389 
390  feBd1.coorMap ( M_xcoord_unknown[localToGlobalMapOnBFacet1[lDof1]],
391  M_ycoord_unknown[localToGlobalMapOnBFacet1[lDof1]],
392  M_zcoord_unknown[localToGlobalMapOnBFacet1[lDof1]],
393  feBd1.refFE().xi ( lDof1 ),
394  feBd1.refFE().eta ( lDof1 ) );
395 
396  if ( lDof1 < 3 )
397  FaceDof[lDof1] = fespace->mesh()->boundaryFacet ( i ).point ( lDof1 ).markerID ();
398  }
399 
400  if ( localToGlobalMapOnBFacet1.size() > 3 )
401  {
402  // a p2 dof that was not in the mesh, so a dof the we inserted, has flag 1439 (random number) or it inherits the flag of the edge
403  FaceDof[3] = ( FaceDof[0] == FaceDof[1] ) ? FaceDof[0] : M_flag;
404  FaceDof[4] = ( FaceDof[1] == FaceDof[2] ) ? FaceDof[1] : M_flag;
405  FaceDof[5] = ( FaceDof[0] == FaceDof[2] ) ? FaceDof[0] : M_flag;
406  }
407 
408  for (ID lDof1 = 0; lDof1 < localToGlobalMapOnBFacet1.size(); lDof1++)
409  {
410  M_marker_unknown[localToGlobalMapOnBFacet1[lDof1]] = FaceDof[lDof1];
411  if ( FaceDof[lDof1] == M_flag )
412  M_GIdsUnknownMesh_common.insert(localToGlobalMapOnBFacet1[lDof1]);
413  }
414  }
415  }
416 
417  /*
418  if ( fespace->map().commPtr()->MyPID() == 0 )
419  for ( int i = 0 ; i < M_xcoord_unknown.size(); ++i )
420  std::cout << "GID " << i << ", x = " << M_xcoord_unknown[i] << ", y = " << M_ycoord_unknown[i] << ", z = " << M_zcoord_unknown[i] << std::endl;
421  */
422 
423  /*
424  // stampa connettivita tra dof
425  if ( fespace->map().commPtr()->MyPID() == 0 )
426  {
427  for ( int i = 0 ; i < M_dof_connectivity_unknown.size(); ++i )
428  {
429  std::cout << "GID " << i << " ha " << M_dof_connectivity_unknown[i].size() << " vicini\n";
430  for ( int j = 0 ; j < M_dof_connectivity_unknown[i].size(); ++j )
431  {
432  std::cout << " " << M_dof_connectivity_unknown[i][j];
433  }
434  std::cout << "\n";
435  }
436  }
437  */
438  /*
439  // stampa flag di ogni dof
440  if ( fespace->map().commPtr()->MyPID() == 0 )
441  {
442  for ( int i = 0 ; i < M_marker_unknown.size(); ++i )
443  std::cout << "DOF " << i << " has flag " << M_marker_unknown[i] << std::endl;
444  }
445  */
446 }
447 
448 void
450 {
451  for (std::set<ID>::iterator it = M_GIdsKnownMesh_common.begin(); it != M_GIdsKnownMesh_common.end(); ++it)
452  {
453  if ( M_knownField->mapPtr()->map(Unique)->LID( static_cast<EpetraInt_Type> ( *it ) ) >= 0 )
454  {
455  M_GIdsKnownMesh.insert(*it);
456  }
457  }
458 }
459 
460 void
462 {
463  for (std::set<ID>::iterator it = M_GIdsUnknownMesh_common.begin(); it != M_GIdsUnknownMesh_common.end(); ++it)
464  {
465  if ( M_unknownField->mapPtr()->map(Unique)->LID( static_cast<EpetraInt_Type> ( *it ) ) >= 0 )
466  {
467  M_GIdsUnknownMesh.insert(*it);
468  }
469  }
470 }
471 
472 void
474 {
475  std::vector<int> dofKnown;
476  dofKnown.reserve ( M_GIdsKnownMesh.size() );
477 
478  std::set<ID>::const_iterator i;
479 
480  for (UInt dim = 0; dim < nDimensions; ++dim)
481  for ( i = M_GIdsKnownMesh.begin(); i != M_GIdsKnownMesh.end(); ++i )
482  {
483  dofKnown.push_back ( *i + dim * M_knownField->size()/nDimensions );
484  }
485 
486  int* pointerToDofs (0);
487  if (dofKnown.size() > 0)
488  {
489  pointerToDofs = &dofKnown[0];
490  }
491 
492  M_knownInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofKnown.size() ), pointerToDofs, M_knownField->mapPtr()->commPtr() ) );
493 
494  // std::cout << " M_knownInterfaceMap size " << M_knownInterfaceMap->map(Unique)->NumGlobalElements() << std::endl;
495  // std::cout << " M_knownInterfaceMap local size " << M_knownInterfaceMap->map(Unique)->NumMyElements() << std::endl;
496 }
497 
498 void
500 {
501  std::vector<int> dofunKnown;
502  dofunKnown.reserve ( M_GIdsUnknownMesh.size() );
503 
504  std::set<ID>::const_iterator i;
505 
506  for (UInt dim = 0; dim < nDimensions; ++dim)
507  for ( i = M_GIdsUnknownMesh.begin(); i != M_GIdsUnknownMesh.end(); ++i )
508  {
509  dofunKnown.push_back ( *i + dim * M_unknownField->size()/nDimensions );
510  }
511 
512  int* pointerToDofs (0);
513  if (dofunKnown.size() > 0)
514  {
515  pointerToDofs = &dofunKnown[0];
516  }
517 
518  M_unknownInterfaceMap.reset ( new MapEpetra ( -1, static_cast<int> (dofunKnown.size() ), pointerToDofs, M_unknownField->mapPtr()->commPtr() ) );
519 
520 // std::cout << " M_unknownInterfaceMap size " << M_unknownInterfaceMap->map(Unique)->NumGlobalElements() << std::endl;
521 }
522 
523 void
525 {
526  std::set<ID>::const_iterator ITrow;
527 
528  Int numtasks = M_knownField->mapPtr()->commPtr()->NumProc(); // Numero di processi
529  int* numInterfaceDof (new int[numtasks]); // vettore lungo tanti quanti sono i processi
530  int pid = M_knownField->mapPtr()->commPtr()->MyPID(); // ID processo
531  M_pid = pid;
532  int numMyElements;
533 
534  numMyElements = M_knownInterfaceMap->map (Unique)->NumMyElements(); // numero di elementi sul processo
535  numInterfaceDof[pid] = numMyElements; // Ogni processore mette nella propria posizione il numero di elementi di interfaccia che ha
536 
537  mapPtr_Type subMap;
538  subMap.reset ( new map_Type ( *M_knownInterfaceMap->map (Unique), (UInt) 0, M_knownField->size()/nDimensions) );
539 
540  M_numerationInterfaceKnown.reset (new VectorEpetra (*subMap, Unique) );
541 
542  for (int j = 0; j < numtasks; ++j)
543  {
544  M_knownField->mapPtr()->commPtr()->Broadcast ( &numInterfaceDof[j], 1, j);
545  }
546 
547  for (int j = numtasks - 1; j > 0 ; --j)
548  {
549  numInterfaceDof[j] = numInterfaceDof[j - 1];
550  }
551  numInterfaceDof[0] = 0;
552  for (int j = 1; j < numtasks ; ++j)
553  {
554  numInterfaceDof[j] += numInterfaceDof[j - 1];
555  }
556 
557  UInt l = 0;
558 
559  Real M_interface = (UInt) M_knownInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions; // Quanti dof ci sono nella mappa scalare di interfaccia
560  for (l = 0, ITrow = M_GIdsKnownMesh.begin(); ITrow != M_GIdsKnownMesh.end() ; ++ITrow)
561  {
562  if (M_knownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
563  {
564  (*M_numerationInterfaceKnown) [*ITrow ] = l + (int) (numInterfaceDof[pid] / nDimensions);
565  if ( (int) (*M_numerationInterfaceKnown) (*ITrow ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
566  {
567  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
568  }
569  ++l;
570  }
571  }
572 
573  M_numerationInterfaceKnownColumns.resize(numtasks);
574 
575  for (int j = 0; j < numtasks ; ++j)
576  (M_numerationInterfaceKnownColumns[j]).reset(new vector_Type ( *M_numerationInterfaceKnown, j ) );
577 
578  std::vector<int> couplingVector;
579  couplingVector.reserve ( (int) (M_knownInterfaceMap->map (Unique)->NumMyElements() ) );
580 
581  for ( ITrow = M_GIdsKnownMesh.begin(); ITrow != M_GIdsKnownMesh.end() ; ++ITrow)
582  {
583  if (M_knownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
584  {
585  couplingVector.push_back ( (*M_numerationInterfaceKnown) (*ITrow ) );
586  }
587  }
588 
589  M_interpolationOperatorMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_knownField->mapPtr()->commPtr() ) );
590 
591  M_interpolationOperatorMapVectorial.reset ( new MapEpetra ( *M_interpolationOperatorMap ) );
592  *M_interpolationOperatorMapVectorial += *M_interpolationOperatorMap;
593  *M_interpolationOperatorMapVectorial += *M_interpolationOperatorMap;
594 
595 // std::cout << "\n\n\n" << M_interpolationOperatorMap->map(Unique)->NumGlobalElements() << "\n\n\n";
596 
597  delete [] numInterfaceDof;
598 }
599 
600 void
602 {
603  std::set<ID>::const_iterator ITrow;
604 
605  Int numtasks = M_unknownField->mapPtr()->commPtr()->NumProc(); // Numero di processi
606  int* numInterfaceDof (new int[numtasks]); // vettore lungo tanti quanti sono i processi
607  int pid = M_unknownField->mapPtr()->commPtr()->MyPID(); // ID processo
608  int numMyElements;
609 
610  numMyElements = M_unknownInterfaceMap->map (Unique)->NumMyElements(); // numero di elementi sul processo
611  numInterfaceDof[pid] = numMyElements; // Ogni processore mette nella propria posizione il numero di elementi di interfaccia che ha
612 
613  mapPtr_Type subMap;
614  subMap.reset ( new map_Type ( *M_unknownInterfaceMap->map (Unique), (UInt) 0, M_unknownField->size()/nDimensions) );
615 
616  M_numerationInterfaceUnknown.reset (new VectorEpetra (*subMap, Unique) );
617 
618  for (int j = 0; j < numtasks; ++j)
619  {
620  M_unknownField->mapPtr()->commPtr()->Broadcast ( &numInterfaceDof[j], 1, j);
621  }
622 
623  for (int j = numtasks - 1; j > 0 ; --j)
624  {
625  numInterfaceDof[j] = numInterfaceDof[j - 1];
626  }
627  numInterfaceDof[0] = 0;
628  for (int j = 1; j < numtasks ; ++j)
629  {
630  numInterfaceDof[j] += numInterfaceDof[j - 1];
631  }
632 
633  UInt l = 0;
634 
635  Real M_interface = (UInt) M_unknownInterfaceMap->map (Unique)->NumGlobalElements() / nDimensions; // Quanti dof ci sono nella mappa scalare di interfaccia
636  for (l = 0, ITrow = M_GIdsUnknownMesh.begin(); ITrow != M_GIdsUnknownMesh.end() ; ++ITrow)
637  {
638  if (M_unknownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
639  {
640  (*M_numerationInterfaceUnknown) [*ITrow ] = l + (int) (numInterfaceDof[pid] / nDimensions);
641  if ( (int) (*M_numerationInterfaceUnknown) (*ITrow ) != floor (l + numInterfaceDof[pid] / nDimensions + 0.2) )
642  {
643  std::cout << "ERROR! the numeration of the coupling map is not correct" << std::endl;
644  }
645  ++l;
646  }
647  }
648 
649  std::vector<int> couplingVector;
650  couplingVector.reserve ( (int) (M_unknownInterfaceMap->map (Unique)->NumMyElements() ) );
651 
652  for ( ITrow = M_GIdsUnknownMesh.begin(); ITrow != M_GIdsUnknownMesh.end() ; ++ITrow)
653  {
654  if (M_unknownInterfaceMap->map (Unique)->LID ( static_cast<EpetraInt_Type> (*ITrow) ) >= 0)
655  {
656  couplingVector.push_back ( (*M_numerationInterfaceUnknown) (*ITrow ) );
657  }
658  }
659 
660  M_projectionOperatorMap.reset (new MapEpetra (-1, static_cast< Int> ( couplingVector.size() ), &couplingVector[0], M_unknownField->mapPtr()->commPtr() ) );
661 
662  M_projectionOperatorMapVectorial.reset ( new MapEpetra ( *M_projectionOperatorMap ) );
663  *M_projectionOperatorMapVectorial += *M_projectionOperatorMap;
664  *M_projectionOperatorMapVectorial += *M_projectionOperatorMap;
665 
666  delete [] numInterfaceDof;
667 }
668 
669 void
671 {
672  M_RhsOne.reset (new vector_Type (*M_interpolationOperatorMap) );
673  *M_RhsOne += 1;
674 
675  M_RhsF1.reset (new vector_Type (*M_interpolationOperatorMap) );
676  M_RhsF2.reset (new vector_Type (*M_interpolationOperatorMap) );
677  M_RhsF3.reset (new vector_Type (*M_interpolationOperatorMap) );
678 
679  UInt offset = M_knownField->size()/3;
680 
681  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
682  {
683  (*M_RhsF1)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
684  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i));
685 
686  (*M_RhsF2)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
687  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
688 
689  (*M_RhsF3)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
690  = (*M_knownField)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
691 
692 // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
693 // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
694  }
695 }
696 
697 void
699 {
700  vectorPtr_Type gamma_one;
701  gamma_one.reset (new vector_Type (*M_interpolationOperatorMap) );
702 
703  // Preconditioner
704  prec_Type* precRawPtr;
705  basePrecPtr_Type precPtr;
706  precRawPtr = new prec_Type;
707  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
708  precPtr.reset ( precRawPtr );
709 
710  LinearSolver solverOne;
711  solverOne.setCommunicator ( M_knownField->mapPtr()->commPtr() );
712  solverOne.setParameters ( *M_belosList );
713  solverOne.setPreconditioner ( precPtr );
714 
716  solverOne.setRightHandSide ( M_RhsOne );
717  solverOne.solve ( gamma_one );
718 
719  M_rbf_one.reset (new vector_Type (*M_projectionOperatorMap) );
720  M_projectionOperator->multiply (false, *gamma_one, *M_rbf_one);
721 }
722 
723 void
725 {
726  vectorOnOmega.reset ( new vector_Type ( M_knownField->map(), Unique ) );
727  vectorOnOmega->zero();
728 
729  UInt offset = vectorOnOmega->map().map(Unique)->NumGlobalElements()/3;
730  UInt offsetGamma = vectorOnGamma->map().map(Unique)->NumGlobalElements()/3;
731 
732  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
733  {
734  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i)]
735  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]);
736 
737  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i) + offset]
738  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + offsetGamma );
739 
740  (*vectorOnOmega)[M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset]
741  = (*vectorOnGamma)((*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + 2*offsetGamma);
742 
743  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
744  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
745  }
746 }
747 
748 void
750 {
751  vectorOnGamma.reset ( new vector_Type ( *M_interpolationOperatorMapVectorial, Unique ) );
752  vectorOnGamma->zero();
753 
754  UInt offset = vectorOnOmega->map().map(Unique)->NumGlobalElements()/3;
755  UInt offsetGamma = vectorOnGamma->map().map(Unique)->NumGlobalElements()/3;
756 
757  for ( int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i )
758  {
759  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
760  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i));
761 
762  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + offsetGamma ]
763  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
764 
765  (*vectorOnGamma)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] + 2*offsetGamma ]
766  = (*vectorOnOmega)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
767 
768  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
769  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
770  }
771 }
772 
773 void
775 {
776  vectorPtr_Type gamma_f1;
777  gamma_f1.reset (new vector_Type (*M_interpolationOperatorMap) );
778 
779  vectorPtr_Type gamma_f2;
780  gamma_f2.reset (new vector_Type (*M_interpolationOperatorMap) );
781 
782  vectorPtr_Type gamma_f3;
783  gamma_f3.reset (new vector_Type (*M_interpolationOperatorMap) );
784 
785  // Preconditioner
786  if ( !M_precBuilt )
787  {
788  prec_Type* precRawPtr;
789  precRawPtr = new prec_Type;
790  precRawPtr->setDataFromGetPot ( M_datafile, "prec" );
791  M_precPtr.reset ( precRawPtr );
792  M_precBuilt = true;
793  }
794 
795  // Solving for component x
796  LinearSolver solverRBF1;
797  solverRBF1.setCommunicator ( M_knownField->mapPtr()->commPtr() );
798  solverRBF1.setParameters ( *M_belosList );
799  solverRBF1.setPreconditioner ( M_precPtr );
800 
802  solverRBF1.setRightHandSide (M_RhsF1);
803  solverRBF1.solve (gamma_f1);
804 
805  // Solving for component y
806  LinearSolver solverRBF2;
807  solverRBF2.setCommunicator ( M_knownField->mapPtr()->commPtr() );
808  solverRBF2.setParameters ( *M_belosList );
809  solverRBF2.setPreconditioner ( M_precPtr );
810 
812  solverRBF2.setRightHandSide (M_RhsF2);
813  solverRBF2.solve (gamma_f2);
814 
815  // Solving for component z
816  LinearSolver solverRBF3;
817  solverRBF3.setCommunicator ( M_knownField->mapPtr()->commPtr() );
818  solverRBF3.setParameters ( *M_belosList );
819  solverRBF3.setPreconditioner ( M_precPtr );
820 
822  solverRBF3.setRightHandSide (M_RhsF3);
823  solverRBF3.solve (gamma_f3);
824 
825  vectorPtr_Type rbf_f1;
826  rbf_f1.reset (new vector_Type (*M_projectionOperatorMap) );
827 
828  vectorPtr_Type solution1;
829  solution1.reset (new vector_Type (*M_projectionOperatorMap) );
830 
831  M_projectionOperator->multiply (false, *gamma_f1, *rbf_f1);
832 
833  // Rescaling component x
834  *solution1 = *rbf_f1;
835  *solution1 /= *M_rbf_one;
836 
837  vectorPtr_Type rbf_f2;
838  rbf_f2.reset (new vector_Type (*M_projectionOperatorMap) );
839 
840  vectorPtr_Type solution2;
841  solution2.reset (new vector_Type (*M_projectionOperatorMap) );
842 
843  M_projectionOperator->multiply (false, *gamma_f2, *rbf_f2);
844 
845  // Rescaling component y
846  *solution2 = *rbf_f2;
847  *solution2 /= *M_rbf_one;
848 
849  vectorPtr_Type rbf_f3;
850  rbf_f3.reset (new vector_Type (*M_projectionOperatorMap) );
851 
852  vectorPtr_Type solution3;
853  solution3.reset (new vector_Type (*M_projectionOperatorMap) );
854 
855  M_projectionOperator->multiply (false, *gamma_f3, *rbf_f3);
856 
857  // Rescaling component z
858  *solution3 = *rbf_f3;
859  *solution3 /= *M_rbf_one;
860 
861  // Solution of the interpolation problem
862 
863  UInt offset = M_unknownField->size()/3;
864 
865  for(int i = 0; i < M_numerationInterfaceUnknown->epetraVector().MyLength(); ++i)
866  {
867  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i)]
868  = (*solution1)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
869 
870  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i) + offset]
871  = (*solution2)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
872 
873  (*M_unknownField)[M_numerationInterfaceUnknown->blockMap().GID(i) + 2*offset]
874  = (*solution3)((*M_numerationInterfaceUnknown)[M_numerationInterfaceUnknown->blockMap().GID(i)]);
875 
876  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
877  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
878  }
879 
880  // Storing also the solution on gamma
881 
882  M_solutionOnGamma.reset ( new vector_Type ( *M_projectionOperatorMapVectorial ) );
883  M_solutionOnGamma->zero();
884 
885  UInt offsetScalar = M_solutionOnGamma->size()/3;
886 
887  M_solutionOnGamma->subset(*solution1, *M_projectionOperatorMap, 0, 0);
888  M_solutionOnGamma->subset(*solution2, *M_projectionOperatorMap, 0, offsetScalar );
889  M_solutionOnGamma->subset(*solution3, *M_projectionOperatorMap, 0, 2*offsetScalar);
890 }
891 
892 void
894 {
895  Solution->zero();
896  *Solution += *M_unknownField;
897 }
898 
899 void
901 {
902  M_RhsF1->zero();
903  M_RhsF2->zero();
904  M_RhsF3->zero();
905 
906  UInt offset = M_knownField->size()/3;
907 
908  for(int i = 0; i < M_numerationInterfaceKnown->epetraVector().MyLength(); ++i)
909  {
910  (*M_RhsF1)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
911  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i));
912 
913  (*M_RhsF2)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
914  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i) + offset);
915 
916  (*M_RhsF3)[(*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)]]
917  = (*newRhs)(M_numerationInterfaceKnown->blockMap().GID(i) + 2*offset);
918 
919  // std::cout << "GID = " << M_numerationInterfaceKnown->blockMap().GID(i)
920  // << ", Value =" << (*M_numerationInterfaceKnown)[M_numerationInterfaceKnown->blockMap().GID(i)] << std::endl;
921  }
922 }
923 
924 } // Namespace LifeV
std::shared_ptr< vector_Type > vectorPtr_Type
void solution(vectorPtr_Type &Solution)
double computeRBFradius_unknown(const ID &index, std::vector< int > indexes)
vectorPtr_Type M_RhsF3
void buildInterpolationOperatorMap()
A class for a finite element on a manifold.
Teuchos::RCP< Teuchos::ParameterList > parameterList_Type
void buildTableDofs_unknown(const FESpacePtr_Type &fespace)
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
vectorPtr_Type M_RhsF1
uint32_type ID
IDs.
Definition: LifeV.hpp:194
void setVectors(const vectorPtr_Type &KnownField, const vectorPtr_Type &UnknownField)
matrixPtr_Type M_interpolationOperator
LinearSolver - Class to wrap linear solver.
void setOperator(operatorPtr_Type operPtr)
Method to set a general linear operator (of class derived from Epetra_Operator) defining the linear s...
vectorPtr_Type M_RhsOne
std::shared_ptr< MapEpetra > mapPtr_Type
void setRightHandSide(const vectorPtr_Type rhsPtr)
Method to set the right hand side (rhs) of the linear system.
LifeV::PreconditionerIfpack prec_Type
vectorPtr_Type M_RhsF2
std::shared_ptr< basePrec_Type > basePrecPtr_Type
parameterList_Type M_belosList
double Real
Generic real data.
Definition: LifeV.hpp:175
double computeRBFradius_known(const ID &index, std::vector< int > indexes)
void setPreconditioner(operatorPtr_Type preconditionerPtr)
Method to set a general Epetra_Operator as preconditioner.
void setup(const GetPot &datafile, parameterList_Type belosList)
void buildTableDofs_known(const FESpacePtr_Type &fespace)
std::shared_ptr< FESpace_Type > FESpacePtr_Type
void updateRhs(const vectorPtr_Type &newRhs)
double rbf(double x1, double y1, double z1, double x2, double y2, double z2, double radius)
void expandGammaToOmega_Known(const vectorPtr_Type &vectorOnGamma, vectorPtr_Type &vectorOnOmega)
Int solve(vectorPtr_Type solutionPtr)
Solves the system and returns the number of iterations.
basePrecPtr_Type M_precPtr
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void restrictOmegaToGamma_Known(const vectorPtr_Type &vectorOnOmega, vectorPtr_Type &vectorOnGamma)