From 211c851d80b87846294d5e7dd43e4af2ab282d35 Mon Sep 17 00:00:00 2001 From: nadir Date: Fri, 29 Aug 2003 12:08:49 +0000 Subject: [PATCH] update from the MedMemory V1.0.1 --- idl/MED.idl | 84 +- .../INTERPOLATION/MEDMEM_Interpolation.hxx | 286 ++++++ .../MEDMEM_InterpolationHighLevelObjects.hxx | 409 ++++++++ ...DMEM_InterpolationHighLevelObjects.hxx.old | 104 ++ .../MEDMEM_InterpolationTools.hxx | 475 ++++++++++ src/MEDMEM/INTERPOLATION/MEDMEM_Mapping.hxx | 242 +++++ .../INTERPOLATION/MEDMEM_MappingTools.hxx | 199 ++++ .../INTERPOLATION/MEDMEM_WrapperCells.hxx | 887 ++++++++++++++++++ .../MEDMEM_WrapperConnectivity.hxx | 61 ++ .../INTERPOLATION/MEDMEM_WrapperField.hxx | 201 ++++ .../INTERPOLATION/MEDMEM_WrapperMesh.hxx | 260 +++++ .../INTERPOLATION/MEDMEM_WrapperNodes.hxx | 109 +++ src/MEDMEM/INTERPOLATION/MEDMEM_dTree.hxx | 620 ++++++++++++ .../INTERPOLATION/MEDMEM_dTreeSommet.hxx | 59 ++ .../INTERPOLATION/create_mesh_interpolation.c | 433 +++++++++ .../test_MEDMEM_Interpolation.cxx | 56 ++ src/Makefile.in | 2 +- src/MedClient/Makefile.in | 40 + src/MedClient/src/CONNECTIVITYClient.cxx | 312 ++++++ src/MedClient/src/CONNECTIVITYClient.hxx | 62 ++ src/MedClient/src/COORDINATEClient.cxx | 107 +++ src/MedClient/src/COORDINATEClient.hxx | 59 ++ src/MedClient/src/FAMILYClient.cxx | 83 ++ src/MedClient/src/FAMILYClient.hxx | 31 + src/MedClient/src/FIELDClient.hxx | 70 ++ src/MedClient/src/GROUPClient.cxx | 44 + src/MedClient/src/GROUPClient.hxx | 32 + src/MedClient/src/MESHClient.cxx | 143 +++ src/MedClient/src/MESHClient.hxx | 30 + src/MedClient/src/Makefile.in | 83 ++ src/MedClient/src/SUPPORTClient.cxx | 134 +++ src/MedClient/src/SUPPORTClient.hxx | 37 + src/MedClient/src/UtilClient.hxx | 113 +++ src/MedClient/src/libMEDClient.i | 50 + src/MedClient/test/Makefile.in | 39 + src/MedClient/test/environ/Makefile.in | 73 ++ src/MedClient/test/environ/csh/Makefile.in | 43 + src/MedClient/test/environ/csh/init1.in | 7 + src/MedClient/test/environ/csh/init2.in | 11 + src/MedClient/test/environ/csh/init3.in | 2 + .../test/environ/csh/runContainer.in | 57 ++ .../test/environ/csh/runEnvironTests.in | 32 + .../test/environ/csh/stopContainer.in | 83 ++ src/MedClient/test/environ/runContainer.in | 17 + src/MedClient/test/environ/runEnvironTests.in | 17 + src/MedClient/test/environ/runTestMedCorba.in | 22 + src/MedClient/test/environ/stopContainer.in | 17 + .../test/resources/carre_en_quad4_seg2.med | Bin 0 -> 50746 bytes src/MedClient/test/resources/maill.0.med | Bin 0 -> 100352 bytes src/MedClient/test/resources/pointe.med | Bin 0 -> 80011 bytes .../test/resources/test_hydro_darcy1a_out.med | Bin 0 -> 328756 bytes src/MedClient/test/test1/Compo1.py | 53 ++ src/MedClient/test/test1/Compo1Py.idl | 14 + src/MedClient/test/test1/Compo1Py.py | 34 + src/MedClient/test/test1/Makefile.in | 52 + src/MedClient/test/test1/TestMedCorba1.py | 78 ++ src/MedClient/test/test1/TestMedCorba2.py | 84 ++ src/MedClient/test/test1/TestMedCorba3.py | 105 +++ src/MedClient/test/test1/TestMedCorba4.py | 76 ++ src/MedClient/test/test1/TestMedCorba5.py | 85 ++ src/MedClient/test/test2/Compo2.cxx | 74 ++ src/MedClient/test/test2/Compo2.hxx | 24 + src/MedClient/test/test2/Makefile.in | 56 ++ src/MedClient/test/test2/TestMedCorba6.py | 69 ++ src/MedClient/test/test2/TestMedCorba7.py | 76 ++ src/MedClient/test/test2/TestMedCorba8.py | 39 + src/MedClient/test/test2/libCompo2.i | 10 + 67 files changed, 7222 insertions(+), 44 deletions(-) create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_Interpolation.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx.old create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationTools.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_Mapping.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_MappingTools.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_WrapperCells.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_WrapperConnectivity.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_WrapperField.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_WrapperMesh.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_WrapperNodes.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_dTree.hxx create mode 100644 src/MEDMEM/INTERPOLATION/MEDMEM_dTreeSommet.hxx create mode 100644 src/MEDMEM/INTERPOLATION/create_mesh_interpolation.c create mode 100644 src/MEDMEM/INTERPOLATION/test_MEDMEM_Interpolation.cxx create mode 100644 src/MedClient/Makefile.in create mode 100644 src/MedClient/src/CONNECTIVITYClient.cxx create mode 100644 src/MedClient/src/CONNECTIVITYClient.hxx create mode 100644 src/MedClient/src/COORDINATEClient.cxx create mode 100644 src/MedClient/src/COORDINATEClient.hxx create mode 100644 src/MedClient/src/FAMILYClient.cxx create mode 100644 src/MedClient/src/FAMILYClient.hxx create mode 100644 src/MedClient/src/FIELDClient.hxx create mode 100644 src/MedClient/src/GROUPClient.cxx create mode 100644 src/MedClient/src/GROUPClient.hxx create mode 100644 src/MedClient/src/MESHClient.cxx create mode 100644 src/MedClient/src/MESHClient.hxx create mode 100644 src/MedClient/src/Makefile.in create mode 100644 src/MedClient/src/SUPPORTClient.cxx create mode 100644 src/MedClient/src/SUPPORTClient.hxx create mode 100644 src/MedClient/src/UtilClient.hxx create mode 100644 src/MedClient/src/libMEDClient.i create mode 100644 src/MedClient/test/Makefile.in create mode 100644 src/MedClient/test/environ/Makefile.in create mode 100644 src/MedClient/test/environ/csh/Makefile.in create mode 100644 src/MedClient/test/environ/csh/init1.in create mode 100644 src/MedClient/test/environ/csh/init2.in create mode 100644 src/MedClient/test/environ/csh/init3.in create mode 100644 src/MedClient/test/environ/csh/runContainer.in create mode 100644 src/MedClient/test/environ/csh/runEnvironTests.in create mode 100644 src/MedClient/test/environ/csh/stopContainer.in create mode 100644 src/MedClient/test/environ/runContainer.in create mode 100644 src/MedClient/test/environ/runEnvironTests.in create mode 100644 src/MedClient/test/environ/runTestMedCorba.in create mode 100644 src/MedClient/test/environ/stopContainer.in create mode 100644 src/MedClient/test/resources/carre_en_quad4_seg2.med create mode 100644 src/MedClient/test/resources/maill.0.med create mode 100644 src/MedClient/test/resources/pointe.med create mode 100644 src/MedClient/test/resources/test_hydro_darcy1a_out.med create mode 100644 src/MedClient/test/test1/Compo1.py create mode 100644 src/MedClient/test/test1/Compo1Py.idl create mode 100644 src/MedClient/test/test1/Compo1Py.py create mode 100644 src/MedClient/test/test1/Makefile.in create mode 100644 src/MedClient/test/test1/TestMedCorba1.py create mode 100644 src/MedClient/test/test1/TestMedCorba2.py create mode 100644 src/MedClient/test/test1/TestMedCorba3.py create mode 100644 src/MedClient/test/test1/TestMedCorba4.py create mode 100644 src/MedClient/test/test1/TestMedCorba5.py create mode 100644 src/MedClient/test/test2/Compo2.cxx create mode 100644 src/MedClient/test/test2/Compo2.hxx create mode 100644 src/MedClient/test/test2/Makefile.in create mode 100644 src/MedClient/test/test2/TestMedCorba6.py create mode 100644 src/MedClient/test/test2/TestMedCorba7.py create mode 100644 src/MedClient/test/test2/TestMedCorba8.py create mode 100644 src/MedClient/test/test2/libCompo2.i diff --git a/idl/MED.idl b/idl/MED.idl index d282c81f5..36dec0a32 100644 --- a/idl/MED.idl +++ b/idl/MED.idl @@ -39,49 +39,44 @@ module SALOME_MED { interface MESH; interface SUPPORT; - enum medGeometryElement { - MED_NONE, - MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_TRIA3, - MED_QUAD4, - MED_TRIA6, - MED_QUAD8, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_ALL_ELEMENTS - }; - - enum medEntityMesh { - MED_CELL, - MED_FACE, - MED_EDGE, - MED_NODE, - MED_ALL_ENTITIES - }; - - enum medModeSwitch { - MED_FULL_INTERLACE, - MED_NO_INTERLACE - }; + typedef long medGeometryElement; + const medGeometryElement MED_NONE = 0; + const medGeometryElement MED_POINT1 = 1; + const medGeometryElement MED_SEG2 = 102; + const medGeometryElement MED_SEG3 = 103; + const medGeometryElement MED_TRIA3 = 203; + const medGeometryElement MED_QUAD4 = 204; + const medGeometryElement MED_TRIA6 = 206; + const medGeometryElement MED_QUAD8 = 208; + const medGeometryElement MED_TETRA4 = 304; + const medGeometryElement MED_PYRA5 = 305; + const medGeometryElement MED_PENTA6 = 306; + const medGeometryElement MED_HEXA8 = 308; + const medGeometryElement MED_TETRA10 = 310; + const medGeometryElement MED_PYRA13 = 313; + const medGeometryElement MED_PENTA15 = 315; + const medGeometryElement MED_HEXA20 = 320; + const medGeometryElement MED_ALL_ELEMENTS = 999; + + typedef long medEntityMesh; + const medEntityMesh MED_CELL = 0; + const medEntityMesh MED_FACE = 1; + const medEntityMesh MED_EDGE = 2; + const medEntityMesh MED_NODE = 3; + const medEntityMesh MED_ALL_ENTITIES = 4; + + typedef long medModeSwitch; + const medModeSwitch MED_FULL_INTERLACE = 0; + const medModeSwitch MED_NO_INTERLACE = 1; - enum medConnectivity { - MED_NODAL, - MED_DESCENDING - }; + typedef long medConnectivity; + const medConnectivity MED_NODAL = 0; + const medConnectivity MED_DESCENDING = 1; - enum medDriverTypes { - MED_DRIVER , - VTK_DRIVER , - NO_DRIVER - }; + typedef long medDriverTypes; + const medDriverTypes MED_DRIVER = 0; + const medDriverTypes VTK_DRIVER = 1; + const medDriverTypes NO_DRIVER = 2; /*! An array of medGeometryElement @@ -135,7 +130,7 @@ module SALOME_MED { - "CYLINDRICAL" - "SPHERICAL" */ - string getCoordinateSystem() raises (SALOME::SALOME_Exception); + string getCoordinatesSystem() raises (SALOME::SALOME_Exception); /*! Returns the number of nodes defined in mesh. @@ -456,7 +451,10 @@ module SALOME_MED { /*! If isOnAllElements is false, returns index of element number. - Use it with getNumber(MED_ALL_ELEMENTS). + Use it with getNumber(MED_ALL_ELEMENTS). + _numberOfCellsFamilies, + IOR_Mesh->getFamilies(MED_CELL), + (void *) (convertFamily), this); Note : See getConnectivityIndex for details. */ diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_Interpolation.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_Interpolation.hxx new file mode 100644 index 000000000..9ea924aed --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_Interpolation.hxx @@ -0,0 +1,286 @@ +# ifndef INTERPOLATION_HXX +# define INTERPOLATION_HXX + +class MESH; +//template < class T> class FIELD; +//template < int > class Wrapper_Nuage; +//template < int > class Wrapper_Noeud; +//template class dTree; + +#include "utilities.h" +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_InterpolationHighLevelObjects.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Field.hxx" + +template class INTERPOLATION +{ +protected: + + FIELD * _fromField; + FIELD * _toField; + MESH * _fromMesh; + MESH * _toMesh; + + Meta_Wrapper * _fromWrapper; + Meta_Wrapper * _toWrapper; + + Meta_Mapping * _mapping; + +public : + + void init(); + + // Initialize INTERPOLATION in order to get : + // 1- the node number in the MESH which + // is the nearest from a given one ( use method : getNearestNode( double * node ) ); + // 2- the cell number (if exists) in the MESH which + // contains a specified node ( use method : getContainingCell ( double * node) ) + INTERPOLATION(const MESH & fromMesh ); + // Initialize INTERPOLATION in order to get : + // 1- the complete mapping ( use methode : getMapping() ) + // 2- the functionalities above + INTERPOLATION(const MESH & fromMesh,const MESH & toMesh ); + // Initialize INTERPOLATION in order to get the interpolation of on + // Moreover, all the others functionalities are so available + INTERPOLATION(const FIELD & fromField, const MESH & toMesh); + + ~INTERPOLATION( ); + + // Get the node number in the MESH which is the nearest from a given one + int getNearestNode ( double * node ); + // Get the cell number (if exists) in the MESH which contains a specified node + int getContainingCell ( double * node , int beginingCell=0, int flagIsConvexMesh=0 ); + // Get the complete mapping, defaultly, fromMesh is supposed to be non-convex, if it is false, set flagIsConvexMesh to 1 + vector getMapping ( int flagIsConvexMesh=0 ); + // Get the interpolated field toField + FIELD * interpolate( /*med_interpolation_type*/ int itype,int flagIsConvexFromMesh=0); + +}; + + +template void INTERPOLATION::init() { + + const char * LOC = "INTERPOLATION::init(): "; + + BEGIN_OF(LOC); + _fromField = ( FIELD * ) NULL; + _toField = ( FIELD * ) NULL; + _fromMesh = ( MESH * ) NULL; + _toMesh = ( MESH * ) NULL; + _fromWrapper = ( Meta_Wrapper * ) NULL; + _toWrapper = ( Meta_Wrapper * ) NULL; + _mapping = ( Meta_Mapping * ) NULL; + END_OF(LOC); +} + + +template INTERPOLATION::INTERPOLATION(const MESH & fromMesh ) { + + const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh ) : "; + BEGIN_OF(LOC); + + init(); + + _fromMesh=const_cast (&fromMesh); + + if (! _fromMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromMesh is a NULL pointer !")) ; + + int spaceDimension = _fromMesh->getSpaceDimension(); + if (spaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" << _fromMesh->getName() << "| is |" << spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ; + + _fromWrapper = new Meta_Wrapper(_fromMesh->getNumberOfNodes(), + const_cast (_fromMesh->getCoordinates(MED_FULL_INTERLACE)), + const_cast (_fromMesh->getConnectivityptr()) + ); + + _mapping = new Meta_Mapping (_fromWrapper); + + END_OF(LOC); +}; + +template INTERPOLATION::INTERPOLATION(const MESH & fromMesh,const MESH & toMesh ) { + + const char * LOC = "INTERPOLATION::INTERPOLATION(MESH * fromMesh,,const MESH & toMesh) : "; + BEGIN_OF(LOC); + + init(); + + _fromMesh = const_cast ( &fromMesh ); + _toMesh = const_cast ( &toMesh ); + + if (! _fromMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromMesh is a NULL pointer !")) ; + if (! _toMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toMesh is a NULL pointer !")) ; + + int fromSpaceDimension = _fromMesh->getSpaceDimension(); + int toSpaceDimension = _toMesh->getSpaceDimension(); + + if (fromSpaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" << _fromMesh->getName() << "| is |" << spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ; + if ( toSpaceDimension != DIMENSION ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"The spaceDimension of mesh |" << _toMesh->getName() << "| is |" << spaceDimension << "| and should be |" << DIMENSION << "|" << endl)) ; + + _fromWrapper = new Meta_Wrapper(_fromMesh->getNumberOfNodes(), + const_cast (_fromMesh->getCoordinates(MED_FULL_INTERLACE)), + const_cast (_fromMesh->getConnectivityptr()) + ); + + _toWrapper = new Meta_Wrapper(_toMesh->getNumberOfNodes(), + const_cast (_toMesh->getCoordinates(MED_FULL_INTERLACE)) + ); + + _mapping = new Meta_Mapping (_fromWrapper); + + END_OF(LOC); +}; + +template INTERPOLATION::INTERPOLATION(const FIELD & fromField,const MESH & toMesh) { + + const char * LOC = "INTERPOLATION::INTERPOLATION(const FIELD & field,const MESH & toMesh) : "; + BEGIN_OF(LOC); + + init(); + + _toMesh = const_cast(&toMesh); + _fromField = const_cast *>(&fromField); + + if ( ! _toMesh ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toMesh is a NULL pointer !")) ; + if ( ! _fromField ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"field is a NULL pointer !")) ; + + _fromMesh = _fromField->getSupport()->getMesh(); + + _fromWrapper = new Meta_Wrapper(_fromMesh->getNumberOfNodes(), + const_cast (_fromMesh->getCoordinates(MED_FULL_INTERLACE)), + const_cast (_fromMesh->getConnectivityptr()), + const_cast *>(_fromField) + ); + + _toWrapper = new Meta_Wrapper(_toMesh->getNumberOfNodes(), + const_cast (_toMesh->getCoordinates(MED_FULL_INTERLACE)) + ); + + _mapping = new Meta_Mapping (_fromWrapper); + + END_OF(LOC); +}; + +template INTERPOLATION::~INTERPOLATION() +{ + if ( _fromWrapper ) delete _fromWrapper ; + if ( _toWrapper ) delete _toWrapper ; + if ( _mapping ) delete _mapping ; +}; + +template int INTERPOLATION::getNearestNode( double * node ) { + + const char * LOC = "INTERPOLATION::getNearestNode( double * node ) "; + + BEGIN_OF(LOC); + + if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; + + return _mapping->Donne_dTree()->trouve_plus_proche_point(Wrapper_Noeud (node) ); + + END_OF(LOC); + +}; + +template int INTERPOLATION::getContainingCell ( double * node , int beginingCell, int flagIsConvexMesh ) { + + const char * LOC = "INTERPOLATION::getContainingCell( double * node ) "; + + BEGIN_OF(LOC); + + if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; + + return _mapping->Trouve_Maille_Contenant_Noeud(node,beginingCell,flagIsConvexMesh); + + END_OF(LOC); + +}; + +template vector INTERPOLATION::getMapping ( int flagIsConvexMesh ) { + + const char * LOC = "INTERPOLATION::getMapping( ) "; + + BEGIN_OF(LOC); + + if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; + if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper is a NULL pointer !")) ; + + mapping_->Cree_Mapping(_toWrapper,flag_convexe); + + return _mapping->Get_Mapping(); + + END_OF(LOC); + +}; + +template FIELD * INTERPOLATION::interpolate( /*med_interpolation_type*/ int itype,int flagIsConvexFromMesh) { + + const char * LOC = "INTERPOLATION::interpolate( /*med_interpolation_type*/ int itype) "; + + BEGIN_OF(LOC); + + if ( ! _mapping ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"mapping is a NULL pointer !")) ; + if ( ! _toWrapper ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"toWrapper is a NULL pointer !")) ; + if ( ! _fromField ) throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"fromField is a NULL pointer !")) ; + + _mapping->Cree_Mapping(_toWrapper,flagIsConvexFromMesh); + + Wrapper_Nuage_Noeud * toNodes = _toWrapper->Get_Nuage_Noeuds(); + + Wrapper_MED_Field resultat; + +cout<<"On commence l'interpolation"<; + + _toField->setName ( _fromField->getName()+"XXX" ); + _toField->setDescription ( _fromField->getDescription() ); + _toField->setNumberOfComponents ( _fromField->getNumberOfComponents() ); + _toField->setNumberOfValues ( _toMesh ->getNumberOfNodes() ); + _toField->setComponentsNames ( _fromField->getComponentsNames() ); + _toField->setComponentsDescriptions ( _fromField->getComponentsDescriptions() ); + _toField->setMEDComponentsUnits ( _fromField->getMEDComponentsUnits() ); + _toField->setIterationNumber ( _fromField->getIterationNumber() ); + _toField->setTime ( _fromField->getTime() ); + _toField->setOrderNumber ( _fromField->getOrderNumber() ); + _toField->setValueType ( MED_EN::MED_REEL64 ); + + SUPPORT * mySupport(new SUPPORT(_toMesh,"support",MED_NODE)); + _toField->setSupport(mySupport); + + _toField->allocValue(_toField->getNumberOfComponents(),_toField->getNumberOfValues()); + + _toField->setValue(MED_FULL_INTERLACE,resultat.Get_Valeurs()); + + _toWrapper->Construit_Wrapper_Champ(_toField); + + return _toField; + + END_OF(LOC); + +}; + +#endif + + diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx new file mode 100644 index 000000000..ece92a5f6 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_InterpolationHighLevelObjects.hxx @@ -0,0 +1,409 @@ +#ifndef MEDMEM_INTERPOLATION_HIGHLEVEL_OBJECTS_HXX +#define MEDMEM_INTERPOLATION_HIGHLEVEL_OBJECTS_HXX + +#include "MEDMEM_Connectivity.hxx" +#include "MEDMEM_WrapperConnectivity.hxx" +#include "MEDMEM_dTree.hxx" +#include "MEDMEM_WrapperNodes.hxx" +#include "MEDMEM_WrapperMesh.hxx" +#include "MEDMEM_WrapperCells.hxx" +#include "MEDMEM_Mapping.hxx" +#include "MEDMEM_WrapperField.hxx" +#include "MEDMEM_InterpolationTools.hxx" + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS /// +/// /// +////////////////////////////////////////////////////////////////// + +template class Meta_Wrapper; + +/*********************************************************/ +/* */ +/* Meta_dTree */ +/* */ +/*********************************************************/ + +template class Meta_dTree : public dTree,Wrapper_Nuage_Noeud,DIMENSION> +{ +public : + inline int trouve_plus_proche_point(double *node); +}; + +/*********************************************************/ +/* */ +/* Meta_Nuage_Maille */ +/* */ +/*********************************************************/ + + +class Meta_Nuage_Maille : public Wrapper_Nuage_Maille +{ +protected : + Wrapper_Med_Connectivity * connectivite_med; +public : + Meta_Nuage_Maille(CONNECTIVITY * connmed); + Meta_Nuage_Maille():connectivite_med(NULL) {} + ~Meta_Nuage_Maille() {if (connectivite_med) delete connectivite_med;} +}; + +/*********************************************************/ +/* */ +/* Meta_Maillage */ +/* */ +/*********************************************************/ + + +typedef Wrapper_Maillage Meta_Maillage; + +/*********************************************************/ +/* */ +/* Meta_Mapping */ +/* */ +/*********************************************************/ + +template class Meta_Mapping : public Mapping,Wrapper_Noeud,DIMENSION> +{ +public : + Meta_Mapping(Meta_Wrapper * MW):Mapping,Wrapper_Noeud,DIMENSION>(MW->Get_Maillage(),MW->Get_Nuage_Noeuds(),NULL) {} + Meta_Mapping(Meta_Wrapper * MW,Meta_Wrapper * TWB):Mapping,Wrapper_Noeud,DIMENSION>(MW->Get_Maillage(),MW->Get_Nuage_Noeuds(),TWB->Get_Nuage_Noeuds()) {} + void Cree_Mapping(Meta_Wrapper * MWB, int flag_convexe) {Mapping,Wrapper_Noeud,DIMENSION>::Cree_Mapping(MWB->Get_Nuage_Noeuds(),flag_convexe);} + inline int Trouve_Maille_Contenant_Noeud(double * node,int num_maille, int flag_convexe=0); +}; + +/*********************************************************/ +/* */ +/* Meta_Wrapper */ +/* */ +/*********************************************************/ + + +template class Meta_Wrapper +{ +protected : + Wrapper_Nuage_Noeud * noeuds ; + Meta_Nuage_Maille * mailles ; + Meta_Maillage * maillage ; + Wrapper_MED_Field * champ ; + + void init( ){noeuds=NULL;mailles=NULL;maillage=NULL;champ=NULL;} +public : + Meta_Wrapper():noeuds(NULL),mailles(NULL),maillage(NULL),champ(NULL){} + ~Meta_Wrapper(); + inline void Construit_Wrapper_Nuage_Noeud ( int nn, double * nodes ); + inline void Construit_Wrapper_Nuage_Maille ( CONNECTIVITY * connmed ); + inline void Construit_Wrapper_Maillage ( void ); + inline void Construit_Wrapper_Champ ( const FIELD * medfield ); + Meta_Wrapper(int nn,double *nodes,CONNECTIVITY *connmed, int flag_maillage=1); + Meta_Wrapper(int nn,double *nodes); + // defaultly, the connectivity (neighbouhood and so like) is built, + // Set flag_mesh to 0 if you don't want these informations to be built + Meta_Wrapper(int nn,double *nodes,CONNECTIVITY *connmed, const FIELD * c,int flag_mesh=1); + // fonctions d'acces sures + inline Wrapper_Nuage_Noeud * Get_Nuage_Noeuds ( void ); + inline Meta_Nuage_Maille * Get_Nuage_Mailles ( void ); + inline Meta_Maillage * Get_Maillage ( void ); + inline Wrapper_MED_Field * Get_Champ ( void ); +}; + +/*********************************************************/ +/* */ +/* Meta_Calcul_Interpolation_Hybride */ +/* */ +/*********************************************************/ + +template class Meta_Calcul_Interpolation_Hybride : public Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille> +{ +public : + Meta_Calcul_Interpolation_Hybride(Meta_Wrapper * MW):Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(MW->Get_Nuage_Noeuds(),MW->Get_Nuage_Mailles(),MW->Get_Champ()) {} + Valeur operator() (Wrapper_Noeud & node, int num_maille){return Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>::operator()(node,num_maille);} + Valeur operator() (double * node, int num_maille) + { + static Wrapper_Noeud tmp; + tmp.positionne(node); + return Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(tmp,num_maille); + } +}; + +/*********************************************************/ +/* */ +/* Meta_Calcul_Interpolation_Hybride_P1 */ +/* */ +/*********************************************************/ + +template class Meta_Calcul_Interpolation_Hybride_P1 : public Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille> +{ +public : + Meta_Calcul_Interpolation_Hybride_P1(Meta_Wrapper * MW) + { + + Wrapper_Nuage_Noeud * nn = MW->Get_Nuage_Noeuds(); + Meta_Nuage_Maille * nm = MW->Get_Nuage_Mailles(); + Wrapper_MED_Field * c = MW->Get_Champ(); + + mailles=nm; + + fonctions[MED_TRIA3 ]=new Calcul_Interpolation_Tria3 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_QUAD4 ]=new Calcul_Interpolation_Quad4 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_TETRA4 ]=new Calcul_Interpolation_Tetra4 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_HEXA8 ]=new Calcul_Interpolation_Hexa8 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_PENTA6 ]=new Calcul_Interpolation_Penta6 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_PYRA5 ]=new Calcul_Interpolation_Pyra5 ,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(nn,nm,c); + fonctions[MED_TRIA6 ]=fonctions[MED_TRIA3 ]; + fonctions[MED_QUAD8 ]=fonctions[MED_QUAD4 ]; + fonctions[MED_TETRA10]=fonctions[MED_TETRA4 ]; + fonctions[MED_HEXA20 ]=fonctions[MED_HEXA8 ]; + fonctions[MED_PENTA15]=fonctions[MED_PENTA6 ]; + fonctions[MED_PYRA13 ]=fonctions[MED_PYRA5 ]; + } + Valeur operator() (Wrapper_Noeud & node, int num_maille){return Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>::operator()(node,num_maille);} + Valeur operator() (double * node, int num_maille) + { + static Wrapper_Noeud tmp; + tmp.positionne(node); + return Calcul_Hybride,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(tmp,num_maille); + } +}; + +/*********************************************************/ +/* */ +/* Meta_Calcul_Interpolation_P0 */ +/* */ +/*********************************************************/ + +template class Meta_Calcul_Interpolation_P0 : public Calcul_Interpolation_P0,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille> +{ +public : + Meta_Calcul_Interpolation_P0(Meta_Wrapper * MW):Calcul_Interpolation_P0,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(MW->Get_Nuage_Noeuds(),MW->Get_Nuage_Mailles(),MW->Get_Champ()) {} + Valeur operator() (Wrapper_Noeud & node, int num_maille){return Calcul_Interpolation_P0,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>::operator()(node,num_maille);} + Valeur operator() (double * node, int num_maille) + { + static Wrapper_Noeud tmp; + tmp.positionne(node); + return Calcul_Interpolation_P0,Wrapper_Nuage_Noeud,Wrapper_Noeud,Meta_Nuage_Maille>(tmp,num_maille); + } +}; + +/*********************************************************/ +/* */ +/* Meta_Interpolateur */ +/* */ +/*********************************************************/ + +template class Meta_Interpolateur +{ +protected : + FONCTEUR * fct; + Meta_Mapping * mapping; + Meta_Wrapper * fromWrapper; +public : + Meta_Interpolateur():fct(NULL),mapping(NULL),fromWrapper(NULL) {} + Meta_Interpolateur(Meta_Mapping * map, Meta_Wrapper * mw):mapping(map),fromWrapper(mw),fct(new FONCTEUR(mw)){} + ~Meta_Interpolateur() {if (fct) delete fct;} + Wrapper_MED_Field Perform_Interpolation(Wrapper_Nuage_Noeud * toNodes) + { + int i; + + int nbr_composantes = fromWrapper->Get_Champ()->Get_Nbr_Composantes(); + int nbr_valeurs = toNodes->SIZE(); + + double * valeurs=new double[nbr_valeurs*nbr_composantes]; + + Wrapper_MED_Field resultat(nbr_valeurs,nbr_composantes,valeurs); + + int nlpp,nmc; + + for (i=0;i OK ! "< inline int Meta_dTree::trouve_plus_proche_point(double *node) + { + static Wrapper_Noeud nodetmp; + nodetmp.positionne(node); + return dTree,Wrapper_Nuage_Noeud,DIMENSION>::trouve_plus_proche_point(Wrapper_Noeud(nodetmp)); + } + +/*********************************************************/ +/* */ +/* Meta_Nuage_Maille */ +/* */ +/*********************************************************/ + +Meta_Nuage_Maille::Meta_Nuage_Maille(CONNECTIVITY * conmed):Wrapper_Nuage_Maille(connectivite_med=new Wrapper_Med_Connectivity(conmed)) + { + } + +/*********************************************************/ +/* */ +/* Meta_Mapping */ +/* */ +/*********************************************************/ + +template inline int Meta_Mapping::Trouve_Maille_Contenant_Noeud(double * node,int num_maille,int flag_convexe) + { + int interdit=num_maille; + int max_loop=100; + int nme=0; + static Wrapper_Noeud nodetmp; + nodetmp.positionne(node); + return Mapping,Wrapper_Noeud,DIMENSION>::Trouve_Maille_Contenant_Point_Mth_Co(nodetmp,num_maille,interdit,max_loop,nme,flag_convexe); + } + +/*********************************************************/ +/* */ +/* Meta_Wrapper */ +/* */ +/*********************************************************/ + +template Meta_Wrapper::~Meta_Wrapper() + { + if ( noeuds ) delete noeuds ; + if ( mailles ) delete mailles ; + if ( maillage ) delete maillage ; + if ( champ ) delete champ ; + } +template inline void Meta_Wrapper::Construit_Wrapper_Nuage_Noeud ( int nn, double * nodes ) + { + if (nodes) noeuds=new Wrapper_Nuage_Noeud(nn,nodes); + else + { + cerr<<"Meta_Wrapper : Nuage MED_FULL_INTERLACE vide passé en argument au constructeur"< inline void Meta_Wrapper::Construit_Wrapper_Nuage_Maille ( CONNECTIVITY * connmed ) + { + if (connmed) mailles=new Meta_Nuage_Maille(connmed); + else + { + cerr<<"Meta_Wrapper : CONNECTIVITY vide passée en argument au constructeur"< inline void Meta_Wrapper::Construit_Wrapper_Maillage ( void ) + { + if (mailles==NULL) + { + cerr<<"Meta_Wrapper : Le nuage de maille n'a pas été initialisé !"<SIZE()); + } +template inline void Meta_Wrapper::Construit_Wrapper_Champ ( const FIELD * medfield ) + { + if (medfield) champ=new Wrapper_MED_Field(medfield); + else + { + cerr<<"Meta_Wrapper : FIELD MED vide passé en argument au constructeur"< Meta_Wrapper::Meta_Wrapper(int nn,double *nodes,CONNECTIVITY *connmed, int flag_maillage=1) + { + init(); + Construit_Wrapper_Nuage_Noeud(nn,nodes); + Construit_Wrapper_Nuage_Maille(connmed); + if (flag_maillage) Construit_Wrapper_Maillage(); + } +template Meta_Wrapper::Meta_Wrapper(int nn,double *nodes,CONNECTIVITY *connmed, const FIELD * c,int flag_maillage=1) + { + init(); + Construit_Wrapper_Nuage_Noeud(nn,nodes); + Construit_Wrapper_Nuage_Maille(connmed); + if (flag_maillage) Construit_Wrapper_Maillage(); + Construit_Wrapper_Champ(c); + } +template Meta_Wrapper::Meta_Wrapper(int nn,double *nodes) + { + init(); + Construit_Wrapper_Nuage_Noeud(nn,nodes); + } +template inline Wrapper_Nuage_Noeud * Meta_Wrapper::Get_Nuage_Noeuds ( void ) + { + if (noeuds) return noeuds; + else + { + cerr<<"Meta_Wrapper : Nuage noeuds demandé alors qu'il n'est pas construit !"< inline Meta_Nuage_Maille * Meta_Wrapper::Get_Nuage_Mailles ( void ) + { + if (mailles) return mailles ; + else + { + cerr<<"Meta_Wrapper : Nuage mailles demandé alors qu'il n'est pas construit !"< inline Meta_Maillage * Meta_Wrapper::Get_Maillage ( void ) + { + if (maillage) return maillage ; + else + { + cerr<<"Meta_Wrapper : Connectivitée maillage demandée alors qu'elle n'est pas construite !"< inline Wrapper_MED_Field * Meta_Wrapper::Get_Champ ( void ) + { + if (champ) return champ; + else + { + cerr<<"Meta_Wrapper : Champ demandé alors qu'il n'est pas construit !"< class Meta_dTree : public dTree,Wrapper_Nuage_Noeud,DIMENSION> +{ +protected : + Wrapper_Nuage_Noeud * nuagetmp; +public : + Meta_dTree(int nn,double * fullinterlace); + ~Meta_dTree() {if ((etat==DTREE_RACINE)&&(nuagetmp)) delete nuagetmp;} + inline int trouve_plus_proche_point(double *node); +}; + +class Meta_Nuage_Maille : public Wrapper_Nuage_Maille +{ +protected : + Wrapper_Med_Connectivity * connectivite_med; +public : + Meta_Nuage_Maille(CONNECTIVITY * connmed); + Meta_Nuage_Maille():Wrapper_Nuage_Maille(connectivite_med=new Wrapper_Med_Connectivity) {} + ~Meta_Nuage_Maille() {if (connectivite_med) delete connectivite_med;} +}; + + +typedef Wrapper_Maillage Meta_Maillage; + +template class Meta_Mapping : public Mapping,Wrapper_Noeud,DIMENSION> +{ +protected : + Wrapper_Nuage_Noeud * wrapping_nuage_source; + Wrapper_Nuage_Noeud * wrapping_nuage_cible; +public : + Meta_Mapping(Meta_Maillage * mb,double * noeudssource,int ns,double * noeudscible,int nc); + ~Meta_Mapping() {if (wrapping_nuage_source) delete wrapping_nuage_source;if (wrapping_nuage_cible) delete wrapping_nuage_cible;} + inline int Trouve_Maille_Contenant_Noeud(double * node,int num_maille, int flag_convexe=0); + double donne_valeur_interpolee_P1(double * node,vector vals); +}; + +// CODE + +template Meta_dTree::Meta_dTree(int nn,double * fullinterlace) +:dTree,Wrapper_Nuage_Noeud,DIMENSION> +(nuagetmp=new Wrapper_Nuage_Noeud(nn,fullinterlace)) + { + } + +template inline int Meta_dTree::trouve_plus_proche_point(double *node) + { + static Wrapper_Noeud nodetmp; + nodetmp.positionne(node); + return dTree,Wrapper_Nuage_Noeud,DIMENSION>::trouve_plus_proche_point(Wrapper_Noeud(nodetmp)); + } + +//* +Meta_Nuage_Maille::Meta_Nuage_Maille(CONNECTIVITY * conmed):Wrapper_Nuage_Maille(connectivite_med=new Wrapper_Med_Connectivity(conmed)) + { + } +//*/ + +template Meta_Mapping::Meta_Mapping(Meta_Maillage * mb,double * noeudssource,int ns,double * noeudscible,int nc) +:Mapping,Wrapper_Noeud,DIMENSION> +(mb, +wrapping_nuage_source=new Wrapper_Nuage_Noeud(ns,noeudssource), +wrapping_nuage_cible=new Wrapper_Nuage_Noeud(nc,noeudscible)) + { + } + +template inline int Meta_Mapping::Trouve_Maille_Contenant_Noeud(double * node,int num_maille,int flag_convexe) + { + int interdit=num_maille; + int max_loop=100; + int nme=0; + static Wrapper_Noeud nodetmp; + nodetmp.positionne(node); + return Mapping,Wrapper_Noeud,DIMENSION>::Trouve_Maille_Contenant_Point_Mth_Co(nodetmp,num_maille,interdit,max_loop,nme,flag_convexe); + } +template double Meta_Mapping::donne_valeur_interpolee_P1(double * node,vector vals) + { + int num_maille_contenant=Trouve_Maille_Contenant_Noeud(node,0); + double valeur_interpol=0; + vector valeurs=CB->Calcule_Coord_Baryc(num_maille_contenant,node); + int i; + int num_som; + for (i=0;i +#define _PARAM_ CHAMP,VALEURCHAMP,NUAGENOEUD,NOEUD,NUAGEMAILLE + +#define face2367(x,y,z) ((x6*(-y2 + y3) + x3*(y2 - y6) + x2*(-y3 + y6))*z - x6*y3*z2 + x3*y6*z2 + x6*y2*z3 - x2*y6*z3 - x3*y2*z6 + x2*y3*z6 + y*(x6*(z2 - z3) + x2*(z3 - z6) + x3*(-z2 + z6)) + x*(y6*(-z2 + z3) + y3*(z2 - z6) + y2*(-z3 + z6))) +#define face4567(x,y,z) ((x6*(-y4 + y5) + x5*(y4 - y6) + x4*(-y5 + y6))*z - x6*y5*z4 + x5*y6*z4 + x6*y4*z5 - x4*y6*z5 - x5*y4*z6 + x4*y5*z6 + y*(x6*(z4 - z5) + x4*(z5 - z6) + x5*(-z4 + z6)) + x*(y6*(-z4 + z5) + y5*(z4 - z6) + y4*(-z5 + z6))) +#define face1256(x,y,z) ((x5*(-y1 + y2) + x2*(y1 - y5) + x1*(-y2 + y5))*z - x5*y2*z1 + x2*y5*z1 + x5*y1*z2 - x1*y5*z2 - x2*y1*z5 + x1*y2*z5 + y*(x5*(z1 - z2) + x1*(z2 - z5) + x2*(-z1 + z5)) + x*(y5*(-z1 + z2) + y2*(z1 - z5) + y1*(-z2 + z5))) +#define face0347(x,y,z) ((x4*(-y0 + y3) + x3*(y0 - y4) + x0*(-y3 + y4))*z - x4*y3*z0 + x3*y4*z0 + x4*y0*z3 - x0*y4*z3 - x3*y0*z4 + x0*y3*z4 + y*(x4*(z0 - z3) + x0*(z3 - z4) + x3*(-z0 + z4)) + x*(y4*(-z0 + z3) + y3*(z0 - z4) + y0*(-z3 + z4))) +#define face0145(x,y,z) ((x4*(-y0 + y1) + x1*(y0 - y4) + x0*(-y1 + y4))*z - x4*y1*z0 + x1*y4*z0 + x4*y0*z1 - x0*y4*z1 - x1*y0*z4 + x0*y1*z4 + y*(x4*(z0 - z1) + x0*(z1 - z4) + x1*(-z0 + z4)) + x*(y4*(-z0 + z1) + y1*(z0 - z4) + y0*(-z1 + z4))) +#define face0123(x,y,z) ((x2*(-y0 + y1) + x1*(y0 - y2) + x0*(-y1 + y2))*z - x2*y1*z0 + x1*y2*z0 + x2*y0*z1 - x0*y2*z1 - x1*y0*z2 + x0*y1*z2 + y*(x2*(z0 - z1) + x0*(z1 - z2) + x1*(-z0 + z2)) + x*(y2*(-z0 + z1) + y1*(z0 - z2) + y0*(-z1 + z2))) + + + +// DECLARATION + +_TEMPLATE_ class Calcul_Interpolation +{ +protected : + NUAGENOEUD * noeuds; + NUAGEMAILLE * mailles; + CHAMP * champ; +public : + Calcul_Interpolation():noeuds(NULL),mailles(NULL),champ(NULL) {} + Calcul_Interpolation(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):noeuds(nn),mailles(nm),champ(c) {} + ~Calcul_Interpolation() {} + virtual VALEURCHAMP operator() (const NOEUD & n, int num_maille) {cerr<<"APPEL OPERATOR() DE LA CLASSE MERE CALCUL_INTERPOLATION => EXIT(-1)"< *> fonctions; +public : + Calcul_Hybride():mailles(NULL) {} + Calcul_Hybride(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c); + ~Calcul_Hybride() {} + VALEURCHAMP operator() (const NOEUD & n, int num_maille); +}; + +//CODE + +_TEMPLATE_ Calcul_Hybride<_PARAM_>::Calcul_Hybride(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):mailles(nm) + { + fonctions[MED_TRIA3 ]=new Calcul_Interpolation_Tria3 <_PARAM_>(nn,nm,c); + fonctions[MED_TRIA6 ]=new Calcul_Interpolation_Tria6 <_PARAM_>(nn,nm,c); + fonctions[MED_QUAD4 ]=new Calcul_Interpolation_Quad4 <_PARAM_>(nn,nm,c); + fonctions[MED_QUAD8 ]=new Calcul_Interpolation_Quad8 <_PARAM_>(nn,nm,c); + fonctions[MED_TETRA4 ]=new Calcul_Interpolation_Tetra4 <_PARAM_>(nn,nm,c); + fonctions[MED_TETRA10]=new Calcul_Interpolation_Tetra10<_PARAM_>(nn,nm,c); + fonctions[MED_HEXA8 ]=new Calcul_Interpolation_Hexa8 <_PARAM_>(nn,nm,c); + fonctions[MED_HEXA20 ]=new Calcul_Interpolation_Hexa20 <_PARAM_>(nn,nm,c); + fonctions[MED_PENTA6 ]=new Calcul_Interpolation_Penta6 <_PARAM_>(nn,nm,c); + fonctions[MED_PENTA15]=new Calcul_Interpolation_Penta15<_PARAM_>(nn,nm,c); + fonctions[MED_PYRA5 ]=new Calcul_Interpolation_Pyra5 <_PARAM_>(nn,nm,c); + fonctions[MED_PYRA13 ]=new Calcul_Interpolation_Pyra13 <_PARAM_>(nn,nm,c); + } + +_TEMPLATE_ VALEURCHAMP Calcul_Hybride<_PARAM_>::operator() (const NOEUD & n, int num_maille) + { + return fonctions[mailles->DONNE_TYPE_MAILLE(num_maille)]->operator()(n,num_maille); + } + +_TEMPLATE_ class Calcul_Interpolation_P0 : public Calcul_Interpolation<_PARAM_> +{ +public : Calcul_Interpolation_P0(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + return (*champ)[num_maille]; + } +}; +_TEMPLATE_ class Calcul_Interpolation_Tria3 : public Calcul_Interpolation<_PARAM_> +{ +public : Calcul_Interpolation_Tria3(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + int num0=mailles->DONNE_SOMMET_MAILLE(num_maille,0); + int num1=mailles->DONNE_SOMMET_MAILLE(num_maille,1); + int num2=mailles->DONNE_SOMMET_MAILLE(num_maille,2); + + double x0=(*noeuds)[num0][0]; + double y0=(*noeuds)[num0][1]; + double x1=(*noeuds)[num1][0]; + double y1=(*noeuds)[num1][1]; + double x2=(*noeuds)[num2][0]; + double y2=(*noeuds)[num2][1]; + + VALEURCHAMP v0=(*champ)[num0]; + VALEURCHAMP v1=(*champ)[num1]; + VALEURCHAMP v2=(*champ)[num2]; + + double x=n[0]; + double y=n[1]; + + double lambda0=(y1-y2)*x+(x2-x1)*y+(x1*y2-x2*y1); + double lambda1=(y2-y0)*x+(x0-x2)*y+(x2*y0-x0*y2); + double lambda2=(y0-y1)*x+(x1-x0)*y+(x0*y1-x1*y0); + + double delta = (x2-x1)*y0+(x0-x2)*y1+(x1-x0)*y2; + + VALEURCHAMP retour(v0.SIZE()); + + return (1/delta)*(lambda0*v0+lambda1*v1+lambda2*v2); + + // return retour; // + } +}; +_TEMPLATE_ class Calcul_Interpolation_Tria6 : public Calcul_Interpolation<_PARAM_> +{ +public : Calcul_Interpolation_Tria6(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + // ON SUPPOSE IMPLICITEMENT QUE LES NOEUDS SUPPLEMENTAIRES SONT BIEN DES NOEUDS MILIEUX + int num0=mailles->DONNE_SOMMET_MAILLE(num_maille,0); + int num1=mailles->DONNE_SOMMET_MAILLE(num_maille,1); + int num2=mailles->DONNE_SOMMET_MAILLE(num_maille,2); + int num01=mailles->DONNE_SOMMET_MAILLE(num_maille,3); + int num12=mailles->DONNE_SOMMET_MAILLE(num_maille,4); + int num20=mailles->DONNE_SOMMET_MAILLE(num_maille,5); + + double x0=(*noeuds)[num0][0]; + double y0=(*noeuds)[num0][1]; + double x1=(*noeuds)[num1][0]; + double y1=(*noeuds)[num1][1]; + double x2=(*noeuds)[num2][0]; + double y2=(*noeuds)[num2][1]; + + VALEURCHAMP v0=(*champ)[num0]; + VALEURCHAMP v1=(*champ)[num1]; + VALEURCHAMP v2=(*champ)[num2]; + VALEURCHAMP v01=(*champ)[num01]; + VALEURCHAMP v12=(*champ)[num12]; + VALEURCHAMP v20=(*champ)[num20]; + + double x=n[0]; + double y=n[1]; + + double lambda0=(y1-y2)*x+(x2-x1)*y+(x1*y2-x2*y1); + double lambda1=(y2-y0)*x+(x0-x2)*y+(x2*y0-x0*y2); + double lambda2=(y0-y1)*x+(x1-x0)*y+(x0*y1-x1*y0); + + double delta = (x2-x1)*y0+(x0-x2)*y1+(x1-x0)*y2; + + + // VALEURCHAMP retour(v0.SIZE()); // + + return 2*(lambda0*lambda0*v0+ + lambda1*lambda1*v1+ + lambda2*lambda2*v2+ + 2*(lambda0*lambda1*v01+ + lambda1*lambda2*v12+ + lambda2*lambda0*v20))/(delta*delta)+ + (lambda0*v0+lambda1*v1+lambda2*v2)/(-delta); + + // return retour; // + } +}; +_TEMPLATE_ class Calcul_Interpolation_Quad4 : public Calcul_Interpolation<_PARAM_> +{ +public : Calcul_Interpolation_Quad4(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + int num0=mailles->DONNE_SOMMET_MAILLE(num_maille,0); + int num1=mailles->DONNE_SOMMET_MAILLE(num_maille,1); + int num2=mailles->DONNE_SOMMET_MAILLE(num_maille,2); + int num3=mailles->DONNE_SOMMET_MAILLE(num_maille,3); + + double x0=(*noeuds)[num0][0]; + double y0=(*noeuds)[num0][1]; + double x1=(*noeuds)[num1][0]; + double y1=(*noeuds)[num1][1]; + double x2=(*noeuds)[num2][0]; + double y2=(*noeuds)[num2][1]; + double x3=(*noeuds)[num3][0]; + double y3=(*noeuds)[num3][1]; + + VALEURCHAMP v0=(*champ)[num0]; + VALEURCHAMP v1=(*champ)[num1]; + VALEURCHAMP v2=(*champ)[num2]; + VALEURCHAMP v3=(*champ)[num3]; + + double x=n[0]; + double y=n[1]; + + + double mu0=-((x3*(y1-y2)+x1*(y2-y3)+x2*(y3-y1))*x*y+(x2*y2*(y1-y3)+x3*(-y1+y2)*y3+x1*y1*(y3-y2))*x+(x2*x3*(y2-y3)+x1*(x2*(y1-y2)+x3*(y3-y1)))*y+(x2*x3*y1*(y3-y2)+x1*(x3*y2*(y1-y3)+x2*(y2-y1)*y3))); + double mu1=(x0*(y2-y3)+x2*(y3-y0)+x3*(y0-y2))*x*y+(x3*y3*(y2-y0)+x0*(-y2+y3)*y0+x2*y2*(y0-y3))*x+(x3*x0*(y3-y0)+x2*(x3*(y2-y3)+x0*(y0-y2)))*y+(x2*x0*y2*(y0-y2)+x2*(x0*y2*(y2-y0)+x3*(y3-y2)*y0)); + double mu2=-((x1*(y3-y0)+x3*(y0-y1)+x0*(y1-y3))*x*y+(x0*y0*(y3-y1)+x1*(-y3+y0)*y1+x3*y3*(y1-y0))*x+(x0*x1*(y0-y1)+x3*(x0*(y3-y0)+x1*(y1-y3)))*y+(x3*x1*y3*(y1-y2)+x3*(x1*y2*(y3-y1)+x0*(y0-y3)*y1))); + double mu3=(x2*(y0-y1)+x0*(y1-y2)+x1*(y2-y0))*x*y+(x1*y1*(y0-y2)+x2*(-y0+y1)*y2+x0*y0*(y2-y1))*x+(x1*x2*(y1-y2)+x0*(x1*(y0-y1)+x2*(y2-y0)))*y+(x0*x2*y0*(y2-y2)+x0*(x2*y2*(y0-y2)+x1*(y1-y0)*y2)); + + double delta=(y0-y2)*(y1-y3)*(x0*x2+x1*x3)-(x1*x2+x0*x3)*(y1-y2)*(y0-y3)-(x0*x1+x2*x3)*(y0-y1)*(y2-y3); + + /* + cout<<" ### Pour ( "< +{ +public : Calcul_Interpolation_Tetra4(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + int num0=mailles->DONNE_SOMMET_MAILLE(num_maille,0); + int num1=mailles->DONNE_SOMMET_MAILLE(num_maille,1); + int num2=mailles->DONNE_SOMMET_MAILLE(num_maille,2); + int num3=mailles->DONNE_SOMMET_MAILLE(num_maille,3); + + double x0=(*noeuds)[num0][0]; + double y0=(*noeuds)[num0][1]; + double z0=(*noeuds)[num0][2]; + double x1=(*noeuds)[num1][0]; + double y1=(*noeuds)[num1][1]; + double z1=(*noeuds)[num1][2]; + double x2=(*noeuds)[num2][0]; + double y2=(*noeuds)[num2][1]; + double z2=(*noeuds)[num2][2]; + double x3=(*noeuds)[num3][0]; + double y3=(*noeuds)[num3][1]; + double z3=(*noeuds)[num3][2]; + + VALEURCHAMP v0=(*champ)[num0]; + VALEURCHAMP v1=(*champ)[num1]; + VALEURCHAMP v2=(*champ)[num2]; + VALEURCHAMP v3=(*champ)[num3]; + + double x=n[0]; + double y=n[1]; + double z=n[2]; + + double lambda0=(y3*(z1-z2)+y1*(z2-z3)+y2*(z3-z1))*x+(x3*(z2-z1)+x2*(z1-z3)+x1*(z3-z2))*y+(x3*(y1-y2)+x1*(y2-y3)+x2*(y3-y1))*z+((x3*y2-x2*y3)*z1+(x1*y3-x3*y1)*z2+(x2*y1-x1*y2)*z3); + double lambda1=-((y0*(z2-z3)+y2*(z3-z0)+y3*(z0-z2))*x+(x0*(z3-z2)+x3*(z2-z0)+x2*(z0-z3))*y+(x0*(y2-y3)+x2*(y3-y0)+x3*(y0-y2))*z+((x0*y3-x2*y0)*z2+(x2*y0-x0*y2)*z3+(x3*y2-x2*y3)*z0)); + double lambda2=(y1*(z3-z0)+y3*(z0-z1)+y0*(z1-z3))*x+(x1*(z0-z3)+x0*(z3-z1)+x3*(z1-z0))*y+(x1*(y3-y0)+x3*(y0-y1)+x0*(y1-y3))*z+((x1*y0-x2*y1)*z3+(x3*y1-x1*y3)*z0+(x0*y3-x3*y0)*z1); + double lambda3=-((y2*(z0-z1)+y0*(z1-z2)+y1*(z2-z0))*x+(x2*(z1-z0)+x1*(z0-z2)+x0*(z2-z1))*y+(x2*(y0-y1)+x0*(y1-y2)+x1*(y2-y0))*z+((x2*y1-x2*y2)*z0+(x0*y2-x2*y0)*z1+(x1*y0-x0*y1)*z2)); + + // A SIMPLFIFIER, FEIGNASSE ! + double delta = (x1*y2-x1*y3)*z0 +(x0-y3- x0*y2)*z1 + x0*y3*z1 - x1*y0*z2 + x0*y1*z2 - x0*y3*z2 + x1*y3*z2 + x3*(y1*z0 - y2*z0 - y0*z1 + y2*z1 + y0*z2 - y1*z2) + x1*y0*z3 - x0*y1*z3 + x0*y2*z3 - x1*y2*z3 + x2*(y3*z0 + y0*z1 - y3*z1 - y0*z3 + y1*(-z0 + z3)); + + VALEURCHAMP retour(v0.SIZE()); // + + retour=(lambda0*v0+lambda1*v1+lambda2*v2+lambda3*v3)/delta; + + return retour; // + } +}; +_TEMPLATE_ class Calcul_Interpolation_Tetra10 : public Calcul_Interpolation<_PARAM_> +{ +public : Calcul_Interpolation_Tetra10(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + // ON SUPPOSE IMPLICITEMENT QUE LES NOEUDS SUPPLEMENTAIRES SONT BIEN DES NOEUDS MILIEUX + int num0=mailles->DONNE_SOMMET_MAILLE(num_maille,0); + int num1=mailles->DONNE_SOMMET_MAILLE(num_maille,1); + int num2=mailles->DONNE_SOMMET_MAILLE(num_maille,2); + int num3=mailles->DONNE_SOMMET_MAILLE(num_maille,3); + int num01=mailles->DONNE_SOMMET_MAILLE(num_maille,4); + int num02=mailles->DONNE_SOMMET_MAILLE(num_maille,6); + int num03=mailles->DONNE_SOMMET_MAILLE(num_maille,7); + int num12=mailles->DONNE_SOMMET_MAILLE(num_maille,5); + int num13=mailles->DONNE_SOMMET_MAILLE(num_maille,8); + int num23=mailles->DONNE_SOMMET_MAILLE(num_maille,9); + + double x0=(*noeuds)[num0][0]; + double y0=(*noeuds)[num0][1]; + double z0=(*noeuds)[num0][2]; + double x1=(*noeuds)[num1][0]; + double y1=(*noeuds)[num1][1]; + double z1=(*noeuds)[num1][2]; + double x2=(*noeuds)[num2][0]; + double y2=(*noeuds)[num2][1]; + double z2=(*noeuds)[num2][2]; + double x3=(*noeuds)[num3][0]; + double y3=(*noeuds)[num3][1]; + double z3=(*noeuds)[num3][2]; + + VALEURCHAMP v0=(*champ)[num0]; + VALEURCHAMP v1=(*champ)[num1]; + VALEURCHAMP v2=(*champ)[num2]; + VALEURCHAMP v3=(*champ)[num3]; + VALEURCHAMP v01=(*champ)[num01]; + VALEURCHAMP v02=(*champ)[num02]; + VALEURCHAMP v03=(*champ)[num03]; + VALEURCHAMP v12=(*champ)[num12]; + VALEURCHAMP v13=(*champ)[num13]; + VALEURCHAMP v23=(*champ)[num23]; + + double x=n[0]; + double y=n[1]; + double z=n[2]; + + double lambda0=(y3*(z1-z2)+y1*(z2-z3)+y2*(z3-z1))*x+(x3*(z2-z1)+x2*(z1-z3)+x1*(z3-z2))*y+(x3*(y1-y2)+x1*(y2-y3)+x2*(y3-y1))*z+((x3*y2-x2*y3)*z1+(x1*y3-x3*y1)*z2+(x2*y1-x1*y2)*z3); + double lambda1=-((y0*(z2-z3)+y2*(z3-z0)+y3*(z0-z2))*x+(x0*(z3-z2)+x3*(z2-z0)+x2*(z0-z3))*y+(x0*(y2-y3)+x2*(y3-y0)+x3*(y0-y2))*z+((x0*y3-x2*y0)*z2+(x2*y0-x0*y2)*z3+(x3*y2-x2*y3)*z0)); + double lambda2=(y1*(z3-z0)+y3*(z0-z1)+y0*(z1-z3))*x+(x1*(z0-z3)+x0*(z3-z1)+x3*(z1-z0))*y+(x1*(y3-y0)+x3*(y0-y1)+x0*(y1-y3))*z+((x1*y0-x2*y1)*z3+(x3*y1-x1*y3)*z0+(x0*y3-x3*y0)*z1); + double lambda3=-((y2*(z0-z1)+y0*(z1-z2)+y1*(z2-z0))*x+(x2*(z1-z0)+x1*(z0-z2)+x0*(z2-z1))*y+(x2*(y0-y1)+x0*(y1-y2)+x1*(y2-y0))*z+((x2*y1-x2*y2)*z0+(x0*y2-x2*y0)*z1+(x1*y0-x0*y1)*z2)); + + + // A SIMPLFIFIER, FEIGNASSE ! + double delta = (x1*y2-x1*y3)*z0 +(x0-y3- x0*y2)*z1 + x0*y3*z1 - x1*y0*z2 + x0*y1*z2 - x0*y3*z2 + x1*y3*z2 + x3*(y1*z0 - y2*z0 - y0*z1 + y2*z1 + y0*z2 - y1*z2) + x1*y0*z3 - x0*y1*z3 + x0*y2*z3 - x1*y2*z3 + x2*(y3*z0 + y0*z1 - y3*z1 - y0*z3 + y1*(-z0 + z3)); + + /* + cout<<" ### Pour ( "< +{ +public : Calcul_Interpolation_Penta6(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + cerr<<"Interpolation Pe1 pasencore implémentée"< +{ +public : Calcul_Interpolation_Penta15(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + cerr<<"Interpolation Pe2 pasencore implémentée"< +{ +public : Calcul_Interpolation_Pyra5(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + cerr<<"Interpolation Py1 pasencore implémentée"< +{ +public : Calcul_Interpolation_Pyra13(NUAGENOEUD * nn,NUAGEMAILLE * nm,CHAMP * c):Calcul_Interpolation<_PARAM_>(nn,nm,c) {} +public : VALEURCHAMP operator() (const NOEUD & n, int num_maille) + { + cerr<<"Interpolation Py2 pasencore implémentée"< +#define _MAPPING_ Mapping + + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Classe Mapping */ +/* */ +/*********************************************************/ + +// ATTENTION LE NUAGE DE NOEUD EST SUPPOSE NON REDONDANT ET AUCUNE VERIFICATION N'EST FAITE ! + +template class Mapping +{ +protected : + MAILLAGE * maillage_back; + NUAGEMAILLE * mailles_back; + NUAGENOEUD * noeuds_back; + NUAGENOEUD * noeuds_front; + Coordonnees_Barycentriques * CB; + dTree * my_dTree; + vector resultat_mapping; + vector point_le_plus_proche; + +public : + + Mapping():maillage_back(NULL),mailles_back(NULL),noeuds_back(NULL),noeuds_front(NULL),CB(NULL),my_dTree(NULL) {} + Mapping(MAILLAGE * mb,NUAGENOEUD * nb,NUAGENOEUD * nf); // le dTree est crée à l'initialisation, par contre, le mapping lui meme doit etre invoqué + ~Mapping() {if (CB) delete CB;if (my_dTree) delete my_dTree;} + dTree * Donne_dTree() {return my_dTree;} + int Donne_Directions(int num_maille,const NOEUD &n,int etat_face[NBR_FACES_MAX]); + // Méthode interne de localisation + int Trouve_Maille_Contenant_Point_Mth_Co(const NOEUD &n,int num_maille,int num_maille_interdit,int max_loop,int &nbr_mailles_examinees,int flag_convexe); + void Cree_Mapping(int flag_convexe=0); // SUPPOSE NON CONVEXE PAR DEFAUT + void Cree_Mapping(NUAGENOEUD * nf, int flag_convexe=0); // SUPPOSE NON CONVEXE PAR DEFAUT + inline int operator[](int i) const {return resultat_mapping[i];} // Renvoie la valeur mappé, si le mapping a été fait, sinon, n'importe quoi + inline vector Get_Mapping() {return resultat_mapping;} // Renvoie le vector contenant le mapping + inline int Get_Noeud_Le_Plus_Proche(int i) const {return point_le_plus_proche[i];} // Invoque la méthode de d-Tree qui donne le noeud le plus proche + inline int Exist_dTree() const {return (my_dTree);} // Teste si le dTree existe +}; + +////////////////////////////////////////////////////////////////// +/// /// +/// CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +_TEMPLATE_ void _MAPPING_::Cree_Mapping(NUAGENOEUD * nf, int flag_convexe) + { + noeuds_front=nf; + Cree_Mapping(flag_convexe); + } + +_TEMPLATE_ void _MAPPING_::Cree_Mapping(int flag_convexe) + { + if (!noeuds_front) + { + cerr<<"Mapping : Pas de noeuds à mapper !"<SIZE(); + int num_maille_depart; + int nma=0; + resultat_mapping = vector(nbr_noeuds,UNDEFINED); + point_le_plus_proche = vector(nbr_noeuds,UNDEFINED); + noeuds_back->affiche(); + + for (i=0;itrouve_plus_proche_point((*noeuds_front)[i]); + num_maille_depart=maillage_back->DONNE_PREMIERE_MAILLE_CONTENANT(point_le_plus_proche[i]); + resultat_mapping[i]=Trouve_Maille_Contenant_Point_Mth_Co((*noeuds_front)[i],num_maille_depart,num_maille_depart,NBR_MAX_MAILLES_EXAMINEES,nma,flag_convexe); + } + } +_TEMPLATE_ _MAPPING_::Mapping(MAILLAGE * mb,NUAGENOEUD * nb,NUAGENOEUD * nf):maillage_back(mb),noeuds_back(nb),noeuds_front(nf),my_dTree(NULL) + { + + if (!maillage_back) + { + cerr<<"Mapping : constructeur appelé avec Maillage Vide"<DONNE_POINTEUR_NUAGEMAILLE(); + + CB=new Coordonnees_Barycentriques(mailles_back,noeuds_back); + + cout<<"MAPPING : VERIFICATION REDONDANCES DANS NUAGE NOEUD BACK"<SIZE(); + + vector redondance(nnb,0); + + for (i=0;i(noeuds_back); + + + } +// Renvoie : +// 1 si le point est intérieur +// -1 si le point est extérieur à la maille via uniquement des faces qui ne sont pas au bord +// -2 si le point est extérieur à la maille par au moins une face de bord +// Et modifie etat_face de telle sorte que : +// etat_face[i] = -1 s'il n'existe pas de voisin via la face i +// etat_face[i] = 0 si le point est intérieur via la face i et que le voisin i existe +// etat_face[i] = 1 si le point est extérieur via la face i et que le voisin i existe +_TEMPLATE_ int _MAPPING_::Donne_Directions(int num_maille,const NOEUD &n,int etat_face[NBR_FACES_MAX]) + { + vector ef=CB->Donne_Pseudo_Coord_Baryc(num_maille,n); + int etat_int=VRAI; + int etat_ext_bord=FAUX; + int tf,tv,tb; + int nbr_faces=mailles_back->DONNE_NBR_FACES(num_maille); + for (int i=0;iDONNE_VOISIN_DE_MAILLE(num_maille,i)==UNDEFINED); + tb=(maillage_back->EST_AU_BORD_FACE_DE_MAILLE(num_maille,i)); + if (tf) + { + etat_int=FAUX; + if (tb) etat_ext_bord=VRAI; + } + if (tv) etat_face[i]=-1; + else + { + if (tf) etat_face[i]=1; + else etat_face[i]=0; + } + } + if (etat_int) return 1; + if (etat_ext_bord) return -2; + return -1; + } +_TEMPLATE_ int _MAPPING_::Trouve_Maille_Contenant_Point_Mth_Co(const NOEUD &n,int num_maille,int num_maille_interdit,int max_loop,int &nbr_mailles_examinees,int flag_convexe) + { + + int etat_face[NBR_FACES_MAX]; + int i,tmp,nbr_rnd; + int indirection[NBR_FACES_MAX]; + int ind_reel; + int num_reel; + int new_num=UNDEFINED; + + int test=Donne_Directions(num_maille,n,etat_face); + + int nbr_faces=maillage_back->DONNE_NBR_FACES_MAILLE(num_maille); + + for (i=0;iDONNE_VOISIN_DE_MAILLE(num_maille,ind_reel); + if ((etat_face[ind_reel]==1)&&(num_reel!=num_maille_interdit)) + { + new_num=num_reel; + } + } + for (i=0;(iDONNE_VOISIN_DE_MAILLE(num_maille,ind_reel); + if ((etat_face[ind_reel]==0)&&(num_reel!=num_maille_interdit)) + { + new_num=num_reel; + } + } + if (new_num==UNDEFINED) + { + new_num=num_maille_interdit; + } + num_maille_interdit=num_maille; + num_maille=new_num; + new_num=UNDEFINED; + test=Donne_Directions(num_maille,n,etat_face); + } + return UNDEFINED; + } + +#undef _TEMPLATE_ +#undef _MAPPING_ + +#endif diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_MappingTools.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_MappingTools.hxx new file mode 100644 index 000000000..1781c4213 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_MappingTools.hxx @@ -0,0 +1,199 @@ +#ifndef COORDONNEES_BARYCENTRIQUES_HPP +#define COORDONNEES_BARYCENTRIQUES_HPP + +// DECLARATIONS + +#define _TEMPL_SPE_ template +#define _COORDBARYC_ Coordonnees_Barycentriques +#define _COORDBARY_2D_ Coordonnees_Barycentriques +#define _COORDBARY_3D_ Coordonnees_Barycentriques + +template class Coordonnees_Barycentriques +{ +// TEMPLATE GENERIQUE VIDE OBLIGE DE PASSER PAR UNE SPECIALISATION +}; + +_TEMPL_SPE_ class _COORDBARY_2D_ +{ +protected : + NUAGEMAILLE * mailles; + NUAGENOEUD * sommets; + + vector etat_coord_baryc; + vector< vector< vector > > coord_baryc; + +public : + + Coordonnees_Barycentriques():mailles(NULL),sommets(NULL) {} + Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n); + ~Coordonnees_Barycentriques() {} + vector Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M); + vector Calcule_Base_Coord_Baryc(const vector &simplexe_base); + vector Calcule_Coord_Baryc(int num_maille, const NOEUD & M); +}; + +_TEMPL_SPE_ class _COORDBARY_3D_ +{ +protected : + NUAGEMAILLE * mailles; + NUAGENOEUD * sommets; + + vector etat_coord_baryc; + vector< vector< vector > > coord_baryc; + +public : + + Coordonnees_Barycentriques():mailles(NULL),sommets(NULL) {} + Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n); + ~Coordonnees_Barycentriques() {} + vector Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M); + vector Calcule_Base_Coord_Baryc(const vector &simplexe_base); + vector Calcule_Coord_Baryc(int num_maille, const NOEUD & M); +}; + +// CODE + +_TEMPL_SPE_ _COORDBARY_2D_::Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n):mailles(m),sommets(n) + { + cout<<"Creation des Coordonnées Barycentriques : "<SIZE(); + etat_coord_baryc=vector(nbr_mailles,FAUX); + coord_baryc=vector< vector< vector > >(nbr_mailles); + cout<<"OK ! "< _COORDBARY_2D_::Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M) + { + int i,j,nbr_faces; + if (etat_coord_baryc[num_maille]==FAUX) + { + nbr_faces=mailles->DONNE_NBR_FACES(num_maille); + + coord_baryc[num_maille]=vector< vector >(nbr_faces); + + for (i=0;i simplexe_base=mailles->DONNE_SIMPLEXE_BASE(num_maille,i); + coord_baryc[num_maille][i]=Calcule_Base_Coord_Baryc(simplexe_base); + etat_coord_baryc[num_maille]=VRAI; + } + } + return Calcule_Coord_Baryc(num_maille,M); + } + +_TEMPL_SPE_ vector _COORDBARY_2D_::Calcule_Base_Coord_Baryc(const vector &simplexe_base) + { + const vector &ref=simplexe_base; + vector retour(3); + int i,j; + + double x0=(*sommets)[ref[0]][0]; + double y0=(*sommets)[ref[0]][1]; + double x1=(*sommets)[ref[1]][0]; + double y1=(*sommets)[ref[1]][1]; + double x2=(*sommets)[ref[2]][0]; + double y2=(*sommets)[ref[2]][1]; + + double delta=(x1*y2-x2*y1)+(x2*y0-x0*y2)+(x0*y1-x1*y0); + + retour[0]=(y1-y2)/delta; + retour[1]=(x2-x1)/delta; + retour[2]=(x1*y2-x2*y1)/delta; + + return retour; + } + +_TEMPL_SPE_ vector _COORDBARY_2D_::Calcule_Coord_Baryc(int num_maille, const NOEUD & M) + { + int i,j; + vector coord_baryc_M(3,0); + for (i=0;i<3;i++) + { + for (j=0;j<2;j++) coord_baryc_M[i]+=coord_baryc[num_maille][i][j]*M[j]; + coord_baryc_M[i]+=coord_baryc[num_maille][i][2]; + } + return coord_baryc_M; + } + +_TEMPL_SPE_ _COORDBARY_3D_::Coordonnees_Barycentriques(NUAGEMAILLE * m, NUAGENOEUD *n):mailles(m),sommets(n) + { + cout<<"Creation des Coordonnées Barycentriques : "<SIZE(); + etat_coord_baryc=vector(nbr_mailles,FAUX); + coord_baryc=vector< vector< vector > >(nbr_mailles); + cout<<"OK ! "< _COORDBARY_3D_::Donne_Pseudo_Coord_Baryc(int num_maille,const NOEUD &M) + { + int i,j,nbr_faces; + if (etat_coord_baryc[num_maille]==FAUX) + { + nbr_faces=mailles->DONNE_NBR_FACES(num_maille); + + coord_baryc[num_maille]=vector< vector >(nbr_faces); + + for (i=0;i simplexe_base=mailles->DONNE_SIMPLEXE_BASE(num_maille,i); + coord_baryc[num_maille][i]=Calcule_Base_Coord_Baryc(simplexe_base); + etat_coord_baryc[num_maille]=VRAI; + } + } + return Calcule_Coord_Baryc(num_maille,M); + } + + +_TEMPL_SPE_ vector _COORDBARY_3D_::Calcule_Base_Coord_Baryc(const vector &simplexe_base) + { + const vector &ref=simplexe_base; + vector retour(4); + int i,j; + + double x0=(*sommets)[ref[0]][0]; + double y0=(*sommets)[ref[0]][1]; + double z0=(*sommets)[ref[0]][2]; + double x1=(*sommets)[ref[1]][0]; + double y1=(*sommets)[ref[1]][1]; + double z1=(*sommets)[ref[1]][2]; + double x2=(*sommets)[ref[2]][0]; + double y2=(*sommets)[ref[2]][1]; + double z2=(*sommets)[ref[2]][2]; + double x3=(*sommets)[ref[3]][0]; + double y3=(*sommets)[ref[3]][1]; + double z3=(*sommets)[ref[3]][2]; + + double delta1=((y2-y1)*(z3-z1)-(z2-z1)*(y3-y1)); + double delta2=((x3-x1)*(z2-z1)-(x2-x1)*(z3-z1)); + double delta3=((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)); + + double delta=delta1*(x0-x1)+delta2*(y0-y1)+delta3*(z0-z1); + + retour[0]=delta1/delta; + retour[1]=delta2/delta; + retour[2]=delta3/delta; + retour[3]=-(delta1*x1+delta2*y1+delta3*z1)/delta; + + return retour; + } + +_TEMPL_SPE_ vector _COORDBARY_3D_::Calcule_Coord_Baryc(int num_maille, const NOEUD & M) + { + int i,j; + int nbr_faces=coord_baryc[num_maille].size(); + vector coord_baryc_M(nbr_faces,0); + for (i=0;i +#undef _COORDBARYC_2D_ Coordonnees_Barycentriques +#undef _COORDBARYC_3D_ Coordonnees_Barycentriques + +#endif diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperCells.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperCells.hxx new file mode 100644 index 000000000..f694a4565 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperCells.hxx @@ -0,0 +1,887 @@ +#ifndef WRAPPERS_CELLS_HXX +#define WRAPPERS_CELLS_HXX + +#include "stdio.h" +#include "stdlib.h" + +#include + +#include +#include + +#ifndef FAUX +#define FAUX 0 +#endif + +#ifndef VRAI +#define VRAI 1 +#endif + +#ifndef UNDEFINED +#define UNDEFINED -1 +#endif + +#include "MEDMEM_define.hxx" + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Fonction Comparaison_Informe(...) */ +/* */ +/*********************************************************/ + +int Comparaison_Informe(const vector &v1,const vector &v2); + + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille */ +/* */ +/*********************************************************/ + +// REMARQUE : A REFAIRE COMPLETEMENT ! + +class Wrapper_Maille +{ +protected : + int * sommets; +public : + Wrapper_Maille():sommets(NULL) {} + ~Wrapper_Maille() {} + inline const Wrapper_Maille & positionne(int * pos){sommets=pos;return *this;} + inline int operator[](int i) const {return sommets[i];} + virtual int DONNE_NBR_NOEUDS() const {cerr<<"APPEL D'UNE FONCTION VIRTUELLE DE LA CLASSE MERE WRAPPER_MAILLE => EXIT"< EXIT"< DONNE_SIMPLEXE_BASE(int num_face) const {cerr<<"APPEL D'UNE FONCTION VIRTUELLE DE LA CLASSE MERE WRAPPER_MAILLE => EXIT"< DONNE_FACE(int num_face) const {cerr<<"APPEL D'UNE FONCTION VIRTUELLE DE LA CLASSE MERE WRAPPER_MAILLE => EXIT"< EXIT"< contenu; +public : + ~Type_Wrapper_Maille(); + Type_Wrapper_Maille(); + inline Wrapper_Maille * operator[] (int i) {return contenu[i];} +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Nuage_Maille */ +/* */ +/*********************************************************/ + +template class Wrapper_Nuage_Maille +{ +protected : + FORME_SKYLINE * mailles; + Type_Wrapper_Maille show; + int nbr_mailles; + vector types; + vector< int* > premier_pointeur; +public : + Wrapper_Nuage_Maille():mailles(NULL) {} + Wrapper_Nuage_Maille(FORME_SKYLINE * fs); + ~Wrapper_Nuage_Maille() {} + // Méthodes de la politique + inline const Wrapper_Maille & operator[](int i); + inline int SIZE() {return nbr_mailles;} + inline int DONNE_NBR_FACES(int num_maille); + inline int DONNE_NBR_NOEUDS(int num_maille); + inline vector DONNE_SIMPLEXE_BASE(int num_maille,int num_face); + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_maille,int num_face_loc); + inline vector DONNE_FACE(int num_maille,int num_local_formant); + inline int DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(int num_maille_sec,const vector &sommets_face); + inline int DONNE_SOMMET_MAILLE(int num_maille,int num_som); + inline int DONNE_TYPE_MAILLE(int num_maille) {return mailles->DONNE_TYPE_MAILLE(num_maille);} +}; + +////////////////////////////////////////////////////////////////// +/// /// +/// CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Fonction Comparaison_Informe(...) */ +/* */ +/*********************************************************/ + +int Comparaison_Informe(const vector &v1,const vector &v2) + { + int s1=v1.size(); + int s2=v2.size(); + if (s1!=s2) return FAUX; + int i1,i2; + int test; + for (i1=0;i1 Wrapper_Nuage_Maille::Wrapper_Nuage_Maille(FORME_SKYLINE * fs):mailles(fs) + { + int i; + nbr_mailles=mailles->SIZE(); + types.resize(nbr_mailles); + premier_pointeur.resize(nbr_mailles); + for (i=0;iDONNE_TYPE_MAILLE(i); + premier_pointeur[i]=mailles->DONNE_PREMIER_POINTEUR(i); + } + show[types[0]]->positionne(premier_pointeur[0]); + } +template const Wrapper_Maille & Wrapper_Nuage_Maille::operator[](int i) + { + return show[types[i]]->positionne(premier_pointeur[i]); + } +template inline int Wrapper_Nuage_Maille::DONNE_SOMMET_MAILLE(int num_maille,int num_som) + { + return (*this)[num_maille][num_som]; + } + +template inline int Wrapper_Nuage_Maille::DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(int num_maille,const vector &sommets_face) + { + vector face_loc; + int num_face; + int test=FAUX; + for (num_face=0;num_face int Wrapper_Nuage_Maille::DONNE_NBR_NOEUDS(int num_maille) + { + return (*this)[num_maille].DONNE_NBR_NOEUDS(); + } +template int Wrapper_Nuage_Maille::DONNE_NBR_FACES(int num_maille) + { + return (*this)[num_maille].DONNE_NBR_FACES(); + } +template vector Wrapper_Nuage_Maille::DONNE_SIMPLEXE_BASE(int num_maille,int num_face) + { + return (*this)[num_maille].DONNE_SIMPLEXE_BASE(num_face); + } +template vector Wrapper_Nuage_Maille::DONNE_FACE(int num_maille,int num_face) + { + return (*this)[num_maille].DONNE_FACE(num_face); + } +template int Wrapper_Nuage_Maille::DONNE_PREMIER_NOEUD_DE_FACE(int num_maille,int num_face) + { + return (*this)[num_maille].DONNE_PREMIER_NOEUD_DE_FACE(num_face); + } + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Seg2 */ +/* */ +/*********************************************************/ + +/* +class Wrapper_Maille_Seg2 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 2;} + inline int DONNE_NBR_NOEUDS() const {return 2;} +}; +//*/ + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Seg3 */ +/* */ +/*********************************************************/ + +/* +class Wrapper_Maille_Seg3 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 2;} + inline int DONNE_NBR_NOEUDS() const {return 3;} +}; +//*/ + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Tria3 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Tria3 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 3;} + inline int DONNE_NBR_NOEUDS() const {return 3;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[1]; + case 2 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(2); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];break; + case 1 : retour[0]=sommets[1];retour[1]=sommets[2];break; + case 2 : retour[0]=sommets[2];retour[1]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[1];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 2 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Tria6 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Tria6 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 3;} + inline int DONNE_NBR_NOEUDS() const {return 6;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[1]; + case 2 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(2); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];break; + case 1 : retour[0]=sommets[1];retour[1]=sommets[2];break; + case 2 : retour[0]=sommets[2];retour[1]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[1];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 2 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Quad4 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Quad4 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 4;} + inline int DONNE_NBR_NOEUDS() const {return 4;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[1]; + case 2 : return sommets[2]; + case 3 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(2); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];break; + case 1 : retour[0]=sommets[1];retour[1]=sommets[2];break; + case 2 : retour[0]=sommets[2];retour[1]=sommets[3];break; + case 3 : retour[0]=sommets[3];retour[1]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[1];break; + case 1 : retour[0]=sommets[3];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[2];retour[2]=sommets[3];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[0];retour[3]=sommets[0];break; + } + return retour; + } +}; + + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Quad8 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Quad8 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 4;} + inline int DONNE_NBR_NOEUDS() const {return 8;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[1]; + case 2 : return sommets[2]; + case 3 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(2); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];break; + case 1 : retour[0]=sommets[1];retour[1]=sommets[2];break; + case 2 : retour[0]=sommets[2];retour[1]=sommets[3];break; + case 3 : retour[0]=sommets[3];retour[1]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[1];break; + case 1 : retour[0]=sommets[3];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[2];retour[2]=sommets[3];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[0];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Tetra4 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Tetra4 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 4;} + inline int DONNE_NBR_NOEUDS() const {return 4;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[0]; + case 2 : return sommets[1]; + case 3 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[3];retour[2]=sommets[1];break; + case 2 : retour[0]=sommets[1];retour[1]=sommets[3];retour[2]=sommets[2];break; + case 3 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[1];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[3];retour[3]=sommets[2];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[3];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Tetra10 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Tetra10 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 4;} + inline int DONNE_NBR_NOEUDS() const {return 10;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[0]; + case 2 : return sommets[1]; + case 3 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(3); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[3];retour[2]=sommets[1];break; + case 2 : retour[0]=sommets[1];retour[1]=sommets[3];retour[2]=sommets[2];break; + case 3 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[1];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[3];retour[3]=sommets[2];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[3];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Hexa8 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Hexa8 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 6;} + inline int DONNE_NBR_NOEUDS() const {return 8;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[4]; + case 2 : return sommets[0]; + case 3 : return sommets[1]; + case 4 : return sommets[2]; + case 5 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];retour[3]=sommets[3];break; + case 1 : retour[0]=sommets[4];retour[1]=sommets[5];retour[2]=sommets[6];retour[3]=sommets[7];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[4];retour[2]=sommets[5];retour[3]=sommets[1];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[5];retour[2]=sommets[6];retour[3]=sommets[2];break; + case 4 : retour[0]=sommets[2];retour[1]=sommets[6];retour[2]=sommets[7];retour[3]=sommets[3];break; + case 5 : retour[0]=sommets[3];retour[1]=sommets[7];retour[2]=sommets[4];retour[3]=sommets[0];break; + + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[5];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[7];retour[2]=sommets[6];retour[3]=sommets[5];break; + case 2 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[4];retour[3]=sommets[5];break; + case 3 : retour[0]=sommets[4];retour[1]=sommets[1];retour[2]=sommets[5];retour[3]=sommets[6];break; + case 4 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[6];retour[3]=sommets[3];break; + case 5 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[7];retour[3]=sommets[0];break; + + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Hexa20 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Hexa20 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 6;} + inline int DONNE_NBR_NOEUDS() const {return 20;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[4]; + case 2 : return sommets[0]; + case 3 : return sommets[1]; + case 4 : return sommets[2]; + case 5 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];retour[3]=sommets[3];break; + case 1 : retour[0]=sommets[4];retour[1]=sommets[5];retour[2]=sommets[6];retour[3]=sommets[7];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[4];retour[2]=sommets[5];retour[3]=sommets[1];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[5];retour[2]=sommets[6];retour[3]=sommets[2];break; + case 4 : retour[0]=sommets[2];retour[1]=sommets[6];retour[2]=sommets[7];retour[3]=sommets[3];break; + case 5 : retour[0]=sommets[3];retour[1]=sommets[7];retour[2]=sommets[4];retour[3]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[5];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[0];retour[1]=sommets[7];retour[2]=sommets[6];retour[3]=sommets[5];break; + case 2 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[4];retour[3]=sommets[5];break; + case 3 : retour[0]=sommets[4];retour[1]=sommets[1];retour[2]=sommets[5];retour[3]=sommets[6];break; + case 4 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[6];retour[3]=sommets[3];break; + case 5 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[7];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Pyra5 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Pyra5 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 5;} + inline int DONNE_NBR_NOEUDS() const {return 5;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[0]; + case 2 : return sommets[1]; + case 3 : return sommets[2]; + case 4 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour; + switch (num_face) + { + case 0 : retour.resize(4);retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];retour[3]=sommets[3];break; + case 1 : retour.resize(3);retour[0]=sommets[0];retour[1]=sommets[4];retour[2]=sommets[1];break; + case 2 : retour.resize(3);retour[0]=sommets[1];retour[1]=sommets[4];retour[2]=sommets[2];break; + case 3 : retour.resize(3);retour[0]=sommets[2];retour[1]=sommets[4];retour[2]=sommets[3];break; + case 4 : retour.resize(3);retour[0]=sommets[3];retour[1]=sommets[4];retour[2]=sommets[0];break; + } + return retour; + } + + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[4];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[4];retour[3]=sommets[1];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[4];retour[3]=sommets[2];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[4];retour[3]=sommets[3];break; + case 4 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[4];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Pyra13 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Pyra13 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 5;} + inline int DONNE_NBR_NOEUDS() const {return 13;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[0]; + case 2 : return sommets[1]; + case 3 : return sommets[2]; + case 4 : return sommets[3]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour; + switch (num_face) + { + case 0 : retour.resize(4);retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];retour[3]=sommets[3];break; + case 1 : retour.resize(3);retour[0]=sommets[0];retour[1]=sommets[4];retour[2]=sommets[1];break; + case 2 : retour.resize(3);retour[0]=sommets[1];retour[1]=sommets[4];retour[2]=sommets[2];break; + case 3 : retour.resize(3);retour[0]=sommets[2];retour[1]=sommets[4];retour[2]=sommets[3];break; + case 4 : retour.resize(3);retour[0]=sommets[3];retour[1]=sommets[4];retour[2]=sommets[0];break; + } + return retour; + } + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[4];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[4];retour[3]=sommets[1];break; + case 2 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[4];retour[3]=sommets[2];break; + case 3 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[4];retour[3]=sommets[3];break; + case 4 : retour[0]=sommets[2];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[4];break; + } + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Penta6 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Penta6 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 5;} + inline int DONNE_NBR_NOEUDS() const {return 6;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[3]; + case 2 : return sommets[0]; + case 3 : return sommets[1]; + case 4 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour; + switch (num_face) + { + case 0 : retour.resize(3);retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 1 : retour.resize(3);retour[0]=sommets[3];retour[1]=sommets[4];retour[2]=sommets[5];break; + case 2 : retour.resize(4);retour[0]=sommets[0];retour[1]=sommets[3];retour[2]=sommets[4];retour[3]=sommets[1];break; + case 3 : retour.resize(4);retour[0]=sommets[1];retour[1]=sommets[4];retour[2]=sommets[5];retour[3]=sommets[2];break; + case 4 : retour.resize(4);retour[0]=sommets[2];retour[1]=sommets[5];retour[2]=sommets[3];retour[3]=sommets[1];break; + } + return retour; + } + + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[4];retour[3]=sommets[5];break; + case 2 : retour[0]=sommets[5];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[1];break; + case 3 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[4];retour[3]=sommets[2];break; + case 4 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[5];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Wrapper_Maille_Penta15 */ +/* */ +/*********************************************************/ + +class Wrapper_Maille_Penta15 : public Wrapper_Maille +{ +public : + inline int DONNE_NBR_FACES() const {return 5;} + inline int DONNE_NBR_NOEUDS() const {return 15;} + inline int DONNE_PREMIER_NOEUD_DE_FACE(int num_face) const + { + switch (num_face) + { + case 0 : return sommets[0]; + case 1 : return sommets[3]; + case 2 : return sommets[0]; + case 3 : return sommets[1]; + case 4 : return sommets[2]; + } + } + inline vector DONNE_FACE(int num_face) const + { + vector retour; + switch (num_face) + { + case 0 : retour.resize(3);retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[2];break; + case 1 : retour.resize(3);retour[0]=sommets[3];retour[1]=sommets[4];retour[2]=sommets[5];break; + case 2 : retour.resize(4);retour[0]=sommets[0];retour[1]=sommets[3];retour[2]=sommets[4];retour[3]=sommets[1];break; + case 3 : retour.resize(4);retour[0]=sommets[1];retour[1]=sommets[4];retour[2]=sommets[5];retour[3]=sommets[2];break; + case 4 : retour.resize(4);retour[0]=sommets[2];retour[1]=sommets[5];retour[2]=sommets[3];retour[3]=sommets[1];break; + } + return retour; + } + + inline vector DONNE_SIMPLEXE_BASE(int num_face) const + { + vector retour(4); + switch (num_face) + { + case 0 : retour[0]=sommets[3];retour[1]=sommets[0];retour[2]=sommets[1];retour[3]=sommets[2];break; + case 1 : retour[0]=sommets[2];retour[1]=sommets[3];retour[2]=sommets[4];retour[3]=sommets[5];break; + case 2 : retour[0]=sommets[5];retour[1]=sommets[0];retour[2]=sommets[3];retour[3]=sommets[1];break; + case 3 : retour[0]=sommets[0];retour[1]=sommets[1];retour[2]=sommets[4];retour[3]=sommets[2];break; + case 4 : retour[0]=sommets[1];retour[1]=sommets[2];retour[2]=sommets[5];retour[3]=sommets[0];break; + } + return retour; + } +}; + +/*********************************************************/ +/* */ +/* Classe Type_Wrapper_Maille */ +/* */ +/*********************************************************/ + +Type_Wrapper_Maille::~Type_Wrapper_Maille() + { + // delete contenu[MED_SEG2 ]; + // delete contenu[MED_SEG3 ]; + delete contenu[MED_TRIA3 ]; + delete contenu[MED_TRIA6 ]; + delete contenu[MED_QUAD4 ]; + delete contenu[MED_QUAD8 ]; + delete contenu[MED_TETRA4 ]; + delete contenu[MED_TETRA10]; + delete contenu[MED_HEXA8 ]; + delete contenu[MED_HEXA20 ]; + delete contenu[MED_PYRA5 ]; + delete contenu[MED_PYRA13 ]; + delete contenu[MED_PENTA6 ]; + delete contenu[MED_PENTA15]; + } + +Type_Wrapper_Maille::Type_Wrapper_Maille() + { + // contenu[MED_SEG2 ]= new Wrapper_Maille_Seg2 (); + // contenu[MED_SEG3 ]= new Wrapper_Maille_Seg3 (); + contenu[MED_TRIA3 ]= new Wrapper_Maille_Tria3 (); + contenu[MED_TRIA6 ]= new Wrapper_Maille_Tria6 (); + contenu[MED_QUAD4 ]= new Wrapper_Maille_Quad4 (); + contenu[MED_QUAD8 ]= new Wrapper_Maille_Quad8 (); + contenu[MED_TETRA4 ]= new Wrapper_Maille_Tetra4 (); + contenu[MED_TETRA10]= new Wrapper_Maille_Tetra10 (); + contenu[MED_HEXA8 ]= new Wrapper_Maille_Hexa8 (); + contenu[MED_HEXA20 ]= new Wrapper_Maille_Hexa20 (); + contenu[MED_PYRA5 ]= new Wrapper_Maille_Pyra5 (); + contenu[MED_PYRA13 ]= new Wrapper_Maille_Pyra13 (); + contenu[MED_PENTA6 ]= new Wrapper_Maille_Penta6 (); + contenu[MED_PENTA15]= new Wrapper_Maille_Penta15 (); + } + + +#endif diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperConnectivity.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperConnectivity.hxx new file mode 100644 index 000000000..439864aa7 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperConnectivity.hxx @@ -0,0 +1,61 @@ +#ifndef MEDMEM_WRAPPER_CONNECTIVITY_HXX +#define MEDMEM_WRAPPER_CONNECTIVITY_HXX + +#include "MEDMEM_Connectivity.hxx" + +#include + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS ET CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Wrapper_Med_Connectivity */ +/* */ +/*********************************************************/ + +// obligé de faire de la recopie car MED n'utilise pas la numérotation standart C + +class Wrapper_Med_Connectivity +{ +protected : + int * mailles; + int nbr_mailles; + vector types; + vector< int* > premier_pointeur; + +public : + ~Wrapper_Med_Connectivity() {if (mailles) delete [] mailles;} + Wrapper_Med_Connectivity():mailles(NULL) {} + Wrapper_Med_Connectivity(CONNECTIVITY * maillesmed) + { + const med_int * tab_sommets_mailles=maillesmed->getConnectivity(MED_NODAL,MED_CELL,MED_ALL_ELEMENTS); + const med_int * med_connectivite=maillesmed->getConnectivityIndex(MED_FULL_INTERLACE,MED_CELL); + const med_int * med_index=maillesmed->getValueIndex(MED_FULL_INTERLACE); + nbr_mailles=maillesmed->getNumberOf(MED_CELL,MED_ALL_ELEMENTS); + int size=med_index[nbr_mailles]-med_index[0]; + types.resize(nbr_mailles); + premier_pointeur.resize(nbr_mailles); + mailles=new int[size]; + int i; + for (i=0;igetElementType(MED_CELL,i+1); // A VERIFIER : le +1 + premier_pointeur[i]=&mailles[med_index[i]-1]; // A VERIFIER : la formule + } + } + // Méthodes de la politique + inline int SIZE() {return nbr_mailles;} + inline int DONNE_TYPE_MAILLE(int i) {return types[i];} + inline int * DONNE_PREMIER_POINTEUR(int i) {return premier_pointeur[i];} +}; + + +#endif diff --git a/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperField.hxx b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperField.hxx new file mode 100644 index 000000000..c345d4d26 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/MEDMEM_WrapperField.hxx @@ -0,0 +1,201 @@ +#ifndef MEDMEM_WRAPPER_FIELD_HXX +#define MEDMEM_WRAPPER_FIELD_HXX + +#include "MEDMEM_Field.hxx" + +#include + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS ET CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Template Arithmétiques de Valdhuizen */ +/* */ +/*********************************************************/ + +template class Valeur; + +struct Plus +{ +public : + static double apply(double a,double b) {return a+b;} +}; + +struct Multiply +{ +public : + static double apply(double a,double b) {return a*b;} +}; + + +template struct X +{ + Left left; + Right right; + X(Left l,Right r):left(l),right(r){} + double operator[](int i) + { + return Op::apply(left[i],right[i]); + } +}; + +template struct X +{ + double left; + Right right; + X(double l,Right r):left(l),right(r){} + double operator[](int i) + { + return Multiply::apply(left,right[i]); + } +}; + +template X< Valeur,Plus,Valeur > operator+(Valeur v1,Valeur v2) +{ +return X< Valeur,Plus,Valeur >(v1,v2); +} + +template X< double,Multiply,Valeur > operator*(TYPE sca,Valeur v) +{ +return X< TYPE,Multiply,Valeur >(sca,v); +} + +template X< Valeur,Plus,X > operator+(Valeur v,X expression) +{ +return X< Valeur,Plus,X >(v,expression); +} + +template X< X,Plus,Valeur > operator+(X expression,Valeur v) +{ +return X< X,Plus,Valeur >(expression,v); +} + +template X< X,Plus, X > operator+(X el, X er ) +{ +return X< X,Plus,X >(el,er); +} + +template X< double,Multiply,X > operator*(double sca,X expression) +{ +return X< double,Multiply,X >(sca,expression); +} + +template X< double,Multiply,X > operator/(X l,double x) +{ +return X< double,Multiply,X >(((double) 1/x),l); +} + +/*********************************************************/ +/* */ +/* Classe Valeur */ +/* */ +/*********************************************************/ + +// Problèmes : les constructeurs par copie ne sont pas satisfaisants + +template class Valeur +{ +protected : + TYPE * valeurs; + int nbr_valeurs; + int a_detruire; +public : + Valeur():valeurs(NULL),a_detruire(0){} + Valeur(TYPE * val,int nv):valeurs(val),nbr_valeurs(nv),a_detruire(0){} // A VERIFIER + Valeur(int n):nbr_valeurs(n),a_detruire(1) + { + valeurs=new TYPE[nbr_valeurs]; + } + template Valeur(X expression) + { + for (int i=0;i void operator=(X expression) + { + for (int i=0;i ostream &operator<<(ostream &os,Valeur v) +{ +os<<"("< * medfield) + { + nbr_valeurs=medfield->getNumberOfValues(); + nbr_composantes=medfield->getNumberOfComponents(); + valeurs=const_cast(medfield->getValue(MED_FULL_INTERLACE)); + } + ~Wrapper_MED_Field(){} + inline Valeur operator[](int i) + { + if ((i<0)||(i>=nbr_valeurs)) + { + cerr< + +#ifndef UNDEFINED +#define UNDEFINED -1 +#endif + +#ifndef FAUX +#define FAUX 0 +#endif + +#ifndef VRAI +#define VRAI 1 +#endif + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Wrapper_Maillage */ +/* */ +/*********************************************************/ + +template class Wrapper_Maillage +{ +protected : + NUAGEMAILLE * mailles; + + int nbr_noeuds; + + vector< vector > faces_contenues; + vector< vector > mailles_contenant_noeud; + vector< vector > voisins_de_maille; + + vector face_au_bord; + vector maille_au_bord; + + // Méthode privée + void Construit_Contenant_Noeud(); + +public : + + Wrapper_Maillage():mailles(NULL) {} + // Construit les Connectivités du maillage à la construction + Wrapper_Maillage(NUAGEMAILLE * fs, int nn); + ~Wrapper_Maillage() {} + + // Méthodes de la politique + inline int DONNE_NBR_FACES_MAILLE(int num_maille); + inline int DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const; + inline int EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const; + inline int DONNE_NBR_FACES(int num_maille) const; + inline vector DONNE_SIMPLEXE_BASE(int num_maille,int num_face) const; + inline int DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const; + inline NUAGEMAILLE * DONNE_POINTEUR_NUAGEMAILLE(); + +}; + +////////////////////////////////////////////////////////////////// +/// /// +/// CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +template int Wrapper_Maillage::DONNE_PREMIERE_MAILLE_CONTENANT(int num_noeud) const + { + return mailles_contenant_noeud[num_noeud][0]; + } +template int Wrapper_Maillage::DONNE_VOISIN_DE_MAILLE(int num_maille,int num_face) const + { + return voisins_de_maille[num_maille][num_face]; + } +template int Wrapper_Maillage::EST_AU_BORD_FACE_DE_MAILLE(int num_maille,int num_face) const + { + return face_au_bord[faces_contenues[num_maille][num_face]]; + } +template int Wrapper_Maillage::DONNE_NBR_FACES_MAILLE(int num_maille) + { + return mailles->DONNE_NBR_FACES(num_maille); + } +template vector Wrapper_Maillage::DONNE_SIMPLEXE_BASE(int num_maille,int num_face) const + { + return mailles->DONNE_SIMPLEXE_BASE(num_maille,num_face); + } +template NUAGEMAILLE * Wrapper_Maillage::DONNE_POINTEUR_NUAGEMAILLE() + { + return mailles; + } +template void Wrapper_Maillage::Construit_Contenant_Noeud() + { + int nbr_noeuds_maille; + int num,num_noeud,num_maille; + + mailles_contenant_noeud.resize(nbr_noeuds); + + for (num_maille=0;num_mailleSIZE();num_maille++) + { + nbr_noeuds_maille=mailles->DONNE_NBR_NOEUDS(num_maille); + for (num_noeud=0;num_noeudDONNE_SOMMET_MAILLE(num_maille,num_noeud); +// if ((num<0)||(num>=mailles_contenant_noeud.size())) +// { +// cerr<SIZE(); + int nbr_formants=0; + int approx_nbr_formants=0; + int tmp; + int num_loc; + + nbr_noeuds=nn; + + voisins_de_maille.resize(nbr_mailles); + faces_contenues.resize(nbr_mailles); + maille_au_bord.resize(nbr_mailles,UNDEFINED); + + vector sommets_face; + + cout<<"Calcul du lien Sommet->Maille"<DONNE_NBR_FACES(num_maille); + voisins_de_maille[num_maille]=vector(tmp,UNDEFINED); + faces_contenues[num_maille]=vector(tmp,UNDEFINED); + approx_nbr_formants+=tmp; + } + + face_au_bord.reserve(approx_nbr_formants/10); + + cout<<"Calcul des voisins"<DONNE_NBR_FACES(num_maille);num_local_face++) + { + num_noeud=mailles->DONNE_PREMIER_NOEUD_DE_FACE(num_maille,num_local_face); + flag_existence=0; + sommets_face=mailles->DONNE_FACE(num_maille,num_local_face); + flag_interm=0; + for (ind_num_maille_sec=0;(flag_existence==0)&&(ind_num_maille_secnum_maille) + { + flag_interm=1; + num_loc=mailles->DONNE_NUM_LOC_FACE_EGALE_A_FORMANT(num_maille_sec,sommets_face); + if (num_loc>UNDEFINED) + { + cout<<"La maille "< class Wrapper_Noeud +{ +protected : + double * coordonnees; +public : + Wrapper_Noeud():coordonnees(NULL) + { + } + Wrapper_Noeud(double * coord):coordonnees(coord) + { + } + ~Wrapper_Noeud() + { + } + void positionne(double *place) + { + coordonnees=place; + } + const double & operator[] (int i) const + { + return coordonnees[i]; + } + double operator[] (int i) + { + return coordonnees[i]; + } + friend double DistanceInf(const Wrapper_Noeud &A,const Wrapper_Noeud &B) + { + double max=0; + double tmp; + for (int i=0;imax) max=tmp; + } + return max; + } + friend double DistanceL2(const Wrapper_Noeud &A,const Wrapper_Noeud &B) + { + double tmp,somme=0; + for (int i=0;i &A,const Wrapper_Noeud &B) + { + for (int i=0;i &A) + { + os<<"( "< class Wrapper_Nuage_Noeud + { + protected : + int nbr_noeuds; + double *noeuds; + Wrapper_Noeud show; + public : + Wrapper_Nuage_Noeud():nbr_noeuds(0),noeuds(NULL) {} + Wrapper_Nuage_Noeud(int nn, double *n):nbr_noeuds(nn),noeuds(n),show(noeuds) {} + ~Wrapper_Nuage_Noeud() {} + Wrapper_Noeud & operator [] (int i) + { + if ((i<0)||(i>=nbr_noeuds)) + { + cerr<<"Outbound call dans Wrapper Nuage Noeud"< +#define _DTREE_ dTree + +////////////////////////////////////////////////////////////////// +/// /// +/// DECLARATIONS /// +/// /// +////////////////////////////////////////////////////////////////// + +/*********************************************************/ +/* */ +/* Calcul Statique de Puissance */ +/* */ +/*********************************************************/ + +// Permet de Calculer 2^n de façon statique + +template < int DIMENSION > struct DeuxPuissance + { + enum { valeur = 2 * DeuxPuissance::valeur } ; + }; + +template <> struct DeuxPuissance<0> + { + enum { valeur = 1 } ; + }; + +/*********************************************************/ +/* */ +/* DTREE */ +/* */ +/*********************************************************/ + +// Classe Utilisateur +// # Bugs connus : +// - Problemes avec points sur les faces des hypercubes ? +// - Plantage sauvage si le point est plus loin de l'hypercube père que le diametre Linf de celui-ci. +// # Politique de classe : +// - NOEUD : voir dans MEDMEM_WrapperNodes.hxx la classe Wrapper_Noeud<..> +// - NUAGENOEUD : typiquement, c'est vector en rédefinissant NUAGENOEUD<...>::SIZE()=vector<...>::size() +// Remarques : +// - NBR_NOEUDS_PAR_CASE ne doit pas être modifié sauf peut-être dans le cas où l'utilisateur veut utiliser des d-Tree parallèles + +template class dTree +{ +protected : + // types + typedef _DTREE_ * Ptr_dTree; + // Static Const + static const int nbr_descendants=DeuxPuissance::valeur; + // champs + NUAGENOEUD * nuage; + Ptr_dTree descendant[nbr_descendants]; + vector * noeud_contenu; + int etat; + int niveau; + dTree * pere; + Sommet_dTree coord_max; + Sommet_dTree coord_min; +public : + + void init(); + dTree(); + dTree(NUAGENOEUD *n); + dTree(const Sommet_dTree &A,const Sommet_dTree &B,dTree *mypere); + dTree(const dTree &F); + ~dTree(); + void Get_Noeuds_Filtre(vector &tmp); + Sommet_dTree Get_Max() const; + Sommet_dTree Get_Min() const; + int is_in_dTree(NOEUD P) const; + double calcule_distance(NOEUD P) const; + dTree & operator = (const dTree & F); + Sommet_dTree dTree::donne_sommet(int selecteur) const; + int a_des_fils() const; + dTree * trouve_dTree_contenant(NOEUD P) const; + int trouve_plus_proche_point_bourrin(NOEUD P) const; + int trouve_plus_proche_point(NOEUD P) const; + int trouve_un_point() const; + int tppp_rec(NOEUD P,double &delta,int &flag) const; + int Localise_Point(NOEUD P,double d) const; + void cree_filiation(); + int Get_Nbr_Descendants_Non_Vides() const; + int Get_Nbr_Descendants_Vides() const; + int Get_Profondeur_Max() const; +}; + + +////////////////////////////////////////////////////////////////// +/// /// +/// CODE /// +/// /// +////////////////////////////////////////////////////////////////// + +_TEMPLATE_ void _DTREE_::init() + { + int i; + nuage=NULL; + noeud_contenu=NULL; + etat=DTREE_FANTOME; + for (i=0;i(nuage->size()); + niveau=0; + + for (i=0;isize();i++) + { + (*noeud_contenu)[i]=i; + for (j=0;jcoord_max[j]) coord_max[j]=(*nuage)[i][j]; + if ((*nuage)[i][j] &A,const Sommet_dTree &B,dTree *mypere) + { + if (mypere!=NULL) + { + int i,j; + double tmp; + + init(); + + pere=mypere; + nuage=pere->nuage; + niveau=pere->niveau+1; + + etat=DTREE_COURANT; + + noeud_contenu=new vector; + noeud_contenu->reserve((pere->noeud_contenu->size())/nbr_descendants); + + for (i=0;iB[i]) + { + coord_max[i]=A[i]; + coord_min[i]=B[i]; + } + else + { + coord_min[i]=A[i]; + coord_max[i]=B[i]; + } + } + } + else + { + cerr<<"DTREE : Construction de descendance sans père !"< &tmp) + { + int i; + switch (etat) + { + case DTREE_RACINE : int pourlefunlecompilolesttropcon; + case DTREE_COURANT : + for (i=0;iGet_Noeuds_Filtre(tmp); + case DTREE_TERMINAL : + if (noeud_contenu->size()>0) + { + for (i=0;i _DTREE_::Get_Max() const + { + return coord_max; + } +_TEMPLATE_ Sommet_dTree _DTREE_::Get_Min() const + { + return coord_min; + } +_TEMPLATE_ int _DTREE_::is_in_dTree(NOEUD P) const + { + int test; + for (int i=0;itmp) min=tmp; + tmp=fabs(coord_min[i]-P[i]); + if (min>tmp) min=tmp; + } + return min; + } +_TEMPLATE_ _DTREE_ & _DTREE_::operator = (const _DTREE_ & F) + { + // Pas Super Top Moumoute ... Recopie de pointeurs et pas de contenus, merdique + int i,j; + init(); + for (i=0;i _DTREE_::donne_sommet(int selecteur) const + { + Sommet_dTree p; + int i; + int residu=selecteur; + int reste; + for (i=0;i B(coord_min,coord_max); + int i; + if ((etat==DTREE_RACINE)&&(!is_in_dTree(P))) return NULL; // Le noeud est extérieur a l'dTree + else if (etat==DTREE_TERMINAL) return (dTree *) this; // Le noeud est dans *this qui est terminal + + for (i=0;i A=donne_sommet(i); + int test,j; + for (j=0;j=P[j])&&(P[j]>=B[j])); + if (!test) break; + } + + if (test) return descendant[i]->trouve_dTree_contenant(P); // Propagation + } + } +// si de le dTree n'est pas TERMINAL, scanne tous les points du nuage du pere pour trouver le point le plus proche +// sinon scanne uniquement les points contenus dans le dTree +_TEMPLATE_ int _DTREE_::trouve_plus_proche_point_bourrin(NOEUD P) const + { + int i; + int num_sol; + double min; + double tmp; + if (etat!=DTREE_TERMINAL) + { + min=DistanceL2(P,(*nuage)[0]); + for (i=1;isize();i++) + { + tmp=DistanceL2(P,(*nuage)[i]); + if (tmpsize()!=0) + { + num_sol=(*noeud_contenu)[0]; + min=DistanceL2(P,(*nuage)[num_sol]); + for (i=1;isize();i++) + { + tmp=DistanceL2(P,(*nuage)[(*noeud_contenu)[i]]); + if (tmppere!=NULL) + { + delta=DistanceInf((ref->pere->coord_max),(ref->pere->coord_min)); + } + else + { + cerr<<"DTREE : TROUVE PLUS PROCHE POINT : l'octree contenant le noeud n'a pas de pere !"<size()>0) return (*(noeud_contenu))[0]; + } + else + { + int i; + for (i=0;itrouve_un_point(); + } + } + } +// partie recursive de l'algo ci dessus +// change le flag en 1 si un point plus proche est trouvé +// adapte automatiquement la distance delta de filtrage +_TEMPLATE_ int _DTREE_::tppp_rec(NOEUD P,double &delta,int &flag) const + { + if (Localise_Point(P,delta)==0) + { + // La distance du point à l'octree est plus grande que delta + return DTREE_FANTOME; + } + int num_Ptmp; + double dtmp; + if (etat==DTREE_TERMINAL) + { + if (noeud_contenu->size()>0) + { + num_Ptmp=trouve_plus_proche_point_bourrin(P); + dtmp=DistanceL2((*nuage)[num_Ptmp],P); + if (dtmp<=delta) + { + // Le point le plus proche minimise delta, c'est un bon candidat, on l'envoie ! + delta=dtmp; + flag=1; + return num_Ptmp; + } + // Le point le plus proche ne minimise pas delta + // ===========> peut etre rajouter exit(-1); ?????????? + return DTREE_FANTOME; + } + else + { + // L'octree qui contient P ne contient aucun point + return DTREE_FANTOME; + } + } + int i; + int num_sol=DTREE_FANTOME; + for (i=0;itppp_rec(P,delta,flag); + if ((num_Ptmp!=DTREE_FANTOME)&&(flag==1)) + { + // On a trouvé un point qui minimise delta dans une branche + num_sol=num_Ptmp; + } + } + // A ce stade, on a trouvé un point qui minimise tous les deltas, c'est donc le point le plus proche + return num_sol; + } +// renvoie 1 si la distance L inf du noeud a l'octree est plus petite que d, 0 sinon +_TEMPLATE_ int _DTREE_::Localise_Point(NOEUD P,double d) const + { + int i; + for (i=0;icoord_max[i]+d) return 0; + if (P[i]niveau+1; + } + else + { + niveau=0; + } + + if (noeud_contenu->size()<=NBR_NOEUDS_PAR_CASE) + { + etat=DTREE_TERMINAL; + } + else + { + int i,num_loc,test; + + Sommet_dTree centre(coord_max,coord_min); + + for (i=0;isize();num_loc++) + { + int indice=(*noeud_contenu)[num_loc]; + NOEUD & courant=(*nuage)[indice]; + test=1; + for (i=0;(test)&&(iis_in_dTree(courant)) + { + descendant[i]->noeud_contenu->push_back(indice); + test=0; + } + } + } + + delete noeud_contenu; + noeud_contenu=NULL; + + for (i=0;icree_filiation(); + } + } +_TEMPLATE_ int _DTREE_::Get_Nbr_Descendants_Non_Vides() const + { + int i; + int ndnv=0; + switch (etat) + { + case DTREE_RACINE : int pourlefunlecompilolesttropcon; + case DTREE_COURANT : + for (i=0;iGet_Nbr_Descendants_Non_Vides(); + return ndnv; + case DTREE_TERMINAL : + if (noeud_contenu->size()>0) return 1; + else return 0; + default : + cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"<Get_Nbr_Descendants_Vides(); + return ndnv; + case DTREE_TERMINAL : + if (noeud_contenu->size()==0) return 1; + else return 0; + default : + cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"<Get_Profondeur_Max(); + if (tmp>prof) prof=tmp; + } + return prof; + case DTREE_TERMINAL : return niveau; + default : + cerr<<"dTree Non Valide dans Get_Nbr_Descendants_Non_Vides"< class Sommet_dTree +{ +protected : + double coord[DIMENSION]; +public : + Sommet_dTree() + { + } + Sommet_dTree(double *c) + { + for (int i=0;i &A,const Sommet_dTree &B) + { + double max=0; + double tmp; + for (int i=0;imax) max=tmp; + } + return max; + } +}; + +#endif diff --git a/src/MEDMEM/INTERPOLATION/create_mesh_interpolation.c b/src/MEDMEM/INTERPOLATION/create_mesh_interpolation.c new file mode 100644 index 000000000..609a00db4 --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/create_mesh_interpolation.c @@ -0,0 +1,433 @@ +#include +#include + +#define MED_NOPG 1 /* -> pas de point de Gauss */ +#define MED_NOPFL "" /* -> pas de profils utilisateur */ +#define MED_NOPFLi " " /* Variable Interne */ +#define MED_NOPF 0 /* -> pas de profils pour _MEDdataseNnumEcrire */ +#define MED_NOPDT -1 /* rem: pas de pas de temps negatifs */ +#define MED_NONOR -1 /* rem: pas de n°ordre negatif */ +#define MED_DIM1 1 /* PAS */ + +#define MED_ALL 0 + +/*****************************************************************************************************/ + +void affiche_noeuds(med_float * nodes,int nnpl) + { + int nbr_nodes=nnpl*nnpl*nnpl; + int i; + + for (i=0;i=3*nbr_nodes) {printf("%d : OUT OF RANGE REQUEST\n",num_noeud);exit(-1);} + if (3*num_noeud+1>=3*nbr_nodes) {printf("%d : OUT OF RANGE REQUEST\n",num_noeud);exit(-1);} + if (3*num_noeud+2>=3*nbr_nodes) {printf("%d : OUT OF RANGE REQUEST\n",num_noeud);exit(-1);} + + coord_nodes[3*num_noeud ]= (double) (i+flag)/diviseur; + coord_nodes[3*num_noeud+1]= (double) (j+flag)/diviseur; + coord_nodes[3*num_noeud+2]= (double) (k+flag)/diviseur; + } + + affiche_noeuds(coord_nodes,nnpl); + + } +void cree_num_nodes(med_int * num_nodes,int nnpl) + { + int nbr_nodes=nnpl*nnpl*nnpl; + int i; + /*num_nodes=(med_int *) malloc(nbr_nodes*sizeof(med_int));*/ + for (i=0;i=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+1>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+2>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+3>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+4>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+5>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+6>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + if (8*num_hexa8+7>=8*nbr_hexa8) {printf("%d : OUT OF RANGE REQUEST\n",num_hexa8);exit(-1);} + + conn_hexa8[8*num_hexa8 ] = 1 + i0+nnpl*j1+nnpl*nnpl*k1 ; printf("%4d ",1+i0+nnpl*j1+nnpl*nnpl*k1); + conn_hexa8[8*num_hexa8+1] = 1 + i0+nnpl*j0+nnpl*nnpl*k1 ; printf("%4d ",1+i0+nnpl*j0+nnpl*nnpl*k1); + conn_hexa8[8*num_hexa8+2] = 1 + i1+nnpl*j0+nnpl*nnpl*k1 ; printf("%4d ",1+i1+nnpl*j0+nnpl*nnpl*k1); + conn_hexa8[8*num_hexa8+3] = 1 + i1+nnpl*j1+nnpl*nnpl*k1 ; printf("%4d ",1+i1+nnpl*j1+nnpl*nnpl*k1); + conn_hexa8[8*num_hexa8+4] = 1 + i0+nnpl*j1+nnpl*nnpl*k0 ; printf("%4d ",1+i0+nnpl*j1+nnpl*nnpl*k0); + conn_hexa8[8*num_hexa8+5] = 1 + i0+nnpl*j0+nnpl*nnpl*k0 ; printf("%4d ",1+i0+nnpl*j0+nnpl*nnpl*k0); + conn_hexa8[8*num_hexa8+6] = 1 + i1+nnpl*j0+nnpl*nnpl*k0 ; printf("%4d ",1+i1+nnpl*j0+nnpl*nnpl*k0); + conn_hexa8[8*num_hexa8+7] = 1 + i1+nnpl*j1+nnpl*nnpl*k0 ; printf("%4d ",1+i1+nnpl*j1+nnpl*nnpl*k0); + + printf("\n"); + } + } +void cree_noms_mailles(char * noms, int nnpl) + { + int nbr_hexa8=(nnpl-1)*(nnpl-1)*(nnpl-1); + int i; + char pnom[MED_TAILLE_PNOM+1]="hexa "; + + /*noms=(char *) malloc((nbr_hexa8*MED_TAILLE_PNOM+1)*sizeof(char));*/ + + for (i=0;i 0 + - les numeros de familles des elements sont < 0 + - rien d'imposer sur les noms de familles + */ + +/* la famille 0 */ + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(fromfid,frommaa,nomfam,numfam,&attide,&attval,attdes,0,gro,0); + } + printf("MEDfamCr : %d \n",ret); +/*****************************************************************************************************/ + + if (ret == 0) + { + strcpy(nomfam,"FAMILLE_0"); + numfam = 0; + ret = MEDfamCr(tofid,tomaa,nomfam,numfam,&attide,&attval,attdes,0,gro,0); + } + printf("MEDfamCr : %d \n",ret); + +/*****************************************************************************************************/ +/* Les champs */ + + if (ret == 0) + { + ret = MEDchampCr(fromfid,champnode,MED_REEL64,champnode_comp,champnode_unit,1); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) + { + ret = MEDchampEcr(fromfid, frommaa, champnode, (unsigned char *)fieldnodedouble, + MED_NO_INTERLACE, fromnnoe, + MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_NOEUD, + 0, MED_NOPDT," ", 0. , MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + if (ret == 0) + { + ret = MEDchampCr(fromfid,champcell,MED_REEL64,champcell_comp,champcell_unit,3); + printf("MEDchampCr : %d \n",ret); + if (ret == 0) + { + ret = MEDchampEcr(fromfid, frommaa, champcell, (unsigned char *)fieldcelldoublevector, + MED_NO_INTERLACE, fromnhexa8, + MED_NOPG, MED_ALL, MED_NOPFL, MED_ECRI, MED_MAILLE, + MED_HEXA8, MED_NOPDT," ", 0., MED_NONOR); + printf("MEDchampEcr : %d \n",ret); + } + } + + +/***************************************************************************/ +ret = MEDfermer(fromfid); +printf("MEDfermer : %d\n",ret); +/***************************************************************************/ +ret = MEDfermer(tofid); +printf("MEDfermer : %d\n",ret); + +return 0; +} + diff --git a/src/MEDMEM/INTERPOLATION/test_MEDMEM_Interpolation.cxx b/src/MEDMEM/INTERPOLATION/test_MEDMEM_Interpolation.cxx new file mode 100644 index 000000000..5d8112d8e --- /dev/null +++ b/src/MEDMEM/INTERPOLATION/test_MEDMEM_Interpolation.cxx @@ -0,0 +1,56 @@ +#include "MEDMEM_Exception.hxx" +#include "MEDMEM_define.hxx" + +#include "MEDMEM_Field.hxx" +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Interpolation.hxx" + +#include "stdio.h" + +main () { + + const char * fromFileName = "fromMesh.med"; + const char * toFileName = "toMesh.med"; + //const char * fieldName = "fieldcelldoublevector"; + const char * fieldName = "fieldnodedouble"; + + const char * fromMeshName = "fromMesh"; + const char * toMeshName = "toMesh"; + + try { + + cout<<"Lecture du Maillage Source : "< fromField (&fromSupport,MED_DRIVER,fromFileName,fieldName); cout<<"OK !"< myInter (fromField,toMesh); + + //FIELD * toField = myInter.interpolate(0,1); + FIELD * toField = myInter.interpolate(1,1); + + cout<<"Creation du driver"<addDriver(MED_DRIVER,toFileName,toField->getName()) ; + + cout<<"toField->getName() = "<getName() <getDescription() = "<getDescription() <getNumberOfComponents() = "<getNumberOfComponents() <getNumberOfValues() = "<getNumberOfValues() <getComponentsNames() = "<getComponentsNames() <getComponentsDescriptions() = "<getComponentsDescriptions()<getMEDComponentsUnits() = "<getMEDComponentsUnits() <getIterationNumber() = "<getIterationNumber() <getTime() = "<getTime() <getOrderNumber() = "<getOrderNumber() <getValueType() = "<getValueType() <write(); + + cout<<"Fin"< +#include "UtilClient.hxx" +#include "CONNECTIVITYClient.hxx" + +CONNECTIVITYClient::CONNECTIVITYClient(const SALOME_MED::MESH_ptr m, + medEntityMesh Entity) : + CONNECTIVITY(m->getNumberOfTypes(Entity), Entity), + IOR_Mesh(SALOME_MED::MESH::_duplicate(m)), + _numberOfElements_client(0), + _complete(false) +{ + BEGIN_OF("CONNECTIVITYClient::CONNECTIVITYClient()"); + + ASSERT(m); + + blankCopy(); + + END_OF("CONNECTIVITYClient::CONNECTIVITYClient()"); +} + +CONNECTIVITYClient::~CONNECTIVITYClient() +{ + BEGIN_OF("CONNECTIVITYClient::~CONNECTIVITYClient()"); + + if (_numberOfElements_client) + delete [] _numberOfElements_client; + + END_OF("CONNECTIVITYClient::~CONNECTIVITYClient()"); +} + +void CONNECTIVITYClient::blankCopy() +{ + BEGIN_OF("CONNECTIVITYClient::blankCopy()"); + + _numberOfNodes = IOR_Mesh->getNumberOfNodes(); + + medEntityMesh Entity = getEntity(); + medGeometryElement * Types; + + long iT, nT; + convertCorbaArray + (Types, nT, IOR_Mesh->getTypes(Entity)); + + ASSERT(nT == (int) getNumberOfTypes(Entity)); + SCRUTE(nT); + + setGeometricTypes(Types, Entity); + + _totalNumberOfElements_client = 0L; + _numberOfElements_client = new long[nT]; + for (iT=0; iTgetNumberOfElements(Entity, Types[iT]); + _totalNumberOfElements_client += _numberOfElements_client[iT]; + SCRUTE(iT); + SCRUTE(_numberOfElements_client[iT]); + } + + _complete = false; + + END_OF("CONNECTIVITYClient::blankCopy()"); +} + + +void CONNECTIVITYClient::fillCopy() +{ + BEGIN_OF("void CONNECTIVITYClient::fillCopy()"); + + + if (!_complete) { + + int *pC; + long nC; + + medEntityMesh Entity = getEntity(); + int iT, nT = getNumberOfTypes(Entity); + SCRUTE(nT); + const medGeometryElement * T = getGeometricTypes(Entity); + + int * Count = new int[nT+1] ; + Count[0]=1 ; + SCRUTE(Count[0]); + for (iT=0; iTgetConnectivity + (MED_FULL_INTERLACE, MED_NODAL, Entity, T[iT])); + SCRUTE(nC); + ASSERT(nC == (T[iT]%100) * kT); + + setNodal(pC, Entity, T[iT]); + delete [] pC; + } + + delete[] Count; + + _complete = true; + } + + END_OF("void CONNECTIVITYClient::fillCopy()"); +} + +med_int CONNECTIVITYClient::getNumberOf(medEntityMesh Entity, + medGeometryElement Type) const +{ + BEGIN_OF("void CONNECTIVITYClient::getNumberOf()"); + + med_int n = 0; + + SCRUTE(Type); + SCRUTE(Entity); + + if (!_complete) { + + if (Entity == _entity) { + + if (Type==MED_ALL_ELEMENTS) + n = _totalNumberOfElements_client; + + for (med_int i=0; i<_numberOfTypes; i++) { + SCRUTE(_geometricTypes[i]); + if (_geometricTypes[i] == Type) { + n = _numberOfElements_client[i]; + break; + } + } + } + else if (_constituent != NULL) + n = _constituent->getNumberOf(Entity,Type); + + } + else + n = CONNECTIVITY::getNumberOf(Entity, Type); + + SCRUTE(n); + END_OF("void CONNECTIVITYClient::getNumberOf()"); + return n; +} + +const med_int * CONNECTIVITYClient::getConnectivity + (medConnectivity ConnectivityType, + medEntityMesh Entity, + medGeometryElement Type) +{ + BEGIN_OF("void CONNECTIVITYClient::getConnectivity()"); + + if (!_complete) + fillCopy(); + + const med_int * c = CONNECTIVITY::getConnectivity + (ConnectivityType, Entity, Type); + + END_OF("void CONNECTIVITYClient::getConnectivity()"); + return c; +} + +const med_int * CONNECTIVITYClient::getConnectivityIndex + (medConnectivity ConnectivityType, + medEntityMesh Entity) +{ + BEGIN_OF("void CONNECTIVITYClient::getConnectivityIndex()"); + + if (!_complete) + fillCopy(); + + const med_int *c = CONNECTIVITY::getConnectivityIndex + (ConnectivityType, Entity); + + END_OF("void CONNECTIVITYClient::getConnectivityIndex()"); + return c; +} + +void CONNECTIVITYClient::calculateConnectivity + (medConnectivity connectivityType, + medEntityMesh Entity) +{ + BEGIN_OF("void CONNECTIVITYClient::calculateConnectivity()"); + + if (!_complete) + fillCopy(); + + CONNECTIVITY::calculateConnectivity(connectivityType, Entity); + + END_OF("void CONNECTIVITYClient::calculateConnectivity()"); +} + +void CONNECTIVITYClient::updateFamily (vector myFamilies) +{ + BEGIN_OF("void CONNECTIVITYClient::updateFamily()"); + + if (!_complete) + fillCopy(); + + CONNECTIVITY::updateFamily(myFamilies); + + END_OF("void CONNECTIVITYClient::updateFamily()"); +} + +const int * CONNECTIVITYClient::getGlobalNumberingIndex + (medEntityMesh Entity) const throw (MEDEXCEPTION) +{ + BEGIN_OF("void CONNECTIVITYClient::getGlobalNumberingIndex()"); + + if (!_complete) + (const_cast(this))->fillCopy(); + + CONNECTIVITY::getGlobalNumberingIndex(Entity); + + END_OF("void CONNECTIVITYClient::getGlobalNumberingIndex()"); +} + +bool CONNECTIVITYClient::existConnectivity(medConnectivity ConnectivityType, + medEntityMesh Entity) const +{ + BEGIN_OF("void CONNECTIVITYClient::existConnectivity()"); + + if (!_complete) + (const_cast(this))->fillCopy(); + + bool b = CONNECTIVITY::existConnectivity(ConnectivityType, Entity); + + END_OF("void CONNECTIVITYClient::existConnectivity()"); + + return b; +} + +const med_int * CONNECTIVITYClient::getReverseConnectivity + (medConnectivity ConnectivityType, + medEntityMesh Entity) throw (MEDEXCEPTION) +{ + BEGIN_OF("void CONNECTIVITYClient::getReverseConnectivity()"); + + if (!_complete) + fillCopy(); + + const med_int *c = CONNECTIVITY::getReverseConnectivity + (ConnectivityType, Entity); + + END_OF("void CONNECTIVITYClient::getReverseConnectivity()"); + + return c; +} + +const med_int * CONNECTIVITYClient::getReverseConnectivityIndex + (medConnectivity ConnectivityType, + medEntityMesh Entity) throw (MEDEXCEPTION) +{ + BEGIN_OF("void CONNECTIVITYClient::getReverseConnectivityIndex()"); + + if (!_complete) + fillCopy(); + + const med_int *c = CONNECTIVITY::getReverseConnectivityIndex + (ConnectivityType, Entity); + + END_OF("void CONNECTIVITYClient::getReverseConnectivityIndex()"); + + return c; +} + +const med_int* CONNECTIVITYClient::getValue(medConnectivity TypeConnectivity, + medGeometryElement Type) +{ + BEGIN_OF("void CONNECTIVITYClient::getValue()"); + + if (!_complete) + fillCopy(); + + const med_int * c = CONNECTIVITY::getValue(TypeConnectivity, Type); + + END_OF("void CONNECTIVITYClient::()"); + + return c; +} + +const med_int* CONNECTIVITYClient::getValueIndex(medConnectivity TypeConnectivity) +{ + BEGIN_OF("void CONNECTIVITYClient::getValueIndex()"); + + if (!_complete) + fillCopy(); + + const med_int * c = CONNECTIVITY::getValueIndex(TypeConnectivity); + + END_OF("void CONNECTIVITYClient::getValueIndex()"); + + return c; +} + +const med_int* CONNECTIVITYClient::getNeighbourhood() const +{ + BEGIN_OF("void CONNECTIVITYClient::getNeighbourhood()"); + + if (!_complete) + (const_cast(this))->fillCopy(); + + const med_int * c = CONNECTIVITY::getNeighbourhood(); + + END_OF("void CONNECTIVITYClient::getNeighbourhood()"); + + return c; +} + diff --git a/src/MedClient/src/CONNECTIVITYClient.hxx b/src/MedClient/src/CONNECTIVITYClient.hxx new file mode 100644 index 000000000..9240db5e5 --- /dev/null +++ b/src/MedClient/src/CONNECTIVITYClient.hxx @@ -0,0 +1,62 @@ +#ifndef _CONNECTIVITY_CLIENT_HXX +#define _CONNECTIVITY_CLIENT_HXX + +#include +#include "MEDMEM_Connectivity.hxx" +#include CORBA_CLIENT_HEADER(MED) + +class CONNECTIVITYClient : public CONNECTIVITY { + +protected: + + long *_numberOfElements_client; + long _totalNumberOfElements_client; + + mutable bool _complete; + SALOME_MED::MESH_var IOR_Mesh ; + +public: + + CONNECTIVITYClient(const SALOME_MED::MESH_ptr m, + medEntityMesh Entity=MED_CELL); + + virtual ~CONNECTIVITYClient(); + + void fillCopy(); + void blankCopy(); + + med_int getNumberOf(medEntityMesh Entity, medGeometryElement Type) const; + + const med_int * getConnectivity (medConnectivity ConnectivityType, + medEntityMesh Entity, + medGeometryElement Type); + const med_int * getConnectivityIndex (medConnectivity ConnectivityType, + medEntityMesh Entity); + + void calculateConnectivity (medConnectivity connectivityType, + medEntityMesh Entity); + + void updateFamily (vector myFamilies); + + const int * getGlobalNumberingIndex (medEntityMesh Entity) const throw (MEDEXCEPTION); + + bool existConnectivity(medConnectivity ConnectivityType, + medEntityMesh Entity) const; + + const med_int* getReverseConnectivity (medConnectivity ConnectivityType, + medEntityMesh Entity=MED_CELL) + throw (MEDEXCEPTION); + + const med_int* getReverseConnectivityIndex (medConnectivity ConnectivityType, + medEntityMesh Entity=MED_CELL) + throw (MEDEXCEPTION); + + const med_int* getValue (medConnectivity TypeConnectivity, + medGeometryElement Type); + + const med_int* getValueIndex (medConnectivity TypeConnectivity); + const med_int* getNeighbourhood() const; +}; + + +#endif diff --git a/src/MedClient/src/COORDINATEClient.cxx b/src/MedClient/src/COORDINATEClient.cxx new file mode 100644 index 000000000..f5ebf51b0 --- /dev/null +++ b/src/MedClient/src/COORDINATEClient.cxx @@ -0,0 +1,107 @@ +#include "COORDINATEClient.hxx" +#include +#include "UtilClient.hxx" + +COORDINATEClient::COORDINATEClient(const SALOME_MED::MESH_ptr m, + medModeSwitch Mode) : + COORDINATE(m->getSpaceDimension(), 1, Mode), + _complete(false), + IOR_Mesh(SALOME_MED::MESH::_duplicate(m)) +{ + BEGIN_OF("COORDINATEClient::COORDINATEClient(...)"); + + blankCopy(); + + END_OF("COORDINATEClient::COORDINATEClient(...)"); +} + +void COORDINATEClient::blankCopy() +{ + BEGIN_OF("void COORDINATEClient::blankCopy()"); + + std::string *tA; + long nA; + + convertCorbaArray(tA, nA, IOR_Mesh->getCoordinatesNames()); + ASSERT(nA == getSpaceDimension()); + setCoordinatesNames(tA); + delete [] tA; + + convertCorbaArray(tA, nA, IOR_Mesh->getCoordinatesUnits()); + ASSERT(nA == getSpaceDimension()); + setCoordinatesUnits(tA); + delete [] tA; + + setCoordinatesSystem(IOR_Mesh->getCoordinatesSystem()); + + _complete = false; + + END_OF("void COORDINATEClient::blankCopy()"); +} + +void COORDINATEClient::fillCopy() +{ + BEGIN_OF("void COORDINATEClient::fillCopy()"); + + long nN = IOR_Mesh->getNumberOfNodes(); + double *tC; + long nC; + convertCorbaArray(tC, nC, IOR_Mesh->getCoordinates(MED_FULL_INTERLACE)); + ASSERT(nC == (getSpaceDimension() * nN)); + + MEDARRAY mC(tC, getSpaceDimension(), nN); + setCoordinates(&mC); + + _complete = true; + + END_OF("void COORDINATEClient::fillCopy()"); +} + + +const double * COORDINATEClient::getCoordinates(medModeSwitch Mode) +{ + BEGIN_OF("void COORDINATEClient::getCoordinates()"); + + if (!_complete) fillCopy(); + const double * c = COORDINATE::getCoordinates(Mode); + + END_OF("void COORDINATEClient::getCoordinates()"); + + return c; +} + +double COORDINATEClient::getCoordinate(int Number,int Axis) +{ + BEGIN_OF("void COORDINATEClient::getCoordinate()"); + + if (!_complete) fillCopy(); + double d = COORDINATE::getCoordinate(Number, Axis); + + END_OF("void COORDINATEClient::getCoordinate()"); + + return d; +} + +const double * COORDINATEClient::getCoordinateAxis(int Axis) +{ + BEGIN_OF("void COORDINATEClient::getCoordinateAxis()"); + + if (!_complete) fillCopy(); + const double *c = COORDINATE::getCoordinateAxis(Axis); + + END_OF("void COORDINATEClient::getCoordinateAxis()"); + + return c; +} + +const int* COORDINATEClient::getNodesNumbers() const +{ + BEGIN_OF("void COORDINATEClient::getNodesNumbers()"); + + if (!_complete) (const_cast < COORDINATEClient * >(this))->fillCopy(); + + MESSAGE("NON IMPLEMENTE DANS L'API CORBA"); + END_OF("void COORDINATEClient::getNodesNumbers()"); + + return NULL; +} diff --git a/src/MedClient/src/COORDINATEClient.hxx b/src/MedClient/src/COORDINATEClient.hxx new file mode 100644 index 000000000..2f64e4636 --- /dev/null +++ b/src/MedClient/src/COORDINATEClient.hxx @@ -0,0 +1,59 @@ +#ifndef _COORDINATE_CLIENT_HXX +#define _COORDINATE_CLIENT_HXX + +#include +#include "MEDMEM_Coordinate.hxx" +#include CORBA_CLIENT_HEADER(MED) + +class COORDINATEClient : public COORDINATE { + +protected: + + mutable bool _complete; + SALOME_MED::MESH_var IOR_Mesh ; + +public: + + /*! + COORDINATEClient constructor + + Build an "empty" coordinate object (without the actual coordinate values). + The object hold a Corba IOR and get data from it on user demand. + + Parameters in : m (Mesh Corba IOR) + mode (FULL_ or NO_ interlace) + */ + COORDINATEClient(const SALOME_MED::MESH_ptr m, medModeSwitch Mode); + + + /*! + COORDINATEClient::blankCopy() + + "(Re)Blank" the coordinate object. + + Update fixed sized data from the Corba IOR (dimensions, strings). + Get rid of variable sized data (coordinate values). + Next call of getCoordinates (for instance) will update the + object. + */ + void blankCopy(); + + + /*! + COORDINATEClient::fillCopy() + + (Re)fill the coordinate object from the Corba IOR + */ + void fillCopy(); + + + virtual ~COORDINATEClient() {}; + + virtual const double * getCoordinates(medModeSwitch Mode); + virtual double getCoordinate(int Number,int Axis); + virtual const double * getCoordinateAxis(int Axis); + virtual const int* getNodesNumbers() const; + +}; + +#endif diff --git a/src/MedClient/src/FAMILYClient.cxx b/src/MedClient/src/FAMILYClient.cxx new file mode 100644 index 000000000..a648cd9a2 --- /dev/null +++ b/src/MedClient/src/FAMILYClient.cxx @@ -0,0 +1,83 @@ +#include "FAMILYClient.hxx" +#include "MESHClient.hxx" +#include "UtilClient.hxx" + +FAMILYClient::FAMILYClient(const SALOME_MED::FAMILY_ptr F, + MESH * M) + : SUPPORTClient(F, M), + FAMILY(), + IOR_Family(SALOME_MED::FAMILY::_duplicate(F)) +{ + BEGIN_OF("FAMILYClient::FAMILYClient(SALOME_MED::FAMILY_ptr m)"); + + SCRUTE(F); + SCRUTE(M); + + blankCopy(false); + + END_OF("FAMILYClient::FAMILYClient(SALOME_MED::FAMILY_ptr m)"); +} + +void FAMILYClient::blankCopy(bool blankSupport) +{ + BEGIN_OF("FAMILYClient::blankCopy()"); + + if (blankSupport) + SUPPORTClient::blankCopy(); + + MESSAGE(""); + +// setIdentifier(IOR_Family->getIdentifier()); + +// int nAttr, nGr, n; +// int *i; +// std::string *s; + +// nAttr = IOR_Family->getNumberOfAttributes(); +// setNumberOfAttributes(nAttr); + +// convertCorbaArray(i, n, IOR_Family->getAttributesIdentifiers()); +// ASSERT(n == nAttr); +// setAttributesIdentifiers(i); + +// convertCorbaArray(i, n, IOR_Family->getAttributesValues()); +// ASSERT(n == _numberOfAttribute); +// setAttributesValues(i); + +// convertCorbaArray(s, n, IOR_Family->getAttributesDescriptions()); +// ASSERT(n == _numberOfAttribute); +// setAttributesDescriptions(s); + +// nGr = IOR_Family->getNumberOfGroups(); +// setNumberOfGroups(nGr); + +// convertCorbaArray(s, n, IOR_Family->getGroupsNames()); +// ASSERT(n == _numberOfAttribute); +// setGroupsNames(s); + + _complete = false; + + END_OF("FAMILYClient::blankCopy()"); +} + +void FAMILYClient::fillCopy(bool fillSupport) +{ + BEGIN_OF("FAMILYClient::fillCopy()"); + + if (!_complete) { + + if (fillSupport) + SUPPORTClient::fillCopy(); + + _complete = true; + } + + END_OF("FAMILYClient::fillCopy()"); +} + + +FAMILYClient::~FAMILYClient() +{ + BEGIN_OF("FAMILYClient::~FAMILYClient()"); + END_OF("FAMILYClient::~FAMILYClient()"); +} diff --git a/src/MedClient/src/FAMILYClient.hxx b/src/MedClient/src/FAMILYClient.hxx new file mode 100644 index 000000000..c74ef20db --- /dev/null +++ b/src/MedClient/src/FAMILYClient.hxx @@ -0,0 +1,31 @@ +#ifndef _FAMILYCLIENT_HXX +#define _FAMILYCLIENT_HXX + +#include +#include +#include "MEDMEM_Family.hxx" +#include CORBA_CLIENT_HEADER(MED) +#include "SUPPORTClient.hxx" + + +class FAMILYClient : + public SUPPORTClient, public FAMILY { + +private : + + const SALOME_MED::FAMILY_var IOR_Family; + + mutable bool _complete; + +public : + + FAMILYClient(const SALOME_MED::FAMILY_ptr S, + MESH * M = NULL); + virtual ~FAMILYClient(); + + virtual void blankCopy(bool blankSupport = true); + virtual void fillCopy(bool fillSupport = true); +}; + + +#endif diff --git a/src/MedClient/src/FIELDClient.hxx b/src/MedClient/src/FIELDClient.hxx new file mode 100644 index 000000000..0582515ef --- /dev/null +++ b/src/MedClient/src/FIELDClient.hxx @@ -0,0 +1,70 @@ +#ifndef _FIELDCLIENT_HXX +#define _FIELDCLIENT_HXX + +#include +#include +#include "MEDMEM_Field.hxx" +#include CORBA_CLIENT_HEADER(MED) + +template +class FIELDClient : virtual public FIELD { + +private : + + const SALOME_MED::FIELD_var IOR_Field; + + mutable bool _complete_field; + +public : + + FIELDClient(const SALOME_MED::FIELD_ptr S, + SUPPORT * S = NULL); + virtual ~FIELDClient(); + + void blankCopy(); + void fillCopy(); + + +}; + +template +FIELDClient::FIELDClient(const SALOME_MED::FIELD_ptr F, + SUPPORT * S) : + FIELD(), + IOR_Field(SALOME_MED::FIELD::_duplicate(F)) +{ + BEGIN_OF("FIELDClient::FIELDClient(SALOME_MED::FIELD_ptr m)"); + + if (S) setSupport(S); + + END_OF("FIELDClient::FIELDClient(SALOME_MED::FIELD_ptr m)"); +} + +template +void FIELDClient::blankCopy() +{ + BEGIN_OF("FIELDClient::blankCopy"); + + + END_OF("FIELDClient::blankCopy"); + +} + +template +void FIELDClient::fillCopy() +{ + BEGIN_OF("FIELDClient::fillCopy"); + + END_OF("FIELDClient::fillCopy"); +} + + +template +FIELDClient::~FIELDClient() +{ + BEGIN_OF("FIELDClient::~FIELDClient"); + + END_OF("FIELDClient::~FIELDClient"); +} + +#endif diff --git a/src/MedClient/src/GROUPClient.cxx b/src/MedClient/src/GROUPClient.cxx new file mode 100644 index 000000000..99ec27a1e --- /dev/null +++ b/src/MedClient/src/GROUPClient.cxx @@ -0,0 +1,44 @@ +#include "GROUPClient.hxx" +#include "MESHClient.hxx" + +GROUPClient::GROUPClient(const SALOME_MED::GROUP_ptr G, + MESH * M) + : SUPPORTClient(G, M), + GROUP(), + IOR_Group(SALOME_MED::GROUP::_duplicate(G)) +{ + BEGIN_OF("GROUPClient::GROUPClient()"); + + SCRUTE(G); + SCRUTE(M); + + END_OF("GROUPClient::GROUPClient()"); +} + + +void GROUPClient::blankCopy() +{ + BEGIN_OF("GROUPClient::blankCopy()"); + + SUPPORTClient::blankCopy(); + _complete = false; + + END_OF("GROUPClient::blankCopy()"); +} + +void GROUPClient::fillCopy() +{ + BEGIN_OF("GROUPClient::fillCopy()"); + + SUPPORTClient::fillCopy(); + _complete = true; + + END_OF("GROUPClient::fillCopy()"); +} + + +GROUPClient::~GROUPClient() +{ + BEGIN_OF("GROUPClient::~GROUPClient()"); + END_OF("GROUPClient::~GROUPClient()"); +} diff --git a/src/MedClient/src/GROUPClient.hxx b/src/MedClient/src/GROUPClient.hxx new file mode 100644 index 000000000..fd6d32edd --- /dev/null +++ b/src/MedClient/src/GROUPClient.hxx @@ -0,0 +1,32 @@ +#ifndef _GROUPCLIENT_HXX +#define _GROUPCLIENT_HXX + +#include +#include +#include "MEDMEM_Group.hxx" +#include CORBA_CLIENT_HEADER(MED) +#include "SUPPORTClient.hxx" + +class GROUPClient : + public SUPPORTClient, + public GROUP +{ + +private : + + const SALOME_MED::GROUP_var IOR_Group; + + mutable bool _complete; + +public : + + GROUPClient(const SALOME_MED::GROUP_ptr S, + MESH * M = NULL); + virtual ~GROUPClient(); + + virtual void blankCopy(); + virtual void fillCopy(); +}; + + +#endif diff --git a/src/MedClient/src/MESHClient.cxx b/src/MedClient/src/MESHClient.cxx new file mode 100644 index 000000000..4a530dfe9 --- /dev/null +++ b/src/MedClient/src/MESHClient.cxx @@ -0,0 +1,143 @@ +#include "MESHClient.hxx" +#include +#include "UtilClient.hxx" +#include "COORDINATEClient.hxx" +#include "CONNECTIVITYClient.hxx" +#include "FAMILYClient.hxx" +#include "GROUPClient.hxx" + +MESHClient::MESHClient(const SALOME_MED::MESH_ptr m) : + MESH(), + IOR_Mesh(SALOME_MED::MESH::_duplicate(m)), + _complete(false) + +{ + BEGIN_OF("MESHClient::MESHClient(SALOME_MED::MESH_ptr m)"); + + ASSERT(m); + + _coordinate = new COORDINATEClient(m, MED_FULL_INTERLACE); + _connectivity = new CONNECTIVITYClient(m, MED_FULL_INTERLACE); + + blankCopy(); + + END_OF("MESHClient::MESHClient(SALOME_MED::MESH_ptr m)"); +} + +FAMILY * convertFamily(const SALOME_MED::FAMILY_ptr &F, MESH *M) { + return new FAMILYClient(F, M); +} + +GROUP * convertGroup(const SALOME_MED::GROUP_ptr &F, MESH *M) { + return new GROUPClient(F, M); +} + +void MESHClient::blankCopy() +{ + BEGIN_OF("MESHClient::blankCopy()"); + + CORBA::String_var s; + + s= IOR_Mesh->getName(); _name = s; + _spaceDimension = IOR_Mesh->getSpaceDimension(); + _meshDimension = IOR_Mesh->getMeshDimension(); + _numberOfNodes = IOR_Mesh->getNumberOfNodes(); + + COORDINATEClient *_coord + = dynamic_cast(_coordinate); + ASSERT(_coord); + CONNECTIVITYClient *_connect + = dynamic_cast(_connectivity); + ASSERT(_connect); + + _coord->blankCopy(); + _connect->blankCopy(); + + MESSAGE(""); + convertCorbaArray + (_familyNode, + _numberOfNodesFamilies, + IOR_Mesh->getFamilies(MED_NODE), + (void *) (convertFamily), this); + + MESSAGE(""); + convertCorbaArray + (_familyEdge, + _numberOfEdgesFamilies, + IOR_Mesh->getFamilies(MED_EDGE), + (void *) (convertFamily), this); + + MESSAGE(""); + convertCorbaArray + (_familyFace, + _numberOfFacesFamilies, + IOR_Mesh->getFamilies(MED_FACE), + (void *) (convertFamily), this); + + MESSAGE(""); + convertCorbaArray + (_familyCell, + _numberOfCellsFamilies, + IOR_Mesh->getFamilies(MED_CELL), + (void *) (convertFamily), this); + + MESSAGE(""); + convertCorbaArray + (_groupNode, + _numberOfNodesGroups, + IOR_Mesh->getGroups(MED_NODE), + (void *) (convertGroup), this); + + MESSAGE(""); + convertCorbaArray + (_groupEdge, + _numberOfEdgesGroups, + IOR_Mesh->getGroups(MED_EDGE), + (void *) (convertGroup), this); + + MESSAGE(""); + convertCorbaArray + (_groupFace, + _numberOfFacesGroups, + IOR_Mesh->getGroups(MED_FACE), + (void *) (convertGroup), this); + + MESSAGE(""); + convertCorbaArray + (_groupCell, + _numberOfCellsGroups, + IOR_Mesh->getGroups(MED_CELL), + (void *) (convertGroup), this); + + MESSAGE(""); + _complete = false; + + END_OF("MESHClient::blankCopy()"); +} + +void MESHClient::fillCopy() +{ + BEGIN_OF("MESHClient::fillCopy()"); + + COORDINATEClient *_coord + = dynamic_cast (_coordinate); + ASSERT(_coord); + CONNECTIVITYClient *_connect + = dynamic_cast (_connectivity); + ASSERT(_connect); + + _coord->fillCopy(); + _connect->fillCopy(); + + _complete = true; + + END_OF("MESHClient::fillCopy()"); +} + + +MESHClient::~MESHClient() +{ + BEGIN_OF("MESHClient::~MESHClient()"); + END_OF("MESHClient::~MESHClient()"); +} + diff --git a/src/MedClient/src/MESHClient.hxx b/src/MedClient/src/MESHClient.hxx new file mode 100644 index 000000000..4b268edbb --- /dev/null +++ b/src/MedClient/src/MESHClient.hxx @@ -0,0 +1,30 @@ +#ifndef _MESHCLIENT_HXX +#define _MESHCLIENT_HXX + +#include +#include +#include "MEDMEM_Mesh.hxx" +#include CORBA_CLIENT_HEADER(MED) + +class MESHClient : public MESH { + +private : + + const SALOME_MED::MESH_var IOR_Mesh; + + mutable bool _complete; + + +public : + + MESHClient(const SALOME_MED::MESH_ptr m); + + virtual ~MESHClient(); + + void blankCopy(); + void fillCopy(); + +}; + +#endif + diff --git a/src/MedClient/src/Makefile.in b/src/MedClient/src/Makefile.in new file mode 100644 index 000000000..bad4bec34 --- /dev/null +++ b/src/MedClient/src/Makefile.in @@ -0,0 +1,83 @@ +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Nadir BOUHAMOU (CEA/DEN/DM2S/SFME/LGLS) +# Module : MED +# source path +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:$(srcdir):$(top_srcdir)/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome + +MACHINE=PCLINUX + +@COMMENCE@ + + +EXPORT_HEADERS = \ + COORDINATEClient.hxx \ + CONNECTIVITYClient.hxx \ + MESHClient.hxx \ + SUPPORTClient.hxx \ + FAMILYClient.hxx \ + GROUPClient.hxx \ + FIELDClient.hxx \ + libMEDClient.i + +SWIG_DEF = libMEDClient.i + +EXPORT_PYSCRIPTS = libMEDClient.py + +# Libraries targets + +LIB=libMEDClientcmodule.la +LIB_SRC = \ + COORDINATEClient.cxx \ + CONNECTIVITYClient.cxx \ + MESHClient.cxx \ + SUPPORTClient.cxx \ + FAMILYClient.cxx \ + GROUPClient.cxx + +LIB_CLIENT_IDL= \ + SALOME_Component.idl \ + SALOMEDS.idl \ + SALOMEDS_Attributes.idl \ + SALOME_Exception.idl \ + MED.idl + +# Executables targets +BIN_SRC = +BIN_SERVER_IDL = +BIN_CLIENT_IDL = + + +CPPFLAGS+= $(MED2_INCLUDES) $(HDF5_INCLUDES) $(PYTHON_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome +CXXFLAGS+=-I${KERNEL_ROOT_DIR}/include/salome +LDFLAGS+=-L${KERNEL_ROOT_DIR}/lib/salome -lOpUtil -lMedCorba_Swigcmodule -lmedmem + +MED.hh MEDSK.cc: MED.idl + omniidl -bcxx -Wbtp -I$(top_builddir)/idl -I${KERNEL_ROOT_DIR}/idl/salome $^ + +@CONCLUDE@ diff --git a/src/MedClient/src/SUPPORTClient.cxx b/src/MedClient/src/SUPPORTClient.cxx new file mode 100644 index 000000000..37ed8d6ef --- /dev/null +++ b/src/MedClient/src/SUPPORTClient.cxx @@ -0,0 +1,134 @@ +#include "UtilClient.hxx" +#include "SUPPORTClient.hxx" +#include "MESHClient.hxx" + +SUPPORTClient::SUPPORTClient(const SALOME_MED::SUPPORT_ptr S, + MESH * M) : + SUPPORT(), + IOR_Support(SALOME_MED::SUPPORT::_duplicate(S)) +{ + BEGIN_OF("SUPPORTClient::SUPPORTClient(SALOME_MED::SUPPORT_ptr m)"); + + SCRUTE(S); + SCRUTE(M); + + setMesh(M ? M : new MESHClient(IOR_Support->getMesh())); + + blankCopy(); + + END_OF("SUPPORTClient::SUPPORTClient(SALOME_MED::SUPPORT_ptr m)"); +} + +void SUPPORTClient::blankCopy() +{ + BEGIN_OF("SUPPORTClient::blankCopy"); + + setName(IOR_Support->getName()); + setDescription(IOR_Support->getDescription()); + setAll(IOR_Support->isOnAllElements()); + setEntity(IOR_Support->getEntity()); + + convertCorbaArray(_geometricType, _numberOfGeometricType, + IOR_Support->getTypes()); + + int *nE = new int[_numberOfGeometricType]; + int i; + for (i=0; i<_numberOfGeometricType; i++) + nE[i] = IOR_Support->getNumberOfElements(_geometricType[i]); + setNumberOfElements(nE); + SCRUTE(_totalNumberOfElements); + + SCRUTE(_name); + SCRUTE(_description); + + _complete_support = false; + + END_OF("SUPPORTClient::blankCopy"); + +} + +void SUPPORTClient::fillCopy() +{ + BEGIN_OF("SUPPORTClient::fillCopy"); + + int * index, * value; + long n_index, n_value; + + MESSAGE(""); + try { + convertCorbaArray(value, n_value, + IOR_Support->getNumber(MED_ALL_ELEMENTS)); + } + catch (...) { + std::cerr << "erreur ...." << std::endl; + exit(-1); + } + + SCRUTE(n_value); + SCRUTE(value[0]); + SCRUTE(value[1]); + MESSAGE(""); + + try { + convertCorbaArray(index, n_index, + IOR_Support->getNumberIndex()); + } + catch (...) { + std::cerr << "erreur ...." << std::endl; + exit(-1); + } + + SCRUTE(n_index); + SCRUTE(n_value); + setNumber(index, value); + + delete [] index; + delete [] value; + + _complete_support = true; + + END_OF("SUPPORTClient::fillCopy"); +} + + +SUPPORTClient::~SUPPORTClient() +{ + BEGIN_OF("SUPPORTClient::~SUPPORTClient"); + + END_OF("SUPPORTClient::~SUPPORTClient"); +} + +MEDSKYLINEARRAY * SUPPORTClient::getnumber() const throw (MEDEXCEPTION) +{ + BEGIN_OF("SUPPORTClient::getnumber()"); + + if (!_complete_support) (const_cast(this))->fillCopy(); + MEDSKYLINEARRAY *m = SUPPORT::getnumber(); + + END_OF("SUPPORTClient::getnumber()"); + return m; +} + +const int * SUPPORTClient::getNumber(medGeometryElement GeometricType) + const throw (MEDEXCEPTION) +{ + BEGIN_OF("SUPPORTClient::getnumber(medGeometryElement)"); + + if (!_complete_support) (const_cast(this))->fillCopy(); + const int *n = SUPPORT::getNumber(GeometricType); + + END_OF("SUPPORTClient::getnumber(medGeometryElement)"); + return n; +} + +const int * SUPPORTClient::getNumberIndex() const throw (MEDEXCEPTION) +{ + BEGIN_OF("SUPPORTClient::getnumberIndex()"); + + if (!_complete_support) (const_cast(this))->fillCopy(); + const int * n = SUPPORT::getNumberIndex(); + + END_OF("SUPPORTClient::getnumberIndex()"); + return n; +} + diff --git a/src/MedClient/src/SUPPORTClient.hxx b/src/MedClient/src/SUPPORTClient.hxx new file mode 100644 index 000000000..6e03691db --- /dev/null +++ b/src/MedClient/src/SUPPORTClient.hxx @@ -0,0 +1,37 @@ +#ifndef _SUPPORTCLIENT_HXX +#define _SUPPORTCLIENT_HXX + +#include +#include +#include "MEDMEM_Support.hxx" +#include CORBA_CLIENT_HEADER(MED) + + +class SUPPORTClient : virtual public SUPPORT { + +private : + + const SALOME_MED::SUPPORT_var IOR_Support; + + mutable bool _complete_support; + +public : + + SUPPORTClient(const SALOME_MED::SUPPORT_ptr S, + MESH * M = NULL); + virtual ~SUPPORTClient(); + + void blankCopy(); + void fillCopy(); + + MEDSKYLINEARRAY * getnumber() + const throw (MEDEXCEPTION); + const int * getNumber(medGeometryElement GeometricType) + const throw (MEDEXCEPTION); + const int * getNumberIndex() + const throw (MEDEXCEPTION); + +}; + + +#endif diff --git a/src/MedClient/src/UtilClient.hxx b/src/MedClient/src/UtilClient.hxx new file mode 100644 index 000000000..d497d3108 --- /dev/null +++ b/src/MedClient/src/UtilClient.hxx @@ -0,0 +1,113 @@ +#ifndef UTILCLIENT_HXX_ +#define UTILCLIENT_HXX_ + +#include +#include + +template +inline void convertCorbaArray (TLocal * & T, Tint &nT, const TCorbaSeq & S) +{ + Tint i, n = S->length(); + + nT = n; + T = n > 0 ? new TLocal[n] : NULL; + + for (i=0; i +inline void convertCorbaArray (TLocal * & T, long &nT, const TCorbaSeq & S, + void *f) +{ + int i, n = S->length(); + SCRUTE(n); + + nT = n; + T = n > 0 ? new TLocal[n] : NULL; + + typedef TLocal (*pfn) (const TCorba &T); + + pfn convert = pfn(f); + for (i=0; i +inline void convertCorbaArray (vector & T, int &nT, + const TCorbaSeq & S) +{ + int i, n = S->length(); + SCRUTE(n); + + nT = n; + T.resize(nT); + + for (i=0; i +inline void convertCorbaArray (vector & T, int &nT, + const TCorbaSeq & S, + void *f) +{ + int i, n = S->length(); + SCRUTE(n); + + nT = n; + T.resize(nT); + + typedef TLocal (*pfn) (const TCorba &T); + + pfn convert = pfn(f); + for (i=0; i +inline void convertCorbaArray (vector & T, int &nT, + const TCorbaSeq & S, + void *f, TInfo M) +{ + int i, n = S->length(); + SCRUTE(n); + + nT = n; + T.resize(nT); + + typedef TLocal (*pfn) (const TCorba & , TInfo); + + pfn convert = pfn(f); + for (i=0; i +class FIELDClient : public FIELD { + + public: + + FIELDClient(const SALOME_MED::FIELD_ptr S, + MESH * M = NULL); + ~FIELDClient(); + + void blankCopy(); + void fillCopy(); + +}; diff --git a/src/MedClient/test/Makefile.in b/src/MedClient/test/Makefile.in new file mode 100644 index 000000000..586744316 --- /dev/null +++ b/src/MedClient/test/Makefile.in @@ -0,0 +1,39 @@ +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Nadir BOUHAMOU (CEA/DEN/DM2S/SFME/LGLS) +# Module : MED +# source path +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@srcdir@/resources + +@COMMENCE@ + +RESOURCES_FILES = pointe.med carre_en_quad4_seg2.med maill.0.med test_hydro_darcy1a_out.med + +SUBDIRS = environ test1 test2 + +@MODULE@ diff --git a/src/MedClient/test/environ/Makefile.in b/src/MedClient/test/environ/Makefile.in new file mode 100644 index 000000000..c688571ea --- /dev/null +++ b/src/MedClient/test/environ/Makefile.in @@ -0,0 +1,73 @@ +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Nadir BOUHAMOU (CEA/DEN/DM2S/SFME/LGLS) +# Module : MED +# source path +top_srcdir=@top_srcdir@ +top_builddir=../../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +BIN= runEnvironTests + +all: + $(MAKE) inc + $(MAKE) depend_idl + $(MAKE) depend + $(MAKE) lib + $(MAKE) bin + $(MAKE) resources + +depend depend_idl clean_dep lib idl resources: + +inc: ${BIN} Makefile + + +bin: + chmod u+x ${BIN} + cp -f runTestMedCorba ${top_builddir}/bin + chmod +x ${top_builddir}/bin/runTestMedCorba + chmod +x runContainer stopContainer runEnvironTests + chmod +x csh/* + +install: + mkdir -p @prefix@/Tests/environ + cp -rf ${BIN} csh @prefix@/Tests/environ + cd @prefix@/Tests/environ ; chmod u+x ${BIN} + cp -f ${top_builddir}/bin/runTestMedCorba @prefix@/bin + chmod +x @prefix@/bin/runTestMedCorba + +./%: @srcdir@/%.in + cd $(top_builddir) ; \ + ./config.status + +$(top_builddir)/config.status: $(top_srcdir)/configure + cd $(top_builddir) ; ./config.status --recheck + +clean: + \rm -f dummy *~ */*~ + +cleandep: + diff --git a/src/MedClient/test/environ/csh/Makefile.in b/src/MedClient/test/environ/csh/Makefile.in new file mode 100644 index 000000000..ee46a855f --- /dev/null +++ b/src/MedClient/test/environ/csh/Makefile.in @@ -0,0 +1,43 @@ + +top_srcdir=@top_srcdir@ +top_builddir=../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@ + +BIN= init1 init2 init3 init4 init5 runContainer stopContainer + +TYPESHELL=csh +INSTALLDIR=@prefix@/Tests/environ/${TYPESHELL} + +all: + $(MAKE) inc + $(MAKE) depend_idl + $(MAKE) depend + $(MAKE) lib + $(MAKE) bin + $(MAKE) resources + chmod u+x ${BIN} + +depend depend_idl clean_dep lib idl resources: + +inc: ${BIN} Makefile + +bin: + chmod u+x ${BIN} + +install: + mkdir -p ${INSTALLDIR} + cp -rf ${BIN} ${INSTALLDIR} + cd ${INSTALLDIR} ; chmod u+x ${BIN} + +%: @srcdir@/%.in + @echo $^ "->" $@ + cd $(top_builddir) ; \ + ./config.status ${patsubst @top_srcdir@/%, ./%, @srcdir@/$@} + +%: @srcdir@/% + @echo $^ "->" $@ + cp -f $^ $@ + +$(top_builddir)/config.status: $(top_srcdir)/configure + cd $(top_builddir) ; ./config.status --recheck diff --git a/src/MedClient/test/environ/csh/init1.in b/src/MedClient/test/environ/csh/init1.in new file mode 100644 index 000000000..e0eb68e16 --- /dev/null +++ b/src/MedClient/test/environ/csh/init1.in @@ -0,0 +1,7 @@ +cd ${SALOME_ROOT_DIR}/bin +pwd +./allkill || true +./killall python || true +./runSession +csh + diff --git a/src/MedClient/test/environ/csh/init2.in b/src/MedClient/test/environ/csh/init2.in new file mode 100644 index 000000000..451835ead --- /dev/null +++ b/src/MedClient/test/environ/csh/init2.in @@ -0,0 +1,11 @@ +#!/bin/csh + +cd ${SALOME_BIN_TESTS} + +while ( `ps | grep omniNames > /dev/null ` ) + sleep 2 +end +sleep 2 + +./csh/runContainer TrucPy +csh diff --git a/src/MedClient/test/environ/csh/init3.in b/src/MedClient/test/environ/csh/init3.in new file mode 100644 index 000000000..388d8bb64 --- /dev/null +++ b/src/MedClient/test/environ/csh/init3.in @@ -0,0 +1,2 @@ +cd ${SALOME_ROOT_DIR}/bin +csh diff --git a/src/MedClient/test/environ/csh/runContainer.in b/src/MedClient/test/environ/csh/runContainer.in new file mode 100644 index 000000000..90fe75670 --- /dev/null +++ b/src/MedClient/test/environ/csh/runContainer.in @@ -0,0 +1,57 @@ +#! /bin/csh + +set CONTAINER_NAME=$1 + +set PYTHON_VERSION=python@PYTHON_VERSION@ + +# you must define SALOME_ROOT_DIR and SALOME_SITE_DIR (if you need it) + +setenv SALOME_ROOT_DIR @prefix@ + +if ( ${?SALOME_ROOT_DIR} ) then + setenv PATH ${SALOME_ROOT_DIR}/bin:${SALOME_ROOT_DIR}/Tests:${PATH} + setenv LD_LIBRARY_PATH ${SALOME_ROOT_DIR}/lib:${LD_LIBRARY_PATH} + setenv PYTHONPATH ${SALOME_ROOT_DIR}/lib:${SALOME_ROOT_DIR}/lib/${PYTHON_VERSION}/site-packages/salome:${PYTHONPATH} +endif + +if ( ${?SALOME_SITE_DIR} ) then + setenv PATH ${SALOME_SITE_DIR}/bin:${PATH} + setenv LD_LIBRARY_PATH ${SALOME_SITE_DIR}/lib:${LD_LIBRARY_PATH} + setenv PYTHONPATH ${SALOME_SITE_DIR}/lib:${SALOME_SITE_DIR}/lib/${PYTHON_VERSION}/site-packages/salome:${PYTHONPATH} +endif + +if ( -d ${HOME}/.salome/bin ) then + setenv PATH ${HOME}/.salome/bin:${PATH} +endif + +if ( -d ${HOME}/.salome/lib ) then + setenv LD_LIBRARY_PATH ${HOME}/.salome/lib:${LD_LIBRARY_PATH} +endif + +setenv tmp /usr/tmp + +echo +./csh/stopContainer ${CONTAINER_NAME} + +switch ($?) +case 11: + echo " Start container ${CONTAINER_NAME}" + breaksw +case 12: + echo " Restart container ${CONTAINER_NAME}" + breaksw +default: + exit 0 + breaksw +endsw +echo + +set CONTAINER_TYPE = `echo ${CONTAINER_NAME} | grep 'Py$'` +echo ${?CONTAINER_TYPE} + +if ( ${?CONTAINER_TYPE} ) then + ( ${SALOME_ROOT_DIR}/bin/SALOME_ContainerPy.py ${CONTAINER_NAME} &) +else + ( ${SALOME_ROOT_DIR}/bin/SALOME_Container ${CONTAINER_NAME} & ) +endif + diff --git a/src/MedClient/test/environ/csh/runEnvironTests.in b/src/MedClient/test/environ/csh/runEnvironTests.in new file mode 100644 index 000000000..23d4400bc --- /dev/null +++ b/src/MedClient/test/environ/csh/runEnvironTests.in @@ -0,0 +1,32 @@ +# +[ -f ~/.Xresources ] && xrdb ~/.Xresources + +setenv SALOME_BIN_TESTS ${SALOME_ROOT_DIR}/MED/src/MedClient/test/environ + +[ -f ${SALOME_BIN_TESTS}/killEnviron ] && ${SALOME_BIN_TESTS}/killEnviron + + +set TERMINAL="konsole --caption" +set TERMINAL="xterm -vb -sl 1000 -title" + +\rm -f ${SALOME_BIN_TESTS}/killEnviron +touch ${SALOME_BIN_TESTS}/killEnviron +chmod u+x ${SALOME_BIN_TESTS}/killEnviron + +set TITRE1="Session" +set TITRE2="Container" +set TITRE3="Essais" + +setenv PATH .:${PATH} + +echo "#! /bin/sh" >> ${SALOME_BIN_TESTS}/killEnviron +${TERMINAL} ${TITRE1} -e ${SALOME_BIN_TESTS}/csh/init1 & +echo "kill -9 $! >& /dev/null" >> ${SALOME_BIN_TESTS}/killEnviron +${TERMINAL} ${TITRE2} -e ${SALOME_BIN_TESTS}/csh/init2 & +echo "kill -9 $! >& /dev/null" >> ${SALOME_BIN_TESTS}/killEnviron +${TERMINAL} ${TITRE3} -e ${SALOME_BIN_TESTS}/csh/init3 & +echo "kill -9 $! >& /dev/null" >> ${SALOME_BIN_TESTS}/killEnviron + +echo "cd ${SALOME_ROOT_DIR}/bin ; ./allkill ; killall python >& /dev/null" >> ${SALOME_BIN_TESTS}/killEnviron +echo "\\rm -f ${SALOME_BIN_TESTS}/killEnviron" >> ${SALOME_BIN_TESTS}/killEnviron +chmod u+x ${SALOME_BIN_TESTS}/killEnviron diff --git a/src/MedClient/test/environ/csh/stopContainer.in b/src/MedClient/test/environ/csh/stopContainer.in new file mode 100644 index 000000000..5d3a362be --- /dev/null +++ b/src/MedClient/test/environ/csh/stopContainer.in @@ -0,0 +1,83 @@ +#! /bin/sh + +EXEC_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` + +removeTree() { + + local list + local noeud=$1 + + case $noeud in + *.dir/ | *.dir) + j=`echo $noeud | sed -e 's,^/,,' -e 's,/$,,' -` + list=`nameclt list $j 2> /dev/null` + for i in "$list" + do + [ -n "$i" ] && removeTree "$j/$i" + done + nameclt remove_context $j 2> /dev/null + ;; + *) + nameclt unbind $noeud 2> /dev/null + ;; + esac + +} + +CONTAINER_NAME="$1" +if test -z ${CONTAINER_NAME=} +then + echo "Usage : $0 " + exit -1 +fi + + +PYTHON_VERSION=python2.2 + +# you must define SALOME_ROOT_DIR and SALOME_SITE_DIR (if you need it) + +if test -n ${SALOME_ROOT_DIR} +then + export PATH=${SALOME_ROOT_DIR}/bin:${PATH} + export LD_LIBRARY_PATH=${SALOME_ROOT_DIR}/lib:${LD_LIBRARY_PATH} + export PYTHONPATH=${SALOME_ROOT_DIR}/lib:${SALOME_ROOT_DIR}/lib/${PYTHON_VERSION}/site-packages/salome:${PYTHONPATH} +fi +if test -n ${SALOME_SITE_DIR} +then + export PATH=${SALOME_SITE_DIR}/bin:${PATH} + export LD_LIBRARY_PATH=${SALOME_SITE_DIR}/lib:${LD_LIBRARY_PATH} + export PYTHONPATH=${SALOME_SITE_DIR}/lib:${SALOME_SITE_DIR}/lib/${PYTHON_VERSION}/site-packages/salome:${PYTHONPATH} +fi + +if test -d ${HOME}/.salome/bin +then + export PATH=${HOME}/.salome/bin:${PATH} +fi +if test -d ${HOME}/.salome/lib +then + export LD_LIBRARY_PATH=${HOME}/.salome/lib:${LD_LIBRARY_PATH} +fi + +export tmp=/usr/tmp + +NODE=Containers.dir/${HOSTNAME}.dir/${CONTAINER_NAME} +removeTree ${NODE}.object +removeTree ${NODE}.dir/ + + +PROCESS=`ps --width 200 -f -u ${USER} | \ + grep -w ${CONTAINER_NAME} | \ + grep SALOME_Container | + awk '{print \$2}'` + + +if test -n "${PROCESS}" +then + kill -9 `echo ${PROCESS}` >& /dev/null + echo + echo " Stop container ${CONTAINER_NAME}" + echo + exit 12 +fi + +exit 11 diff --git a/src/MedClient/test/environ/runContainer.in b/src/MedClient/test/environ/runContainer.in new file mode 100644 index 000000000..579a99034 --- /dev/null +++ b/src/MedClient/test/environ/runContainer.in @@ -0,0 +1,17 @@ +# + +set xTest = 1 +test "$xTest" = 1 && goto CSH + +echo BASH +`dirname $0`/bash/runContainer $1 + +exit 0 + +CSH: + +echo CSH +set dir=`expr "x$0" : 'x\(.*\)/[^/]*' \| '.'` +${dir}/csh/runContainer $1 + + diff --git a/src/MedClient/test/environ/runEnvironTests.in b/src/MedClient/test/environ/runEnvironTests.in new file mode 100644 index 000000000..ef3305285 --- /dev/null +++ b/src/MedClient/test/environ/runEnvironTests.in @@ -0,0 +1,17 @@ +# + +set xTest = 1 +test "$xTest" = 1 && goto CSH + +echo BASH +`dirname $0`/bash/runEnvironTests + +exit 0 + +CSH: + +echo CSH +set dir=`expr "x$0" : 'x\(.*\)/[^/]*' \| '.'` +${dir}/csh/runEnvironTests + + diff --git a/src/MedClient/test/environ/runTestMedCorba.in b/src/MedClient/test/environ/runTestMedCorba.in new file mode 100644 index 000000000..0e33fed11 --- /dev/null +++ b/src/MedClient/test/environ/runTestMedCorba.in @@ -0,0 +1,22 @@ +#! /bin/bash + +PYTHON_VERSION=python@PYTHON_VERSION@ + +if test -n $SALOME_ROOT_DIR +then + export PATH=$SALOME_ROOT_DIR/bin:${PATH} + export LD_LIBRARY_PATH=$SALOME_ROOT_DIR/lib:${LD_LIBRARY_PATH} + export PYTHONPATH=${SALOME_ROOT_DIR}/lib:${SALOME_ROOT_DIR}/lib/$PYTHON_VERSION/site-packages/salome:${SALOME_ROOT_DIR}/share/salome/resources:${PYTHONPATH} + # add bin, because some script are in (SALOME_SWIG) !!!! + export PYTHONPATH=${SALOME_ROOT_DIR}/bin:${PYTHONPATH} +fi +if test -n $SALOME_SITE_DIR +then + export PATH=$SALOME_SITE_DIR/bin:${PATH} + export LD_LIBRARY_PATH=$SALOME_SITE_DIR/lib:${LD_LIBRARY_PATH} + export PYTHONPATH=${SALOME_SITE_DIR}/lib:${SALOME_SITE_DIR}/lib/$PYTHON_VERSION/site-packages/salome:${SALOME_SITE_DIR}/share/salome/resources:${PYTHONPATH} +fi + +mkdir -p resultats +((python $1 2>&1 1>&3 | tee resultats/$1_err) 3>&1 1>&2 | tee resultats/$1_out ) 2>&1 + diff --git a/src/MedClient/test/environ/stopContainer.in b/src/MedClient/test/environ/stopContainer.in new file mode 100644 index 000000000..f09fc1c68 --- /dev/null +++ b/src/MedClient/test/environ/stopContainer.in @@ -0,0 +1,17 @@ +# + +set xTest = 1 +test "$xTest" = 1 && goto CSH + +echo BASH +`dirname $0`/bash/stopContainer $1 + +exit 0 + +CSH: + +echo CSH +set dir=`expr "x$0" : 'x\(.*\)/[^/]*' \| '.'` +${dir}/csh/stopContainer $1 + + diff --git a/src/MedClient/test/resources/carre_en_quad4_seg2.med b/src/MedClient/test/resources/carre_en_quad4_seg2.med new file mode 100644 index 0000000000000000000000000000000000000000..7d7c75370bbe7d054379e2019eb751a44d8b2b87 GIT binary patch literal 50746 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 T=qDiL&_Kfh!vVvAd^zxcbZ|)^ literal 0 HcmV?d00001 diff --git a/src/MedClient/test/resources/maill.0.med b/src/MedClient/test/resources/maill.0.med new file mode 100644 index 0000000000000000000000000000000000000000..e5a7b130dddf5374413ab2d40e08b6b258f4c524 GIT binary patch literal 100352 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 JsCT&Z{{fo~BwYXi literal 0 HcmV?d00001 diff --git a/src/MedClient/test/resources/pointe.med b/src/MedClient/test/resources/pointe.med new file mode 100644 index 0000000000000000000000000000000000000000..430a74bd66aa41aa72035b1b3c284dbc81c04ec4 GIT binary patch literal 80011 zcmeHQ3y@UhmHwLs%9g!J_F|rK9@bnQ~ zu*d_eEkj9SiC7V%m6(uFWT`b;rWTTQLoBxk!w$nu~F|@TdcbS)zUqkuZi85*J=w8*{+$Fu;YdMTd?ueVyts3LmkJSxD93bm8N zF4PbrltTr$fFyNtSW%7u97{DCGON3zvjxhq{LMIud@O}$UcmIJA0lPBnoIhQ`E>PT zDgU3<^=#0PPuQ&IT#>O`_r_GLiRUNRdP6>cAP^A~)9gSC1JOotEM3{>*bW9;bj02(An{0Q5^guL>UTP&t-!5 zZTB_d9bV6U*I@cmqAXX(&QIq%I33e>5@maG`rLFrT|ba3JQo^)h&ad8?|2e&?_XnH zPMf`eRCP==Mn&UjVxNyQ93cU?mO3<*>_UBQZGByBU1MEiV{KiX3@K23kqK0Q1PRK4 z3{;9*vxbO_JXFe@j_a11=_+{>T}y-Rn?zJ2v6Nfd+GXC+m7`*^m)QU6>DZrLe1j;< zJIg1rD_qGWuZ!EcW64`-SJ!6ytz}5Xl)NLDPV_6!_7n9e{a0EQ2|jL5Lq&{A zYG?)J>u43-*U{-Q@Mb2+54dSy2Peu8gwkM}4Z3iO{J>Tm-1|!T0k<1MJ0FrCu)we_ z1lI)YDAWZXs4F$B2lc~&ei>58gS1Myyq&(Tm<2UrAMh$X2MGb4zV0PIM$AY@gZ*>% zyX$K4KFAv!)2>AN+7(FI?|$}TOf%mj7h$@WDEkZB$$wxzT|cn2ch6(>M+t7JI}lmB z{a)`!5hExEdcvuH4!R1D;`-;RTy@Rib~96!m$M(qe4le!{<;j#@i!f-T=6{TDpv;0 z50rDWT={#p?MDZCH1z|1f|HNxzo=>OPhkGp-$}iOd+L4giBj`Yui+l}NU3c=-=V)M zUn)<1{t!=%p<(D{w3 zU&kRh9g(Iw4K%^lpBj(0$qbgDg2#sVNh!?UQQPp!v4-%1o0T%7Mmo>OUvtsn@+A`lx68{Y|F2 zp?x43-j^TnBOnF?>kHy95T}8;2K@n&1M>&6Ge=o~LK@WybAbzQQ2 z<*KJ%q;(19+^nb6K-0{t8L7;a9j`uK$eGy^j@Oh%4MUjiD+J&H4zCe#B%(46jsye* zARq37BLNS2z_9>F19(85fCn56-~mSic*eR;o%$0~{!%t3kII+G*5YYJ(>K98H6_!H|Ah3P>X%llG#nqM6kr+@E+8^4bmkv`w zLjb;j3NmBR!1;@!-RGkub@?0+{xS#;6aCZ*(_etRDf96Tud9=^-o8te*W+{a6&U8* z^9d~1N3<4`;y(#c=KE0x-guB`8}Tja#|!4Wybsgw_97)B9={9I%(v|hOmE$SbQp=) z6;J0Iz8}*~M7I;))UT%Vo!X1(XNc}1z84Or^F4I{(}P4=U)2&n=^Q$BzvPY6DIRSfPeUDIz_UsGP%M5dw3WD zG(yn_ez5f^nFmL%@w%BykRQt7oIZjXEeY$yLw&4e2>32hSyh*kzvGc2b{9{B3*o9Cuxr)I_e^w_~kbALZ8cJu3_hub8*OpRnU^k7qL zs;Y0o^vDXNY3mbaFn2Q1EtO&Q6^mhACGkX#Prs63XG+xZ4R*BTYMQ42&og zbfBscH>ma=QntFr?3~F5NS@d!(A5*>`x6135szz(xK+OuC(`u50OAcg&dre~zeq*F zBP41F?u}L1p<;)kpBxVzH!G@FZqaf0E5B3=ZkI$j zng_2&+}>Lg99byjNL7c%pvp%=ho+D)d#0{}M@Z}(im4kB8}_6o7dxwn{*uh$}g2%{hdeT%8Ex} zBaqJ!4qlHy_K=?P*J>!-Xh46yB43^5o9~d=IW(WX2f<@STR14gn!JF3&Y_8G92#{8 z#)fyqMzPq*;kIp|9C|@siq%J*97Zq9>{zRjx>-B0XUHwz!m%CGM~Sk2yM*)|^G&`R z`Cg`9_hTwJXQz(S69i4J-;LY$MJxd25Oa5bH_mS}kLx7)tJ25s_1g$bGal9M8PseK z=_g$;?CjpE&tXZnqq=&+e19UKvwLxk-LvZJ;slh8orpK+Y%c|r=2E|P(!zc~C;1CH zK3AKjCH;(#OLIX zV{Vq|bKexPvjdSBqz5mR_cI(=UxPTZCX(@fY7yXp&$GAext4#qn|j~81_iTPeyjpm z*a+U-UD&kOBX}cuIvi~eA`YwwF%_PJf`HE9h<*gOXI%;qs^iOsv4{8-_C(Uo@r^u$ ztf3qxAPdxmP7dQ5IaC8aPkaU8La7zvzTKE!OqAuShV&itou$_^9w8bi&|N%O-#l?~ z>c~7nlagyh?QII6K{*s^cSqFJ2-Mr;h`Cr6UD-9&5F6CXkvt9Y>knf^Y}j2n_^?w& zLqKPUqkoRtMRf?R`mHz-sE798kf9e|ia>q+(d<*jj>%8SfzfgEdVH90(D8-&?m~bg zB!!K*G!{1EQmRG#FnB5QaQh;*;!)V>)1!og*P~B8WE5~#t!KMkfB)C83@brv4PlO- z5zsjsagDQ~I=yTZNAi@z=bsAY(9d#aH#VIdMrVPg5<+!)?dtQ|{U6H?`zGR|h6a0{ z#_7PR6k`6@FFD(@j>t82^7nJnLrCD|#^)f49X69JtOk86y$RlgM{a#el^@dh2|=E#*_ zq@pRM@GlZif_rcbsYZ6FVzCB@W=wT;!)VBRVCrz z^{CZIo{q-Hp22m*>(XDVDjba+0y;+{YT!0TjTWd5FYD~?1NK8q6=DolR~a;~G%Da^P=VX6_lMgM>;p?VeK;_qYnpPoa?a`oQdr}O=c9F}(v zVt&xhP8~w0?_K-Z^N6Td-@CT%dqIA@%`udl#olp+b@eWEV zA||KFVU?6aIDSiVbyfj_9m!hCpYsl0fGopNCf_Fk$4jS?@+0qWyoPD!`{JvZ?j*|c z_c-ZA=G%4@`K~95Des?oJ-5+NnuwnGD39FxV+`^L?DX!8`9(UeQCB}}p2W&4HJPKbGP7|F~S*{$cv|BB_p^_&?$zvo6o zG@~EYLvmF$AsqpAJ^$uk@IFi7(PNnY64CV1Van|YSOa6Z1)!^GV7a~xiVI(tm%g%PLJ%Qyy+nE_Zzvt@qe(|{| zSDE*IWr=5hCw`3xu@wH}FEJe_%CX@;{wAGoMnYa3( zvlDwS;}tp{<2k(mTUDuuQEwDlL1~p%QNBv2Q@%=TC|{))#_a6k{FA~wLc54K1nsP| zi!aeSQte`?_4&x}aYnqN&*!}rGzluqcy;=G1b&m3<*?IlJN_FBhx#oGh(5lh({Ir$ zP_9({=1(Zt9~nPC1aZAE#pB;&w!HPmV z;%q+r!mWGuas$a#jUrwwhiwD^$A{vz3Znv$oj)`3e^?-tLj|~iBz4bT;_n~;-9)_s z2m2)|9X~$><8#T^fV~vO^~$Su{}jC1M3ldqcEf~pzIkSpQ;5%gfHT4Cb^m*q=K8!j zZ}!r~`cHk1b39M|*YJKip7uQnIsAlxZa-I6hbv0m&#CeD{bWBA>yN%P(M{A(SQT;)qR!;{ow?{J7Jzc7J9idxICpzFo`Z~Lg#;}aZBzx%c1Ij zoyb!T*G>!NkTDJ-)%jo5*PvY3`Cr|n$5sEhI^`Cmke`N$i>I{K(eSLLMg7t)9Q@o?I)#PYzUTo4u&D|#D^87rH-}ObC z3b7A<Ax=9%lGpEXF{J1M_hmZ}iTJ8m@7@O`A@ zo4SP<{>=Kp)wde$>xYca{>?^RqfvLw#~W)uURP(-*Vfh>*ETgZTq7Qc4Zk*exbNRY zZ1uWGjJhTsdR4@B%KU2wCd6d5wbS1mJxniUmq|Ppc6OQ<9m}!bi<*&ge|h|s6zYU= zLVr6tkq`PiQ+}BLP6Lm-h~7;UTLZje<|Ws&yaRDp>*-&I1y#!RFkRN#XkK>Rgl{%( zYsH8$_lNt>{2iSw=B3?uE&McIT{(_ZbGclp)Bec$S-fOP>nfBwAvoQ-q_w@ZW7#TG z_+{g2em!+a&2Lch<$74&B5PqjOxG*v1|{8?n16%nQwgu1lLXXviK^>|@zt##wchKO zqWm^5TV~$kd9P6zx&1w#z#Dx;owh$JkJPGp9dNrw>dlmEZhv+RGf&blLoDrIx71|N zji1}$su#DQ{<^VwiJ8^X+HF$iWBKRyzqtrYZXlX(`?=!J{Y9$&F2(96FhBSEM;(~+ zAW=)dNq^~Z`ykJG>j0%JkMoII+As3FRo{f|kE}qNZ~M8<8{>a@AGZ5$ucmz){NK+L z|CP64yZ7{K+AlKx2ZpfS_QArm?-c)ScVN3)w`kh8!JqX3mKF*7&G`o3P$%xKbCAFYH8mFe|7v$?Z(+Swts}ErF|Ru zSKD`r|9!i${l!F`wx2Klr}kp|&k(h=Z-YPk-B^or`B(pE+|quL@mK#3-D&&z;{VhE zL~f9%rF|RxaWBN^JI7!Bmncj7Hu$UKcPjttzggwm{%vap23HTQUp=s9XfvRaNUvVM z<<`N01W;yv|G?lNm9F7q~xLet4caj+5S7Yf7!JYZ2~))cTYOwIsRbR6H;)v)H@^ z^`*)aSCFZkIe*tTo40iH$K&MkPS>mYF7DKRo9!2Ay+Rxnj@0&wv0gt(0Ap*(Gvl5@ zv#!?^KEAByizH31?_?fd<)#mICc8MUSGnq;aqXmo##vvg@7GC{zg+YsueY)4%SZRX z@%92syP>``XOs20&i;1Oa^k7C;OJ0a<|^kbKk9pzEbZIaTi!p7Rel=G6Hs{e#CC@F2dsb8|5&lekBz^^ z@e8$_-To@+ufxgna zPARF46q1`?#`D1KIkg+{vsjXU52oVpw|!bA0j2J%!hIS7lOlk0SsFQ1zi;k$IZXOn eVY~n&kL?OAPcdF{sDAG*l*3@htymt5MgJfEK{B-f literal 0 HcmV?d00001 diff --git a/src/MedClient/test/resources/test_hydro_darcy1a_out.med b/src/MedClient/test/resources/test_hydro_darcy1a_out.med new file mode 100644 index 0000000000000000000000000000000000000000..df24a1ea636d0be1c58398882d349517c9424357 GIT binary patch literal 328756 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 1e-7): + raise RuntimeError, "getCoordinates : INTERLACE" + +x4 = transpose(x1, n, m); +print "Coordinates (MED_NO_INTERLACE) : ", x4 + +if (ecart(x2, x4) > 1e-7): + raise RuntimeError, "getCoordinates : NO_INTERLACE" + +print +print "All tests passed" diff --git a/src/MedClient/test/test1/TestMedCorba3.py b/src/MedClient/test/test1/TestMedCorba3.py new file mode 100644 index 000000000..a13b7555d --- /dev/null +++ b/src/MedClient/test/test1/TestMedCorba3.py @@ -0,0 +1,105 @@ +import os +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + +# MED Mesh read from a (local) file + +from libMEDMEM_Swig import * + +md = MED() + +mdDriver = MED_MED_RDONLY_DRIVER(fileName, md) + +mdDriver.open() +mdDriver.readFileStruct() +mdDriver.close() + +mLocal = md.getMesh(md.getMeshName(0)) +mLocal.read() + +# MED Mesh recieved from a distant component (via CORBA) + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") +C.Initialise(fileName) + +mDistant = C.Calcul1() + +# Compare local and distant copies + +def ecart(x, y): + s = 0. + if (len(x) != len(y)): + return 1. + + for i in xrange(len(x)): + s = s + abs(x[i] - y[i]); + return s + +def compare(x, y): + if (len(x) != len(y)): + return 0 + for i in xrange(len(x)): + if x[i] != y[i]: + return 0 + return 1 + +print "Name : ", mDistant.getName() +if (mLocal.getName() != mDistant.getName()): + raise RuntimeError, "MESH::getName()" + +print "SpaceDimension : ", mDistant.getSpaceDimension() +if (mLocal.getSpaceDimension() != mDistant.getSpaceDimension()): + raise RuntimeError, "MESH::getSpaceDimension()" + +print "MeshDimension : ", mDistant.getMeshDimension() +if (mLocal.getMeshDimension() != mDistant.getMeshDimension()): + raise RuntimeError, "MESH::getMeshDimension()" + +print "CoordinatesSystem : ", mDistant.getCoordinatesSystem() +if (mLocal.getCoordinatesSystem() != mDistant.getCoordinatesSystem()): + raise RuntimeError, "MESH::getCoordinatesSystem()" + +print "NumberOfNodes : ", mDistant.getNumberOfNodes() +if (mLocal.getNumberOfNodes() != mDistant.getNumberOfNodes()): + raise RuntimeError, "MESH::getNumberOfNodes()" + +x1 = mLocal.getCoordinates(MED_FULL_INTERLACE); +x2 = mDistant.getCoordinates(MED_FULL_INTERLACE); + +print "Coordinates (local) : ", x1 +print "Coordinates (distant) : ", x2 + +d = ecart(x1, x2); +print " (differences between local and distant) : ", d +if (d > 1.0e-7): + raise RuntimeError, "MESH::getCoordinates()" + +s1 = mLocal.getCoordinatesNames(); +s2 = mDistant.getCoordinatesNames(); +print "CoordinatesNames (local) : ", s1 +print "CoordinatesNames (distant) : ", s2 + +if (not compare(s1, s2)): + raise RuntimeError, "MESH::CoordinatesNames()" + +s1 = mLocal.getCoordinatesUnits(); +s2 = mDistant.getCoordinatesUnits(); +print "CoordinatesUnits (local) : ", s1 +print "CoordinatesUnits (distant) : ", s2 + +if (not compare(s1, s2)): + raise RuntimeError, "MESH::CoordinatesUnits()" + + + +print +print "All tests passed" diff --git a/src/MedClient/test/test1/TestMedCorba4.py b/src/MedClient/test/test1/TestMedCorba4.py new file mode 100644 index 000000000..341db6e7d --- /dev/null +++ b/src/MedClient/test/test1/TestMedCorba4.py @@ -0,0 +1,76 @@ +import os +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + +# MED Mesh read from a (local) file + +from libMEDMEM_Swig import * + +md = MED() + +mdDriver = MED_MED_RDONLY_DRIVER(fileName, md) + +mdDriver.open() +mdDriver.readFileStruct() +mdDriver.close() + +mLocal = md.getMesh(md.getMeshName(0)) +mLocal.read() + +# MED Mesh recieved from a distant component (via CORBA) + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") +C.Initialise(fileName) + +mDistant = C.Calcul1() + + +print "Name : ", mDistant.getName() + + +for i in [MED_CELL, + MED_FACE, + MED_EDGE, + MED_NODE, + MED_ALL_ENTITIES ]: + + n1 = mLocal.getNumberOfTypes(i); + n2 = mDistant.getNumberOfTypes(i); + + if (n1 != n2): + raise RuntimeError, "MESH::getNumberOfTypes()" + + if ((n1 > 0) & (i != MED_NODE)): + T1 = mLocal.getTypes(i); + T2 = mDistant.getTypes(i); + print "types (local) : ", i, " : ", T1; + print "types (distant) : ", i, " : ", T2; + + if (n2 != len(T2)): + raise RuntimeError, \ + "len(MESH::getTypes()) <> MESH::getNumberOfTypes()" + + for j in range(n2): + if (T1[j] != eval(T2[j].__str__())): + raise RuntimeError, "MESH::getTypes()" + + e1 = mLocal.getNumberOfElements(i, T1[j]); + e2 = mDistant.getNumberOfElements(i, T2[j]); + + print "elements (local) : ", T1[j], " : ", e1; + print "elements (distant) : ", T2[j], " : ", e2; + + if (e1 != e2): + raise RuntimeError, "MESH::getNumberOfElements" + +print +print "All tests passed" diff --git a/src/MedClient/test/test1/TestMedCorba5.py b/src/MedClient/test/test1/TestMedCorba5.py new file mode 100644 index 000000000..7b5b47da9 --- /dev/null +++ b/src/MedClient/test/test1/TestMedCorba5.py @@ -0,0 +1,85 @@ +import os +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + + +def compare(x, y): + if (len(x) != len(y)): + return 0 + for i in xrange(len(x)): + if x[i] != y[i]: + return 0 + return 1 + +# MED Mesh read from a (local) file + +from libMEDMEM_Swig import * + +md = MED() + +mdDriver = MED_MED_RDONLY_DRIVER(fileName, md) + +mdDriver.open() +mdDriver.readFileStruct() +mdDriver.close() + +mLocal = md.getMesh(md.getMeshName(0)) +mLocal.read() + +# MED Mesh recieved from a distant component (via CORBA) + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") +C.Initialise(fileName) + +mDistant = C.Calcul1() + + +print "Name : ", mDistant.getName() + + +for i in [MED_CELL, + MED_FACE, + MED_EDGE, + MED_NODE, + MED_ALL_ENTITIES ]: + + n1 = mLocal.getNumberOfTypes(i); + n2 = mDistant.getNumberOfTypes(i); + + if (n1 != n2): + raise RuntimeError, "MESH::getNumberOfTypes()" + + if ((n1 > 0) & (i != MED_NODE)): + T1 = mLocal.getTypes(i); + T2 = mDistant.getTypes(i); + + if (n2 != len(T2)): + raise RuntimeError, \ + "len(MESH::getTypes()) <> MESH::getNumberOfTypes()" + + for j in range(n2): + if (T1[j] != T2[j]): + raise RuntimeError, "MESH::getTypes()" + + c1 = mLocal.getConnectivity(MED_FULL_INTERLACE, MED_NODAL, \ + i, T1[j]); + c2 = mDistant.getConnectivity(MED_FULL_INTERLACE, MED_NODAL, \ + i, T2[j]); + + print "connectivity (local) : ", T1[j], " : ", c1; + print "connectivity (distant) : ", T2[j], " : ", c2; + + if (compare(c1, c2) == 0): + raise RuntimeError, "MESH::getConnectivity()" + +print +print "All tests passed" diff --git a/src/MedClient/test/test2/Compo2.cxx b/src/MedClient/test/test2/Compo2.cxx new file mode 100644 index 000000000..f9abdd2a1 --- /dev/null +++ b/src/MedClient/test/test2/Compo2.cxx @@ -0,0 +1,74 @@ +#ifndef _DEBUG_ +#define _DEBUG_ +#endif + +#include "Compo2.hxx" +#include +#include +#include + +Compo2::Compo2() : _F(NULL) +{ +} + +Compo2::~Compo2() +{ + if (_F) delete _F; +} + +std::string Compo2::Calcul(const MESH &M) +{ + BEGIN_OF("std::string Compo2::Calcul(MESH &M)"); + + MESSAGE("type virtuel : MESH"); + MESSAGE("type reel : " << typeid(M).name()); + + std::string name = M.getName(); + + name += " recu"; + + try { + std::cerr << M << std::endl; + } + catch (...) { + std::cerr << "erreur Compo2::Calcul" << std::endl; + } + + END_OF("std::string Compo2::Calcul(MESH &M)"); + return name; +} + +const FAMILY * Compo2::Calcul2(const MESH &M) +{ + BEGIN_OF("const FAMILY * Compo2::Calcul2(const MESH &M)"); + + const FAMILY * F = M.getFamily(MED_CELL, 1); + std::cerr << "ok ici 2" << std::endl; + try { + std::cout << F << std::endl; + } + catch (...) { + std::cerr << "erreur Compo2::Calcul2" << std::endl; + } + + END_OF("const FAMILY * Compo2::Calcul2(const MESH &M)"); + return F; +} + +void Compo2::Calcul3(const FIELD &F) +{ + BEGIN_OF("void Compo2::Calcul3(const FIELD *)"); + + const double *v = F.getValue(MED_FULL_INTERLACE); + long i, n = F.getSupport()->getNumberOfElements(MED_CELL); + int j, m = F.getNumberOfComponents(); + + for (i=0; i *)"); +} diff --git a/src/MedClient/test/test2/Compo2.hxx b/src/MedClient/test/test2/Compo2.hxx new file mode 100644 index 000000000..c296dbb9a --- /dev/null +++ b/src/MedClient/test/test2/Compo2.hxx @@ -0,0 +1,24 @@ +#ifndef __COMPO2 +#define __COMPO2 + +#ifndef SWIG +#include "MEDMEM_Mesh.hxx" +#include "MEDMEM_Family.hxx" +#include "MEDMEM_Field.hxx" +#endif + +class Compo2 +{ + + FIELD * _F; + +public: + Compo2(); + ~Compo2(); + + std::string Calcul(const MESH &M); + const FAMILY * Calcul2(const MESH &M); + void Calcul3(const FIELD &S); +}; + +#endif diff --git a/src/MedClient/test/test2/Makefile.in b/src/MedClient/test/test2/Makefile.in new file mode 100644 index 000000000..8b2a5d4e2 --- /dev/null +++ b/src/MedClient/test/test2/Makefile.in @@ -0,0 +1,56 @@ +# MED MedClient : tool to transfer MED CORBA from server producer of MED object to a client using those MED object +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : Makefile.in +# Author : Nadir BOUHAMOU (CEA/DEN/DM2S/SFME/LGLS) +# Module : MED +# source path +top_srcdir=@top_srcdir@ +top_builddir=../../../.. +srcdir=@srcdir@ +VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome + +@COMMENCE@ + +EXPORT_PYSCRIPTS = \ + ${patsubst ${srcdir}/%, %, ${wildcard ${srcdir}/TestMedCorba*.py} } \ + libCompo2.py + +# Libraries targets + +LIB = libCompo2cmodule.la +LIB_SRC = Compo2.cxx +LIB_CLIENT_IDL= SALOME_Component.idl SALOMEDS.idl SALOMEDS_Attributes.idl SALOME_Exception.idl MED.idl + +CPPFLAGS += ${MED2_INCLUDES} ${HDF5_INCLUDES} ${PYTHON_INCLUDES} -I${KERNEL_ROOT_DIR}/include/salome +LIBS = -L${KERNEL_ROOT_DIR}/lib/salome -lMEDClientcmodule -lMEDMEM_Swigcmodule -lMEDImpl -lmedmem ${MED2_LIBS} ${HDF5_LIBS} + +# Executables targets + +SWIG_DEF = libCompo2.i + +MED.hh MEDSK.cc: MED.idl + omniidl -bcxx -Wbtp -I$(top_builddir)/idl -I${KERNEL_ROOT_DIR}/idl/salome $^ + +@CONCLUDE@ + diff --git a/src/MedClient/test/test2/TestMedCorba6.py b/src/MedClient/test/test2/TestMedCorba6.py new file mode 100644 index 000000000..7b6dc840e --- /dev/null +++ b/src/MedClient/test/test2/TestMedCorba6.py @@ -0,0 +1,69 @@ +import os + +## ne fonctionne pas ? +## import salome + +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + + +def compare(x, y): + if (len(x) != len(y)): + return 0 + for i in xrange(len(x)): + if x[i] != y[i]: + return 0 + return 1 + +# MED Mesh read from a (local) file + +from libMEDMEM_Swig import * + +md = MED() + +mdDriver = MED_MED_RDONLY_DRIVER(fileName, md) + +mdDriver.open() +mdDriver.readFileStruct() +mdDriver.close() + +mLocal = md.getMesh(md.getMeshName(0)) +mLocal.read() + +# MED Mesh received from a distant component (via CORBA) + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * +from libMEDClient import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") +C.Initialise(fileName) + +mDistant = C.Calcul1() +mDistantCopy = MESHClient(mDistant) + +from libCompo2 import * +C2 = Compo2() + +print "Local ", C2.Calcul(mLocal) +print "DistantCopy ", C2.Calcul(mDistantCopy) + +testDistant = 0; +try: + print "Distant ", C2.Calcul(mDistant) +except: + print "an exception has been received, it's the normal behaviour" + testDistant = 1 + +if (testDistant == 0): + raise RuntimeError, "no exception has been received, test failed" + + +print +print "All tests passed" diff --git a/src/MedClient/test/test2/TestMedCorba7.py b/src/MedClient/test/test2/TestMedCorba7.py new file mode 100644 index 000000000..f0672e41f --- /dev/null +++ b/src/MedClient/test/test2/TestMedCorba7.py @@ -0,0 +1,76 @@ +import os + +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'test_hydro_darcy1a_out.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + +def compare(x, y): + if (len(x) != len(y)): + return 0 + for i in xrange(len(x)): + if x[i] != y[i]: + return 0 + return 1 + +# MED Mesh read from a (local) file + +from libMEDMEM_Swig import * + +md = MED() + +mdDriver = MED_MED_RDONLY_DRIVER(fileName, md) + +mdDriver.open() +mdDriver.readFileStruct() +mdDriver.close() + +mLocal = md.getMesh(md.getMeshName(0)) +mLocal.read() + +# MED Mesh received from a distant component (via CORBA) + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * +from libMEDClient import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") +C.Initialise(fileName) + +mDistant = C.Calcul1() +mDistantCopy = MESHClient(mDistant) + +from libCompo2 import * +C2 = Compo2() + +for i in xrange(10): + print "-" + +print "Local " +print C2.Calcul(mLocal) + +for i in xrange(10): + print "-" + +print "DistantCopy " +s = C2.Calcul(mDistantCopy) +print + +##print "ok ici" +##for i in xrange(10): +## print "-" + +##try: +## sDistant = C.Calcul2() +##except: +## print "erreur" + +##sDistantCopy = SUPPORTClient(sDistant) +##print sDistant +print +print "All tests passed" diff --git a/src/MedClient/test/test2/TestMedCorba8.py b/src/MedClient/test/test2/TestMedCorba8.py new file mode 100644 index 000000000..b141b1e62 --- /dev/null +++ b/src/MedClient/test/test2/TestMedCorba8.py @@ -0,0 +1,39 @@ +import os + +# import salome + +BASE = os.environ["SALOME_ROOT_DIR"] + '/share/salome/resources/' + +fileName = BASE + 'pointe.med' +fileName = BASE + 'test_hydro_darcy1a_out.med' +fileName = BASE + 'carre_en_quad4_seg2.med' + + +from omniORB import CORBA +from LifeCycleCORBA import * +from libSALOME_Swig import * +from libMEDClient import * + +orb = CORBA.ORB_init([''], CORBA.ORB_ID) +lcc = LifeCycleCORBA(orb) + +C = lcc.FindOrLoadComponent("FactoryServerPy", "Compo1Py") + +print "ok" +C.Initialise(fileName) + +mDistant = C.Calcul1() +print mDistant +mDistantCopy = MESHClient(mDistant) +print mDistantCopy + +print "###################################" +for i in xrange(10): + print mDistantCopy.getName() + +for i in xrange(1): + print "-" + + +print +print "All tests passed" diff --git a/src/MedClient/test/test2/libCompo2.i b/src/MedClient/test/test2/libCompo2.i new file mode 100644 index 000000000..a43ee3d18 --- /dev/null +++ b/src/MedClient/test/test2/libCompo2.i @@ -0,0 +1,10 @@ +%module libCompo2 + +%{ +#include "Compo2.hxx" +%} + +%include "std_string.i" +%include "libMEDClient.i" + +%include "Compo2.hxx" -- 2.39.2