src/INTERPOLATION/MEDMEM_Interpolation.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00002 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00003 // 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either 
00007 // version 2.1 of the License.
00008 // 
00009 // This library is distributed in the hope that it will be useful 
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
00012 // Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public  
00015 // License along with this library; if not, write to the Free Software 
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 //
00018 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00019 //
00020 # ifndef INTERPOLATION_HXX
00021 # define INTERPOLATION_HXX
00022 
00023 //template < class T> class FIELD;
00024 //template < int > class Wrapper_Nuage;
00025 //template < int > class Wrapper_Noeud;
00026 //template <class ,class ,int ,int > class dTree;
00027 
00028 #include <vector>
00029 #include "MEDMEM_Utilities.hxx"
00030 #include "MEDMEM_Exception.hxx"
00031 #include "MEDMEM_define.hxx"
00032 
00033 #include "MEDMEM_InterpolationHighLevelObjects.hxx"
00034 #include "MEDMEM_Mesh.hxx"
00035 #include "MEDMEM_Field.hxx"
00036 
00037 namespace MEDMEM {
00038 class MESH;
00039 
00040 template <int DIMENSION=3> class INTERPOLATION
00041 {
00042 protected:
00043 
00044   FIELD<double> *          _fromField;
00045   FIELD<double> *             _toField;
00046   MESH   *                        _fromMesh;
00047   MESH   *                        _toMesh;
00048   
00049   Meta_Wrapper<DIMENSION>  *      _fromWrapper;
00050   Meta_Wrapper<DIMENSION>  *      _toWrapper;
00051   
00052   Meta_Mapping <DIMENSION> *      _mapping;
00053 
00054 // only used when multi timestep are interpolated
00055 // but always coherent
00056   int                      _iType;
00057   int                      _isConvexFromMesh;
00058   
00059 public :
00060 
00061   void init();
00062 
00063   // Initialize INTERPOLATION in order to get : 
00064   // 1- the node number in the MESH  <fromMesh> which
00065   //     is the nearest from a given one ( use method : getNearestNode( double * node ) ); 
00066   // 2- the cell number (if exists) in the MESH <fromMesh> which
00067   //     contains a specified node ( use method : getContainingCell ( double * node) )
00068   INTERPOLATION(const MESH & fromMesh ); 
00069   // Initialize INTERPOLATION in order to get :
00070   // 1- the complete mapping ( use methode : getMapping() )
00071   // 2- the functionalities above 
00072   INTERPOLATION(const MESH & fromMesh,const MESH & toMesh ); 
00073   // Initialize INTERPOLATION in order to get the interpolation of <field> on <toMesh>
00074   // Moreover, all the others functionalities are so available
00075   INTERPOLATION(const FIELD<double> & fromField, const MESH & toMesh);
00076 
00077   ~INTERPOLATION( ); 
00078 
00079   //  Get the node number in the MESH  <fromMesh> which is the nearest from a given one
00080   int getNearestNode    ( double * node );
00081   //  Get the cell number (if exists) in the MESH <fromMesh> which contains a specified node 
00082   int getContainingCell ( double * node , int beginingCell=0, int flagIsConvexMesh=0 );
00083   // Get the complete mapping, defaultly, fromMesh is supposed to be non-convex, if it is false, set flagIsConvexMesh to 1
00084   vector<int> getMapping ( int flagIsConvexMesh=0 );
00085   // Get the interpolated field toField
00086   FIELD<double> * interpolate( /*med_interpolation_type*/ int itype,int flagIsConvexFromMesh=0);
00087   // reset the <from> parameters in order not to redo the mapping (if the mesh are identical)
00088   // and then get the interpoated field toField
00089   // this method is specifictly used on multi-timestep (or order number) fields
00090   // it has only to be used after the first step, the interpolation paramaters are the same for every step
00091   FIELD<double> * interpolateNextStep(const FIELD <double> &nextFromField ,int & flagNewMapping);
00092 
00093 };
00094 
00095 template <int DIMENSION> void INTERPOLATION<DIMENSION>::init() {
00096 
00097   const char * LOC = "INTERPOLATION::init(): ";
00098 
00099   BEGIN_OF(LOC);
00100   _fromField   = ( FIELD<double> * )           NULL;
00101   _toField     = ( FIELD<double> * )           NULL;
00102   _fromMesh    = ( MESH * )                    NULL;
00103   _toMesh      = ( MESH * )                    NULL;
00104   _fromWrapper = ( Meta_Wrapper<DIMENSION> * ) NULL;
00105   _toWrapper   = ( Meta_Wrapper<DIMENSION> * ) NULL;
00106   _mapping     = ( Meta_Mapping<DIMENSION> * ) NULL;
00107   _iType            = UNDEFINED ;
00108   _isConvexFromMesh = UNDEFINED ;
00109   END_OF(LOC);
00110 }
00111 
00112 
00113 template <int DIMENSION> INTERPOLATION<DIMENSION>::INTERPOLATION(const MESH & fromMesh ) {
00114 
00115   const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh ) : ";
00116   BEGIN_OF(LOC);
00117   
00118   init(); 
00119   
00120   _fromMesh=const_cast<MESH * > (&fromMesh);
00121   
00122   if (! _fromMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromMesh is a NULL pointer  !")) ;
00123   
00124   int spaceDimension = _fromMesh->getSpaceDimension();
00125   if (spaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" << _fromMesh->getName() << "| is |" << spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ;
00126 
00127   _fromWrapper = new Meta_Wrapper<DIMENSION>(_fromMesh->getNumberOfNodes(),
00128                                              const_cast<double *> (_fromMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)),
00129                               const_cast<CONNECTIVITY *> (_fromMesh->getConnectivityptr())
00130                               );
00131 
00132   _mapping     = new  Meta_Mapping<DIMENSION> (_fromWrapper);
00133                                  
00134   END_OF(LOC);
00135 }; 
00136 
00137 template <int DIMENSION> INTERPOLATION<DIMENSION>::INTERPOLATION(const MESH & fromMesh,const MESH & toMesh ) {
00138 
00139   const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh,,const MESH & toMesh) : ";
00140   BEGIN_OF(LOC);
00141   
00142   init(); 
00143   
00144   _fromMesh = const_cast<MESH * > ( &fromMesh );
00145   _toMesh   = const_cast<MESH * > ( &toMesh   );
00146   
00147   if (! _fromMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromMesh is a NULL pointer  !")) ;
00148   if (! _toMesh   ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toMesh   is a NULL pointer  !")) ;
00149   
00150   int fromSpaceDimension = _fromMesh->getSpaceDimension();
00151   int toSpaceDimension   =   _toMesh->getSpaceDimension();
00152   
00153   if (fromSpaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" << _fromMesh->getName() << "| is |" << INTERPOLATION<DIMENSION>::spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ;
00154   if (  toSpaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" <<   _toMesh->getName() << "| is |" << INTERPOLATION<DIMENSION>::spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ;
00155  
00156   _fromWrapper = new Meta_Wrapper<DIMENSION>(_fromMesh->getNumberOfNodes(),
00157                                              const_cast<double *> (_fromMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)),
00158                               const_cast<CONNECTIVITY *> (_fromMesh->getConnectivityptr())
00159                               );
00160 
00161   _toWrapper   = new Meta_Wrapper<DIMENSION>(_toMesh->getNumberOfNodes(),
00162                                              const_cast<double *> (_toMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE))
00163                               );
00164 
00165   _mapping     = new  Meta_Mapping<DIMENSION> (_fromWrapper);
00166                                  
00167   END_OF(LOC);
00168 };
00169 
00170 template <int DIMENSION> INTERPOLATION<DIMENSION>::INTERPOLATION(const FIELD<double> & fromField,const MESH & toMesh) {
00171 
00172   const char * LOC = "INTERPOLATION(const FIELD<double> & field,const MESH & toMesh) : ";
00173   BEGIN_OF(LOC);
00174   
00175   init();
00176 
00177   _toMesh    = const_cast<MESH *>(&toMesh);
00178   _fromField = const_cast<FIELD<double> *>(&fromField);
00179 
00180   if ( ! _toMesh    )  throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toMesh is a NULL pointer  !")) ;
00181   if ( ! _fromField )  throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"field is a NULL pointer  !")) ;
00182 
00183   _fromMesh = _fromField->getSupport()->getMesh();
00184   
00185   if ( ! _fromMesh    )  throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromMesh is a NULL pointer  !")) ;
00186 
00187   _fromWrapper = new Meta_Wrapper<DIMENSION>(_fromMesh->getNumberOfNodes(),
00188                                              const_cast<double *> (_fromMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)),
00189                               const_cast<MEDMEM::CONNECTIVITY *> (_fromMesh->getConnectivityptr()),
00190                               const_cast<MEDMEM::FIELD<double> *>(_fromField)
00191                               );
00192                               
00193                               
00194   _toWrapper   = new Meta_Wrapper<DIMENSION>(_toMesh->getNumberOfNodes(),
00195                                              const_cast<double *> (_toMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE))
00196                               );  
00197 
00198   
00199   _mapping     = new  Meta_Mapping<DIMENSION> (_fromWrapper);
00200   
00201                            
00202   END_OF(LOC);
00203 };
00204 
00205 template <int DIMENSION> INTERPOLATION<DIMENSION>::~INTERPOLATION()
00206 {
00207   if ( _fromWrapper  ) delete _fromWrapper ;    
00208   if ( _toWrapper    ) delete _toWrapper   ;    
00209   if ( _mapping      ) delete _mapping     ;
00210 };
00211 
00212 template <int DIMENSION> int INTERPOLATION<DIMENSION>::getNearestNode(  double * node ) {
00213   
00214   const char * LOC = "INTERPOLATION::getNearestNode( double * node ) ";
00215 
00216   BEGIN_OF(LOC);
00217   
00218   if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer  !")) ;
00219   
00220   return _mapping->Donne_dTree()->trouve_plus_proche_point(Wrapper_Noeud<DIMENSION > (node) );
00221   
00222   END_OF(LOC);
00223 
00224 };
00225 
00226 template <int DIMENSION> int INTERPOLATION<DIMENSION>::getContainingCell ( double * node , int beginingCell, int flagIsConvexMesh ) {
00227   
00228   const char * LOC = "INTERPOLATION::getContainingCell( double * node ) ";
00229 
00230   BEGIN_OF(LOC);
00231   
00232   if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer  !")) ;
00233 
00234   _isConvexFromMesh=flagIsConvexMesh;
00235 
00236   _mapping->Cree_Mapping(_toWrapper,_isConvexFromMesh);
00237 
00238   return _mapping->Trouve_Maille_Contenant_Noeud(node,beginingCell,flagIsConvexMesh);
00239   
00240   END_OF(LOC);
00241 
00242 };
00243 
00244 template <int DIMENSION> vector<int> INTERPOLATION<DIMENSION>::getMapping ( int flagIsConvexMesh ) {
00245   
00246   const char * LOC = "INTERPOLATION::getMapping( ) ";
00247 
00248   BEGIN_OF(LOC);
00249 
00250   if ( ! _mapping   ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer  !")) ;
00251   if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper  is a NULL pointer  !")) ;
00252 
00253   _isConvexFromMesh=flagIsConvexMesh;
00254 
00255   _mapping->Cree_Mapping(_toWrapper,_isConvexFromMesh);
00256 
00257   return _mapping->Get_Mapping();
00258   
00259   END_OF(LOC);
00260 
00261 };
00262 
00263 template <int DIMENSION> FIELD<double> * INTERPOLATION<DIMENSION>::interpolate(int itype,int flagIsConvexFromMesh) {
00264   
00265   const char * LOC = "INTERPOLATION::interpolate(int itype,int flagIsConvexFromMesh) ";
00266 
00267   BEGIN_OF(LOC);
00268 
00269   if ( ! _mapping      ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer  !")) ;
00270   if ( ! _toWrapper    ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper  is a NULL pointer  !")) ;
00271   if ( ! _fromField    ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromField  is a NULL pointer  !")) ;
00272 
00273   _iType=itype;
00274 
00275   _isConvexFromMesh=flagIsConvexFromMesh;
00276 
00277   _mapping->Cree_Mapping(_toWrapper,_isConvexFromMesh);
00278   
00279   Wrapper_Nuage_Noeud<DIMENSION> * toNodes = _toWrapper->Get_Nuage_Noeuds();
00280   
00281   Wrapper_MED_Field resultat;
00282   
00283   /*
00284   cout<<"Mapping"<<endl;
00285   _mapping->affiche();
00286   cout<<"Mailles"<<endl;
00287   _fromWrapper->Get_Maillage()->DONNE_POINTEUR_NUAGEMAILLE()->affiche();
00288   cout<<"Noeuds"<<endl;
00289   _fromWrapper->Get_Nuage_Noeuds()->affiche();
00290   */
00291   
00292   switch (_iType)
00293     {
00294     case 0 : // INTERPOLATION P0
00295       cout<<"Avant ="<<endl;
00296       resultat=Meta_Interpolateur< Meta_Calcul_Interpolation_P0<DIMENSION>,DIMENSION >(_mapping,_fromWrapper).Perform_Interpolation(toNodes);
00297       break;
00298     case 1 : // INTERPOLATION P-Hybride (Interpole avec la fonction d'interpolation naturelle de la maille contenant le point)
00299       resultat=Meta_Interpolateur< Meta_Calcul_Interpolation_Hybride<DIMENSION>,DIMENSION >(_mapping,_fromWrapper).Perform_Interpolation(toNodes);
00300       break;
00301     case 2 : // INTERPOLATION (P/Q) 1 forcée (Interpole avec la fonction élément fini de la maille de degré 1 -meme si la maille est de degré supérieur-)
00302       resultat=Meta_Interpolateur< Meta_Calcul_Interpolation_Hybride_P1<DIMENSION>, DIMENSION >(_mapping,_fromWrapper).Perform_Interpolation(toNodes);
00303       break;
00304     default : 
00305       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Interpolation type "<<itype<<" not yet implemented !")) ;
00306     }
00307 
00308   cout<<"On a fini l'interpolation"<<endl;   
00309 
00310   _toField = new FIELD<double>;
00311   
00312   _toField->setName            ( _fromField->getName()           );
00313   _toField->setDescription          ( _fromField->getDescription()         );
00314   _toField->setNumberOfComponents     ( _fromField->getNumberOfComponents()     );
00315   _toField->setNumberOfValues       ( _toMesh   ->getNumberOfNodes()       );
00316   _toField->setComponentsNames        ( _fromField->getComponentsNames()        );
00317   _toField->setComponentsDescriptions ( _fromField->getComponentsDescriptions() );
00318   _toField->setMEDComponentsUnits     ( _fromField->getMEDComponentsUnits()     );
00319   _toField->setIterationNumber        ( _fromField->getIterationNumber()        );
00320   _toField->setTime            ( _fromField->getTime()              );
00321   _toField->setOrderNumber          ( _fromField->getOrderNumber()         );
00322   //  _toField->setValueType        ( MED_EN::MED_REEL64              );
00323 
00324   SUPPORT * mySupport(new SUPPORT(_toMesh,"support",MED_EN::MED_NODE));
00325   _toField->setSupport(mySupport);  
00326   
00327   _toField->allocValue(_toField->getNumberOfComponents(),_toField->getNumberOfValues());
00328     
00329   _toField->setValue(resultat.Get_Valeurs());
00330  
00331   _toWrapper->Construit_Wrapper_Champ(_toField);
00332 
00333   return _toField;
00334   
00335   END_OF(LOC);
00336 
00337 };
00338 
00339 template <int DIMENSION> FIELD<double> * INTERPOLATION<DIMENSION>::interpolateNextStep(const FIELD <double> & nextFromField, int & flagNewMapping) {
00340   
00341   const char * LOC = "INTERPOLATION::interpolateNextStep(int itype,int flagIsConvexFromMesh) ";
00342 
00343   BEGIN_OF(LOC);
00344 
00345   if ( ! _mapping      ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer  !"        ));
00346   if ( ! _toWrapper    ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper  is a NULL pointer  !"     )) ;
00347   if ( ! _fromWrapper  ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromWrapper  is a NULL pointer  !"   )) ;  
00348   if ( ! _fromField    ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromField  is a NULL pointer  !"     )) ;
00349   
00350   
00351   if ( ! _toField                   ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toField  is a NULL pointer, wrong use of interpolateNextStep"       )) ;
00352   if ( _iType==UNDEFINED            ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_iType is not defined, wrong use of interpolateNextStep"            )) ;
00353   if ( _isConvexFromMesh==UNDEFINED ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"_isConvexFromMesh is not defined, wrong use of interpolateNextStep" )) ;  
00354 
00355   // delete _toField; ????????????????????????????
00356 
00357   // if the mesh are identical, the mapping is the same, if not, the mapping has to be re-calculated
00358   if (nextFromField.getSupport()->getMesh()->getName()!=_fromMesh->getName())
00359      {
00360      
00361      flagNewMapping=1;
00362      
00363      delete _mapping;
00364      delete _fromWrapper;
00365 
00366         _fromField = const_cast<FIELD<double> *>(&nextFromField);
00367 
00368         _fromMesh = _fromField->getSupport()->getMesh();
00369 
00370      _fromWrapper = new Meta_Wrapper<DIMENSION>(_fromMesh->getNumberOfNodes(),
00371                                  const_cast<double *> (_fromMesh->getCoordinates(MED_EN::MED_FULL_INTERLACE)),
00372                                  const_cast<MEDMEM::CONNECTIVITY *> (_fromMesh->getConnectivityptr()),
00373                                  const_cast<MEDMEM::FIELD<double> *>(_fromField)
00374                                  );
00375      _mapping     = new  Meta_Mapping<DIMENSION> (_fromWrapper);
00376      
00377      _mapping->Cree_Mapping(_toWrapper,_isConvexFromMesh);
00378      
00379      }
00380   else
00381      {
00382      
00383      flagNewMapping=0;
00384      
00385      _fromField = const_cast<MEDMEM::FIELD<double> *>(&nextFromField);
00386      _fromWrapper->Change_Champ(const_cast<MEDMEM::FIELD<double> *>(_fromField));         
00387      }
00388   
00389   return interpolate(_iType,_isConvexFromMesh);
00390 
00391 };
00392 
00393 };
00394 
00395 #endif
00396 
00397