From: vsr Date: Thu, 25 Nov 2010 12:33:05 +0000 (+0000) Subject: Merge from V5_1_main branch 24/11/2010 X-Git-Tag: V6_main_FINAL~1145 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f5e4828c3bbd77d51720451fee5b2d52fade9f4d;p=tools%2Fmedcoupling.git Merge from V5_1_main branch 24/11/2010 --- diff --git a/doc/doxygen/Doxyfile_med_user.in b/doc/doxygen/Doxyfile_med_user.in index 95bbc0d62..ef07e414c 100644 --- a/doc/doxygen/Doxyfile_med_user.in +++ b/doc/doxygen/Doxyfile_med_user.in @@ -73,6 +73,7 @@ INPUT = @srcdir@ \ @srcdir@/../../src/INTERP_KERNEL \ @srcdir@/../../src/INTERP_KERNEL/Geometric2D \ @srcdir@/../../src/MEDCoupling \ + @srcdir@/../../src/MEDLoader \ @srcdir@/../../src/MEDMEM FILE_PATTERNS = MEDMEM_Mesh.* \ @@ -95,6 +96,7 @@ FILE_PATTERNS = MEDMEM_Mesh.* \ PlanarIntersector.* \ TargetIntersector.* \ Interpolation.* \ + InterpolationOptions.* \ InterpKernelGeo2DAbstractEdge.* \ InterpKernelGeo2DEdge.* \ InterpKernelGeo2DEdgeArcCircle.* \ @@ -111,8 +113,14 @@ FILE_PATTERNS = MEDMEM_Mesh.* \ MEDCouplingCMesh.* \ MEDCouplingExtrudedMesh.* \ MEDCouplingFieldDouble.* \ + MEDCouplingField.* \ MEDCouplingFieldDiscretization.* \ MEDCouplingTimeDiscretization.* \ + MEDCouplingTimeLabel.* \ + MEDCouplingRefCountObject.* \ + MEDCouplingMemArray.* \ + MEDCouplingRemapper.* \ + MEDLoader.* \ *.dox RECURSIVE = NO EXCLUDE = CVS diff --git a/doc/doxygen/Makefile.am b/doc/doxygen/Makefile.am index 0e2909df1..178b3c688 100644 --- a/doc/doxygen/Makefile.am +++ b/doc/doxygen/Makefile.am @@ -28,7 +28,12 @@ guidoc_DATA = images/head.png install-data-local : html-local $(INSTALL) -d $(DESTDIR)$(docdir)/gui/MED - cp -rp doc_ref_user/html/*.* $(DESTDIR)$(docdir)/gui/MED + @if test -d doc_ref_user/html ; then \ + for filen in `find doc_ref_user/html -maxdepth 1 -type f` ; do\ + echo "Installing $${filen}" ; \ + cp -rp $${filen} $(DESTDIR)$(docdir)/gui/MED ; \ + done ; \ + fi ; uninstall-local: rm -rf $(DESTDIR)$(docdir)/gui/MED diff --git a/doc/doxygen/interpkernel.dox b/doc/doxygen/interpkernel.dox index afe4b70c3..bfed9661f 100644 --- a/doc/doxygen/interpkernel.dox +++ b/doc/doxygen/interpkernel.dox @@ -214,10 +214,33 @@ interpolation. To be able to be filled by the interpolator the \c MatrixType cla \subsection InterpKerHighLevUsage high-level usage -This the simplest mode of usage of interpolator. This way is strongly -linked with MED data-structure. All interpolators is completely hidden -to you. Even sparse interpolation matrix is hidden. An exemple of -usage : +The simplest mode of usage of interpolator in sequential mode is to use REMAPPER classes. These classes fulfill HXX2SALOME rules to allow the user to use it +in coupling graphs. 2 REMAPPERS exist, ParaMEDMEM::MEDCouplingRemapper and Remapper. These classes are strongly linked to their corresponding data structure, respectively +MEDCoupling and MEDMEM. In return, all interpolation request and spare interpolation matrix are hidden from you. Here two examples of REMAPPER classes : + +- If you intend to use MEDCoupling data struture, ParaMEDMEM::MEDCouplingRemapper class should be used : + +\code +... +const char sourceFileName[]="source.med"; +MEDCouplingFieldDouble *sourceField=MEDLoader::ReadFieldCell(sourceFileName,"Source_Mesh",0,"Density",/*iteration*/0,/*order*/0); +const char targetFileName[]="target.med"; +MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile(targetFileName,"Target_Mesh",0); +// +sourceField->setNature(ConservativeVolumic);//Specify nature is needed to allow remapper object to apply correct policy for denominator computation ! +MEDCouplingRemapper remapper; +remapper.setPrecision(1e-12); +remapper.setIntersectionType(INTERP_KERNEL::Triangulation); +remapper.prepare(sourceField->getMesh(),med_target_mesh,"P0P0"); +MEDCouplingFieldDouble *targetField=remapper.transferField(sourceField,/*default_value*/4.57);//Any target cell not intercepted by any source cell will have value set to 4.57. +... +// clean-up +targetField->decrRef(); +sourceField->decrRef(); +med_target_mesh->decrRef(); +\endcode + +- If you intend to use MEDMEM data structure, Remapper class should be used : \code ... @@ -244,7 +267,29 @@ As consequence of genericity of interpolators, they are usable only by instanciating an underneath mesh data structure. The two following examples show how to use interpolator at this level. -- The simplest way to use the interpolator with MED datastructure is : +- The simplest way to use interpolator with MEDCoupling datastruture is put in the following example. Note that this code is close to those used by ParaMEDMEM +to perform synchronization of meshes between processes of a MPI communicator : + +\code +... +MEDCouplingUMesh *med_source_mesh=MEDLoader::ReadUMeshFromFile("source.med","Source_mesh",0); +MEDCouplingUMesh *med_target_mesh=MEDLoader::ReadUMeshFromFile("target.med","Target_mesh",0); +MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(med_source_mesh); +MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(med_target_mesh); +// Go for interpolation... +INTERP_KERNEL::Interpolation2D myInterpolator; +myInterpolator.setPrecision(1e-7); +myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); +std::vector > resultMatrix; +INTERP_KERNEL::Matrix resultMatrix2; +// here the interpolation is performed twice for this code to show the capability of storing data of out matrix in 2 different data structures. +myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix,"P0P0"); +myInterpolator.interpolateMeshes(wrap_source_mesh,wrap_target_mesh,resultMatrix2,"P0P0"); +//Ok resultMatrix and resultMatrix2 contain matrix now +... +\endcode + +- An another way to use the interpolator with MEDMEM datastructure is : \code ... diff --git a/doc/doxygen/main.dox b/doc/doxygen/main.dox index 69d054975..d7e4c3893 100644 --- a/doc/doxygen/main.dox +++ b/doc/doxygen/main.dox @@ -19,6 +19,8 @@ localization library. - Chapter \ref medcoupling describes DataStructures used for cross process exchange of meshes and fields. - Chapter \ref paramedmem describes its MPI implementation, which is called %ParaMEDMEM. +- Chapter \ref medloader describes API for I/O from or to a MED file +coming from a \ref medcoupling data structure. - Chapter \ref tools describes various tools based on MEDMEM that can be helpful for handling MED files (conversion tools and splitting tools). diff --git a/doc/doxygen/medloader.dox b/doc/doxygen/medloader.dox new file mode 100644 index 000000000..9cb490e52 --- /dev/null +++ b/doc/doxygen/medloader.dox @@ -0,0 +1,357 @@ +/*! +\page medloader MEDLoader + +\section MEDLoaderIntro Introduction + +MEDLoader is a package in charge of loading from a file or write to a file +in MED format a \ref medcoupling data structure. The fact that these +functionalities are not merged in \ref medcoupling is explained by a +willingness of reducing as much as possible the dependancies of \ref medcoupling libraries. + +As a MED file can combine several \ref medcoupling aspects in one (for exemple meshes in +MED file on different mesh dimension with families and groups) the API of MEDLoader is much more rich than simply read and write. + +MEDLoader offers \b static methods whose method names have the first +character in capital. You are intended to use these methods. The following +chapters will try to describe in details some of important ones. + +The basic idea of MEDLoader is to exploite as much as possible MED +file capabilities to store MEDCoupling data file in a MED file and +reversely to load from a MED file into a MEDCoupling data structure. +Basically, the info on components of ParaMEDMEM::DataArrayDouble +instances are stores into components and units into MED files. The +name of meshes and fields are used by MEDLoader to use it as this into +MED file. A field f with \ref ParaMEDMEM::MEDCouplingTimeDiscretization +"time discretization" set to ONE_TIME, the value of +\c f->getTime(time,iteration,order) are used by MEDLoader to store +identifies the field into MED file. All strings used by MEDLoader to +use it into MED file should fulfill the rules of MED file where length +are limited. +That's why the user should be aware of these constaints when trying to read/write a MED file using MEDLoader. +MEDLoader tries to manage that by protecting the user by throwing exceptions when the rules are not followed. + +\section MEDLoaderMainC Main concepts of MED files + +Here we will describes some of basic concepts of MED files in order to +use the best methods proposed by MEDLoader API. + +\subsection MEDLoaderMEDFileGen Basics in MED files + +First of all MEDLoader \b will \b not read MED files whose version is +\b lower \b than \b 2.2. The MEDLoader::CheckFileForRead will perform +the check of that before any attempt of read. + + +For new comers in MED file world some of basics principles are +recalled here. Let's recall basic principles that explains some of the aspect of MEDLoade API. +\anchor MEDLoaderMeshNameConstraint MED file can contain several meshes. These meshes are +discriminated by their names (two meshes could not have the same +names). By the same way a MED file can contain several fields in MED. +So MEDLoader propose to you the MEDLoader::GetMeshNames method to +discover all the mesh names contained in your file. + +A field is also discriminated by its name. The method MEDLoader::GetCellFieldNamesOnMesh and MEDLoader::GetNodeFieldNamesOnMesh are available to know all fields +respectively on cells and on nodes lying on a specified mesh. + + A field is defined by several time steps discriminated by a pair of int +(iteration,order). It is \b not possible to store 2 time steps of a same +field having the same iteration and order +number. The floatting point value attached on this couple of ids (iteration,order) is only present for information. +Static methods MEDLoader::GetCellFieldIterations and +MEDLoader::GetNodeFieldIterations return a vector of pair containing +each respectively iteration and order. + +A time step of a field lyies on one \b or \b more mesh(es) specified by its \b or \b their name. A time step of a field in +MED file could be defined on point \b and on cell \b and, \b or on gauss points \b and, \b or on point per element. + +This recalled specificities of MED file explains that it is necessary to specify +each time, at field-read time, the type of field, the iteration and order +number the mesh you are interested in. + +\subsection MEDLoaderMEDFileMesh Meshes in MED files + +In MED file meshes could combine in one unstructured mesh cells that +have different dimension. For example it is possible to mix +MED_TETRA4, MED_TRIA6, MED_SEG2, MED_POINT0, MED_POLYGON, +MED_POLYHEDRA in a same mesh. In MEDCouplingUMesh such a mix is not +allowed as described \ref MEDCouplingUMeshes "here". So to \b read such mesh it +is important to know which meshdimension you are interested to. In API +the parameter \b meshDimRelToMax discreminates the meshdim you are +interested to relatively to the maximal dimension of cells contained +in the mesh in file. + +Let's take 2 examples : + +- If you have a mesh called "MyMesh" in file "file1.med" with +MED_POLYGON, MED_TRI3, MED_SEG2 and MED_SEG3 : The max dimension of +cells is 2 (for MED_POLYGON and MED_TRI3). So if you want exclusively +cells with type MED_POLYGON and MED_TRI3 you should use : + +\code +MEDCouplingUMesh *m2D=MEDLoader::ReadUMeshFromFile("file1.med","MyMesh",0); +\endcode + +If you are interested in MED_SEG2 and MED_SEG3 you should use : + +\code +MEDCouplingUMesh *m1D=MEDLoader::ReadUMeshFromFile("file1.med","MyMesh",-1); +\endcode + +The method MEDLoader::ReadUMeshDimFromFile could +help you to have this mesh dimension. +\anchor MEDLoaderExample2 +- Consider an another mesh called "Example2" in file "file2.med" +containing MED_POLYHEDRA, MED_TETRA4, MED_QUAD8, MED_TRI6, MED_SEG2 +and MED_POINT0. In this case you will have : + +\code +assert(3==MEDLoader::ReadUMeshDimFromFile("file2.med","Example2")); +\endcode + +To get 3D cells (MED_POLYHEDRA and MED_TETRA4) you should type : +\code +MEDCouplingUMesh *m3D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",0); +\endcode + +To get 2D cells (MED_TRI6 and MED_QUAD8) you should type : + +\code +MEDCouplingUMesh *m2D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-1); +\endcode + +To get 1D cells (MED_SEG2) you should type : + +\code +MEDCouplingUMesh *m1D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-2); +\endcode + +And finally for 0D cells (MED_POINT0) you will write : + +\code +MEDCouplingUMesh *m0D=MEDLoader::ReadUMeshFromFile("file2.med","Example2",-3); +\endcode + +To finish this subsection, it is important to know that MEDLoader +takes into account of the cell numbers stored in a mesh of a med +file. This renumbering allows MEDLoader to conserve the order of +MEDCoupling cells into the file. So if the renumbering of cells in MED +file is not correct an exception will be thrown. + +\subsection MEDLoaderMEDFilePoMesh Part of meshes in MED files + +A mesh contains one or more families on nodes and/or on cells. A family is a partition +(mathematical sense) of the mesh it lies to. A family can be described +by an integer field on \b all nodes and on \b all cells of a same mesh. +All cells and nodes having the same ids defines this family. This id +is called the familyId. A family is discriminated by its id. MED file +attach a name to its id to be more userfriendly. So by construction, 2 different +families could not share anything. The user can retrieve all the +families names available on a mesh with the static method MEDLoader::GetMeshFamiliesNames. + +A group is a set of families. So groups can overlap each other, +contrary to families. Groups are also discriminated by a name. As for +families the static method to retrieves the groups of a specified mesh is MEDLoader::GetMeshGroupsNames. + +MEDLoader allows you to retrieve the +corresponding "part of meshes" thanks to static methods +MEDLoader::ReadUMeshFromFamilies and MEDLoader::ReadUMeshFromGroups. +This method allows you to combine several families and groups in the +same returned mesh. + +\subsection MEDLoaderMEDFileField Reading a field at one time step in MED files + +A field at one time step on one mesh, with one entity (cell, node) +lies on all mesh on on a part of it. In this last case a definition of +a profile is needed. Even if the notions of profile on mesh and group +on mesh could appear close, these two concepts are totally +disconnected in MED file. +The aspect of profile is managed by MEDLoader, thats why this +aspect does not appear in the MEDLoader API. +So to retrieve a field on 3D cell called "F1Cell" in example file +\ref MEDLoaderExample2 "file2.med (seen in meshes section)" on a mesh "Example2" on time +step defined by iteration number 2 and iteration 3 the request will be : + +\code +MEDCouplingFieldDouble *f1Cell_3D=MEDLoader::ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3); +\endcode + +To retrive the same field (same iteration) on 2D cells only the call will be : + +\code +MEDCouplingFieldDouble *f1Cell_2D=MEDLoader::ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3); +\endcode + +\subsection MEDLoaderMEDFieldsRead Reading several field time steps at a time in MED files + +It is possible with MEDLoader to read several time steps of a field at +a time. +The advantage with this approach is to avoid to read and load several +time a same mesh. This is typically recommanded to use the following +code when you desire to load all time steps of a field on cell "myField" lying on +same mesh "mesh1" in one shot : + +\code + +std::vector > timeStepsIds=MEDLoader::GetCellFieldIterations("file4.med"); +std::vector fs=MEDLoader::ReadFieldsCellOnSameMesh("file4.med","mesh1",0,"myField",timeStepsIds); + +\endcode + +\section MEDLoaderWriteMain Writing a MED file with MEDLoader + +As MEDMEM and MED file do, MEDLoader write process separates clearly +meshes from fields. The reason is that a common use case in write mode +is to write in a first time a mesh and then writes several time steps +of a same field in appended mode. + +The fact that the write process is rarely in a one shot put a +constraint on API (as MEDMEM does) to precise to MEDLoader if you intend +to append data to an existing file, or if you want to create a new +file from scratch. This explains the presence of boolean parameter \b +writeFromScratch in API of MEDLoader starting with \b +MEDLoader::Write* . + +If \b writeFromScratch parameter is set to \b true and if the file +already exists the file will be crashed and replaced by the new +corresponding data. If \b writeFromScratch parameter is set to \b false and if the +file does \b not \b exist the new file is created, but if the file +exists MEDLoader will enter in appended mode. + +Two classes of MEDLoader write methods exists when \b writeFromScratch +is set to \b false : + +- Methods \b MEDLoader::Write*Dep : The behaviour is as MEDMEM, that + is to say, the write is done without any question in file. The + responsability is let to the user because the MED file could be + corrupted. The advantage of this method is that it is faster + because no check is done. +- Methods \b MEDLoader::Write* : MEDLoader will not corrupt your file + by always trying to append data. The consequence of that is that a + read of part (and data processing) of MED file could be needed before any attempt of + writing. So these methods could be in some cases much time and memory consuming. + +The behaviour of MEDLoader when \b writeFromScratch is set to false will be precised +for each \b MEDLoader::Write* methods is the next subsections. + +\subsection MEDLoaderWriteMesh Writing one mesh in a MED file with MEDLoader + +The first think to know is that MEDLoader is using the \b meshName in +ParaMEDMEM::MEDCouplingMesh instance to put it in MED file. + +As explained in previous section \ref MEDLoaderMeshNameConstraint "here", +a mesh in MED file is discriminated by a name, so the \b meshName +\b should \b be \b non \b empty. If it is the case an +INTERP_KERNEL::Exception will be thrown. + +To write one mesh \b myMesh with name \b "myMeshName" in a MED file \b "wfile1.med" the following code should be typed : + +\code + +MEDCouplingUMesh *myMesh=...; +myMesh->setName("myMeshName"); +MEDLoader::WriteUMesh("wFile1.med",myMesh,true); + +\endcode + +With the previous code, if "wFile1.med" file existed the file is +crashed and will contain after the call only the content of myMesh +instance. + +If you desire to append a mesh in "wFile1.med" you should type : + +\code + +MEDCouplingUMesh *myMesh=...; +myMesh->setName("myMeshName"); +MEDLoader::WriteUMesh("wFile1.med",myMesh,false); + +\endcode + +With the previous code, if the "wFile1.med" had already a mesh called "myMeshName" an +INTERP_KERNEL::Exception will be thrown. + +\subsection MEDLoaderWriteMeshes Writing several meshes in a MED file with MEDLoader + +It could be interesting to write several meshes in one shot. Two +possiblities are possible : + +- Write several instances of ParaMEDMEM::MEDCouplingUMesh + lying \b on \b same \b coords \b with \b different \b mesh \b dimension. In this case the + use of MEDLoader::WriteUMeshes is the method you should + use. Typically this method should be used to write such of file + defined \ref MEDLoaderExample2 "here". + This method first checks that all instances share the same + ParaMEDMEM::DataArrayDouble instance as coords. If not an + INTERP_KERNEL::Exception will be thrown and an invocation on + ParaMEDMEM::MEDCouplingPointSet::tryToShareSameCoords will be necessary. + +- Write a partition of meshes having \b same \b mesh \b dimension, that is to say a set of + groups and families from given meshes. As in the previous case the + check of same coords will be done (if not an INTERP_KERNEL::Exception is + thrown). After this step this method will + merge (by concerving the order in input) and will simplify the + merged mesh. After this operation, the groups will be constituted by + assigning the groups names with the conresponding names of + instance. That's why all meshes have to have a not empty name and + different each other. The method to use in this case is + MEDLoader::WriteUMeshesPartition. + +For these 2 described methods the semantic of \b writeFromScratch when +\b false is the same, that is to say : no writing +(INTERP_KERNEL::Exception thrown) will be done if the +file already exists and contains already a mesh with name 'meshName' +for MEDLoader::WriteUMeshesPartition method and the name of the first +of the vector of unstructured meshes passed as first parameter of +MEDLoader::WriteUMeshes. + +\subsection MEDLoaderWriteField Writing one time step of a field in a MED file with MEDLoader + +To write \b one \b time \b step of a field from scratch with MEDLoader is to +use MEDLoader::WriteField method. The behviour of this method depends +on the value of the \b writeFromScratch paramter : + +- When \b writeFromScratch equals to \b true, this method performs two things, it +writes the underlying mesh and write the specified time step on it. + +- When \b writeFromScatch equals to \b false, this method looks that + the underlying mesh exists (by looking the content of \c field->getMesh()->getName() ) in file. If not, the behaviour is the + same that previous case with \b writeFromScratch parameter set to + \b true. If the mesh already exists, MEDLoader reads the field and + tries to apply field on it. This operation could be rather time + consuming because a read operation is performed and a reorder + operation too. If the file already contains the same field at the + same time step (iteration and order ids) the corresponding time step + will be replaced by the field passed in parameter. + +\subsection MEDLoaderWriteFields Writing several time steps of a field in a MED file with MEDLoader + +To write a serie of time steps in a "file3.med" file lying on the same +unstructured mesh the typical code +to write is the following : + +\code + +MEDCouplingFieldDouble *f=...; +MEDLoader::WriteUMesh("file3.med",static_castf->getMesh(),true); +f->setTime(1.2,1,0); +//Writing first time step with iteration==1 and order==0 +MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file3.med",f); +f->setTime(1.3,2,0); +f->applyFunc("sqrt(x)"); +//Writing second time step with iteration==2 and order==0 +MEDLoader::WriteFieldUsingAlreadyWrittenMesh("file3.med",f); + +\endcode + +In the previous code, it is important to note that the values of pair +(iteration,order) should be different between two calls to avoid that +a call to MEDLoader::WriteFieldUsingAlreadyWrittenMesh overwrites a +previous call. +An another important thing is the fact that \c f->getMesh() does not be +modified. +This method of writing presents the big advantage to be fast, because +no check neither read is performed by this method. That's why contrary +to other MEDLoader::Write* method the parameter of \b writeFromScratch +is not needed here. + +*/ diff --git a/src/INTERP_KERNEL/CellModel.cxx b/src/INTERP_KERNEL/CellModel.cxx index af6dac5ad..88bc7a820 100644 --- a/src/INTERP_KERNEL/CellModel.cxx +++ b/src/INTERP_KERNEL/CellModel.cxx @@ -27,6 +27,16 @@ namespace INTERP_KERNEL { + const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT0", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4 + "NORM_POLYGON", "NORM_TRI6", "" , "NORM_QUAD8", "",//5->9 + "", "", "", "", "NORM_TETRA4",//10->14 + "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19 + "NORM_TETRA10", "", "", "NORM_PYRA13", "",//20->24 + "NORM_PENTA15", "", "", "", "",//25->29 + "NORM_HEXA20", "NORM_POLYHED", "", "", "",//30->34 + "", "", "", "", "",//35->39 + "NORM_ERROR"}; + std::map CellModel::_map_of_unique_instance; const CellModel& CellModel::getCellModel(NormalizedCellType type) @@ -42,6 +52,11 @@ namespace INTERP_KERNEL return (*iter).second; } + const char *CellModel::getRepr() const + { + return CELL_TYPES_REPR[(int)_type]; + } + /*! * This method is compatible with all types including dynamic one. */ @@ -87,6 +102,8 @@ namespace INTERP_KERNEL _quadratic=false; _dyn=false; _extruded_type=NORM_ERROR; + _linear_type=NORM_ERROR; + _quadratic_type=NORM_ERROR; switch(type) { case NORM_POINT0: @@ -96,17 +113,17 @@ namespace INTERP_KERNEL break; case NORM_SEG2: { - _nb_of_pts=2; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD4; + _nb_of_pts=2; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD4; _quadratic_type=NORM_SEG3; } break; case NORM_SEG3: { - _nb_of_pts=3; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD8; + _nb_of_pts=3; _nb_of_sons=0; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2; } break; case NORM_TETRA4: { - _nb_of_pts=4; _nb_of_sons=4; _dim=3; + _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10; _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; @@ -116,7 +133,7 @@ namespace INTERP_KERNEL break; case NORM_HEXA8: { - _nb_of_pts=8; _nb_of_sons=6; _dim=3; + _nb_of_pts=8; _nb_of_sons=6; _dim=3; _quadratic_type=NORM_HEXA20; _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_QUAD4; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _nb_of_sons_con[1]=4; @@ -128,7 +145,7 @@ namespace INTERP_KERNEL break; case NORM_QUAD4: { - _nb_of_pts=4; _nb_of_sons=4; _dim=2; + _nb_of_pts=4; _nb_of_sons=4; _dim=2; _quadratic_type=NORM_QUAD8; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_type[3]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -138,7 +155,7 @@ namespace INTERP_KERNEL break; case NORM_TRI3: { - _nb_of_pts=3; _nb_of_sons=3; _dim=2; + _nb_of_pts=3; _nb_of_sons=3; _dim=2; _quadratic_type=NORM_TRI6; _sons_type[0]=NORM_SEG2; _sons_type[1]=NORM_SEG2; _sons_type[2]=NORM_SEG2; _sons_con[0][0]=0; _sons_con[0][1]=1; _nb_of_sons_con[0]=2; _sons_con[1][0]=1; _sons_con[1][1]=2; _nb_of_sons_con[1]=2; @@ -147,7 +164,7 @@ namespace INTERP_KERNEL break; case NORM_TRI6: { - _nb_of_pts=6; _nb_of_sons=3; _dim=2; + _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; @@ -156,7 +173,7 @@ namespace INTERP_KERNEL break; case NORM_QUAD8: { - _nb_of_pts=8; _nb_of_sons=4; _dim=2; + _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; @@ -166,7 +183,7 @@ namespace INTERP_KERNEL break; case NORM_PYRA5: { - _nb_of_pts=5; _nb_of_sons=5; _dim=3; + _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13; _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _nb_of_sons_con[0]=4; _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; @@ -177,7 +194,7 @@ namespace INTERP_KERNEL break; case NORM_PENTA6: { - _nb_of_pts=6; _nb_of_sons=5; _dim=3; + _nb_of_pts=6; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PENTA15; _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _nb_of_sons_con[0]=3; _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; @@ -188,7 +205,7 @@ namespace INTERP_KERNEL break; case NORM_TETRA10: { - _nb_of_pts=10; _nb_of_sons=4; _dim=3; + _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4; _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6; _sons_con[1][0]=0; _sons_con[1][1]=3; _sons_con[1][2]=1; _sons_con[1][3]=7; _sons_con[1][4]=8; _sons_con[1][5]=4; _nb_of_sons_con[1]=6; @@ -198,7 +215,7 @@ namespace INTERP_KERNEL break; case NORM_PYRA13: { - _nb_of_pts=13; _nb_of_sons=5; _dim=3; + _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5; _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8; _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6; @@ -209,7 +226,7 @@ namespace INTERP_KERNEL break; case NORM_PENTA15: { - _nb_of_pts=15; _nb_of_sons=5; _dim=3; + _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; @@ -220,7 +237,7 @@ namespace INTERP_KERNEL break; case NORM_HEXA20: { - _nb_of_pts=20; _nb_of_sons=6; _dim=3; + _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8; _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=8; _sons_con[0][5]=9; _sons_con[0][6]=10; _sons_con[0][7]=11; _nb_of_sons_con[0]=8; _sons_con[1][0]=4; _sons_con[1][1]=7; _sons_con[1][2]=6; _sons_con[1][3]=5; _sons_con[1][4]=15; _sons_con[1][5]=14; _sons_con[1][6]=13; _sons_con[1][7]=12; _nb_of_sons_con[1]=8; diff --git a/src/INTERP_KERNEL/CellModel.hxx b/src/INTERP_KERNEL/CellModel.hxx index 393fea0eb..23b735512 100644 --- a/src/INTERP_KERNEL/CellModel.hxx +++ b/src/INTERP_KERNEL/CellModel.hxx @@ -41,6 +41,7 @@ namespace INTERP_KERNEL static void buildUniqueInstance(); public: INTERPKERNEL_EXPORT static const CellModel& getCellModel(NormalizedCellType type); + INTERPKERNEL_EXPORT const char *getRepr() const; INTERPKERNEL_EXPORT bool isDynamic() const { return _dyn; } INTERPKERNEL_EXPORT bool isQuadratic() const { return _quadratic; } INTERPKERNEL_EXPORT unsigned getDimension() const { return _dim; } @@ -53,6 +54,8 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon(unsigned sonId) const { return _nb_of_sons_con[sonId]; } INTERPKERNEL_EXPORT unsigned getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const; INTERPKERNEL_EXPORT NormalizedCellType getExtrudedType() const { return _extruded_type; } + INTERPKERNEL_EXPORT NormalizedCellType getLinearType() const { return _linear_type; } + INTERPKERNEL_EXPORT NormalizedCellType getQuadraticType() const { return _quadratic_type; } INTERPKERNEL_EXPORT NormalizedCellType getSonType(unsigned sonId) const { return _sons_type[sonId]; } INTERPKERNEL_EXPORT NormalizedCellType getSonType2(unsigned sonId) const; INTERPKERNEL_EXPORT unsigned fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const; @@ -65,10 +68,13 @@ namespace INTERP_KERNEL unsigned _nb_of_sons; NormalizedCellType _type; NormalizedCellType _extruded_type; + NormalizedCellType _linear_type; + NormalizedCellType _quadratic_type; unsigned _sons_con[MAX_NB_OF_SONS][MAX_NB_OF_NODES_PER_ELEM]; unsigned _nb_of_sons_con[MAX_NB_OF_SONS]; NormalizedCellType _sons_type[MAX_NB_OF_SONS]; static std::map _map_of_unique_instance; + static const char *CELL_TYPES_REPR[]; }; } diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx b/src/INTERP_KERNEL/CurveIntersectorP0P1.txx index c25136b5d..1947a9f5b 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP0P1.txx @@ -60,7 +60,7 @@ namespace INTERP_KERNEL { std::vector segmentsT; BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < segmentsT.size(); ++t ) + for ( int t = 0; t < (int)segmentsT.size(); ++t ) { typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; for(typename std::vector::const_iterator diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx b/src/INTERP_KERNEL/CurveIntersectorP1P0.txx index bafd3ad9e..f4e136dd3 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P0.txx @@ -69,7 +69,7 @@ namespace INTERP_KERNEL int iS = *iter; BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < segmentsS.size(); ++s ) + for ( int s = 0; s < (int)segmentsS.size(); ++s ) { double surf = BASE_INTERSECTOR::intersectSegments(&segmentsS[s]._coords[0], &coordsT[0] + t*SPACEDIM); diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx b/src/INTERP_KERNEL/CurveIntersectorP1P1.txx index fd43fe7fc..7be7429bb 100644 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx +++ b/src/INTERP_KERNEL/CurveIntersectorP1P1.txx @@ -54,7 +54,7 @@ namespace INTERP_KERNEL { std::vector segmentsT, segmentsS; BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < segmentsT.size(); ++t ) + for ( int t = 0; t < (int)segmentsT.size(); ++t ) { typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; for(typename std::vector::const_iterator @@ -63,7 +63,7 @@ namespace INTERP_KERNEL int iS = *iter; BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < segmentsS.size(); ++s ) + for ( int s = 0; s < (int)segmentsS.size(); ++s ) { double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], &segmentsS[s]._coords[0]); diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.cxx b/src/INTERP_KERNEL/DirectedBoundingBox.cxx index 72b5c5101..b59f78db6 100644 --- a/src/INTERP_KERNEL/DirectedBoundingBox.cxx +++ b/src/INTERP_KERNEL/DirectedBoundingBox.cxx @@ -20,7 +20,6 @@ // Created : Mon Apr 12 14:41:22 2010 // Author : Edward AGAPOV (eap) - #include "DirectedBoundingBox.hxx" #include "InterpolationUtils.hxx" @@ -31,7 +30,7 @@ #define __MAX(i) _minmax[i*2+1] #define __MYID (long(this)%10000) #define __DMP(msg) \ - //cout << msg << endl + // cout << msg << endl using namespace std; @@ -237,9 +236,9 @@ namespace INTERP_KERNEL if ( dim > 1 ) { for ( coord = pts; coord < coordEnd; ) - for ( int i = 0; i < dim; ++i ) + for ( int i = 0; i < (int)dim; ++i ) gc[i] += *coord++; - for ( int j = 0; j < dim; ++j ) + for ( int j = 0; j < (int)dim; ++j ) gc[j] /= numPts; } @@ -309,9 +308,9 @@ namespace INTERP_KERNEL if ( dim > 1 ) { for ( unsigned i = 0; i < numPts; ++i ) - for ( int j = 0; j < dim; ++j ) + for ( int j = 0; j < (int)dim; ++j ) gc[j] += pts[i][j]; - for ( int j = 0; j < dim; ++j ) + for ( int j = 0; j < (int)dim; ++j ) gc[j] /= numPts; } @@ -347,6 +346,7 @@ namespace INTERP_KERNEL if ( pts[i][0] < _minmax[0] ) _minmax[0] = pts[i][0]; if ( pts[i][0] > _minmax[1] ) _minmax[1] = pts[i][0]; } + _axes[0] = 1.0; } } @@ -568,7 +568,7 @@ namespace INTERP_KERNEL const double* minmax) const { int iC, nbCorners = 1; - for ( int i=0;i<_dim;++i ) nbCorners *= 2; + for ( int i=0;i<(int)_dim;++i ) nbCorners *= 2; corners.resize( nbCorners * _dim ); // each coordinate is filled with either min or max, nbSwap is number of corners // after which min and max swap @@ -595,6 +595,8 @@ namespace INTERP_KERNEL bool DirectedBoundingBox::isDisjointWith(const DirectedBoundingBox& box) const { if ( _dim < 1 || box._dim < 1 ) return false; // empty box includes all + if ( _dim == 1 ) + return isMinMaxOut( &box._minmax[0], &this->_minmax[0], _dim ); // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect for ( int isThisCS = 0; isThisCS < 2; ++isThisCS ) @@ -632,6 +634,8 @@ namespace INTERP_KERNEL bool DirectedBoundingBox::isDisjointWith(const double* box) const { if ( _dim < 1 ) return false; // empty box includes all + if ( _dim == 1 ) + return isMinMaxOut( &_minmax[0], box, _dim ); // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect @@ -657,7 +661,7 @@ namespace INTERP_KERNEL for ( int iC = 0, nC = cornersThis.size()/_dim; iC < nC; ++iC) { fromLocalCS( &cornersThis[iC*_dim], globCorner ); - for ( int i = 0; i < _dim; ++i ) + for ( int i = 0; i < (int)_dim; ++i ) { if ( globCorner[i] < mmBox._minmax[i*2] ) mmBox._minmax[i*2] = globCorner[i]; if ( globCorner[i] > mmBox._minmax[i*2+1] ) mmBox._minmax[i*2+1] = globCorner[i]; @@ -710,7 +714,7 @@ namespace INTERP_KERNEL data.insert( data.end(), &_axes[0], &_axes[0] + _axes.size()); data.insert( data.end(), &_minmax[0], &_minmax[0] + _minmax.size()); } - if ( data.size() < dataSize( _dim )) + if ( data.size() < (unsigned)dataSize( _dim )) data.resize( dataSize( _dim ), 0 ); return data; } diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.hxx b/src/INTERP_KERNEL/DirectedBoundingBox.hxx index 93874acdb..344f65909 100644 --- a/src/INTERP_KERNEL/DirectedBoundingBox.hxx +++ b/src/INTERP_KERNEL/DirectedBoundingBox.hxx @@ -16,8 +16,9 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __DirectedBoundingBox_HXX__ -#define __DirectedBoundingBox_HXX__ + +#ifndef __DIRECTEDBOUNDINGBOX_HXX__ +#define __DIRECTEDBOUNDINGBOX_HXX__ #include "INTERPKERNELDefines.hxx" @@ -92,7 +93,7 @@ namespace INTERP_KERNEL inline bool DirectedBoundingBox::isLocalOut(const double* pLoc) const { - for ( int i = 0; i < _dim; ++i ) + for ( int i = 0; i < (int)_dim; ++i ) if ( pLoc[i] < _minmax[i*2] || pLoc[i] > _minmax[i*2+1] ) return true; return false; @@ -106,10 +107,10 @@ namespace INTERP_KERNEL inline void DirectedBoundingBox::addPointToBox(const double* coord) { - for ( int i = 0; i < _dim; ++i ) + for ( int i = 0; i < (int)_dim; ++i ) { double c = 0; - for ( int j = 0; j < _dim; ++j ) c += coord[j]*_axes[i*_dim+j]; + for ( int j = 0; j < (int)_dim; ++j ) c += coord[j]*_axes[i*_dim+j]; if ( c < _minmax[i*2] ) _minmax[i*2] = c; if ( c > _minmax[i*2+1] ) _minmax[i*2+1] = c; } diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx new file mode 100644 index 000000000..ee7116fd2 --- /dev/null +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx @@ -0,0 +1,477 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "InterpKernelAsmX86.hxx" + +#include +#include +#include + +const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"}; + +std::vector INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + std::vector ret; + for(std::vector::const_iterator iter=asmb.begin();iter!=asmb.end();iter++) + convertOneInstructionInML(*iter,ret); + return ret; +} + +char *INTERP_KERNEL::AsmX86::convertMachineLangageInBasic(const std::vector& ml, int& lgth) const +{ + lgth=ml.size(); + char *ret=new char[lgth]; + std::copy(ml.begin(),ml.end(),ret); + return ret; +} + +void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector& ml) const throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string op; + std::string param; + if(pos!=std::string::npos) + { + op=inst.substr(0,pos); + param=inst.substr(pos+1); + } + else + op=inst; + int id=0; + for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++) + { + std::string tmp(*it); + if(op==tmp) + break; + } + switch(id) + { + case 0: + convertMov(param,ml); + break; + case 1: + convertPush(param,ml); + break; + case 2: + convertPop(param,ml); + break; + case 3: + convertFld(param,ml); + break; + case 4: + convertFaddp(param,ml); + break; + case 5: + convertFsubp(param,ml); + break; + case 6: + convertFmulp(param,ml); + break; + case 7: + convertFdivp(param,ml); + break; + case 8: + convertFcos(param,ml); + break; + case 9: + convertFsin(param,ml); + break; + case 10: + convertFabs(param,ml); + break; + case 11: + convertFchs(param,ml); + break; + case 12: + convertFsqrt(param,ml); + break; + case 13: + convertSub(param,ml); + break; + case 14: + convertAdd(param,ml); + break; + case 15: + convertRet(param,ml); + break; + case 16: + convertLeave(param,ml); + break; + case 17: + convertMovsd(param,ml); + break; + case 18: + convertFst(param,ml); + break; + default: + { + std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +#include + +void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="ebp,esp"; + const char ML1[2]={0x89,0xe5}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="rbp,rsp"; + const char ML2[3]={0x48,0x89,0xe5}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::string::size_type pos=inst.find_first_of(' '); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst2=inst.substr(pos+1); + pos=inst2.find_first_of(','); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst3=inst2.substr(0,pos); + std::string inst4=inst2.substr(pos+1); + convertMovToEsp(inst3,inst4,ml); +} + +void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst1[0]!='[' || inst1[inst1.length()-1]!=']') + throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !"); + std::string inst1bis=inst1.substr(1,inst1.length()-2); + const char ASM1[]="esp"; + const char ML1[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM1) + {//mov dword [esp],0x3ff3c0ca + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM1) + { + if(inst1bis[3]=='+') + {//mov dword [esp+4],0x3ff3c0ca + const char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + const char ASM3[]="rsp"; + const char ML3[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM3) + {//mov dword [rsp],0x3ff3c0ca + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM3) + { + if(inst1bis[3]=='+') + {//mov dword [rsp+4],0x3ff3c0ca + const char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + throw INTERP_KERNEL::Exception("Not recognized exp : mov"); +} + +void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const char ML1[1]={0x55}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const char ML2[1]={0x53}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + const char ASM3[]="rbp"; + const char ML3[1]={0x55}; + if(inst2==ASM3) + {//push rbp + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized push instruction"); +} + +void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const char ML1[1]={0x5d}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const char ML2[1]={0x5b}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized pop instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string params=inst.substr(pos+1); + std::string params2=params.substr(1,params.length()-2); + if(params2.substr(0,3)=="esp") + { + const char ML1[3]={0xdd,0x04,0x24}; + if(params2.length()==3) + {//fld qword [esp] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld esp..."); + } + if(params2.substr(0,3)=="ebp") + { + const char ML2[2]={0xdd,0x45}; + if(params2.length()==3) + {//fld qword [ebp] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + ml.push_back(0); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld ebp..."); + } + if(params2.substr(0,3)=="rsp") + { + const char ML2[3]={0xdd,0x04,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed ! + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xc1}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xe9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xc9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML1[2]={0xde,0xf9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xff}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xfe}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xe1}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xe0}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[2]={0xd9,0xfa}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst.substr(0,4)=="esp,") + { + const char ML[2]={0x81,0xec}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const char ML[4]={0x48,0x83,0xec,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized sub instruction."); +} + +void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + if(inst.substr(0,4)=="esp,") + { + const char ML[2]={0x81,0xc4}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const char ML[4]={0x48,0x83,0xc4,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized add instruction."); +} + +void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[1]={0xc3}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ML[1]={0xc9}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="[rsp],xmm0"; + const char ML1[5]={0xf2,0x0f,0x11,0x04,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="xmm0,[rsp]"; + const char ML2[5]={0xf2,0x0f,0x10,0x04,0x24}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction movsd : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + const char ASM1[]="qword [rsp]"; + const char ML1[3]={0xdd,0x14,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction fst : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + //tony +} + + +void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) throw(INTERP_KERNEL::Exception) +{ + int i,j; + char v; + std::istringstream iss(addr); + if(addr.length()>2) + { + if(addr[0]=='0' && addr[1]=='x') + iss >> std::hex; + } + iss >> i; + for(int k=0;k>=8; + } +} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx new file mode 100644 index 000000000..11b8733e5 --- /dev/null +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __INTERPKERNELASMX86_HXX__ +#define __INTERPKERNELASMX86_HXX__ + +#include "INTERPKERNELEXPREVALDefines.hxx" +#include "InterpKernelException.hxx" + +#include +#include + +namespace INTERP_KERNEL +{ + class AsmX86 + { + public: + std::vector convertIntoMachineLangage(const std::vector& asmb) const throw(INTERP_KERNEL::Exception); + char *convertMachineLangageInBasic(const std::vector& ml, int& lgth) const; + private: + void convertOneInstructionInML(const std::string& inst, std::vector& ml) const throw(INTERP_KERNEL::Exception); + private: + static void convertMov(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertPush(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertPop(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFld(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFaddp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsubp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFmulp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFdivp(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFcos(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsin(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFabs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFchs(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFsqrt(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertSub(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertAdd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertRet(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertLeave(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertMovsd(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void convertFst(const std::string& inst, std::vector& ml) throw(INTERP_KERNEL::Exception); + // + static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) throw(INTERP_KERNEL::Exception); + static void appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) throw(INTERP_KERNEL::Exception); + private: + static const int NB_OF_OPS=19; + static const char *OPS[NB_OF_OPS]; + }; +} + +#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx index 5dde84961..585fac2f8 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx @@ -19,13 +19,23 @@ #include "InterpKernelExprParser.hxx" #include "InterpKernelValue.hxx" +#include "InterpKernelAsmX86.hxx" #include #include #include #include +#include #include +#ifdef _POSIX_MAPPED_FILES +#include +#else +#ifdef WNT +#include +#endif +#endif + using namespace INTERP_KERNEL; const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec"; @@ -120,12 +130,12 @@ LeafExprVar::~LeafExprVar() { } -ExprParser::ExprParser(const char *expr):_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) +ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) { } //! For \b NOT null terminated strings coming from FORTRAN. -ExprParser::ExprParser(const char *expr, int lgth):_is_parsed(false),_leaf(0),_is_parsing_ok(false) +ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false) { _expr=buildStringFromFortran(expr,lgth); } @@ -228,7 +238,7 @@ DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Ex return ret; } -void ExprParser::evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception) +void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception) { Value *gen=new ValueDoubleExpr(szOfOutParam,inParam); ValueDoubleExpr *res=0; @@ -404,7 +414,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception) if(pos5!=std::string::npos) len=pos5-pos6; std::string newExp3=newExp2.substr(pos6,len); - _sub_expr.push_back(ExprParser(newExp3.c_str())); + _sub_expr.push_back(ExprParser(newExp3.c_str(),this)); pos6=pos5+1; } _is_parsing_ok=true; @@ -456,7 +466,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception) if(*accessor!='*' && *accessor!='/' && *accessor!='^') { isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -483,7 +493,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -515,7 +525,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception) isParsingSucceed=true; if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -546,7 +556,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -576,7 +586,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception) if(!curPart.empty()) { isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); curPart.clear(); _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); } @@ -606,7 +616,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception) { if(!curPart.empty()) { - _sub_expr.push_back(ExprParser(curPart.c_str())); + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); _is_parsing_ok=true; } else @@ -691,3 +701,169 @@ void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcO { stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; } + +char *ExprParser::compileX86() const +{ + std::vector ass; + //need in stack + ass.push_back("push ebp"); + ass.push_back("mov ebp,esp"); + compileX86LowLev(ass); + ass.push_back("pop ebp"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector output=asmb.convertIntoMachineLangage(ass); + for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + int lgth; + char *lm=asmb.convertMachineLangageInBasic(output,lgth); + char *ret=0; +#ifdef _POSIX_MAPPED_FILES + ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); +#else +#ifdef WNT + HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL); + ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth); +#endif +#endif + if(ret) + std::copy(lm,lm+lgth,ret); + delete [] lm; + return ret; +} + +char *ExprParser::compileX86_64() const +{ + std::vector ass; + //need in stack + ass.push_back("push rbp"); + ass.push_back("mov rbp,rsp"); + compileX86_64LowLev(ass); + ass.push_back("sub rsp,8"); + ass.push_back("fst qword [rsp]"); + ass.push_back("movsd xmm0,[rsp]"); + ass.push_back("add rsp,8"); + ass.push_back("leave"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector output=asmb.convertIntoMachineLangage(ass); + for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + int lgth; + char *lm=asmb.convertMachineLangageInBasic(output,lgth); + char *ret=0; +#ifdef _POSIX_MAPPED_FILES + ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); +#else +#ifdef WNT + HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL); + ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth); +#endif +#endif + if(ret) + std::copy(lm,lm+lgth,ret); + delete [] lm; + return ret; +} + +void ExprParser::compileX86LowLev(std::vector& ass) const +{ + if(_leaf) + _leaf->compileX86(ass); + else + { + for(std::list::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86LowLev(ass); + for(std::list::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); + } +} + +void ExprParser::compileX86_64LowLev(std::vector& ass) const +{ + if(_leaf) + _leaf->compileX86_64(ass); + else + { + for(std::list::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86_64LowLev(ass); + for(std::list::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); + } +} + +void LeafExprVal::compileX86(std::vector& ass) const +{ + ass.push_back("sub esp,8"); + int *b=(int *)&_value,*c=(int *)&_value; + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [esp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [esp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [esp]"); + ass.push_back("add esp,8"); +} + +void LeafExprVal::compileX86_64(std::vector& ass) const +{ + ass.push_back("sub rsp,8"); + int *b=(int *)&_value,*c=(int *)&_value; + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [rsp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [rsp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +void LeafExprVar::compileX86(std::vector& ass) const +{ + ass.push_back("fld qword [ebp+8]"); +} + +void LeafExprVar::compileX86_64(std::vector& ass) const +{ + ass.push_back("sub rsp,8"); + ass.push_back("movsd [rsp],xmm0"); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const +{ + if(asker) + { + int sz=_father->getStackSizeToPlayX86(this); + int i=0; + for(std::list::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++) + { + const ExprParser& obj=(*iter); + const ExprParser *pt=&obj; + if(pt==asker) + return sz-i; + } + throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !"); + } + else + { + if(!_father) + return MAX_X86_FP_ST; + return _father->getStackSizeToPlayX86(this); + } +} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx index 032f7070a..7ff8babb5 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -39,6 +39,8 @@ namespace INTERP_KERNEL public: virtual ~LeafExpr(); virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0; + virtual void compileX86(std::vector& ass) const = 0; + virtual void compileX86_64(std::vector& ass) const = 0; static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception); }; @@ -47,6 +49,8 @@ namespace INTERP_KERNEL public: LeafExprVal(double value); ~LeafExprVal(); + void compileX86(std::vector& ass) const; + void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); private: double _value; @@ -57,6 +61,8 @@ namespace INTERP_KERNEL public: LeafExprVar(const std::string& var); ~LeafExprVar(); + void compileX86(std::vector& ass) const; + void compileX86_64(std::vector& ass) const; void fillValue(Value *val) const throw(INTERP_KERNEL::Exception); std::string getVar() const { return _var_name; } void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); @@ -72,18 +78,25 @@ namespace INTERP_KERNEL class INTERPKERNELEXPREVAL_EXPORT ExprParser { public: - ExprParser(const char *expr); - ExprParser(const char *expr, int lgth); + ExprParser(const char *expr, ExprParser *father=0); + ExprParser(const char *expr, int lgth, ExprParser *father=0); ~ExprParser(); void parse() throw(INTERP_KERNEL::Exception); bool isParsingSuccessfull() const { return _is_parsing_ok; } double evaluate() const throw(INTERP_KERNEL::Exception); DecompositionInUnitBase evaluateUnit() const throw(INTERP_KERNEL::Exception); void prepareExprEvaluation(const std::vector& vars) const throw(INTERP_KERNEL::Exception); - void evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception); + void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception); void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception); void getSetOfVars(std::set& vars) const; void getTrueSetOfVars(std::set& vars) const; + // + char *compileX86() const; + char *compileX86_64() const; + void compileX86LowLev(std::vector& ass) const; + void compileX86_64LowLev(std::vector& ass) const; + int getStackSizeToPlayX86(const ExprParser *asker) const; + // static std::string buildStringFromFortran(const char *expr, int lgth); static std::string deleteWhiteSpaces(const std::string& expr); private: @@ -102,6 +115,7 @@ namespace INTERP_KERNEL static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); private: + ExprParser *_father; bool _is_parsed; LeafExpr *_leaf; bool _is_parsing_ok; @@ -109,6 +123,7 @@ namespace INTERP_KERNEL std::list _sub_expr; std::list _func_btw_sub_expr; private: + static const int MAX_X86_FP_ST=8; static const char WHITE_SPACES[]; static const char EXPR_PARSE_ERR_MSG[]; }; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx index 6e8316526..dd16329f6 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx @@ -140,6 +140,10 @@ void IdentityFunction::operate(std::vector& stack) const throw(INTERP_K { } +void IdentityFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ +} + const char *IdentityFunction::getRepr() const { return REPR; @@ -163,6 +167,10 @@ void PositiveFunction::operate(std::vector& stack) const throw(INTERP_K { } +void PositiveFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ +} + const char *PositiveFunction::getRepr() const { return REPR; @@ -183,6 +191,11 @@ void NegateFunction::operate(std::vector& stack) const throw(INTERP_KER val->negate(); } +void NegateFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fchs"); +} + const char *NegateFunction::getRepr() const { return REPR; @@ -203,6 +216,11 @@ void CosFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->cos(); } +void CosFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fcos"); +} + const char *CosFunction::getRepr() const { return REPR; @@ -223,6 +241,11 @@ void SinFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->sin(); } +void SinFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsin"); +} + const char *SinFunction::getRepr() const { return REPR; @@ -243,6 +266,11 @@ void TanFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->tan(); } +void TanFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *TanFunction::getRepr() const { return REPR; @@ -263,6 +291,11 @@ void SqrtFunction::operate(std::vector& stack) const throw(INTERP_KERNE val->sqrt(); } +void SqrtFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsqrt"); +} + const char *SqrtFunction::getRepr() const { return REPR; @@ -283,6 +316,11 @@ void AbsFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val->abs(); } +void AbsFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fabs"); +} + const char *AbsFunction::getRepr() const { return REPR; @@ -298,7 +336,12 @@ void ExpFunction::operate(std::vector& stack) const throw(INTERP_KERNEL Value *val=stack.back(); val->exp(); } - + +void ExpFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *ExpFunction::getRepr() const { return REPR; @@ -319,6 +362,11 @@ void LnFunction::operate(std::vector& stack) const throw(INTERP_KERNEL: val->ln(); } +void LnFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *LnFunction::getRepr() const { return REPR; @@ -358,6 +406,11 @@ void PlusFunction::operate(std::vector& stack) const throw(INTERP_KERNE val2=val3; } +void PlusFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("faddp st1"); +} + const char *PlusFunction::getRepr() const { return REPR; @@ -392,6 +445,11 @@ void MinusFunction::operate(std::vector& stack) const throw(INTERP_KERN val2=val3; } +void MinusFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fsubp st1"); +} + const char *MinusFunction::getRepr() const { return REPR; @@ -417,6 +475,11 @@ void MultFunction::operate(std::vector& stack) const throw(INTERP_KERNE val2=val3; } +void MultFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fmulp st1"); +} + const char *MultFunction::getRepr() const { return REPR; @@ -451,6 +514,11 @@ void DivFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void DivFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + asmb.push_back("fdivp st1"); +} + const char *DivFunction::getRepr() const { return REPR; @@ -485,6 +553,11 @@ void PowFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void PowFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *PowFunction::getRepr() const { return REPR; @@ -523,6 +596,11 @@ void MaxFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void MaxFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *MaxFunction::getRepr() const { return REPR; @@ -557,6 +635,11 @@ void MinFunction::operate(std::vector& stack) const throw(INTERP_KERNEL val2=val3; } +void MinFunction::operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + const char *MinFunction::getRepr() const { return REPR; diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx index 548a09f1e..160e15ba9 100644 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx @@ -46,6 +46,7 @@ namespace INTERP_KERNEL virtual ~Function(); virtual int getNbInputParams() const = 0; virtual void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception) = 0; + virtual void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception) = 0; virtual const char *getRepr() const = 0; virtual bool isACall() const = 0; }; @@ -61,6 +62,7 @@ namespace INTERP_KERNEL public: ~IdentityFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -72,6 +74,7 @@ namespace INTERP_KERNEL public: ~PositiveFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -83,6 +86,7 @@ namespace INTERP_KERNEL public: ~NegateFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -94,6 +98,7 @@ namespace INTERP_KERNEL public: ~CosFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -105,6 +110,7 @@ namespace INTERP_KERNEL public: ~SinFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -116,6 +122,7 @@ namespace INTERP_KERNEL public: ~TanFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -127,6 +134,7 @@ namespace INTERP_KERNEL public: ~SqrtFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -138,6 +146,7 @@ namespace INTERP_KERNEL public: ~AbsFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -149,6 +158,7 @@ namespace INTERP_KERNEL public: ~ExpFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -160,6 +170,7 @@ namespace INTERP_KERNEL public: ~LnFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -177,6 +188,7 @@ namespace INTERP_KERNEL public: ~PlusFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -188,6 +200,7 @@ namespace INTERP_KERNEL public: ~MinusFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -199,6 +212,7 @@ namespace INTERP_KERNEL public: ~MultFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -210,6 +224,7 @@ namespace INTERP_KERNEL public: ~DivFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -221,6 +236,7 @@ namespace INTERP_KERNEL public: ~PowFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -232,6 +248,7 @@ namespace INTERP_KERNEL public: ~MaxFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: @@ -243,6 +260,7 @@ namespace INTERP_KERNEL public: ~MinFunction(); void operate(std::vector& stack) const throw(INTERP_KERNEL::Exception); + void operateX86(std::vector& asmb) const throw(INTERP_KERNEL::Exception); const char *getRepr() const; bool isACall() const; public: diff --git a/src/INTERP_KERNEL/ExprEval/Makefile.am b/src/INTERP_KERNEL/ExprEval/Makefile.am index 4a67afba5..28f5e9124 100644 --- a/src/INTERP_KERNEL/ExprEval/Makefile.am +++ b/src/INTERP_KERNEL/ExprEval/Makefile.am @@ -30,8 +30,8 @@ INTERPKERNELEXPREVALDefines.hxx \ InterpKernelExprParser.hxx \ InterpKernelFunction.hxx \ InterpKernelUnit.hxx \ -InterpKernelValue.hxx - +InterpKernelValue.hxx \ +InterpKernelAsmX86.hxx EXTRA_DIST += \ INTERPKERNELEXPREVALDefines.hxx \ @@ -44,7 +44,8 @@ dist_libinterpkernelexpreval_la_SOURCES = \ InterpKernelExprParser.cxx \ InterpKernelFunction.cxx \ InterpKernelUnit.cxx \ - InterpKernelValue.cxx + InterpKernelValue.cxx \ + InterpKernelAsmX86.cxx libinterpkernelexpreval_la_CPPFLAGS=-I$(srcdir)/../Bases diff --git a/src/INTERP_KERNEL/GenMathFormulae.hxx b/src/INTERP_KERNEL/GenMathFormulae.hxx new file mode 100644 index 000000000..42ce4f43f --- /dev/null +++ b/src/INTERP_KERNEL/GenMathFormulae.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __GENMATHFORMULAE_HXX__ +#define __GENMATHFORMULAE_HXX__ + +#include "InterpKernelException.hxx" + +#include + +namespace INTERP_KERNEL +{ + /*! + * This method computes eigenvalues of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: + * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, + * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz + * This method returns the 3 eigenvalues in 'eigenVals'. + */ + void computeEigenValues6(const double *matrix, double *eigenVals) + { + double tr=(matrix[0]+matrix[1]+matrix[2])/3.; + double K[6]={matrix[0]-tr,matrix[1]-tr,matrix[2]-tr,matrix[3],matrix[4],matrix[5]}; + double q=(K[0]*K[1]*K[2]+2.*K[4]*K[5]*K[3]-K[0]*K[4]*K[4]-K[2]*K[3]*K[3]-K[1]*K[5]*K[5])/2.; + double p=K[0]*K[0]+K[1]*K[1]+K[2]*K[2]+2*(K[3]*K[3]+K[4]*K[4]+K[5]*K[5]); + p/=6.; + double sqp=sqrt(p); + double tmp=p*sqp; + double phi; + if(fabs(q)<=fabs(tmp)) + phi=1./3.*acos(q/tmp); + else + phi=0.; + if(phi<0.) + phi+=M_PI/3.; + eigenVals[0]=tr+2.*sqp*cos(phi); + eigenVals[1]=tr-sqp*(cos(phi)+sqrt(3.)*sin(phi)); + eigenVals[2]=tr-sqp*(cos(phi)-sqrt(3.)*sin(phi)); + } + + /*! + * This method computes one eigenvector of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: + * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, + * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz + * This method returns the eigenvector of the corresponding eigenvalue in 'eigenVal'. The returned eigenValue is normalized. + */ + void computeEigenVectorForEigenValue6(const double *matrix, double eigenVal, double eps, double *eigenVector) throw(INTERP_KERNEL::Exception) + { + //if(fabs(eigenVal)>eps) + { + const double m9[9]={matrix[0]-eigenVal,matrix[3],matrix[5],matrix[3],matrix[1]-eigenVal,matrix[4],matrix[5],matrix[4],matrix[2]-eigenVal}; + for(int i=0;i<3;i++) + { + double w[9]={m9[0+3*i],m9[1+3*i],m9[2+3*i],m9[0+(3*(i+1))%6],m9[1+(3*(i+1))%6],m9[2+(3*(i+1))%6],1.,1.,1.}; + double det=w[0]*w[4]*w[8]+w[1]*w[5]*w[6]+w[2]*w[3]*w[7]-w[0]*w[5]*w[7]-w[1]*w[3]*w[8]-w[2]*w[4]*w[6]; + if(fabs(det)>eps) + { + eigenVector[0]=(w[1]*w[5]-w[4]*w[2])/det; + eigenVector[1]=(w[2]*w[3]-w[0]*w[5])/det; + eigenVector[2]=(w[0]*w[4]-w[1]*w[3])/det; + double norm=sqrt(eigenVector[0]*eigenVector[0]+eigenVector[1]*eigenVector[1]+eigenVector[2]*eigenVector[2]); + eigenVector[0]/=norm; + eigenVector[1]/=norm; + eigenVector[2]/=norm; + return; + } + } + } + //else + { + eigenVector[0]=0.; + eigenVector[1]=0.; + eigenVector[2]=0.; + return; + } + //throw INTERP_KERNEL::Exception("computeEigenVector : Do not succed in finding eigen vector !"); + } +} + +#endif diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx new file mode 100644 index 000000000..271771edd --- /dev/null +++ b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx @@ -0,0 +1,209 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "InterpKernelMeshQuality.hxx" + +#include +#include +#include +#include + +double INTERP_KERNEL::quadSkew(const double *coo) +{ + double pa0[3]={ + coo[3]+coo[6]-coo[0]-coo[9], + coo[4]+coo[7]-coo[1]-coo[10], + coo[5]+coo[8]-coo[2]-coo[11] + }; + double pa1[3]={ + coo[6]+coo[9]-coo[0]-coo[3], + coo[7]+coo[10]-coo[1]-coo[4], + coo[8]+coo[11]-coo[2]-coo[5], + }; + double l0=sqrt(pa0[0]*pa0[0]+pa0[1]*pa0[1]+pa0[2]*pa0[2]); + double l1=sqrt(pa1[0]*pa1[0]+pa1[1]*pa1[1]+pa1[2]*pa1[2]); + if(l0<1.e-15) + return 0.; + if(l1<1.e-15) + return 0.; + pa0[0]/=l0; pa0[1]/=l0; pa0[2]/=l0; + pa1[0]/=l1; pa1[1]/=l1; pa1[2]/=l1; + return pa0[0]*pa1[0]+pa0[1]*pa1[1]+pa0[2]*pa1[2]; +} + +double INTERP_KERNEL::quadEdgeRatio(const double *coo) +{ + double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); + double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); + double c2=(coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]); + double d2=(coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]); + double mab=a2Mcd?Mab:Mcd; + if(m2>1.e-15) + return sqrt(M2/m2); + else + return std::numeric_limits::max(); +} + +double INTERP_KERNEL::quadAspectRatio(const double *coo) +{ + double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); + double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); + double c=sqrt((coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8])); + double d=sqrt((coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11])); + double ma=a>b?a:b; + double mb=c>d?c:d; + double hm=ma>mb?ma:mb; + double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), + (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), + (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; + double cd[3]={(coo[10]-coo[7])*(coo[2]-coo[11])-(coo[1]-coo[10])*(coo[11]-coo[8]), + (coo[11]-coo[8])*(coo[0]-coo[9])-(coo[9]-coo[6])*(coo[2]-coo[11]), + (coo[9]-coo[6])*(coo[1]-coo[10])-(coo[10]-coo[7])*(coo[0]-coo[9])}; + double e=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2])+sqrt(cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]); + if(d>1e-15) + return 0.5*(a+b+c+d)*hm/e; + else + return std::numeric_limits::max(); +} + +double INTERP_KERNEL::quadWarp(const double *coo) +{ + double e0[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double e1[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double e2[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + double e3[3]={coo[0]-coo[9],coo[1]-coo[10],coo[2]-coo[11]}; + + double n0[3]={e3[1]*e0[2]-e3[2]*e0[1],e3[2]*e0[0]-e3[0]*e0[2],e3[0]*e0[1]-e3[1]*e0[0]}; + double n1[3]={e0[1]*e1[2]-e0[2]*e1[1],e0[2]*e1[0]-e0[0]*e1[2],e0[0]*e1[1]-e0[1]*e1[0]}; + double n2[3]={e1[1]*e2[2]-e1[2]*e2[1],e1[2]*e2[0]-e1[0]*e2[2],e1[0]*e2[1]-e1[1]*e2[0]}; + double n3[3]={e2[1]*e3[2]-e2[2]*e3[1],e2[2]*e3[0]-e2[0]*e3[2],e2[0]*e3[1]-e2[1]*e3[0]}; + + double l0=sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]); + double l1=sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]); + double l2=sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]); + double l3=sqrt(n3[0]*n3[0]+n3[1]*n3[1]+n3[2]*n3[2]); + + if(l0<1.e-15 || l1<1.e-15 || l2<1.e-15 || l3<1e-15) + return std::numeric_limits::min(); + + double warp=std::min(n0[0]/l0*n2[0]/l2+n0[1]/l0*n2[1]/l2+n0[2]/l0*n2[2]/l2,n1[0]/l1*n3[0]/l3+n1[1]/l1*n3[1]/l3+n1[2]/l1*n3[2]/l3); + return warp*warp*warp; +} + +double INTERP_KERNEL::triEdgeRatio(const double *coo) +{ + double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); + double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); + double c2=(coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]); + double mab=a2mab?mab:c2; + double M2=c2>Mab?c2:Mab; + if(m2>1.e-15) + return sqrt(M2/m2); + else + return std::numeric_limits::max(); +} + +double INTERP_KERNEL::triAspectRatio(const double *coo) +{ + double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); + double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); + double c=sqrt((coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8])); + + double hm=a>b?a:b; + hm=hm>c?hm:c; + + double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), + (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), + (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; + double d=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]); + static const double normalizeCoeff=sqrt(3.)/6.; + if(d>1.e-15) + return normalizeCoeff*hm*(a+b+c)/d; + else + return std::numeric_limits::max(); +} + +double INTERP_KERNEL::tetraEdgeRatio(const double *coo) +{ + double a[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double b[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double c[3]={coo[0]-coo[6],coo[1]-coo[7],coo[2]-coo[8]}; + double d[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; + double e[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; + double f[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + + double l2[6]= + {a[0]*a[0]+a[1]*a[1]+a[2]*a[2], + b[0]*b[0]+b[1]*b[1]+b[2]*b[2], + c[0]*c[0]+c[1]*c[1]+c[2]*c[2], + d[0]*d[0]+d[1]*d[1]+d[2]*d[2], + e[0]*e[0]+e[1]*e[1]+e[2]*e[2], + f[0]*f[0]+f[1]*f[1]+f[2]*f[2]}; + + double M2=*std::max_element(l2,l2+6); + double m2=*std::min_element(l2,l2+6); + if(m2>1e-15) + return sqrt(M2/m2); + else + return std::numeric_limits::max(); +} + +double INTERP_KERNEL::tetraAspectRatio(const double *coo) +{ + static const double normalizeCoeff=sqrt(6.)/12.; + double ab[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double ac[3]={coo[6]-coo[0],coo[7]-coo[1],coo[8]-coo[2]}; + double ad[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; + double detTet=(ab[0]*(ac[1]*ad[2]-ac[2]*ad[1]))+(ab[1]*(ac[2]*ad[0]-ac[0]*ad[2]))+(ab[2]*(ac[0]*ad[1]-ac[1]*ad[0])); + //if(detTet<1.e-15) + // return std::numeric_limits::max(); + double bc[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double bd[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; + double cd[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + + double ab2=ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]; + double bc2=bc[0]*bc[0]+bc[1]*bc[1]+bc[2]*bc[2]; + double ac2=ac[0]*ac[0]+ac[1]*ac[1]+ac[2]*ac[2]; + double ad2=ad[0]*ad[0]+ad[1]*ad[1]+ad[2]*ad[2]; + double bd2=bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]; + double cd2=cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]; + + double A=ab2>bc2?ab2:bc2; + double B=ac2>ad2?ac2:ad2; + double C=bd2>cd2?bd2:cd2; + double D=A>B?A:B; + double hm=D>C?sqrt(D):sqrt(C); + + bd[0]=ab[1]*bc[2]-ab[2]*bc[1]; bd[1]=ab[2]*bc[0]-ab[0]*bc[2]; bd[2]=ab[0]*bc[1]-ab[1]*bc[0]; + A=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=ab[1]*ad[2]-ab[2]*ad[1]; bd[1]=ab[2]*ad[0]-ab[0]*ad[2]; bd[2]=ab[0]*ad[1]-ab[1]*ad[0]; + B=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=ac[1]*ad[2]-ac[2]*ad[1]; bd[1]=ac[2]*ad[0]-ac[0]*ad[2]; bd[2]=ac[0]*ad[1]-ac[1]*ad[0]; + C=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=bc[1]*cd[2]-bc[2]*cd[1]; bd[1]=bc[2]*cd[0]-bc[0]*cd[2]; bd[2]=bc[0]*cd[1]-bc[1]*cd[0]; + D=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + return normalizeCoeff*hm*(A+B+C+D)/fabs(detTet); +} diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx new file mode 100644 index 000000000..2f11bb4d1 --- /dev/null +++ b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __INTERPKERNELMESHQUALITY_HXX_ +#define __INTERPKERNELMESHQUALITY_HXX__ + +#include "INTERPKERNELDefines.hxx" + +namespace INTERP_KERNEL +{ + INTERPKERNEL_EXPORT double quadSkew(const double *coo); + INTERPKERNEL_EXPORT double quadEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double quadAspectRatio(const double *coo); + INTERPKERNEL_EXPORT double quadWarp(const double *coo); + INTERPKERNEL_EXPORT double triEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double triAspectRatio(const double *coo); + INTERPKERNEL_EXPORT double tetraEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double tetraAspectRatio(const double *coo); +} + +#endif diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx index 6eb93e9aa..6069bf22d 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.cxx +++ b/src/INTERP_KERNEL/InterpolationOptions.cxx @@ -121,7 +121,7 @@ bool INTERP_KERNEL::InterpolationOptions::setOptionInt(const std::string& key, i return false; } -bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, std::string& value) +bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, const std::string& value) { if(key==INTERSEC_TYPE_STR) { diff --git a/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/INTERP_KERNEL/InterpolationOptions.hxx index 49068a01a..667e320b6 100644 --- a/src/INTERP_KERNEL/InterpolationOptions.hxx +++ b/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -118,10 +118,10 @@ namespace INTERP_KERNEL bool measure_abs, std::string splitting_policy, bool P1P0_bary_method ); - void copyOptions(InterpolationOptions & other) { *this = other; } + void copyOptions(const InterpolationOptions & other) { *this = other; } bool setOptionDouble(const std::string& key, double value); bool setOptionInt(const std::string& key, int value); - bool setOptionString(const std::string& key, std::string& value); + bool setOptionString(const std::string& key, const std::string& value); private: static const double DFT_MEDIAN_PLANE; static const double DFT_SURF3D_ADJ_EPS; diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx index 2d5ca00df..e96f3fc1b 100644 --- a/src/INTERP_KERNEL/InterpolationUtils.hxx +++ b/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -221,13 +221,13 @@ namespace INTERP_KERNEL // make upper triangular matrix (forward elimination) int iR[nbRow];// = { 0, 1, 2 }; - for ( int i = 0; i < nbRow; ++i ) iR[i] = i; + for ( int i = 0; i < (int) nbRow; ++i ) iR[i] = i; - for ( int i = 0; i < nbRow-1; ++i ) // nullify nbRow-1 rows + for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows { // swap rows to have max value of i-th column in i-th row double max = std::fabs( M[ iR[i] ][i] ); - for ( int r = i+1; r < nbRow; ++r ) { + for ( int r = i+1; r < (int)nbRow; ++r ) { double m = std::fabs( M[ iR[r] ][i] ); if ( m > max ) { max = m; @@ -240,7 +240,7 @@ namespace INTERP_KERNEL } // make 0 below M[i][i] (actually we do not modify i-th column) double* tUpRow = M[ iR[i] ]; - for ( int r = i+1; r < nbRow; ++r ) { + for ( int r = i+1; r < (int)nbRow; ++r ) { double* mRow = M[ iR[r] ]; double coef = mRow[ i ] / tUpRow[ i ]; for ( int c = i+1; c < nbCol; ++c ) diff --git a/src/INTERP_KERNEL/Makefile.am b/src/INTERP_KERNEL/Makefile.am index a12507012..e3dfc56cb 100644 --- a/src/INTERP_KERNEL/Makefile.am +++ b/src/INTERP_KERNEL/Makefile.am @@ -43,6 +43,7 @@ PointLocator2DIntersector.hxx \ PointLocator2DIntersector.txx \ INTERPKERNELDefines.hxx \ InterpKernelMatrix.hxx \ +InterpKernelMeshQuality.hxx \ Interpolation.hxx \ Interpolation.txx \ Interpolation2D.hxx \ @@ -141,6 +142,7 @@ VTKNormalizedUnstructuredMesh.hxx \ VTKNormalizedUnstructuredMesh.txx \ VectorUtils.hxx \ VolSurfFormulae.hxx \ +GenMathFormulae.hxx \ VolSurfUser.hxx \ VolSurfUser.txx \ CurveIntersector.hxx \ @@ -177,15 +179,17 @@ VolSurfUser.txx # Libraries targets dist_libinterpkernel_la_SOURCES = \ - TransformedTriangle.cxx\ - TransformedTriangleIntersect.cxx\ - TransformedTriangleMath.cxx\ + TransformedTriangle.cxx \ + TransformedTriangleIntersect.cxx \ + TransformedTriangleMath.cxx \ BoundingBox.cxx \ - TetraAffineTransform.cxx\ - CellModel.cxx\ + TranslationRotationMatrix.cxx \ + TetraAffineTransform.cxx \ + CellModel.cxx \ UnitTetraIntersectionBary.cxx \ InterpolationOptions.cxx \ - DirectedBoundingBox.cxx + DirectedBoundingBox.cxx \ + InterpKernelMeshQuality.cxx libinterpkernel_la_CPPFLAGS=-I$(srcdir)/Geometric2D -I$(srcdir)/Bases diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx new file mode 100644 index 000000000..0e31b21e0 --- /dev/null +++ b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx @@ -0,0 +1,22 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TranslationRotationMatrix.hxx" + +const double INTERP_KERNEL::TranslationRotationMatrix::EPS=1e-12; diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx index 8258cf18e..e1108573b 100644 --- a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx +++ b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx @@ -20,11 +20,13 @@ #ifndef __TRANSLATIONROTATIONMATRIX_HXX__ #define __TRANSLATIONROTATIONMATRIX_HXX__ +#include "INTERPKERNELDefines.hxx" + #include namespace INTERP_KERNEL { - class TranslationRotationMatrix + class INTERPKERNEL_EXPORT TranslationRotationMatrix { public: @@ -125,7 +127,6 @@ namespace INTERP_KERNEL double _rotation_coeffs[ROT_SIZE]; double _translation_coeffs[TRANSL_SIZE]; }; - const double TranslationRotationMatrix::EPS=1e-12; } #endif diff --git a/src/INTERP_KERNEL/VolSurfFormulae.hxx b/src/INTERP_KERNEL/VolSurfFormulae.hxx index e62956e29..e9bdd855d 100644 --- a/src/INTERP_KERNEL/VolSurfFormulae.hxx +++ b/src/INTERP_KERNEL/VolSurfFormulae.hxx @@ -20,7 +20,9 @@ #ifndef __VOLSURFFORMULAE_HXX__ #define __VOLSURFFORMULAE_HXX__ -#include +#include "InterpolationUtils.hxx" + +#include namespace INTERP_KERNEL { @@ -31,6 +33,19 @@ namespace INTERP_KERNEL int spaceDim); + inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim) + { + if(spaceDim==1) + return *p2-*p1; + else + { + double ret=0; + for(int i=0;i + inline double calculateVolumeForPolyh2(const ConnType *connec, int lgth, const double *coords) + { + int nbOfFaces=std::count(connec,connec+lgth,-1)+1; + double volume=0.; + const int *work=connec; + for(int iFace=0;iFace::coo2C(work[ptId]); + const double *pti1=coords+3*OTT::coo2C(work[(ptId+1)%nbOfNodesOfCurFace]); + areaVector[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; + areaVector[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; + areaVector[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; + } + const double *pt=coords+3*work[0]; + volume+=pt[0]*areaVector[0]+pt[1]*areaVector[1]+pt[2]*areaVector[2]; + work=work2+1; + } + return volume/6.; + } + + /*! + * This method returns the area oriented vector of a polygon. This method is useful for normal computation without + * any troubles if several edges are colinears. + * @param res must be of size at least 3 to store the result. + */ + template + inline void areaVectorOfPolygon(const ConnType *connec, int lgth, const double *coords, double *res) + { + res[0]=0.; res[1]=0.; res[2]=0.; + for(int ptId=0;ptId::coo2C(connec[ptId]); + const double *pti1=coords+3*OTT::coo2C(connec[(ptId+1)%lgth]); + res[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; + res[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; + res[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; + } + } + + inline double integrationOverA3DLine(double u1, double v1, double u2, double v2, double A, double B, double C) + { + return (u1-u2)*(6.*C*C*(v1+v2)+B*B*(v1*v1*v1+v1*v1*v2+v1*v2*v2+v2*v2*v2)+A*A*(2.*u1*u2*(v1+v2)+u1*u1*(3.*v1+v2)+u2*u2*(v1+3.*v2))+ + 4.*C*(A*(2*u1*v1+u2*v1+u1*v2+2.*u2*v2)+B*(v1*v1+v1*v2+v2*v2))+A*B*(u1*(3.*v1*v1+2.*v1*v2+v2*v2)+u2*(v1*v1+2.*v1*v2+3.*v2*v2)))/24.; + } + + template + inline void barycenterOfPolyhedron(const ConnType *connec, int lgth, const double *coords, double *res) + { + int nbOfFaces=std::count(connec,connec+lgth,-1)+1; + res[0]=0.; res[1]=0.; res[2]=0.; + const int *work=connec; + for(int i=0;i(work,nbOfNodesOfCurFace,coords,normal); + double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); + normal[0]/=normOfNormal; normal[1]/=normOfNormal; normal[2]/=normOfNormal; + double u[2]={normal[1],-normal[0]}; + double s=sqrt(u[0]*u[0]+u[1]*u[1]); + double c=normal[2]; + if(fabs(s)>1e-12) + { + u[0]/=std::abs(s); u[1]/=std::abs(s); + } + else + { u[0]=1.; u[1]=0.; } + //C : high in plane of polyhedron face : always constant + double w=normal[0]*coords[3*OTT::coo2C(work[0])]+ + normal[1]*coords[3*OTT::coo2C(work[0])+1]+ + normal[2]*coords[3*OTT::coo2C(work[0])+2]; + // A,B,D,F,G,H,L,M,N coeffs of rotation matrix defined by (u,c,s) + double A=u[0]*u[0]*(1-c)+c; + double B=u[0]*u[1]*(1-c); + double D=u[1]*s; + double F=B; + double G=u[1]*u[1]*(1-c)+c; + double H=-u[0]*s; + double L=-u[1]*s; + double M=u[0]*s; + double N=c; + double CX=-w*D; + double CY=-w*H; + double CZ=-w*N; + for(int j=0;j::coo2C(work[j]); + const double *p2=coords+3*OTT::coo2C(work[(j+1)%nbOfNodesOfCurFace]); + double u1=A*p1[0]+B*p1[1]+D*p1[2]; + double u2=A*p2[0]+B*p2[1]+D*p2[2]; + double v1=F*p1[0]+G*p1[1]+H*p1[2]; + double v2=F*p2[0]+G*p2[1]+H*p2[2]; + // + double gx=integrationOverA3DLine(u1,v1,u2,v2,A,B,CX); + double gy=integrationOverA3DLine(u1,v1,u2,v2,F,G,CY); + double gz=integrationOverA3DLine(u1,v1,u2,v2,L,M,CZ); + res[0]+=gx*normal[0]; + res[1]+=gy*normal[1]; + res[2]+=gz*normal[2]; + } + work=work2+1; + } + double vol=calculateVolumeForPolyh2(connec,lgth,coords); + res[0]/=vol; res[1]/=vol; res[2]/=vol; + } + // ============================================================================================================================================ // Calculate Volume for NON Generic Polyedron. Only polydrons with bary included in pts is supported by this method. Result is always positive. // ============================================================================================================================================ @@ -503,6 +637,56 @@ namespace INTERP_KERNEL bary[i]=temp/nbPts; } } + + template + inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) + { + double area=0.; + res[0]=0.; res[1]=0.; + for(int i=0;i::coo2C(connec[i])]*coords[2*OTT::coo2C(connec[(i+1)%lgth])+1]- + coords[2*OTT::coo2C(connec[i])+1]*coords[2*OTT::coo2C(connec[(i+1)%lgth])]; + area+=cp; + res[0]+=cp*(coords[2*OTT::coo2C(connec[i])]+coords[2*OTT::coo2C(connec[(i+1)%lgth])]); + res[1]+=cp*(coords[2*OTT::coo2C(connec[i])+1]+coords[2*OTT::coo2C(connec[(i+1)%lgth])+1]); + } + res[0]/=3.*area; + res[1]/=3.*area; + } + + template + inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res) + { + double area[3]; + areaVectorOfPolygon(connec,lgth,coords,area); + double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]); + area[0]/=norm; area[1]/=norm; area[2]/=norm; + res[0]=0.; res[1]=0.; res[2]=0.; + for(int i=1;i::coo2C(connec[0])]+ + coords[3*OTT::coo2C(connec[i])]+ + coords[3*OTT::coo2C(connec[i+1])])/3.; + v[1]=(coords[3*OTT::coo2C(connec[0])+1]+ + coords[3*OTT::coo2C(connec[i])+1]+ + coords[3*OTT::coo2C(connec[i+1])+1])/3.; + v[2]=(coords[3*OTT::coo2C(connec[0])+2]+ + coords[3*OTT::coo2C(connec[i])+2]+ + coords[3*OTT::coo2C(connec[i+1])+2])/3.; + ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]}; + areaVectorOfPolygon(tmpConn,3,coords,tmpArea); + double norm2=sqrt(tmpArea[0]*tmpArea[0]+tmpArea[1]*tmpArea[1]+tmpArea[2]*tmpArea[2]); + if(norm2>1e-12) + { + tmpArea[0]/=norm2; tmpArea[1]/=norm2; tmpArea[2]/=norm2; + double signOfArea=area[0]*tmpArea[0]+area[1]*tmpArea[1]+area[2]*tmpArea[2]; + res[0]+=signOfArea*norm2*v[0]/norm; res[1]+=signOfArea*norm2*v[1]/norm; res[2]+=signOfArea*norm2*v[2]/norm; + } + } + } } #endif diff --git a/src/INTERP_KERNEL/VolSurfUser.hxx b/src/INTERP_KERNEL/VolSurfUser.hxx index a0eafd221..99083c319 100644 --- a/src/INTERP_KERNEL/VolSurfUser.hxx +++ b/src/INTERP_KERNEL/VolSurfUser.hxx @@ -29,6 +29,12 @@ namespace INTERP_KERNEL template double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim); + + template + void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res); + + template + void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); } #endif diff --git a/src/INTERP_KERNEL/VolSurfUser.txx b/src/INTERP_KERNEL/VolSurfUser.txx index d6fcd11bf..f14ba420a 100644 --- a/src/INTERP_KERNEL/VolSurfUser.txx +++ b/src/INTERP_KERNEL/VolSurfUser.txx @@ -23,6 +23,8 @@ #include "VolSurfFormulae.hxx" #include "InterpolationUtils.hxx" +#include + namespace INTERP_KERNEL { template @@ -30,6 +32,13 @@ namespace INTERP_KERNEL { switch(type) { + case INTERP_KERNEL::NORM_SEG2 : + case INTERP_KERNEL::NORM_SEG3 : + { + int N1 = OTT::coo2C(connec[0]); + int N2 = OTT::coo2C(connec[1]); + return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM); + } case INTERP_KERNEL::NORM_TRI3 : case INTERP_KERNEL::NORM_TRI6 : { @@ -64,7 +73,7 @@ namespace INTERP_KERNEL { const double **pts=new const double *[lgth]; for(int inod=0;inod::coo2C(connec[inod]); + pts[inod] = coords+SPACEDIM*OTT::coo2C(connec[inod]); double val=INTERP_KERNEL::calculateAreaForPolyg(pts,lgth,SPACEDIM); delete [] pts; return val; @@ -146,11 +155,11 @@ namespace INTERP_KERNEL case INTERP_KERNEL::NORM_POLYHED : { - throw INTERP_KERNEL::Exception("Polyedra Not yet implemented !"); + return calculateVolumeForPolyh2(connec,lgth,coords); } break; default: - throw INTERP_KERNEL::Exception("Not recognized cell type to get Area/Volume on it !"); + throw INTERP_KERNEL::Exception("Not recognized cell type to get Length/Area/Volume on it !"); } } @@ -161,7 +170,127 @@ namespace INTERP_KERNEL return computeVolSurfOfCell(type,connec,lgth,coords); if(spaceDim==2) return computeVolSurfOfCell(type,connec,lgth,coords); - throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 2 or 3"); + if(spaceDim==1) + return computeVolSurfOfCell(type,connec,lgth,coords); + throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 1, 2 or 3"); + } + + template + void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res) + { + switch(type) + { + case NORM_SEG3: + case NORM_SEG2: + { + std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), + coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),0.5)); + break; + } + case NORM_TRI3: + case NORM_TRI6: + { + std::copy(coords+SPACEDIM*OTT::coo2C(connec[0]), + coords+SPACEDIM*OTT::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[1]),res,std::plus()); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT::coo2C(connec[2]),res,std::plus()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies(),1./3.)); + break; + } + case NORM_QUAD4: + case NORM_POLYGON: + { + if(SPACEDIM==2) + computePolygonBarycenter2D(connec,lgth,coords,res); + else if(SPACEDIM==3) + computePolygonBarycenter3D(connec,lgth,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } + case NORM_QUAD8: + { + if(SPACEDIM==2) + computePolygonBarycenter2D(connec,lgth/2,coords,res); + else if(SPACEDIM==3) + computePolygonBarycenter3D(connec,lgth/2,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } + case NORM_TETRA4: + { + res[0]=coords[3*OTT::coo2C(connec[0])]; + res[1]=coords[3*OTT::coo2C(connec[0])+1]; + res[2]=coords[3*OTT::coo2C(connec[0])+2]; + res[0]+=coords[3*OTT::coo2C(connec[1])]; + res[1]+=coords[3*OTT::coo2C(connec[1])+1]; + res[2]+=coords[3*OTT::coo2C(connec[1])+2]; + res[0]+=coords[3*OTT::coo2C(connec[2])]; + res[1]+=coords[3*OTT::coo2C(connec[2])+1]; + res[2]+=coords[3*OTT::coo2C(connec[2])+2]; + res[0]+=coords[3*OTT::coo2C(connec[3])]; + res[1]+=coords[3*OTT::coo2C(connec[3])+1]; + res[2]+=coords[3*OTT::coo2C(connec[3])+2]; + res[0]/=4.; res[1]/=4.; res[2]/=4.; + break; + } + case NORM_PYRA5: + { + double tmp[3]; + computePolygonBarycenter3D(connec,lgth-1,coords,tmp); + res[0]=(coords[3*OTT::coo2C(connec[4])]+3.*tmp[0])/4.; + res[1]=(coords[3*OTT::coo2C(connec[4])+1]+3.*tmp[1])/4.; + res[2]=(coords[3*OTT::coo2C(connec[4])+2]+3.*tmp[2])/4.; + break; + } + case NORM_HEXA8: + { + const int conn[29]={ + OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),-1, + OTT::coo2C(connec[4]),OTT::coo2C(connec[7]),OTT::coo2C(connec[6]),OTT::coo2C(connec[5]),-1, + OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[7]),OTT::coo2C(connec[4]),-1, + OTT::coo2C(connec[3]),OTT::coo2C(connec[2]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),-1, + OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[5]),OTT::coo2C(connec[6]),-1, + OTT::coo2C(connec[0]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),OTT::coo2C(connec[1]), + }; + barycenterOfPolyhedron(conn,29,coords,res); + break; + } + case NORM_PENTA6: + { + const int conn[22]={ + OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),-1, + OTT::coo2C(connec[3]),OTT::coo2C(connec[5]),OTT::coo2C(connec[4]),-1, + OTT::coo2C(connec[0]),OTT::coo2C(connec[2]),OTT::coo2C(connec[5]),OTT::coo2C(connec[3]),-1, + OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, + OTT::coo2C(connec[1]),OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]) + }; + barycenterOfPolyhedron(conn,22,coords,res); + break; + } + case NORM_POLYHED: + { + barycenterOfPolyhedron(connec,lgth,coords,res); + break; + } + default: + throw INTERP_KERNEL::Exception("Not recognized cell type to get Barycenter on it !"); + } + } + + template + void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res) + { + if(spaceDim==3) + return computeBarycenter(type,connec,lgth,coords,res); + if(spaceDim==2) + return computeBarycenter(type,connec,lgth,coords,res); + if(spaceDim==1) + return computeBarycenter(type,connec,lgth,coords,res); + throw INTERP_KERNEL::Exception("Invalid spaceDim specified for compute barycenter : must be 1, 2 or 3"); } } diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx index 947f8fa5c..b62b39e35 100644 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx +++ b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx @@ -228,13 +228,13 @@ void ExprEvalInterpTest::testInterpreter2() double res1; std::vector vars; vars.push_back("x"); vars.push_back("y"); expr1.prepareExprEvaluation(vars); - expr1.evaluateExpr(1,&res1,xyValue); + expr1.evaluateExpr(1,xyValue,&res1); CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13); xyValue[0]=-2.; - CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,&res1,xyValue),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,xyValue,&res1),INTERP_KERNEL::Exception); double res2[2]; xyValue[0]=1.; - expr1.evaluateExpr(2,res2,xyValue); + expr1.evaluateExpr(2,xyValue,res2); CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13); CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13); INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)"); @@ -245,13 +245,13 @@ void ExprEvalInterpTest::testInterpreter2() expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec"); CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); expr2.prepareExprEvaluation(vars); - expr2.evaluateExpr(2,res2,xyValue); + expr2.evaluateExpr(2,xyValue,res2); CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14); INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2."); expr3.parse(); expr3.prepareExprEvaluationVec(); - expr3.evaluateExpr(2,res2,xyValue); + expr3.evaluateExpr(2,xyValue,res2); CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14); CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14); INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2."); diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx new file mode 100644 index 000000000..9a30b7d8f --- /dev/null +++ b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ + +#include "MEDCouplingRefCountObject.hxx" + +namespace ParaMEDMEM +{ + template + class MEDCouplingAutoRefCountObjectPtr + { + public: + MEDCouplingAutoRefCountObjectPtr(const MEDCouplingAutoRefCountObjectPtr& other):_ptr(0) { referPtr(other._ptr); } + MEDCouplingAutoRefCountObjectPtr(T *ptr=0):_ptr(ptr) { } + ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); } + MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; } + MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { if(_ptr!=ptr) { destroyPtr(); _ptr=ptr; } return *this; } + T *operator->() { return _ptr ; } + const T *operator->() const { return _ptr; } + T& operator*() { return *_ptr; } + const T& operator*() const { return *_ptr; } + operator T *() { return _ptr; } + operator const T *() const { return _ptr; } + private: + void referPtr(T *ptr) { _ptr=ptr; if(_ptr) _ptr->incrRef(); } + void destroyPtr() { if(_ptr) _ptr->decrRef(); } + private: + T *_ptr; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx index 8829b19de..e7d9bcd3a 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ b/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -18,6 +18,7 @@ // #include "MEDCouplingCMesh.hxx" +#include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" @@ -31,6 +32,31 @@ MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) { } +MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy):MEDCouplingMesh(other) +{ + if(deepCpy) + { + if(other._x_array) + _x_array=_x_array->deepCopy(); + if(other._y_array) + _y_array=_y_array->deepCopy(); + if(other._z_array) + _z_array=_z_array->deepCopy(); + } + else + { + _x_array=other._x_array; + if(_x_array) + _x_array->incrRef(); + _y_array=other._y_array; + if(_y_array) + _y_array->incrRef(); + _z_array=other._z_array; + if(_z_array) + _z_array->incrRef(); + } +} + MEDCouplingCMesh::~MEDCouplingCMesh() { if(_x_array) @@ -46,6 +72,16 @@ MEDCouplingCMesh *MEDCouplingCMesh::New() return new MEDCouplingCMesh; } +MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingCMesh(*this,recDeepCpy); +} + void MEDCouplingCMesh::updateTime() { if(_x_array) @@ -56,41 +92,119 @@ void MEDCouplingCMesh::updateTime() updateTimeWith(*_z_array); } +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingCMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingMesh::copyTinyStringsFrom(other); + if(_x_array && otherC->_x_array) + _x_array->copyStringInfoFrom(*otherC->_x_array); + if(_y_array && otherC->_y_array) + _y_array->copyStringInfoFrom(*otherC->_y_array); + if(_z_array && otherC->_z_array) + _z_array->copyStringInfoFrom(*otherC->_z_array); +} + bool MEDCouplingCMesh::isEqual(const MEDCouplingMesh *other, double prec) const { const MEDCouplingCMesh *otherC=dynamic_cast(other); if(!otherC) return false; + if(!MEDCouplingMesh::isEqual(other,prec)) + return false; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; + for(int i=0;i<3;i++) + { + if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) + return false; + if(thisArr[i]) + if(!thisArr[i]->isEqual(*otherArr[i],prec)) + return false; + } return true; } +bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingCMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; + for(int i=0;i<3;i++) + { + if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) + return false; + if(thisArr[i]) + if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec)) + return false; + } + return true; +} + +void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + void MEDCouplingCMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) { const char msg0[]="Invalid "; const char msg1[]=" array ! Must contain more than 1 element."; + const char msg2[]=" array ! Must be with only one component."; if(_x_array) - if(_x_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'X' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } + { + if(_x_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'X' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_x_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'X' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + } if(_y_array) - if(_y_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Y' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } + { + if(_y_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Y' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_y_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'Y' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + + } if(_z_array) - if(_z_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Z' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } -} - -bool MEDCouplingCMesh::isStructured() const -{ - return true; + { + if(_z_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Z' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_z_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'Z' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + } } int MEDCouplingCMesh::getNumberOfCells() const @@ -123,7 +237,7 @@ void MEDCouplingCMesh::getSplitCellValues(int *res) const for(int l=0;lgetNbOfElems()-1; res[spaceDim-l-1]=val; } @@ -135,7 +249,7 @@ void MEDCouplingCMesh::getSplitNodeValues(int *res) const for(int l=0;lgetNbOfElems(); res[spaceDim-l-1]=val; } @@ -204,6 +318,27 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingCMesh::getTypeOfCell(int cellId) co } } +int MEDCouplingCMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + int ret=getNumberOfCells(); + int dim=getMeshDimension(); + switch(type) + { + case INTERP_KERNEL::NORM_HEXA8: + if(dim==3) + return ret; + case INTERP_KERNEL::NORM_QUAD4: + if(dim==2) + return ret; + case INTERP_KERNEL::NORM_SEG2: + if(dim==1) + return ret; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCMesh::getTypeOfCell !"); + } + return 0; +} + void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const { //not implemented yet @@ -211,7 +346,43 @@ void MEDCouplingCMesh::getNodeIdsOfCell(int cellId, std::vector& conn) cons void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const { - //not implemented yet + int tmp[3]; + int spaceDim=getSpaceDimension(); + getSplitNodeValues(tmp); + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + int tmp2[3]; + getPosFromId(nodeId,spaceDim,tmp,tmp2); + for(int j=0;jgetConstPointer()[tmp2[j]]); +} + +std::string MEDCouplingCMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "Cartesian mesh with name : \"" << getName() << "\"\n"; + ret << "Mesh and SpaceDimension dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n"; + if(_x_array) + { + ret << "X Array :\n"; + _x_array->reprZipWithoutNameStream(ret); + } + if(_y_array) + { + ret << "Y Array :\n"; + _y_array->reprZipWithoutNameStream(ret); + } + if(_z_array) + { + ret << "Z Array :\n"; + _z_array->reprZipWithoutNameStream(ret); + } + return ret.str(); +} + +std::string MEDCouplingCMesh::advancedRepr() const +{ + return simpleRepr(); } DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL::Exception) @@ -229,6 +400,22 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const throw(INTERP_KERNEL: } } +void MEDCouplingCMesh::setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) +{ + DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; + if(i<0 || i>2) + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + if(arr!=*(thisArr[i])) + { + if(*(thisArr[i])) + (*(thisArr[i]))->decrRef(); + (*(thisArr[i]))=arr; + if(*(thisArr[i])) + (*(thisArr[i]))->incrRef(); + declareAsNew(); + } +} + void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coordsY, DataArrayDouble *coordsZ) { if(_x_array) @@ -249,15 +436,94 @@ void MEDCouplingCMesh::setCoords(DataArrayDouble *coordsX, DataArrayDouble *coor declareAsNew(); } +MEDCouplingUMesh *MEDCouplingCMesh::buildUnstructured() const +{ + int spaceDim=getSpaceDimension(); + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(getName(),spaceDim); + DataArrayDouble *coords=getCoordinatesAndOwner(); + ret->setCoords(coords); + coords->decrRef(); + switch(spaceDim) + { + case 1: + fill1DUnstructuredMesh(ret); + break; + case 2: + fill2DUnstructuredMesh(ret); + break; + case 3: + fill3DUnstructuredMesh(ret); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::buildUnstructured : big problem spacedim must be in 1,2 or 3 !"); + }; + return ret; +} + +MEDCouplingMesh *MEDCouplingCMesh::buildPart(const int *start, const int *end) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPart(start,end); + um->decrRef(); + return ret; +} + +MEDCouplingMesh *MEDCouplingCMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); + um->decrRef(); + return ret; +} + void MEDCouplingCMesh::getBoundingBox(double *bbox) const { - //not implemented yet ! + int dim=getSpaceDimension(); + int j=0; + for (int idim=0; idimgetConstPointer(); + int nb=c->getNbOfElems(); + bbox[2*j]=coords[0]; + bbox[2*j+1]=coords[nb-1]; + j++; + } + } } MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const { - //not implemented yet ! - return 0; + std::string name="MeasureOfMesh_"; + name+=getName(); + int nbelem=getNumberOfCells(); + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS); + field->setName(name.c_str()); + DataArrayDouble* array=DataArrayDouble::New(); + array->alloc(nbelem,1); + double *area_vol=array->getPointer(); + field->setArray(array) ; + array->decrRef(); + field->setMesh(const_cast(this)); + int tmp[3]; + getSplitCellValues(tmp); + int dim=getSpaceDimension(); + const double **thisArr=new const double *[dim]; + const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array}; + for(int i=0;igetConstPointer(); + for(int icell=0;icellgetConstPointer(); + int nbOfNodes=getCoordsAt(i)->getNbOfElems(); + double ref=pos[i]; + const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater(),ref)); + int w2=std::distance(d,w); + if(w2getPointer(),std::bind2nd(std::plus(),vector[2])); } +void MEDCouplingCMesh::scale(const double *point, double factor) +{ + for(int i=0;i<3;i++) + { + DataArrayDouble *c=getCoordsAt(i); + if(c) + { + double *coords=c->getPointer(); + int lgth=c->getNbOfElems(); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus(),point[i])); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies(),factor)); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus(),point[i])); + c->declareAsNew(); + } + } + updateTime(); +} + MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const { //not implemented yet ! @@ -364,3 +665,166 @@ DataArrayDouble *MEDCouplingCMesh::getBarycenterAndOwner() const } return ret; } + +void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); +} + +void MEDCouplingCMesh::fill1DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + const DataArrayDouble *c=getCoordsAt(0); + int nbOfCells=c->getNbOfElems()-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(nbOfCells+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(3*nbOfCells,1); + ci[0]=0; + int *cp=conn->getPointer(); + for(int i=0;isetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingCMesh::fill2DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + const DataArrayDouble *c1=getCoordsAt(0); + const DataArrayDouble *c2=getCoordsAt(1); + int n1=c1->getNbOfElems()-1; + int n2=c2->getNbOfElems()-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(5*n1*n2,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int j=0;jsetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingCMesh::fill3DUnstructuredMesh(MEDCouplingUMesh *m) const +{ + const DataArrayDouble *c1=getCoordsAt(0); + const DataArrayDouble *c2=getCoordsAt(1); + const DataArrayDouble *c3=getCoordsAt(2); + int n1=c1->getNbOfElems()-1; + int n2=c2->getNbOfElems()-1; + int n3=c3->getNbOfElems()-1; + DataArrayInt *connI=DataArrayInt::New(); + connI->alloc(n1*n2*n3+1,1); + int *ci=connI->getPointer(); + DataArrayInt *conn=DataArrayInt::New(); + conn->alloc(9*n1*n2*n3,1); + ci[0]=0; + int *cp=conn->getPointer(); + int pos=0; + for(int k=0;ksetConnectivity(conn,connI,true); + conn->decrRef(); + connI->decrRef(); +} + +void MEDCouplingCMesh::getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const +{ + tinyInfo.clear(); + littleStrings.clear(); + littleStrings.push_back(getName()); + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + for(int i=0;i<3;i++) + { + int val=-1; + std::string st; + if(thisArr[i]) + { + val=thisArr[i]->getNumberOfTuples(); + st=thisArr[i]->getInfoOnComponent(0); + } + tinyInfo.push_back(val); + littleStrings.push_back(st); + } +} + +void MEDCouplingCMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const +{ + a1->alloc(0,1); + int sum=0; + for(int i=0;i<3;i++) + if(tinyInfo[i]!=-1) + sum+=tinyInfo[i]; + a2->alloc(sum,1); +} + +void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); + a1->alloc(0,1); + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + int sz=0; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + sz+=thisArr[i]->getNumberOfTuples(); + } + a2=DataArrayDouble::New(); + a2->alloc(sz,1); + double *a2Ptr=a2->getPointer(); + for(int i=0;i<3;i++) + if(thisArr[i]) + a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr); +} + +void MEDCouplingCMesh::unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings) +{ + setName(littleStrings[0].c_str()); + DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; + const double *data=a2->getConstPointer(); + for(int i=0;i<3;i++) + { + if(tinyInfo[i]!=-1) + { + (*(thisArr[i]))=DataArrayDouble::New(); + (*(thisArr[i]))->alloc(tinyInfo[i],1); + (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+1].c_str()); + std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer()); + data+=tinyInfo[i]; + } + } +} + diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx index a8f0b5301..434091f41 100644 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ b/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -26,16 +26,24 @@ namespace ParaMEDMEM { class DataArrayDouble; + class MEDCouplingUMesh; class MEDCOUPLING_EXPORT MEDCouplingCMesh : public MEDCouplingMesh { public: static MEDCouplingCMesh *New(); + MEDCouplingMesh *deepCpy() const; + MEDCouplingCMesh *clone(bool recDeepCpy) const; void updateTime(); MEDCouplingMeshType getType() const { return CARTESIAN; } + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); void checkCoherency() const throw(INTERP_KERNEL::Exception); - bool isStructured() const; int getNumberOfCells() const; int getNumberOfNodes() const; int getSpaceDimension() const; @@ -44,13 +52,20 @@ namespace ParaMEDMEM int getNodeIdFromPos(int i, int j, int k) const; static void getPosFromId(int nodeId, int spaceDim, const int *split, int *res); INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; void getNodeIdsOfCell(int cellId, std::vector& conn) const; void getCoordinatesOfNode(int nodeId, std::vector& coo) const; + std::string simpleRepr() const; + std::string advancedRepr() const; DataArrayDouble *getCoordsAt(int i) const throw(INTERP_KERNEL::Exception); + void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); void setCoords(DataArrayDouble *coordsX, DataArrayDouble *coordsY=0, DataArrayDouble *coordsZ=0); // tools + MEDCouplingUMesh *buildUnstructured() const; + MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; void getBoundingBox(double *bbox) const; MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; @@ -58,14 +73,26 @@ namespace ParaMEDMEM int getCellContainingPoint(const double *pos, double eps) const; void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); + void scale(const double *point, double factor); MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; DataArrayDouble *getCoordinatesAndOwner() const; DataArrayDouble *getBarycenterAndOwner() const; + void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + void fill1DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill2DUnstructuredMesh(MEDCouplingUMesh *m) const; + void fill3DUnstructuredMesh(MEDCouplingUMesh *m) const; //some useful methods void getSplitCellValues(int *res) const; void getSplitNodeValues(int *res) const; + //serialisation-unserialization + void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); private: MEDCouplingCMesh(); + MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy); ~MEDCouplingCMesh(); private: DataArrayDouble *_x_array; diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx index 3233ac549..d01e29149 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -47,25 +47,77 @@ MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *me return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId); } +/*! + * This constructor is here only for unserialisation process. + * This constructor is normally completely useless for end user. + */ +MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New() +{ + return new MEDCouplingExtrudedMesh; +} + MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const { return EXTRUDED; } +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingMesh::copyTinyStringsFrom(other); + _mesh2D->copyTinyStringsFrom(otherC->_mesh2D); + _mesh1D->copyTinyStringsFrom(otherC->_mesh1D); +} + MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception) try:_mesh2D(mesh2D),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId) { if(_mesh2D!=0) _mesh2D->incrRef(); computeExtrusion(mesh3D); + setName(mesh3D->getName()); } -catch(INTERP_KERNEL::Exception&) +catch(INTERP_KERNEL::Exception& e) { + if(_mesh2D) + _mesh2D->decrRef(); + if(_mesh1D) + _mesh1D->decrRef(); + if(_mesh3D_ids) + _mesh3D_ids->decrRef(); + throw e; } -bool MEDCouplingExtrudedMesh::isStructured() const +MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1) +{ +} + +MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCpy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id) { - return false; + if(deepCpy) + { + _mesh2D=other._mesh2D->clone(true); + _mesh1D=other._mesh1D->clone(true); + _mesh3D_ids=other._mesh3D_ids->deepCopy(); + } + else + { + _mesh2D=other._mesh2D; + if(_mesh2D) + _mesh2D->incrRef(); + _mesh1D=other._mesh1D; + if(_mesh1D) + _mesh1D->incrRef(); + _mesh3D_ids=other._mesh3D_ids; + if(_mesh3D_ids) + _mesh3D_ids->incrRef(); + } } int MEDCouplingExtrudedMesh::getNumberOfCells() const @@ -88,14 +140,88 @@ int MEDCouplingExtrudedMesh::getMeshDimension() const return 3; } +MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingExtrudedMesh(*this,recDeepCpy); +} + +bool MEDCouplingExtrudedMesh::isEqual(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!MEDCouplingMesh::isEqual(other,prec)) + return false; + if(!_mesh2D->isEqual(otherC->_mesh2D,prec)) + return false; + if(!_mesh1D->isEqual(otherC->_mesh1D,prec)) + return false; + if(!_mesh3D_ids->isEqual(*otherC->_mesh3D_ids)) + return false; + if(_cell_2D_id!=otherC->_cell_2D_id) + return false; + return true; +} + +bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec)) + return false; + if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec)) + return false; + if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids)) + return false; + if(_cell_2D_id!=otherC->_cell_2D_id) + return false; + return true; +} + +void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !"); +} + +void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !"); +} + INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const { + const int *ids=_mesh3D_ids->getConstPointer(); + int nbOf3DCells=_mesh3D_ids->getNumberOfTuples(); + const int *where=std::find(ids,ids+nbOf3DCells,cellId); + if(where==ids+nbOf3DCells) + throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !"); int nbOfCells2D=_mesh2D->getNumberOfCells(); - int locId=cellId%nbOfCells2D; + int locId=std::distance(ids,where)%nbOfCells2D; INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId); return INTERP_KERNEL::CellModel::getCellModel(tmp).getExtrudedType(); } +int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + int ret=0; + int nbOfCells2D=_mesh2D->getNumberOfCells(); + for(int i=0;igetTypeOfCell(i); + if(INTERP_KERNEL::CellModel::getCellModel(t).getExtrudedType()==type) + ret++; + } + return ret*_mesh1D->getNumberOfCells(); +} + void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const { int nbOfCells2D=_mesh2D->getNumberOfCells(); @@ -127,6 +253,31 @@ void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vectorgetNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; + ret << "1D Mesh info : _____________________\n\n\n"; + ret << _mesh1D->simpleRepr(); + ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n"; + return ret.str(); +} + +std::string MEDCouplingExtrudedMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << "3D Extruded mesh from a 2D Surf Mesh with name : \"" << getName() << "\"\n"; + ret << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; + ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; + ret << "1D Mesh info : _____________________\n\n\n"; + ret << _mesh1D->advancedRepr(); + ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n"; + ret << "3D cell ids per level :\n"; + return ret.str(); +} + void MEDCouplingExtrudedMesh::checkCoherency() const throw (INTERP_KERNEL::Exception) { } @@ -165,13 +316,49 @@ void MEDCouplingExtrudedMesh::updateTime() } } +void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh"); +} + +MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const +{ + MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMeshFromThis(_mesh1D,0); + const int *renum=_mesh3D_ids->getConstPointer(); + ret->renumberCells(renum,false); + ret->setName(getName()); + return ret; +} + MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const { - //not implemented yet - return 0; + std::string name="MeasureOfMesh_"; + name+=getName(); + MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true); + MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true); + const double *ret2DPtr=ret2D->getArray()->getConstPointer(); + const double *ret1DPtr=ret1D->getArray()->getConstPointer(); + int nbOf2DCells=_mesh2D->getNumberOfCells(); + int nbOf1DCells=_mesh1D->getNumberOfCells(); + int nbOf3DCells=nbOf2DCells*nbOf1DCells; + const int *renum=_mesh3D_ids->getConstPointer(); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + ret->setMesh(this); + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(nbOf3DCells,1); + double *retPtr=da->getPointer(); + for(int i=0;isetArray(da); + da->decrRef(); + ret->setName(name.c_str()); + ret2D->decrRef(); + ret1D->decrRef(); + return ret; } -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) const +MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const { //not implemented yet return 0; @@ -179,8 +366,7 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) con MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const { - //not implemented yet - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField not implemented yet !"); + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !"); } int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const @@ -376,6 +562,24 @@ void MEDCouplingExtrudedMesh::translate(const double *vector) _mesh1D->translate(vector); } +void MEDCouplingExtrudedMesh::scale(const double *point, double factor) +{ + _mesh2D->scale(point,factor); + _mesh1D->scale(point,factor); +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const +{ + // not implemented yet ! + return 0; +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + // not implemented yet ! + return 0; +} + MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const { // not implemented yet ! @@ -470,3 +674,109 @@ void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D revDesc->decrRef(); revDescIndx->decrRef(); } + +void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const +{ + std::vector tinyInfo1; + std::vector ls1; + _mesh2D->getTinySerializationInformation(tinyInfo1,ls1); + std::vector tinyInfo2; + std::vector ls2; + _mesh1D->getTinySerializationInformation(tinyInfo2,ls2); + tinyInfo.clear(); littleStrings.clear(); + tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end()); + littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end()); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end()); + tinyInfo.push_back(_cell_2D_id); + tinyInfo.push_back(tinyInfo1.size()); + tinyInfo.push_back(_mesh3D_ids->getNbOfElems()); + littleStrings.push_back(getName()); +} + +void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const +{ + int sz=tinyInfo.size(); + int sz1=tinyInfo[sz-2]; + std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); + std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); + MEDCouplingUMesh *um=MEDCouplingUMesh::New(); + DataArrayInt *a1tmp=DataArrayInt::New(); + DataArrayDouble *a2tmp=DataArrayDouble::New(); + int la1=0,la2=0; + std::vector ls1,ls2; + um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); + la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); + a1tmp->decrRef(); a2tmp->decrRef(); + a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); + um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2); + la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); + a1tmp->decrRef(); a2tmp->decrRef(); + um->decrRef(); + // + a1->alloc(la1+tinyInfo[sz-1],1); + a2->alloc(la2,1); + littleStrings.resize(ls1.size()+ls2.size()+1); +} + +void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); a2=DataArrayDouble::New(); + DataArrayInt *a1_1=0,*a1_2=0; + DataArrayDouble *a2_1=0,*a2_2=0; + _mesh2D->serialize(a1_1,a2_1); + _mesh1D->serialize(a1_2,a2_2); + a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1); + int *ptri=a1->getPointer(); + ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri); + a1_1->decrRef(); + ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri); + a1_2->decrRef(); + std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri); + a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1); + double *ptrd=a2->getPointer(); + ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd); + a2_1->decrRef(); + std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd); + a2_2->decrRef(); +} + +void MEDCouplingExtrudedMesh::unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) +{ + setName(littleStrings.back().c_str()); + int sz=tinyInfo.size(); + int sz1=tinyInfo[sz-2]; + _cell_2D_id=tinyInfo[sz-3]; + std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); + std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); + DataArrayInt *a1tmp=DataArrayInt::New(); + DataArrayDouble *a2tmp=DataArrayDouble::New(); + const int *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + _mesh2D=MEDCouplingUMesh::New(); + std::vector ls1,ls2; + _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); + std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); + std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); + a2Ptr+=a2tmp->getNbOfElems(); + a1Ptr+=a1tmp->getNbOfElems(); + ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size()); + _mesh2D->unserialization(ti1,a1tmp,a2tmp,ls2); + a1tmp->decrRef(); a2tmp->decrRef(); + // + ls2.clear(); + ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-1); + _mesh1D=MEDCouplingUMesh::New(); + a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); + _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1); + std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); + std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); + a1Ptr+=a1tmp->getNbOfElems(); + _mesh1D->unserialization(ti2,a1tmp,a2tmp,ls2); + a1tmp->decrRef(); a2tmp->decrRef(); + // + _mesh3D_ids=DataArrayInt::New(); + int szIds=std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems()); + _mesh3D_ids->alloc(szIds,1); + std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer()); +} diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx index 60f46c047..39a0dbf47 100644 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -36,21 +36,35 @@ namespace ParaMEDMEM { public: static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); + static MEDCouplingExtrudedMesh *New(); MEDCouplingMeshType getType() const; - bool isStructured() const; + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); int getNumberOfCells() const; int getNumberOfNodes() const; int getSpaceDimension() const; int getMeshDimension() const; + MEDCouplingMesh *deepCpy() const; + MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const; + bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; void getNodeIdsOfCell(int cellId, std::vector& conn) const; void getCoordinatesOfNode(int nodeId, std::vector& coo) const; + std::string simpleRepr() const; + std::string advancedRepr() const; void checkCoherency() const throw (INTERP_KERNEL::Exception); void getBoundingBox(double *bbox) const; void updateTime(); + void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *getMesh2D() const { return _mesh2D; } MEDCouplingUMesh *getMesh1D() const { return _mesh1D; } DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; } + MEDCouplingUMesh *build3DUnstructuredMesh() const; MEDCouplingFieldDouble *getMeasureField(bool) const; MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const; MEDCouplingFieldDouble *buildOrthogonalField() const; @@ -61,11 +75,22 @@ namespace ParaMEDMEM MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) throw(INTERP_KERNEL::Exception); void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); + void scale(const double *point, double factor); + MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; DataArrayDouble *getCoordinatesAndOwner() const; DataArrayDouble *getBarycenterAndOwner() const; + //Serialization unserialisation + void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); private: MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); + MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCpy); + MEDCouplingExtrudedMesh(); void computeExtrusion(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception); void computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) throw(INTERP_KERNEL::Exception); void build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, @@ -80,6 +105,7 @@ namespace ParaMEDMEM private: MEDCouplingUMesh *_mesh2D; MEDCouplingUMesh *_mesh1D; + //! New to old 3D cell Ids Array DataArrayInt *_mesh3D_ids; int _cell_2D_id; }; diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx index d64a03822..41c3029f3 100644 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ b/src/MEDCoupling/MEDCouplingField.cxx @@ -29,7 +29,7 @@ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, d return false; if(_desc!=other->_desc) return false; - if(!_type->isEqual(other->_type)) + if(!_type->isEqual(other->_type,valsPrec)) return false; if(_mesh==0 && other->_mesh==0) return true; @@ -40,21 +40,50 @@ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, d return _mesh->isEqual(other->_mesh,meshPrec); } -bool MEDCouplingField::areCompatible(const MEDCouplingField *other) const +bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const { - if(!_type->isEqual(other->_type)) + if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec)) + return false; + if(_mesh==0 && other->_mesh==0) + return true; + if(_mesh==0 || other->_mesh==0) + return false; + if(_mesh==other->_mesh) + return true; + return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec); +} + +/*! + * This method states if 'this' and 'other' are compatibles each other before performing any treatment. + * This method is good for methods like : mergeFields. + * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. + */ +bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const +{ + if(!_type->isEqual(other->_type,1.)) return false; if(_mesh==other->_mesh) return true; - if(!_mesh->areCompatible(other->_mesh)) + return _mesh->areCompatibleForMerge(other->_mesh); +} + +/*! + * This method is more strict than MEDCouplingField::areCompatibleForMerge method. + * This method is used for operation on fields to operate a first check before attempting operation. + */ +bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const +{ + if(!_type->isEqual(other->_type,1.e-12)) return false; - return true; + return _mesh==other->_mesh; } void MEDCouplingField::updateTime() { if(_mesh) updateTimeWith(*_mesh); + if(_type) + updateTimeWith(*_type); } TypeOfField MEDCouplingField::getTypeOfField() const @@ -62,6 +91,17 @@ TypeOfField MEDCouplingField::getTypeOfField() const return _type->getEnum(); } +/*! + * This method retrieves the measure field of 'this'. If no '_mesh' is defined an exception will be thrown. + * Warning the retrieved field life cycle is the responsability of caller. + */ +MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception) +{ + if(_mesh==0) + throw INTERP_KERNEL::Exception("MEDCouplingField::getMeasureField : no mesh defined !!!"); + return _type->getMeasureField(_mesh,isAbs); +} + void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) { if(mesh!=_mesh) @@ -77,6 +117,126 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh) } } +/*! + * This method sets gauss localization by geometric type. + * @param type geometric type on which the gauss localization will be set. + * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType + * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType + * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. + * @throw when size of 'RefCoo' is not valid regarding 'type' parameter, it throws too when the mesh is not set before or if it is not a field on Gauss points. + */ +void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !"); + _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg); +} + +/*! + * This method sets on ids defined by [begin;end) their gauss localization. This method checks the coherency of cells ids in [begin;end) and 'refCoo' size. + * If an incoherence appears an exception will be thrown and no seting will be performed. + * An exception is thrown too if [begin,end) has a size lesser than 1. + * + * @param refCoo is the reference coordinates of the specified element. Its size has to be equal to nbOfNodesPerCell*dimOfType + * @param gsCoo are the coordinates of Gauss points in reference element specified by 'refCoo'. Its size must be equal to wg.size()*dimOfType + * @param wg are the weights on Gauss points. The size of this array is used to determine the number of Gauss point in the element. + * @throw when size of 'RefCoo' is not valid regarding cells in [begin,end) parameters, it throws too when the mesh is not set before or if it is not a field on Gauss points. + */ +void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !"); + _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg); +} + +/*! + * This method resets all Gauss loalizations if any. + */ +void MEDCouplingField::clearGaussLocalizations() +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling clearGaussLocalizations method !"); + _type->clearGaussLocalizations(); +} + +/*! + * This method returns reference to the Gauss localization object corresponding to 'locId' id. + * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by + * MEDCouplingField::getNbOfGaussLocalization method. + * Warning this method is not const, so the returned object could be modified without any problem. + */ +MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + return _type->getGaussLocalization(locId); +} + +/*! + * This method returns reference to the Gauss localization object corresponding to 'locId' id. + * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if several localization ids have been found + * for a type. + */ +int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneType method !"); + return _type->getGaussLocalizationIdOfOneType(type); +} + +/*! + * This method returns number of Gauss localization available. Implicitely all ids in [0,getNbOfGaussLocalization()) is a valid Gauss localisation id. + * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) + */ +int MEDCouplingField::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getNbOfGaussLocalization method !"); + return _type->getNbOfGaussLocalization(); +} + +/*! + * This method returns an id of Gauss localization in [0,getNbOfGaussLocalization()) that corresponds to the localization of the cell specified by its cellId. + * This methods throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) or if at the cell with id 'cellId' in this->_mesh no + * Gauss localization has been set. + */ +int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + return _type->getGaussLocalizationIdOfOneCell(cellId); +} + +/*! + * This method returns all cellIds that share the same Gauss localization given by 'locId' parameter (in range [0,getNbOfGaussLocalization()) ). + * If no cells fit the Gauss localization given by 'locId' cellIds will be returned empty. + * @param locId input that specifies the id of Gauss localization. + * @param cellIds output parameter, that will contain the result if this method succeds. This parameter is systematically cleared when called. + * @throw if there is no mesh, invalid FieldDescription (different from Gauss) or if locId not in [0,getNbOfGaussLocalization()) + */ +void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) +{ + cellIds.clear(); + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !"); + _type->getCellIdsHavingGaussLocalization(locId,cellIds); +} + +/*! + * This method returns reference to the Gauss localization object corresponding to 'locId' id. + * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss) and if 'locId' is invalid because out of range given by + * MEDCouplingField::getNbOfGaussLocalization method. + * Warning this method is const. + */ +const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !"); + return _type->getGaussLocalization(locId); +} + MEDCouplingField::~MEDCouplingField() { if(_mesh) @@ -84,11 +244,15 @@ MEDCouplingField::~MEDCouplingField() delete _type; } +MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type):_mesh(0),_type(type) +{ +} + MEDCouplingField::MEDCouplingField(TypeOfField type):_mesh(0),_type(MEDCouplingFieldDiscretization::New(type)) { } -MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._name),_desc(other._name), +MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._name),_desc(other._desc), _mesh(0),_type(other._type->clone()) { if(other._mesh) @@ -98,8 +262,11 @@ MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):_name(other._n } } - +/*! + * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). + * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh. + */ MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const { - return _type->buildSubMeshData(start,end,_mesh,di); + return _type->buildSubMeshData(_mesh,start,end,di); } diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx index 932c5d54c..e6eedb5bc 100644 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ b/src/MEDCoupling/MEDCouplingField.hxx @@ -23,22 +23,28 @@ #include "MEDCoupling.hxx" #include "MEDCouplingTimeLabel.hxx" #include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" #include "InterpKernelException.hxx" #include +#include namespace ParaMEDMEM { class DataArrayInt; class MEDCouplingMesh; + class MEDCouplingFieldDouble; class MEDCouplingFieldDiscretization; + class MEDCouplingGaussLocalization; class MEDCOUPLING_EXPORT MEDCouplingField : public RefCountObject, public TimeLabel { public: virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; - virtual bool areCompatible(const MEDCouplingField *other) const; + virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; + virtual bool areStrictlyCompatible(const MEDCouplingField *other) const; virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } void setName(const char *name) { _name=name; } @@ -46,13 +52,27 @@ namespace ParaMEDMEM void setDescription(const char *desc) { _desc=desc; } const char *getName() const { return _name.c_str(); } TypeOfField getTypeOfField() const; + MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } + // Gauss point specific methods + void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + void setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + void clearGaussLocalizations(); + MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); + void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); + const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); protected: void updateTime(); protected: MEDCouplingField(TypeOfField type); MEDCouplingField(const MEDCouplingField& other); + MEDCouplingField(MEDCouplingFieldDiscretization *type); virtual ~MEDCouplingField(); protected: std::string _name; diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx index 7e7c7b298..dfa7049cc 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -18,15 +18,16 @@ // #include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingPointSet.hxx" #include "MEDCouplingCMesh.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "CellModel.hxx" #include "InterpolationUtils.hxx" +#include #include #include -#include +#include using namespace ParaMEDMEM; @@ -40,6 +41,14 @@ const char MEDCouplingFieldDiscretizationP1::REPR[]="P1"; const TypeOfField MEDCouplingFieldDiscretizationP1::TYPE=ON_NODES; +const char MEDCouplingFieldDiscretizationGauss::REPR[]="GAUSS"; + +const TypeOfField MEDCouplingFieldDiscretizationGauss::TYPE=ON_GAUSS_PT; + +const char MEDCouplingFieldDiscretizationGaussNE::REPR[]="GSSNE"; + +const TypeOfField MEDCouplingFieldDiscretizationGaussNE::TYPE=ON_GAUSS_NE; + MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) { } @@ -52,6 +61,10 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField return new MEDCouplingFieldDiscretizationP0; case MEDCouplingFieldDiscretizationP1::TYPE: return new MEDCouplingFieldDiscretizationP1; + case MEDCouplingFieldDiscretizationGauss::TYPE: + return new MEDCouplingFieldDiscretizationGauss; + case MEDCouplingFieldDiscretizationGaussNE::TYPE: + return new MEDCouplingFieldDiscretizationGaussNE; default: throw INTERP_KERNEL::Exception("Choosen discretization is not implemented yet."); } @@ -64,9 +77,221 @@ TypeOfField MEDCouplingFieldDiscretization::getTypeOfFieldFromStringRepr(const c return MEDCouplingFieldDiscretizationP0::TYPE; if(reprCpp==MEDCouplingFieldDiscretizationP1::REPR) return MEDCouplingFieldDiscretizationP1::TYPE; + if(reprCpp==MEDCouplingFieldDiscretizationGauss::REPR) + return MEDCouplingFieldDiscretizationGauss::TYPE; + if(reprCpp==MEDCouplingFieldDiscretizationGaussNE::REPR) + return MEDCouplingFieldDiscretizationGaussNE::TYPE; throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !"); } +bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + return isEqual(other,eps); +} + +/*! + * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally. + */ +void MEDCouplingFieldDiscretization::updateTime() +{ +} + +/*! + * Computes normL1 of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingFieldDouble *vol=getMeasureField(mesh,true); + int nbOfCompo=arr->getNumberOfComponents(); + int nbOfElems=getNumberOfTuples(mesh); + std::fill(res,res+nbOfCompo,0.); + const double *arrPtr=arr->getConstPointer(); + const double *volPtr=vol->getArray()->getConstPointer(); + for(int i=0;idecrRef(); +} + +/*! + * Computes normL2 of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingFieldDouble *vol=getMeasureField(mesh,true); + int nbOfCompo=arr->getNumberOfComponents(); + int nbOfElems=getNumberOfTuples(mesh); + std::fill(res,res+nbOfCompo,0.); + const double *arrPtr=arr->getConstPointer(); + const double *volPtr=vol->getArray()->getConstPointer(); + for(int i=0;i(std::sqrt)); + vol->decrRef(); +} + +/*! + * Computes integral of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingFieldDouble *vol=getMeasureField(mesh,isWAbs); + int nbOfCompo=arr->getNumberOfComponents(); + int nbOfElems=getNumberOfTuples(mesh); + std::fill(res,res+nbOfCompo,0.); + const double *arrPtr=arr->getConstPointer(); + const double *volPtr=vol->getArray()->getConstPointer(); + double *tmp=new double[nbOfCompo]; + for (int i=0;i(),volPtr[i])); + std::transform(tmp,tmp+nbOfCompo,res,res,std::plus()); + } + delete [] tmp; + vol->decrRef(); +} + +void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const +{ + arr=0; +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const +{ +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const +{ +} + +void MEDCouplingFieldDiscretization::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) +{ + arr=0; +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::finishUnserialization(const std::vector& tinyInfo) +{ +} + +/*! + * This method is typically the first step of renumbering. The implementation is empty it is not a bug only gauss is impacted + * virtualy by this method. + */ +void MEDCouplingFieldDiscretization::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ +} + +double MEDCouplingFieldDiscretization::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, + int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("getIJK Invalid ! only for GaussPoint and GaussNE discretizations !"); +} + +void MEDCouplingFieldDiscretization::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::clearGaussLocalizations() throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::renumberEntitiesFromO2NArr(const int *old2NewPtr, DataArrayDouble *arr, const char *msg) +{ + int oldNbOfElems=arr->getNumberOfTuples(); + int nbOfComp=arr->getNumberOfComponents(); + int newNbOfTuples=(*std::max_element(old2NewPtr,old2NewPtr+oldNbOfElems))+1; + DataArrayDouble *arrCpy=arr->deepCopy(); + const double *ptSrc=arrCpy->getConstPointer(); + arr->reAlloc(newNbOfTuples); + double *ptToFill=arr->getPointer(); + std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits::max()); + for(int i=0;i=0)//if newNb<0 the node is considered as out. + { + if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to(),std::numeric_limits::max())) + ==ptToFill+(newNb+1)*nbOfComp) + std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp); + else + { + if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) + { + arrCpy->decrRef(); + std::ostringstream oss; + oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr + << " have been merged and " << msg << " field on them are different !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } + arrCpy->decrRef(); +} + +MEDCouplingFieldDiscretization::~MEDCouplingFieldDiscretization() +{ +} + TypeOfField MEDCouplingFieldDiscretizationP0::getEnum() const { return TYPE; @@ -82,7 +307,7 @@ const char *MEDCouplingFieldDiscretizationP0::getStringRepr() const return REPR; } -bool MEDCouplingFieldDiscretizationP0::isEqual(const MEDCouplingFieldDiscretization *other) const +bool MEDCouplingFieldDiscretizationP0::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const { const MEDCouplingFieldDiscretizationP0 *otherC=dynamic_cast(other); return otherC!=0; @@ -93,11 +318,34 @@ int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *m return mesh->getNumberOfCells(); } +void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + const int *array=old2NewBg; + if(check) + array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); + for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) + { + if(*it) + (*it)->renumberInPlace(array); + } + if(check) + delete [] array; +} + DataArrayDouble *MEDCouplingFieldDiscretizationP0::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const { return mesh->getBarycenterAndOwner(); } +void MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest) +{ + cellRest=DataArrayInt::New(); + cellRest->alloc(std::distance(partBg,partEnd),1); + std::copy(partBg,partEnd,cellRest->getPointer()); +} + void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) { } @@ -113,7 +361,7 @@ void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMe } } -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP0::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { return mesh->getMeasureField(isAbs); } @@ -138,20 +386,25 @@ void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr, /*! * Nothing to do. It's not a bug. */ -void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const +void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(const int *, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const { + renumberEntitiesFromO2NArr(old2New,arr,"Cell"); } /*! * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). - * @ param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh. + * @param di is an array returned that specifies entity ids (here cells ids) in mesh 'mesh' of entity in returned submesh. * Example : The first cell id of returned mesh has the (*di)[0] id in 'mesh' */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const +MEDCouplingMesh *MEDCouplingFieldDiscretizationP0::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const { - MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,false); + MEDCouplingMesh *ret=mesh->buildPart(start,end); di=DataArrayInt::New(); - di->alloc(end-start,1); + di->alloc(std::distance(start,end),1); int *pt=di->getPointer(); std::copy(start,end,pt); return ret; @@ -172,12 +425,20 @@ const char *MEDCouplingFieldDiscretizationP1::getStringRepr() const return REPR; } -bool MEDCouplingFieldDiscretizationP1::isEqual(const MEDCouplingFieldDiscretization *other) const +bool MEDCouplingFieldDiscretizationP1::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const { const MEDCouplingFieldDiscretizationP1 *otherC=dynamic_cast(other); return otherC!=0; } +/*! + * Nothing to do here. + */ +void MEDCouplingFieldDiscretizationP1::renumberArraysForCell(const MEDCouplingMesh *, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ +} + int MEDCouplingFieldDiscretizationP1::getNumberOfTuples(const MEDCouplingMesh *mesh) const { return mesh->getNumberOfNodes(); @@ -188,6 +449,12 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP1::getLocalizationOfDiscValues(c return mesh->getCoordinatesAndOwner(); } +void MEDCouplingFieldDiscretizationP1::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest) +{ + cellRest=mesh->getCellIdsFullyIncludedInNodeIds(partBg,partEnd); +} + void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) { if(nat!=ConservativeVolumic) @@ -200,12 +467,12 @@ void MEDCouplingFieldDiscretizationP1::checkCoherencyBetween(const MEDCouplingMe { std::ostringstream message; message << "Field on nodes invalid because there are " << mesh->getNumberOfNodes(); - message << " cells in mesh and " << da->getNumberOfTuples() << " tuples in field !"; + message << " nodes in mesh and " << da->getNumberOfTuples() << " tuples in field !"; throw INTERP_KERNEL::Exception(message.str().c_str()); } } -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const { return mesh->getMeasureFieldOnNode(isAbs); } @@ -252,64 +519,668 @@ void MEDCouplingFieldDiscretizationP1::getValueOnPos(const DataArrayDouble *arr, arr->getTuple(id,res); } -void MEDCouplingFieldDiscretizationP1::renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const +void MEDCouplingFieldDiscretizationP1::renumberValuesOnNodes(const int *old2NewPtr, DataArrayDouble *arr) const { - int oldNbOfElems=old2New->getNbOfElems(); - const int *old2NewPtr=old2New->getConstPointer(); - int nbOfComp=arr->getNumberOfComponents(); - int newNbOfTuples=(*std::max_element(old2NewPtr,old2NewPtr+oldNbOfElems))+1; - DataArrayDouble *arrCpy=arr->deepCopy(); - const double *ptSrc=arrCpy->getConstPointer(); - arr->reAlloc(newNbOfTuples); - double *ptToFill=arr->getPointer(); - std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits::max()); - for(int i=0;ibuildPartAndReduceNodes(start,end,di); + DataArrayInt *di2=di->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di->decrRef(); + di=di2; + return ret; +} + +MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) +{ +} + +MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell() +{ + if(_discr_per_cell) + _discr_per_cell->decrRef(); +} + +MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other):_discr_per_cell(0) +{ + DataArrayInt *arr=other._discr_per_cell; + if(arr) + _discr_per_cell=arr->deepCopy(); +} + +void MEDCouplingFieldDiscretizationPerCell::updateTime() +{ + if(_discr_per_cell) + updateTimeWith(*_discr_per_cell); +} + +void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has no discretization per cell !"); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + if(nbOfTuples!=mesh->getNumberOfCells()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell has a discretization per cell but it's not matching the underlying mesh !"); +} + +bool MEDCouplingFieldDiscretizationPerCell::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_discr_per_cell==0) + return otherC->_discr_per_cell==0; + if(otherC->_discr_per_cell==0) + return false; + return _discr_per_cell->isEqual(*otherC->_discr_per_cell); +} + +bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_discr_per_cell==0) + return otherC->_discr_per_cell==0; + if(otherC->_discr_per_cell==0) + return false; + return _discr_per_cell->isEqualWithoutConsideringStr(*otherC->_discr_per_cell); +} + +/*! + * This method is typically the first step of renumbering. The impact on _discr_per_cell is necessary here. + * virtualy by this method. + */ +void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + int nbCells=_discr_per_cell->getNumberOfTuples(); + const int *array=old2NewBg; + if(check) + array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+nbCells); + // + DataArrayInt *dpc=_discr_per_cell->renumber(array); + _discr_per_cell->decrRef(); + _discr_per_cell=dpc; + // + if(check) + delete [] (int *)array; +} + +void MEDCouplingFieldDiscretizationPerCell::buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m) +{ + if(!_discr_per_cell) { - int newNb=old2NewPtr[i]; - if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to(),std::numeric_limits::max())) - ==ptToFill+(newNb+1)*nbOfComp) - std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp); - else + _discr_per_cell=DataArrayInt::New(); + int nbTuples=m->getNumberOfCells(); + _discr_per_cell->alloc(nbTuples,1); + int *ptr=_discr_per_cell->getPointer(); + std::fill(ptr,ptr+nbTuples,-1); + } +} + +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss() +{ +} + +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other):MEDCouplingFieldDiscretizationPerCell(other),_loc(other._loc) +{ +} + +TypeOfField MEDCouplingFieldDiscretizationGauss::getEnum() const +{ + return TYPE; +} + +bool MEDCouplingFieldDiscretizationGauss::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!MEDCouplingFieldDiscretizationPerCell::isEqual(other,eps)) + return false; + if(_loc.size()!=otherC->_loc.size()) + return false; + int sz=_loc.size(); + for(int i=0;i_loc[i],eps)) + return false; + return true; +} + +bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(other,eps)) + return false; + if(_loc.size()!=otherC->_loc.size()) + return false; + int sz=_loc.size(); + for(int i=0;i_loc[i],eps)) + return false; + return true; +} + +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clone() const +{ + return new MEDCouplingFieldDiscretizationGauss(*this); +} + +const char *MEDCouplingFieldDiscretizationGauss::getStringRepr() const +{ + return REPR; +} + +int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const +{ + int ret=0; + const int *dcPtr=_discr_per_cell->getConstPointer(); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) + ret+=_loc[*w].getNumberOfGaussPt(); + return ret; +} + +void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + const int *array=old2NewBg; + if(check) + array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); + int nbOfCells=_discr_per_cell->getNumberOfTuples(); + int nbOfTuples=getNumberOfTuples(0); + const int *dcPtr=_discr_per_cell->getConstPointer(); + int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. + int *array3=new int[nbOfCells];//store for each cell in present dcp array (already renumbered) the offset needed by each cell in new numbering. + array3[0]=0; + for(int i=1;i::const_iterator it=arrays.begin();it!=arrays.end();it++) + if(*it) + (*it)->renumberInPlace(array2); + delete [] array2; + if(check) + delete [] (int*)array; +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +/*! + * Empty : not a bug + */ +void MEDCouplingFieldDiscretizationGauss::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) +{ +} + +void MEDCouplingFieldDiscretizationGauss::getTinySerializationIntInformation(std::vector& tinyInfo) const +{ + int val=-1; + if(_discr_per_cell) + val=_discr_per_cell->getNumberOfTuples(); + tinyInfo.push_back(val); + tinyInfo.push_back(_loc.size()); + if(_loc.empty()) + tinyInfo.push_back(-1); + else + tinyInfo.push_back(_loc[0].getDimension()); + for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).pushTinySerializationIntInfo(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::getTinySerializationDbleInformation(std::vector& tinyInfo) const +{ + for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).pushTinySerializationDblInfo(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::getSerializationIntArray(DataArrayInt *& arr) const +{ + arr=0; + if(_discr_per_cell) + arr=_discr_per_cell; +} + +void MEDCouplingFieldDiscretizationGauss::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) +{ + int val=tinyInfo[0]; + if(val>=0) + { + _discr_per_cell=DataArrayInt::New(); + _discr_per_cell->alloc(val,1); + } + else + _discr_per_cell=0; + arr=_discr_per_cell; + int nbOfLoc=tinyInfo[1]; + _loc.clear(); + int dim=tinyInfo[2]; + int delta=-1; + if(nbOfLoc>0) + delta=(tinyInfo.size()-3)/nbOfLoc; + for(int i=0;i tmp(tinyInfo.begin()+3+i*delta,tinyInfo.begin()+3+(i+1)*delta); + MEDCouplingGaussLocalization elt=MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo(dim,tmp); + _loc.push_back(elt); + } +} + +void MEDCouplingFieldDiscretizationGauss::finishUnserialization(const std::vector& tinyInfo) +{ + double *tmp=new double[tinyInfo.size()]; + std::copy(tinyInfo.begin(),tinyInfo.end(),tmp); + const double *work=tmp; + for(std::vector::iterator iter=_loc.begin();iter!=_loc.end();iter++) + work=(*iter).fillWithValues(work); + delete [] tmp; +} + +double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, + int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception) +{ + int offset=getOffsetOfCell(cellId); + return da->getIJ(offset+nodeIdInCell,compoId); +} + +void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(mesh,da); + for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).checkCoherency(); + int nbOfDesc=_loc.size(); + int nbOfCells=mesh->getNumberOfCells(); + const int *dc=_discr_per_cell->getConstPointer(); + for(int i=0;i=nbOfDesc) { - if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) - { - arrCpy->decrRef(); - std::ostringstream oss; - oss << "Node " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr - << " have been merged and nodal field on them are different !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has an undefined gauss location ! Should never happend !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(dc[i]<0) + { + std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has no gauss location !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(mesh->getTypeOfCell(i)!=_loc[dc[i]].getType()) + { + std::ostringstream oss; oss << "Types of mesh and gauss location mismatch for cell # " << i; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - arrCpy->decrRef(); + int nbOfTuples=getNumberOfTuples(mesh); + if(nbOfTuples!=da->getNumberOfTuples()) + { + std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); +} + +MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); } /*! - * This method invert array 'di' that is a conversion map from Old to New node numbering to New to Old node numbering. + * No implementation needed ! */ -DataArrayInt *MEDCouplingFieldDiscretizationP1::invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di) -{ - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(mesh->getNumberOfNodes(),1); - int nbOfOldNodes=di->getNumberOfTuples(); - const int *old2New=di->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i!=nbOfOldNodes;i++) - if(old2New[i]!=-1) - pt[old2New[i]]=i; +void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(const int *, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + buildDiscrPerCellIfNecessary(m); + int id=_loc.size(); + MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); + _loc.push_back(elt); + int *ptr=_discr_per_cell->getPointer(); + int nbCells=m->getNumberOfCells(); + for(int i=0;igetTypeOfCell(i)==type) + ptr[i]=id; + zipGaussLocalizations(); +} + +void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) +{ + buildDiscrPerCellIfNecessary(m); + if(std::distance(begin,end)<1) + throw INTERP_KERNEL::Exception("Size of [begin,end) must be equal or greater than 1 !"); + INTERP_KERNEL::NormalizedCellType type=m->getTypeOfCell(*begin); + MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); + int id=_loc.size(); + int *ptr=_discr_per_cell->getPointer(); + for(const int *w=begin+1;w!=end;w++) + { + if(m->getTypeOfCell(*w)!=type) + { + std::ostringstream oss; oss << "The cell with id " << *w << " has been detected to be incompatible in the [begin,end) array specified !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + // + for(const int *w2=begin;w2!=end;w2++) + ptr[*w2]=id; + // + _loc.push_back(elt); + zipGaussLocalizations(); +} + +void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() throw(INTERP_KERNEL::Exception) +{ + if(_discr_per_cell) + { + _discr_per_cell->decrRef(); + _discr_per_cell=0; + } + _loc.clear(); +} + +MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception) +{ + checkLocalizationId(locId); + return _loc[locId]; +} + +int MEDCouplingFieldDiscretizationGauss::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception) +{ + return _loc.size(); +} + +int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception) +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("No Gauss localization still set !"); + int locId=_discr_per_cell->getConstPointer()[cellId]; + if(locId<0) + throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); + return locId; +} + +int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("No Gauss localization still set !"); + std::set ret; + int id=0; + for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++) + if((*iter).getType()==type) + ret.insert(id); + if(ret.empty()) + throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !"); + if(ret.size()>1) + throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !"); + return *ret.begin(); +} + +void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception) +{ + if(locId<0 || locId>=(int)_loc.size()) + throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + const int *ptr=_discr_per_cell->getConstPointer(); + for(int i=0;i=(int)_loc.size()) + throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); +} + +int MEDCouplingFieldDiscretizationGauss::getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception) +{ + int ret=0; + const int *start=_discr_per_cell->getConstPointer(); + for(const int *w=start;w!=start+cellId;w++) + ret+=_loc[*w].getNumberOfGaussPt(); return ret; } /*! - * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end). -* @ param di is an array returned that specifies entity ids (here nodes ids) in mesh 'mesh' of entity in returned submesh. - * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh' + * This method makes the assumption that _discr_per_cell is set. + * This method reduces as much as possible number size of _loc. + * This method is usefull when several set on same cells has been done and that some Gauss Localization are no more used. */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationP1::buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const +void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations() { - MEDCouplingPointSet* ret=((const MEDCouplingPointSet *) mesh)->buildPartOfMySelf(start,end,true); - DataArrayInt *diInv=ret->zipCoordsTraducer(); - di=invertArrayO2N2N2O(ret,diInv); - diInv->decrRef(); + const int *start=_discr_per_cell->getConstPointer(); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + int *tmp=new int[_loc.size()]; + std::fill(tmp,tmp+_loc.size(),-2); + for(const int *w=start;w!=start+nbOfTuples;w++) + if(*w>=0) + tmp[*w]=1; + int fid=0; + for(int i=0;i<(int)_loc.size();i++) + if(tmp[i]!=-2) + tmp[i]=fid++; + if(fid==(int)_loc.size()) + {//no zip needed + delete [] tmp; + return; + } + // zip needed + int *start2=_discr_per_cell->getPointer(); + for(int *w2=start2;w2!=start2+nbOfTuples;w2++) + *w2=tmp[*w2]; + std::vector tmpLoc; + for(int i=0;i<(int)_loc.size();i++) + if(tmp[i]!=-2) + tmpLoc.push_back(_loc[tmp[i]]); + delete [] tmp; + _loc=tmpLoc; +} + +MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() +{ +} + +TypeOfField MEDCouplingFieldDiscretizationGaussNE::getEnum() const +{ + return TYPE; +} + +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGaussNE::clone() const +{ + return new MEDCouplingFieldDiscretizationGaussNE(*this); +} + +const char *MEDCouplingFieldDiscretizationGaussNE::getStringRepr() const +{ + return REPR; +} + +bool MEDCouplingFieldDiscretizationGaussNE::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationGaussNE *otherC=dynamic_cast(other); + return otherC!=0; +} + +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const +{ + int ret=0; + int nbOfCells=mesh->getNumberOfCells(); + for(int i=0;igetTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type); + if(cm.isDynamic()) + throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); + ret+=cm.getNumberOfNodes(); + } return ret; } + +void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + const int *array=old2NewBg; + if(check) + array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); + int nbOfCells=mesh->getNumberOfCells(); + int nbOfTuples=getNumberOfTuples(mesh); + int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. + int *array3=new int[nbOfCells];//store for each cell in after renumbering the offset needed by each cell in new numbering. + array3[0]=0; + for(int i=1;igetTypeOfCell(std::distance(array,std::find(array,array+nbOfCells,i-1))); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type); + array3[i]=array3[i-1]+cm.getNumberOfNodes(); + } + int j=0; + for(int i=0;igetTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type); + for(int k=0;k<(int)cm.getNumberOfNodes();k++,j++) + array2[j]=array3[array[i]]+k; + } + delete [] array3; + for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) + if(*it) + (*it)->renumberInPlace(array2); + delete [] array2; + if(check) + delete [] (int*)array; +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) +{ +} + +double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, + int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception) +{ + int offset=0; + for(int i=0;igetTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(type); + offset+=cm.getNumberOfNodes(); + } + return da->getIJ(offset+nodeIdInCell,compoId); +} + +void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) +{ + int nbOfTuples=getNumberOfTuples(mesh); + if(nbOfTuples!=da->getNumberOfTuples()) + { + std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); +} + +MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +/*! + * No implementation needed ! + */ +void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(const int *, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other) +{ +} + diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx index 25d52f542..316fa753d 100644 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -17,13 +17,17 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __MEDCOUPLINGFIELDDISCRETIZATION_HXX__ -#define __MEDCOUPLINGFIELDDISCRETIZATION_HXX__ +#ifndef __PARAMEDMEM_MEDCOUPLINGFIELDDISCRETIZATION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDDISCRETIZATION_HXX__ #include "MEDCoupling.hxx" #include "MEDCouplingRefCountObject.hxx" #include "InterpKernelException.hxx" +#include "MEDCouplingTimeLabel.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingGaussLocalization.hxx" + +#include namespace ParaMEDMEM { @@ -32,28 +36,58 @@ namespace ParaMEDMEM class DataArrayDouble; class MEDCouplingFieldDouble; - class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization + class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization : public TimeLabel { public: static MEDCouplingFieldDiscretization *New(TypeOfField type); double getPrecision() const { return _precision; } void setPrecision(double val) { _precision=val; } + void updateTime(); static TypeOfField getTypeOfFieldFromStringRepr(const char *repr) throw(INTERP_KERNEL::Exception); virtual TypeOfField getEnum() const = 0; - virtual bool isEqual(const MEDCouplingFieldDiscretization *other) const = 0; + virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const = 0; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; virtual MEDCouplingFieldDiscretization *clone() const = 0; virtual const char *getStringRepr() const = 0; virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; + virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception); + virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const throw(INTERP_KERNEL::Exception); + virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception); virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0; + virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest) = 0; virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception) = 0; + virtual void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) = 0; + virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception) = 0; - virtual MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; + virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0; virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0; - virtual MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const = 0; - virtual void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const = 0; + virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; + virtual void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const = 0; + virtual void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const = 0; + virtual void getSerializationIntArray(DataArrayInt *& arr) const; + virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; + virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; + virtual void finishUnserialization(const std::vector& tinyInfo); + virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); + virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + virtual void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); + virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); + virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); + virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); + virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + virtual void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); + virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); + virtual ~MEDCouplingFieldDiscretization(); protected: MEDCouplingFieldDiscretization(); + static void renumberEntitiesFromO2NArr(const int *old2NewPtr, DataArrayDouble *arr, const char *msg); protected: double _precision; static const double DFLT_PRECISION; @@ -65,16 +99,21 @@ namespace ParaMEDMEM TypeOfField getEnum() const; MEDCouplingFieldDiscretization *clone() const; const char *getStringRepr() const; - bool isEqual(const MEDCouplingFieldDiscretization *other) const; + bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest); void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const; - MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const; + void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const; + void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const; + MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; public: static const char REPR[]; static const TypeOfField TYPE; @@ -86,17 +125,127 @@ namespace ParaMEDMEM TypeOfField getEnum() const; MEDCouplingFieldDiscretization *clone() const; const char *getStringRepr() const; - bool isEqual(const MEDCouplingFieldDiscretization *other) const; + bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest); + void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const; + void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const; + public: + static const char REPR[]; + static const TypeOfField TYPE; + }; + + /*! + * This class abstracts MEDCouplingFieldDiscretization that needs an information on each cell to perform their job. + * All classes that inherits from this are more linked to mesh. + */ + class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization + { + protected: + MEDCouplingFieldDiscretizationPerCell(); + MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other); + ~MEDCouplingFieldDiscretizationPerCell(); + void updateTime(); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; + void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + protected: + void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *m); + protected: + DataArrayInt *_discr_per_cell; + }; + + class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell + { + public: + MEDCouplingFieldDiscretizationGauss(); + TypeOfField getEnum() const; + bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; + MEDCouplingFieldDiscretization *clone() const; + const char *getStringRepr() const; int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest); void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); + void getTinySerializationIntInformation(std::vector& tinyInfo) const; + void getTinySerializationDbleInformation(std::vector& tinyInfo) const; + void finishUnserialization(const std::vector& tinyInfo); + void getSerializationIntArray(DataArrayInt *& arr) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); + double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, const MEDCouplingMesh *mesh, DataArrayInt *&di) const; - void renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const; - static DataArrayInt *invertArrayO2N2N2O(const MEDCouplingMesh *mesh, const DataArrayInt *di); + MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const; + void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const; + void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); + MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); + int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const throw(INTERP_KERNEL::Exception); + const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); + protected: + MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other); + void zipGaussLocalizations(); + int getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception); + void checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception); + public: + static const char REPR[]; + static const TypeOfField TYPE; + private: + std::vector _loc; + }; + + /*! + * Gauss with points of values located on nodes of element. This is a specialization of MEDCouplingFieldDiscretizationGauss. + */ + class MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization + { + public: + MEDCouplingFieldDiscretizationGaussNE(); + TypeOfField getEnum() const; + MEDCouplingFieldDiscretization *clone() const; + const char *getStringRepr() const; + bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, + const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *partBg, const int *partEnd, + DataArrayInt *&cellRest); + void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); + double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + void renumberValuesOnNodes(const int *old2New, DataArrayDouble *arr) const; + void renumberValuesOnCells(const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const; + protected: + MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other); public: static const char REPR[]; static const TypeOfField TYPE; diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index fcbfd84f7..2c62b3f44 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -18,11 +18,14 @@ // #include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingPointSet.hxx" +#include "MEDCouplingUMesh.hxx" #include "MEDCouplingTimeDiscretization.hxx" #include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingNatureOfField.hxx" #include +#include #include using namespace ParaMEDMEM; @@ -37,16 +40,93 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::clone(bool recDeepCpy) const return new MEDCouplingFieldDouble(*this,recDeepCpy); } +MEDCouplingFieldDouble *MEDCouplingFieldDouble::cloneWithMesh(bool recDeepCpy) const +{ + MEDCouplingFieldDouble *ret=clone(recDeepCpy); + if(_mesh) + { + MEDCouplingMesh *mCpy=_mesh->deepCpy(); + ret->setMesh(mCpy); + mCpy->decrRef(); + } + return ret; +} + MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const { MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(_time_discr,td,deepCpy); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,getTypeOfField()); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),tdo,_type->clone()); ret->setMesh(getMesh()); ret->setName(getName()); ret->setDescription(getDescription()); return ret; } +/*! + * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason). + */ +void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception) +{ + if(other) + { + setName(other->_name.c_str()); + setDescription(other->_desc.c_str()); + _time_discr->copyTinyStringsFrom(*other->_time_discr); + } +} + +std::string MEDCouplingFieldDouble::simpleRepr() const +{ + std::ostringstream ret; + ret << "FieldDouble with name : \"" << getName() << "\"\n"; + ret << "Description of field is : \"" << getDescription() << "\"\n"; + ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; + ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; + ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n"; + if(getArray()) + { + int nbOfCompo=getArray()->getNumberOfComponents(); + ret << "FieldDouble default array has " << nbOfCompo << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; + ret << "FieldDouble default array has following info on components : "; + for(int i=0;igetInfoOnComponent(i) << "\" "; + ret << "\n"; + } + if(_mesh) + ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); + else + ret << "Mesh support information : No mesh set !\n"; + return ret.str(); +} + +std::string MEDCouplingFieldDouble::advancedRepr() const +{ + std::ostringstream ret; + ret << "FieldDouble with name : \"" << getName() << "\"\n"; + ret << "Description of field is : \"" << getDescription() << "\"\n"; + ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n"; + ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n"; + if(getArray()) + ret << "FieldDouble default array has " << getArray()->getNumberOfComponents() << " components and " << getArray()->getNumberOfTuples() << " tuples.\n"; + if(_mesh) + ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); + else + ret << "Mesh support information : No mesh set !\n"; + std::vector arrays; + _time_discr->getArrays(arrays); + int arrayId=0; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++) + { + ret << "Array #" << arrayId << " :\n__________\n"; + if(*iter) + (*iter)->reprWithoutNameStream(ret); + else + ret << "Array empty !"; + ret << "\n"; + } + return ret.str(); +} + bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const { const MEDCouplingFieldDouble *otherC=dynamic_cast(other); @@ -61,9 +141,28 @@ bool MEDCouplingFieldDouble::isEqual(const MEDCouplingField *other, double meshP return true; } -bool MEDCouplingFieldDouble::areCompatible(const MEDCouplingField *other) const +bool MEDCouplingFieldDouble::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const { - if(!MEDCouplingField::areCompatible(other)) + const MEDCouplingFieldDouble *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_nature!=otherC->_nature) + return false; + if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) + return false; + if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec)) + return false; + return true; +} + +/*! + * This method states if 'this' and 'other' are compatibles each other before performing any treatment. + * This method is good for methods like : mergeFields. + * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. + */ +bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const +{ + if(!MEDCouplingField::areCompatibleForMerge(other)) return false; const MEDCouplingFieldDouble *otherC=dynamic_cast(other); if(!otherC) @@ -75,20 +174,167 @@ bool MEDCouplingFieldDouble::areCompatible(const MEDCouplingField *other) const return true; } +/*! + * This method is more strict than MEDCouplingField::areCompatibleForMerge method. + * This method is used for operation on fields to operate a first check before attempting operation. + */ +bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const +{ + if(!MEDCouplingField::areStrictlyCompatible(other)) + return false; + const MEDCouplingFieldDouble *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_nature!=otherC->_nature) + return false; + if(!_time_discr->areStrictlyCompatible(otherC->_time_discr)) + return false; + return true; +} + +/*! + * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that + * number of components between 'this' and 'other' can be different here (for operator*). + */ bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const { - if(!MEDCouplingField::areCompatible(other)) + if(!MEDCouplingField::areStrictlyCompatible(other)) return false; const MEDCouplingFieldDouble *otherC=dynamic_cast(other); if(!otherC) return false; if(_nature!=otherC->_nature) return false; - if(!_time_discr->areCompatibleForMul(otherC->_time_discr)) + if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr)) return false; return true; } +/*! + * This method performs a clone of mesh and a renumbering of underlying cells of it. The number of cells remains the same. + * The values of field are impacted in consequence to have the same geometrical field. + */ +void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + renumberCellsWithoutMesh(old2NewBg,check); + MEDCouplingAutoRefCountObjectPtr m=_mesh->deepCpy(); + m->renumberCells(old2NewBg,check); + setMesh(m); + updateTime(); +} + +/*! + * \b WARNING : use this method with lot of care ! + * This method performs half job of MEDCouplingFieldDouble::renumberCells. That is to say no permutation of cells is done on underlying mesh. + * That is to say, the field content is changed by this method. The reason of this method is only for multi-field instances lying on the same mesh to + * avoid a systematic duplication and renumbering of _mesh attribute. + */ +void MEDCouplingFieldDouble::renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("Expecting a defined mesh to be able to operate a renumbering !"); + // + _type->renumberCells(old2NewBg,check); + std::vector arrays; + _time_discr->getArrays(arrays); + _type->renumberArraysForCell(_mesh,arrays,old2NewBg,check); + // + updateTime(); +} + +/*! + * This method performs a clone of mesh and a renumbering of underlying nodes of it. The number of nodes remains not compulsory the same as renumberCells method. + * The values of field are impacted in consequence to have the same geometrical field. + */ +void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !"); + int nbOfNodes=meshC->getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + renumberNodesWithoutMesh(old2NewBg); + meshC2->renumberNodes(old2NewBg,*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1); + setMesh(meshC2); +} + +/*! + * \b WARNING : use this method with lot of care ! + * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh. + * That is to say, the field content is changed by this method. + */ +void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg) throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + _time_discr->getArrays(arrays); + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(old2NewBg,*iter); +} + +/*! + * This method makes the assumption that the default array is set. If not an exception will be thrown. + * This method is usable only if the default array has exactly one component. If not an exception will be thrown too. + * This method returns all tuples ids that fit the range [vmin,vmax]. + * The caller has the responsability of the returned DataArrayInt. + */ +DataArrayInt *MEDCouplingFieldDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception) +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !"); + return getArray()->getIdsInRange(vmin,vmax); +} + +/*! + * Builds a newly created field, that the caller will have the responsability. + * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. + * This method returns a restriction of 'this' so that only tuples id specified in 'part' will be contained in returned field. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception) +{ + if(part==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); + const int *start=part->getConstPointer(); + const int *end=start+part->getNbOfElems(); + return buildSubPart(start,end); +} + +/*! + * Builds a newly created field, that the caller will have the responsability. + * This method makes the assumption that the field is correctly defined when this method is called, no check of this will be done. + * This method returns a restriction of 'this' so that only tuples id specified in ['partBg';'partEnd') will be contained in returned field. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *cellRest; + _type->computeMeshRestrictionFromTupleIds(_mesh,partBg,partEnd,cellRest); + DataArrayInt *arrSelect; + MEDCouplingMesh *m=_type->buildSubMeshData(_mesh,cellRest->getConstPointer(),cellRest->getConstPointer()+cellRest->getNbOfElems(),arrSelect); + if(cellRest) + cellRest->decrRef(); + MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy. + ret->setMesh(m); + m->decrRef(); + std::vector arrays; + _time_discr->getArrays(arrays); + std::vector arrs; + const int *arrSelBg=arrSelect->getConstPointer(); + const int *arrSelEnd=arrSelBg+arrSelect->getNbOfElems(); + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + DataArrayDouble *arr=0; + if(*iter) + arr=(*iter)->selectByTupleId(arrSelBg,arrSelEnd); + arrs.push_back(arr); + } + ret->_time_discr->setArrays(arrs,0); + for(std::vector::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) + if(*iter) + (*iter)->decrRef(); + arrSelect->decrRef(); + return ret; +} + TypeOfTimeDiscretization MEDCouplingFieldDouble::getTimeDiscretization() const { return _time_discr->getEnum(); @@ -104,8 +350,8 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& oth { } -MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, TypeOfField type):MEDCouplingField(type), - _nature(n),_time_discr(td) +MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type), + _nature(n),_time_discr(td) { } @@ -118,37 +364,259 @@ void MEDCouplingFieldDouble::checkCoherency() const throw(INTERP_KERNEL::Excepti { if(!_mesh) throw INTERP_KERNEL::Exception("Field invalid because no mesh specified !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("Field invalid because no values set !"); + _time_discr->checkCoherency(); _type->checkCoherencyBetween(_mesh,getArray()); } /*! - * Returns the accumulation (the sum) of comId_th component of each tuples of default array. + * Returns the accumulation (the sum) of comId_th component of each tuples of \b default and \b only \b default array. */ double MEDCouplingFieldDouble::accumulate(int compId) const { - const double *ptr=getArray()->getConstPointer(); - int nbTuple=getArray()->getNumberOfTuples(); + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); + return getArray()->accumulate(compId); +} + +/*! + * Returns the accumulation (the sum) of all tuples of \b default and \b only default array. + * The res is expected to be of size getNumberOfComponents(). + */ +void MEDCouplingFieldDouble::accumulate(double *res) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); + getArray()->accumulate(res); +} + +/*! + * This method returns the max value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown. + * To getMaxValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'. + * If no arrays exists, an exception will be thrown. + */ +double MEDCouplingFieldDouble::getMaxValue() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits::max(); + bool isExistingArr=false; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + int loc; + ret=std::max(ret,(*iter)->getMaxValue(loc)); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !"); + return ret; +} + +/*! + * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMaxValue method because the returned + * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility + * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array. + * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used + * to compute tupleIds. + */ +double MEDCouplingFieldDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits::max(); + bool isExistingArr=false; + tupleIds=0; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + DataArrayInt *tmp; + ret=std::max(ret,(*iter)->getMaxValue2(tmp)); + if(!tupleIds) + tupleIds=tmp; + else + tmp->decrRef(); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !"); + return ret; +} + +/*! + * This method returns the min value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown. + * To getMinValue on vector field applyFunc is needed before. This method looks only on all arrays stored in 'this->_time_discr'. + * If no arrays exists, an exception will be thrown. + */ +double MEDCouplingFieldDouble::getMinValue() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + _time_discr->getArrays(arrays); + double ret=std::numeric_limits::max(); + bool isExistingArr=false; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + int loc; + ret=std::min(ret,(*iter)->getMinValue(loc)); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !"); + return ret; +} + +/*! + * This method is an extension of ParaMEDMEM::MEDCouplingFieldDouble::getMinValue method because the returned + * value is the same but this method also returns to you a tupleIds object which the caller have the responsibility + * to deal with. The main difference is that the returned tupleIds is those corresponding the first set array. + * If you have more than one array set (in LINEAR_TIME instance for example) only the first not null array will be used + * to compute tupleIds. + */ +double MEDCouplingFieldDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits::max(); + bool isExistingArr=false; + tupleIds=0; + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + DataArrayInt *tmp; + ret=std::max(ret,(*iter)->getMinValue2(tmp)); + if(!tupleIds) + tupleIds=tmp; + else + tmp->decrRef(); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !"); + return ret; +} + +/*! + * This method returns the average value in 'this'. 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown. + * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. + * If default array does not exist, an exception will be thrown. + */ +double MEDCouplingFieldDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !"); + return getArray()->getAverageValue(); +} + +/*! + * This method returns the average value in 'this' weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField. + * 'This' is expected to be a field with exactly \b one component. If not an exception will be thrown. + * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default. + * If default array does not exist, an exception will be thrown. + */ +double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception) +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); + MEDCouplingFieldDouble *w=buildMeasureField(true); + double deno=w->getArray()->accumulate(0); + w->getArray()->multiplyEqual(getArray()); + double res=w->getArray()->accumulate(0); + w->decrRef(); + return res/deno; +} + +/*! + * Returns the normL1 of current field on compId component : + * \f[ + * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} + * \f] + * If compId>=nbOfComponent an exception is thrown. + */ +double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); int nbComps=getArray()->getNumberOfComponents(); - double ret=0.; - for(int i=0;i=nbComps) + throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); + double *res=new double[nbComps]; + try + { + _type->normL1(_mesh,getArray(),res); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] res; + throw e; + } + double ret=res[compId]; + delete [] res; return ret; } /*! - * Returns the accumulation (the sum) of all tuples of default array. + * Returns the normL1 of current field on each components : + * \f[ + * \frac{\sum_{0 \leq i < nbOfEntity}|val[i]*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|} + * \f] * The res is expected to be of size getNumberOfComponents(). */ -void MEDCouplingFieldDouble::accumulate(double *res) const +void MEDCouplingFieldDouble::normL1(double *res) const throw(INTERP_KERNEL::Exception) { - const double *ptr=getArray()->getConstPointer(); - int nbTuple=getArray()->getNumberOfTuples(); + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1"); + _type->normL1(_mesh,getArray(),res); +} + +/*! + * Returns the normL2 of current field on compId component : + * \f[ + * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} + * \f] + * If compId>=nbOfComponent an exception is thrown. + */ +double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); int nbComps=getArray()->getNumberOfComponents(); - std::fill(res,res+nbComps,0.); - for(int i=0;i()); + if(compId>=nbComps) + throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); + double *res=new double[nbComps]; + try + { + _type->normL2(_mesh,getArray(),res); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] res; + throw e; + } + double ret=res[compId]; + delete [] res; + return ret; +} + +/*! + * Returns the normL2 of current field on each components : + * \f[ + * \sqrt{\frac{\sum_{0 \leq i < nbOfEntity}|val[i]^{2}*Vol[i]|}{\sum_{0 \leq i < nbOfEntity}|Vol[i]|}} + * \f] + * The res is expected to be of size getNumberOfComponents(). + */ +void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2"); + _type->normL2(_mesh,getArray(),res); } /*! @@ -156,17 +624,25 @@ void MEDCouplingFieldDouble::accumulate(double *res) const * returns by getWeightingField relative of the _type of field of default array. * This method is usefull to check the conservativity of interpolation method. */ -double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const +double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception) { if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform measureAccumulate"); - MEDCouplingFieldDouble *weight=_type->getWeightingField(_mesh,isWAbs); - const double *ptr=weight->getArray()->getConstPointer(); - int nbOfValues=weight->getArray()->getNbOfElems(); - double ret=0.; - for (int i=0; idecrRef(); + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral"); + int nbComps=getArray()->getNumberOfComponents(); + if(compId>=nbComps) + throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !"); + double *res=new double[nbComps]; + try + { + _type->integral(_mesh,getArray(),isWAbs,res); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] res; + throw e; + } + double ret=res[compId]; + delete [] res; return ret; } @@ -175,24 +651,11 @@ double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const * returns by getWeightingField relative of the _type of field of default array. * This method is usefull to check the conservativity of interpolation method. */ -void MEDCouplingFieldDouble::measureAccumulate(bool isWAbs, double *res) const +void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception) { if(!_mesh) - throw INTERP_KERNEL::Exception("No mesh underlying this field to perform measureAccumulate2"); - MEDCouplingFieldDouble *weight=_type->getWeightingField(_mesh,isWAbs); - const double *ptr=weight->getArray()->getConstPointer(); - int nbOfValues=weight->getArray()->getNbOfElems(); - int nbComps=getArray()->getNumberOfComponents(); - const double *vals=getArray()->getConstPointer(); - std::fill(res,res+nbComps,0.); - double *tmp=new double[nbComps]; - for (int i=0; i(),ptr[i])); - std::transform(tmp,tmp+nbComps,res,res,std::plus()); - } - weight->decrRef(); - delete [] tmp; + throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral2"); + _type->integral(_mesh,getArray(),isWAbs,res); } /*! @@ -242,6 +705,46 @@ void MEDCouplingFieldDouble::applyLin(double a, double b, int compoId) _time_discr->applyLin(a,b,compoId); } +/*! + * This method sets 'this' to a uniform scalar field with one component. + * All tuples will have the same value 'value'. + * An exception is thrown if no underlying mesh is defined. + */ +MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::operator= : no mesh defined !"); + int nbOfTuple=_type->getNumberOfTuples(_mesh); + _time_discr->setUniformValue(nbOfTuple,1,value); + return *this; +} + +/*! + * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic. + * The main difference is that the field as been started to be constructed here. + * An exception is throw if no underlying mesh is set before the call of this method. + */ +void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); + MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic(loc,nbOfComp,func); +} + +/*! + * This method is very similar to this one MEDCouplingMesh::fillFromAnalytic. + * The main difference is that the field as been started to be constructed here. + * An exception is throw if no underlying mesh is set before the call of this method. + */ +void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::fillFromAnalytic : no mesh defined !"); + MEDCouplingAutoRefCountObjectPtr loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic(loc,nbOfComp,func); +} + /*! * Applyies the function specified by pointer 'func' on each tuples on all arrays contained in _time_discr. * If '*func' returns false during one evaluation an exception will be thrown. @@ -251,6 +754,18 @@ void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) _time_discr->applyFunc(nbOfComp,func); } +/*! + * This method is a specialization of other overloaded methods. When 'nbOfComp' equals 1 this method is equivalent to + * ParaMEDMEM::MEDCouplingFieldDouble::operator=. + */ +void MEDCouplingFieldDouble::applyFunc(int nbOfComp, double val) +{ + if(!_mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::applyFunc : no mesh defined !"); + int nbOfTuple=_type->getNumberOfTuples(_mesh); + _time_discr->setUniformValue(nbOfTuple,nbOfComp,val); +} + /*! * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. * If '*func' fails in evaluation during one evaluation an exception will be thrown. @@ -271,11 +786,45 @@ void MEDCouplingFieldDouble::applyFunc(const char *func) _time_discr->applyFunc(func); } -int MEDCouplingFieldDouble::getNumberOfComponents() const +/*! + * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. + * The field will contain exactly the same number of components after the call. + * Use is not warranted for the moment ! + */ +void MEDCouplingFieldDouble::applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception) { + _time_discr->applyFuncFast32(func); +} + +/*! + * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. + * The field will contain exactly the same number of components after the call. + * Use is not warranted for the moment ! + */ +void MEDCouplingFieldDouble::applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception) +{ + _time_discr->applyFuncFast64(func); +} + +/*! + * This method makes the assumption that the default array has been set before. + * If not an exception will be sent. + * If default array set, the number of components will be sent. + */ +int MEDCouplingFieldDouble::getNumberOfComponents() const throw(INTERP_KERNEL::Exception) +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !"); return getArray()->getNumberOfComponents(); } +/*! + * This method makes the assumption that _mesh has be set before the call of this method and description of gauss + * localizations in case of Gauss field. If not an exception will sent. + * \b Contrary to MEDCouplingFieldDouble::getNumberOfComponents and MEDCouplingFieldDouble::getNumberOfValues is + * \b not aware of the presence of the default array. + * \b WARNING \b no coherency check is done here. MEDCouplingFieldDouble::checkCoherency method should be called to check that ! + */ int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Exception) { if(!_mesh) @@ -283,6 +832,18 @@ int MEDCouplingFieldDouble::getNumberOfTuples() const throw(INTERP_KERNEL::Excep return _type->getNumberOfTuples(_mesh); } +/*! + * This method makes the assumption that the default array has been set before. + * If not an exception will be sent. + * If default array set, the number of values present in the default array will be sent. + */ +int MEDCouplingFieldDouble::getNumberOfValues() const throw(INTERP_KERNEL::Exception) +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !"); + return getArray()->getNbOfElems(); +} + void MEDCouplingFieldDouble::updateTime() { MEDCouplingField::updateTime(); @@ -295,11 +856,21 @@ void MEDCouplingFieldDouble::setNature(NatureOfField nat) throw(INTERP_KERNEL::E _nature=nat; } +double MEDCouplingFieldDouble::getIJK(int cellId, int nodeIdInCell, int compoId) const +{ + return _type->getIJK(_mesh,getArray(),cellId,nodeIdInCell,compoId); +} + void MEDCouplingFieldDouble::setArray(DataArrayDouble *array) { _time_discr->setArray(array,this); } +void MEDCouplingFieldDouble::setEndArray(DataArrayDouble *array) +{ + _time_discr->setEndArray(array,this); +} + void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const { tinyInfo.clear(); @@ -320,6 +891,10 @@ void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector tinyInfo.push_back((int)_time_discr->getEnum()); tinyInfo.push_back((int)_nature); _time_discr->getTinySerializationIntInformation(tinyInfo); + std::vector tinyInfo2; + _type->getTinySerializationIntInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.push_back(tinyInfo2.size()); } /*! @@ -330,25 +905,45 @@ void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vectorgetTinySerializationDbleInformation(tinyInfo); + std::vector tinyInfo2; + _type->getTinySerializationDbleInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.push_back(tinyInfo2.size()); } /*! * This method has to be called to the new instance filled by CORBA, MPI, File... * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied. + * @param dataInt out parameter. If not null the pointer is already owned by 'this' after the call of this method. In this case no decrRef must be applied. * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by 'this' after the call of this method. * No decrRef must be applied to every instances in returned vector. */ -void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) +void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays) { - std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); + dataInt=0; + std::vector tinyInfoITmp(tinyInfoI); + int sz=tinyInfoITmp.back(); + tinyInfoITmp.pop_back(); + std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); + std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); _time_discr->resizeForUnserialization(tinyInfoI2,arrays); + std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); + _type->resizeForUnserialization(tinyInfoITmp3,dataInt); } void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) { std::vector tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); - _time_discr->finishUnserialization(tinyInfoI2,tinyInfoD,tinyInfoS); + // + std::vector tmp(tinyInfoD); + int sz=tinyInfoD.back(); + tmp.pop_back(); + std::vector tmp1(tmp.begin(),tmp.end()-sz); + std::vector tmp2(tmp.end()-sz,tmp.end()); + // + _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); _nature=(NatureOfField)tinyInfoI[2]; + _type->finishUnserialization(tmp2); int nbOfElemS=tinyInfoS.size(); _name=tinyInfoS[nbOfElemS-2]; _desc=tinyInfoS[nbOfElemS-1]; @@ -358,48 +953,251 @@ void MEDCouplingFieldDouble::finishUnserialization(const std::vector& tinyI * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. * The values returned must be consulted only in readonly mode. */ -void MEDCouplingFieldDouble::serialize(std::vector& arrays) const +void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector& arrays) const { _time_discr->getArrays(arrays); + _type->getSerializationIntArray(dataInt); +} + +/*! + * This method tries to to change the mesh support of 'this' following the parameter 'levOfCheck' and 'prec'. + * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. This method is used to perform the job. + * If this->_mesh is not defined or other an exeption will be throw. + */ +void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) +{ + if(_mesh==0 || other==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !"); + DataArrayInt *cellCor,*nodeCor; + _mesh->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor); + if(cellCor) + { + renumberCellsWithoutMesh(cellCor->getConstPointer(),false); + cellCor->decrRef(); + } + if(nodeCor) + { + renumberNodesWithoutMesh(nodeCor->getConstPointer()); + nodeCor->decrRef(); + } + setMesh((MEDCouplingMesh *)other); } /*! - * \b Warning ! This method potentially modifies the underlying mesh ! If the mesh is shared by other fields, these fields could be unavailable. + * This method is an extension of MEDCouplingFieldDouble::operator-=. It allows a user to operate a difference of 2 fields ('this' and 'f') even if they do not share same meshes. + * No interpolation will be done here only an analyze of two underlying mesh will be done to see if the meshes are geometrically equivalent. If yes, the eventual renumbering will be done and operator-= applyed after. + * This method requires that 'f' and 'this' are coherent (check coherency) and that 'f' and 'this' would be coherent for a merge. + * Semantic of 'levOfCheck' is explained in MEDCouplingMesh::checkGeoEquivalWith method. */ -bool MEDCouplingFieldDouble::mergeNodes(double eps) +void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception) { - MEDCouplingPointSet *meshC=dynamic_cast((MEDCouplingMesh *)(_mesh)); + checkCoherency(); + f->checkCoherency(); + if(!areCompatibleForMerge(f)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::diffWith : Fields are not compatible ; unable to apply mergeFields on them !"); + changeUnderlyingMesh(f->getMesh(),levOfCheck,prec); + operator-=(*f); +} + +/*! + * Merge nodes of underlying mesh. In case of some node will be merged the underlying mesh instance will change. + */ +bool MEDCouplingFieldDouble::mergeNodes(double eps) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); if(!meshC) - throw INTERP_KERNEL::Exception("Invalid mesh to apply mergeNodes on it !"); + throw INTERP_KERNEL::Exception("Invalid support mesh to apply mergeNodes on it : must be a MEDCouplingPointSet one !"); + MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); bool ret; - DataArrayInt *arr=meshC->mergeNodes(eps,ret); + int ret2; + MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret,ret2); if(!ret)//no nodes have been merged. return ret; std::vector arrays; _time_discr->getArrays(arrays); - try + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(arr->getConstPointer(),*iter); + setMesh(meshC2); + return true; +} + +/*! + * This method applyies ParaMEDMEM::MEDCouplingPointSet::zipCoords method on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingPointSet. + * If some nodes have disappeared true is returned. + */ +bool MEDCouplingFieldDouble::zipCoords() throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + int oldNbOfNodes=meshC2->getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipCoordsTraducer(); + if(meshC2->getNumberOfNodes()!=oldNbOfNodes) { + std::vector arrays; + _time_discr->getArrays(arrays); for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - _type->renumberValuesOnNodes(arr,*iter); + if(*iter) + _type->renumberValuesOnNodes(arr->getConstPointer(),*iter); + setMesh(meshC2); + return true; } - catch(INTERP_KERNEL::Exception& e) + return false; +} + +/*! + * This method applyies ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer on 'this->_mesh' that should be set and of type ParaMEDMEM::MEDCouplingUMesh. + * The semantic of 'compType' is given in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method. + */ +bool MEDCouplingFieldDouble::zipConnectivity(int compType) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::zipCoords : Invalid support mesh to apply zipCoords on it : must be a MEDCouplingPointSet one !"); + MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingUMesh *)meshC->deepCpy()); + int oldNbOfCells=meshC2->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr arr=meshC2->zipConnectivityTraducer(compType); + if(meshC2->getNumberOfCells()!=oldNbOfCells) { - arr->decrRef(); - throw e; + std::vector arrays; + _time_discr->getArrays(arrays); + for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnCells(meshC,arr->getConstPointer(),*iter); + setMesh(meshC2); + return true; } - arr->decrRef(); - return true; + return false; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->doublyContractedProduct(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("DoublyContractedProduct"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::determinant() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->determinant(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Determinant"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenValues() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->eigenValues(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("EigenValues"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::eigenVectors() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->eigenVectors(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("EigenVectors"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::inverse() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->inverse(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Inversion"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::trace() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->trace(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Trace"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::deviator() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->deviator(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Trace"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::magnitude() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->magnitude(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Magnitude"); + ret->setMesh(getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxPerTuple() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->maxPerTuple(); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + std::ostringstream oss; + oss << "Max_" << getName(); + ret->setName(oss.str().c_str()); + ret->setMesh(getMesh()); + return ret; +} + +void MEDCouplingFieldDouble::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception) +{ + _time_discr->changeNbOfComponents(newNbOfComp,dftValue); +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization *td=_time_discr->keepSelectedComponents(compoIds); + td->copyTinyAttrFrom(*_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName(getName()); + ret->setMesh(getMesh()); + return ret; +} + +void MEDCouplingFieldDouble::setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) +{ + _time_discr->setSelectedComponents(f->_time_discr,compoIds); +} + +void MEDCouplingFieldDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) +{ + _time_discr->sortPerTuple(asc); } MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { - if(!f1->areCompatible(f2)) + if(!f1->areCompatibleForMerge(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply mergeFields on them !"); const MEDCouplingMesh *m1=f1->getMesh(); const MEDCouplingMesh *m2=f2->getMesh(); MEDCouplingMesh *m=m1->mergeMyselfWith(m2); MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField()); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(m); m->decrRef(); ret->setName(f1->getName()); @@ -407,38 +1205,86 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::mergeFields(const MEDCouplingFie return ret; } +MEDCouplingFieldDouble *MEDCouplingFieldDouble::dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + if(!f1->areStrictlyCompatible(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply dotFields on them !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + if(!f1->areStrictlyCompatible(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply crossProductFields on them !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + if(!f1->areStrictlyCompatible(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply maxFields on them !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + if(!f1->areStrictlyCompatible(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply minFields on them !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + return ret; +} + MEDCouplingFieldDouble *MEDCouplingFieldDouble::addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { - if(!f1->areCompatible(f2)) + if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply addFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField()); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); return ret; } -void MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other) { - if(!areCompatible(&other)) + if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !"); _time_discr->addEqual(other._time_discr); + return *this; } MEDCouplingFieldDouble *MEDCouplingFieldDouble::substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { - if(!f1->areCompatible(f2)) + if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply substractFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField()); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); return ret; } -void MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other) { - if(!areCompatible(&other)) + if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !"); _time_discr->substractEqual(other._time_discr); + return *this; } MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) @@ -446,31 +1292,35 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::multiplyFields(const MEDCoupling if(!f1->areCompatibleForMul(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply multiplyFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField()); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); return ret; } -void MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) { if(!areCompatibleForMul(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !"); _time_discr->multiplyEqual(other._time_discr); + return *this; } MEDCouplingFieldDouble *MEDCouplingFieldDouble::divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) { - if(!f1->areCompatible(f2)) + if(!f1->areStrictlyCompatible(f2)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply divideFields on them !"); MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->getTypeOfField()); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); ret->setMesh(f1->getMesh()); return ret; } -void MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other) { - if(!areCompatible(&other)) + if(!areStrictlyCompatible(&other)) throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !"); _time_discr->divideEqual(other._time_discr); + return *this; } diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index bffdc3e17..48c0bace0 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -32,64 +32,123 @@ namespace ParaMEDMEM { public: static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME); + void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + std::string advancedRepr() const; bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - bool areCompatible(const MEDCouplingField *other) const; + bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + bool areCompatibleForMerge(const MEDCouplingField *other) const; + bool areStrictlyCompatible(const MEDCouplingField *other) const; bool areCompatibleForMul(const MEDCouplingField *other) const; + void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + void renumberCellsWithoutMesh(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); + void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception); + void renumberNodesWithoutMesh(const int *old2NewBg) throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *clone(bool recDeepCpy) const; + MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const; TypeOfTimeDiscretization getTimeDiscretization() const; void checkCoherency() const throw(INTERP_KERNEL::Exception); NatureOfField getNature() const { return _nature; } void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception); - void setTime(double val, int dt, int it) { _time_discr->setTime(val,dt,it); } - void setStartTime(double val, int dt, int it) { _time_discr->setStartTime(val,dt,it); } - void setEndTime(double val, int dt, int it) { _time_discr->setEndTime(val,dt,it); } - double getTime(int& dt, int& it) const { return _time_discr->getTime(dt,it); } - double getStartTime(int& dt, int& it) const { return _time_discr->getStartTime(dt,it); } - double getEndTime(int& dt, int& it) const { return _time_discr->getEndTime(dt,it); } + void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } + void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } + void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } + double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } + double getStartTime(int& iteration, int& order) const { return _time_discr->getStartTime(iteration,order); } + double getEndTime(int& iteration, int& order) const { return _time_discr->getEndTime(iteration,order); } double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); } + double getIJK(int cellId, int nodeIdInCell, int compoId) const; void setArray(DataArrayDouble *array); + void setEndArray(DataArrayDouble *array); DataArrayDouble *getArray() const { return _time_discr->getArray(); } + DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); } double accumulate(int compId) const; void accumulate(double *res) const; - double measureAccumulate(int compId, bool isWAbs) const; - void measureAccumulate(bool isWAbs, double *res) const; + double getMaxValue() const throw(INTERP_KERNEL::Exception); + double getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); + double getMinValue() const throw(INTERP_KERNEL::Exception); + double getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); + double getAverageValue() const throw(INTERP_KERNEL::Exception); + double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception); + double normL1(int compId) const throw(INTERP_KERNEL::Exception); + void normL1(double *res) const throw(INTERP_KERNEL::Exception); + double normL2(int compId) const throw(INTERP_KERNEL::Exception); + void normL2(double *res) const throw(INTERP_KERNEL::Exception); + double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); + void integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception); void getValueOnPos(int i, int j, int k, double *res) const throw(INTERP_KERNEL::Exception); void getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception); void getValueOn(const double *spaceLoc, double time, double *res) const throw(INTERP_KERNEL::Exception); //! \b temporary void applyLin(double a, double b, int compoId); + MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); void applyFunc(int nbOfComp, FunctionToEvaluate func); + void applyFunc(int nbOfComp, double val); void applyFunc(int nbOfComp, const char *func); void applyFunc(const char *func); - int getNumberOfComponents() const; + void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception); + void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); + int getNumberOfValues() const throw(INTERP_KERNEL::Exception); void updateTime(); // void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; void getTinySerializationStrInformation(std::vector& tinyInfo) const; - void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); + void resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays); void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - void serialize(std::vector& arrays) const; - bool mergeNodes(double eps); + void serialize(DataArrayInt *&dataInt, std::vector& arrays) const; + // + void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception); + bool zipCoords() throw(INTERP_KERNEL::Exception); + bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); + void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return dotFields(this,&other); } + static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return crossProductFields(this,&other); } + static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return maxFields(this,&other); } + static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return minFields(this,&other); } MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const { return addFields(this,&other); } - void operator+=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other); static MEDCouplingFieldDouble *addFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const { return substractFields(this,&other); } - void operator-=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other); static MEDCouplingFieldDouble *substractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const { return multiplyFields(this,&other); } - void operator*=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other); static MEDCouplingFieldDouble *multiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const { return divideFields(this,&other); } - void operator/=(const MEDCouplingFieldDouble& other); + const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other); static MEDCouplingFieldDouble *divideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); private: MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCpy); - MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, TypeOfField type); + MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); ~MEDCouplingFieldDouble(); private: NatureOfField _nature; diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx new file mode 100644 index 000000000..68c9a0611 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx @@ -0,0 +1,215 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingGaussLocalization.hxx" +#include "CellModel.hxx" + +#include +#include +#include +#include + +ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception) +try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w) + { + checkCoherency(); + } +catch(INTERP_KERNEL::Exception& e) + { + _type=INTERP_KERNEL::NORM_ERROR; + _ref_coord.clear(); + _gauss_coord.clear(); + _weight.clear(); + throw e; + } + +void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type); + int nbNodes=cm.getNumberOfNodes(); + int dim=cm.getDimension(); + if(!cm.isDynamic()) + { + if((int)_ref_coord.size()!=nbNodes*dim) + { + std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(_gauss_coord.size()!=dim*_weight.size()) + { + std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const +{ + if(_weight.empty()) + return -1; + return _gauss_coord.size()/_weight.size(); +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const +{ + int dim=getDimension(); + if(dim==0) + return -1; + return _ref_coord.size()/dim; +} + +bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const +{ + if(_type!=other._type) + return false; + if(!areAlmostEqual(_ref_coord,other._ref_coord,eps)) + return false; + if(!areAlmostEqual(_gauss_coord,other._gauss_coord,eps)) + return false; + if(!areAlmostEqual(_weight,other._weight,eps)) + return false; + return true; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type); + int nbNodes=cm.getNumberOfNodes(); + int dim=cm.getDimension(); + if(ptIdInCell<0 || ptIdInCell>=nbNodes) + throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + return _ref_coord[ptIdInCell*dim+comp]; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception) +{ + int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); + return _gauss_coord[gaussPtIdInCell*dim+comp]; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception) +{ + checkCoherencyOfRequest(gaussPtIdInCell,0); + return _weight[gaussPtIdInCell]; +} + +/*! + * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. + * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same. + * @param tinyInfo inout parameter. + */ +void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector& tinyInfo) const +{ + tinyInfo.push_back((int)_type); + tinyInfo.push_back(getNumberOfPtsInRefCell()); + tinyInfo.push_back(getNumberOfGaussPt()); +} + +/*! + * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. + * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo. + * @param tinyInfo inout parameter. + */ +void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector& tinyInfo) const +{ + tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end()); + tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end()); + tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end()); +} + +/*! + * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process. + * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method. + * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method. + * This method returns the pointer 'vals' with an offset of size what it has been read in this method. + */ +const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals) +{ + const double *work=vals; + std::copy(work,work+_ref_coord.size(),_ref_coord.begin()); + work+=_ref_coord.size(); + std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin()); + work+=_gauss_coord.size(); + std::copy(work,work+_weight.size(),_weight.begin()); + work+=_weight.size(); + return work; +} + +/*! + * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type. + * @throw if not 0<=ptIdInCell=nbNodes) + throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + _ref_coord[ptIdInCell*dim+comp]=newVal; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception) +{ + int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); + _gauss_coord[gaussPtIdInCell*dim+comp]=newVal; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception) +{ + checkCoherencyOfRequest(gaussPtIdInCell,0); + _weight[gaussPtIdInCell]=newVal; +} + +/*! + * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo. + */ +ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData) +{ + std::vector v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]); + return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3); +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(_type); + int dim=cm.getDimension(); + int nbGsPts=getNumberOfGaussPt(); + if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts) + throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + return dim; +} + +bool ParaMEDMEM::MEDCouplingGaussLocalization::areAlmostEqual(const std::vector& v1, const std::vector& v2, double eps) +{ + int sz=v1.size(); + if(sz!=(int)v2.size()) + return false; + std::vector tmp(sz); + std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus()); + std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun(fabs)); + return *std::max_element(tmp.begin(),tmp.end()) + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + + class MEDCOUPLING_EXPORT MEDCouplingGaussLocalization + { + public: + MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& w) throw(INTERP_KERNEL::Exception); + INTERP_KERNEL::NormalizedCellType getType() const { return _type; } + int getNumberOfGaussPt() const { return _weight.size(); } + int getDimension() const; + int getNumberOfPtsInRefCell() const; + void checkCoherency() const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; + void pushTinySerializationIntInfo(std::vector& tinyInfo) const; + void pushTinySerializationDblInfo(std::vector& tinyInfo) const; + const double *fillWithValues(const double *vals); + // + const std::vector& getRefCoords() const { return _ref_coord; } + double getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception); + const std::vector& getGaussCoords() const { return _gauss_coord; } + double getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception); + const std::vector& getWeights() const { return _weight; } + double getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception); + void setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); + void setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception); + void setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception); + // + static MEDCouplingGaussLocalization buildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData); + private: + int checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception); + static bool areAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); + private: + INTERP_KERNEL::NormalizedCellType _type; + std::vector _ref_coord; + std::vector _gauss_coord; + std::vector _weight; + }; +} + +#endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 3456e329b..5365cb97c 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -18,9 +18,18 @@ // #include "MEDCouplingMemArray.txx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "GenMathFormulae.hxx" +#include "InterpKernelExprParser.hxx" + +#include +#include +#include #include +typedef double (*MYFUNCPTR)(double); + using namespace ParaMEDMEM; void DataArray::setName(const char *name) @@ -36,6 +45,36 @@ void DataArray::copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL:: _info_on_compo=other._info_on_compo; } +void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) +{ + int nbOfCompoOth=other.getNumberOfComponents(); + int newNbOfCompo=compoIds.size(); + for(int i=0;i=nbOfCompoOth) + { + std::ostringstream oss; oss << "Specified component ids is to high (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception) +{ + int nbOfCompo=getNumberOfComponents(); + int partOfCompoToSet=compoIds.size(); + if(partOfCompoToSet!=other.getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !"); + for(int i=0;i=nbOfCompo) + { + std::ostringstream oss; oss << "Specified component ids is to high (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++) + stream << "\"" << *iter << "\" "; + stream << "\n"; +} + +std::string DataArray::getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception) +{ + if(i<(int)_info_on_compo.size()) + return _info_on_compo[i]; + else + { + std::ostringstream oss; oss << "getInfoOnComponent : Invalid component id transmitted (" << i << ") >= " << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception) +{ + if(i<(int)_info_on_compo.size()) + _info_on_compo[i]=info; + else + { + std::ostringstream oss; oss << "setInfoOnComponent : Invalid component id transmitted (" << i << ") >= " << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + DataArrayDouble *DataArrayDouble::New() { return new DataArrayDouble; @@ -74,6 +144,58 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) declareAsNew(); } +void DataArrayDouble::fillWithZero() +{ + _mem.fillWithValue(0.); + declareAsNew(); +} + +void DataArrayDouble::fillWithValue(double val) +{ + _mem.fillWithValue(val); + declareAsNew(); +} + +std::string DataArrayDouble::repr() const +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayDouble::reprZip() const +{ + std::ostringstream ret; + reprZipStream(ret); + return ret.str(); +} + +void DataArrayDouble::reprStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayDouble::reprZipStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(15); + _mem.repr(getNumberOfComponents(),stream); +} + +void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(15); + _mem.reprZip(getNumberOfComponents(),stream); +} + bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const { if(!areInfoEquals(other)) @@ -81,6 +203,11 @@ bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const return _mem.isEqual(other._mem,prec); } +bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const +{ + return _mem.isEqual(other._mem,prec); +} + void DataArrayDouble::reAlloc(int nbOfTuples) { _mem.reAlloc(_info_on_compo.size()*nbOfTuples); @@ -88,6 +215,220 @@ void DataArrayDouble::reAlloc(int nbOfTuples) declareAsNew(); } +DataArrayInt *DataArrayDouble::convertToIntArr() const +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(getNumberOfTuples(),getNumberOfComponents()); + int nbOfVals=getNbOfElems(); + const double *src=getConstPointer(); + int *dest=ret->getPointer(); + std::copy(src,src+nbOfVals,dest); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This method does \b not change the number of tuples after this call. + * Only a permutation is done. If a permutation reduction is needed substr, or selectByTupleId should be used. + */ +void DataArrayDouble::renumberInPlace(const int *old2New) +{ + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + double *tmp=new double[nbTuples*nbOfCompo]; + const double *iptr=getConstPointer(); + for(int i=0;ialloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret; +} + +/*! + * This method does \b not change the number of tuples after this call. + * Only a permutation is done. + */ +DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const +{ + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret; +} + +/*! + * Idem DataArrayDouble::renumber method except that the number of tuples is reduced. + * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). + * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'+getNumberOfTuples()) the corresponding tuple is + * omitted. + */ +DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const +{ + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(newNbOfTuple,nbOfCompo); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;i=0) + std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); + } + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. + * This method is equavalent to DataArrayDouble::renumberAndReduce except that convention in input is new2old and \b not old2new. + */ +DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const +{ + DataArrayDouble *ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + double *pt=ret->getPointer(); + const double *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components. + * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept. + * This method check that interval is valid regarding this, if not an exception will be thrown. + */ +DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) +{ + int nbt=getNumberOfTuples(); + if(tupleIdBg<0) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); + if(tupleIdBg>=nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + int trueEnd=tupleIdEnd; + if(tupleIdEnd!=-1) + { + if(tupleIdEnd>nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + } + else + trueEnd=nbt; + int nbComp=getNumberOfComponents(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(trueEnd-tupleIdBg,nbComp); + ret->copyStringInfoFrom(*this); + std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); + return ret; +} + +/*! + * This method builds a new instance of DataArrayDouble (to deal with) that is reduction or an extension of 'this'. + * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. + * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + */ +DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception) +{ + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(getNumberOfTuples(),newNbOfComp); + const double *oldc=getConstPointer(); + double *nc=ret->getPointer(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + int dim=std::min(oldNbOfComp,newNbOfComp); + for(int i=0;isetName(getName().c_str()); + for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); + ret->setName(getName().c_str()); + return ret; +} + +DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); + int newNbOfCompo=compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + ret->alloc(nbOfTuples,newNbOfCompo); + ret->copyPartOfStringInfoFrom(*this,compoIds); + const double *oldc=getConstPointer(); + double *nc=ret->getPointer(); + for(int i=0;iincrRef(); + return ret; +} + +void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) +{ + copyPartOfStringInfoFrom2(compoIds,*a); + int partOfCompoSz=compoIds.size(); + int nbOfCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + const double *ac=a->getConstPointer(); + double *nc=getPointer(); + for(int i=0;i 0 !"); + const double *vals=getConstPointer(); + const double *loc=std::max_element(vals,vals+nbOfTuples); + tupleId=std::distance(vals,loc); + return *loc; +} + +double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) +{ + int tmp; + tupleIds=0; + double ret=getMaxValue(tmp); + tupleIds=getIdsInRange(ret,ret); + return ret; +} + +double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception) +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); + const double *vals=getConstPointer(); + const double *loc=std::min_element(vals,vals+nbOfTuples); + tupleId=std::distance(vals,loc); + return *loc; +} + +double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception) +{ + int tmp; + tupleIds=0; + double ret=getMinValue(tmp); + tupleIds=getIdsInRange(ret,ret); + return ret; +} + +double DataArrayDouble::getAverageValue() const throw(INTERP_KERNEL::Exception) +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !"); + const double *vals=getConstPointer(); + double ret=std::accumulate(vals,vals+nbOfTuples,0.); + return ret/nbOfTuples; +} + +void DataArrayDouble::accumulate(double *res) const +{ + const double *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + std::fill(res,res+nbComps,0.); + for(int i=0;i()); +} + +double DataArrayDouble::accumulate(int compId) const +{ + const double *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + if(compId>=nbComps) + throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !"); + double ret=0.; + for(int i=0;ialloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;ialloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + switch(getNumberOfComponents()) + { + case 6: + for(int i=0;idecrRef(); + throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !"); + } +} + +DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception) +{ + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=6) + throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,3); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;ialloc(nbOfTuple,9); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;ialloc(nbOfTuple,nbOfComp); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); +if(nbOfComp==6) + for(int i=0;ialloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + if(nbOfComp==6) + for(int i=0;ialloc(nbOfTuple,6); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;ialloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;ialloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i()); + declareAsNew(); +} + +void DataArrayDouble::applyLin(double a, double b, int compoId) +{ + double *ptr=getPointer()+compoId; + int nbOfComp=getNumberOfComponents(); + int nbOfTuple=getNumberOfTuples(); + for(int i=0;ialloc(nbOfTuples,nbOfComp); + const double *ptr=getConstPointer(); + double *ptrToFill=newArr->getPointer(); + for(int i=0;i(oss,", ")); + oss << ") : Evaluation of function failed !"; + newArr->decrRef(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return newArr; +} + +DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception) +{ + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + std::set vars; + expr.getTrueSetOfVars(vars); + int oldNbOfComp=getNumberOfComponents(); + if((int)vars.size()>oldNbOfComp) + { + std::ostringstream oss; oss << "The field has a " << oldNbOfComp << " components and there are "; + oss << vars.size() << " variables : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector varsV(vars.begin(),vars.end()); + expr.prepareExprEvaluation(varsV); + // + DataArrayDouble *newArr=DataArrayDouble::New(); + int nbOfTuples=getNumberOfTuples(); + newArr->alloc(nbOfTuples,nbOfComp); + const double *ptr=getConstPointer(); + double *ptrToFill=newArr->getPointer(); + for(int i=0;i(oss,", ")); + oss << ") : Evaluation of function failed !" << e.what(); + newArr->decrRef(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return newArr; +} + +DataArrayDouble *DataArrayDouble::applyFunc(const char *func) const throw(INTERP_KERNEL::Exception) +{ + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + expr.prepareExprEvaluationVec(); + // + DataArrayDouble *newArr=DataArrayDouble::New(); + int nbOfTuples=getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + newArr->alloc(nbOfTuples,nbOfComp); + const double *ptr=getConstPointer(); + double *ptrToFill=newArr->getPointer(); + for(int i=0;i(oss,", ")); + oss << ") : Evaluation of function failed ! " << e.what(); + newArr->decrRef(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return newArr; +} + +void DataArrayDouble::applyFuncFast32(const char *func) +{ + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + char *funcStr=expr.compileX86(); + MYFUNCPTR funcPtr=(MYFUNCPTR)funcStr;//he he... + // + double *ptr=getPointer(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + int nbOfElems=nbOfTuples*nbOfComp; + for(int i=0;i res; + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i=vmin && *cptr<=vmax) + res.push_back(i); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(res.size(),1); + std::copy(res.begin(),res.end(),ret->getPointer()); + return ret; +} + +DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { int nbOfComp=a1->getNumberOfComponents(); if(nbOfComp!=a2->getNumberOfComponents()) @@ -132,7 +916,97 @@ DataArrayDouble *DataArrayDouble::aggregate(const DataArrayDouble *a1, const Dat return ret; } -DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArrayDouble *a2) +DataArrayDouble *DataArrayDouble::dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array dot !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array dot !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,1); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + for(int i=0;isetInfoOnComponent(0,a1->getInfoOnComponent(0).c_str()); + ret->setName(a1->getName().c_str()); + return ret; +} + +DataArrayDouble *DataArrayDouble::crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !"); + if(nbOfComp!=3) + throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,3); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + for(int i=0;icopyStringInfoFrom(*a1); + return ret; +} + +DataArrayDouble *DataArrayDouble::max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array max !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array max !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + int nbElem=nbOfTuple*nbOfComp; + for(int i=0;icopyStringInfoFrom(*a1); + return ret; +} + +DataArrayDouble *DataArrayDouble::min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) +{ + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + int nbElem=nbOfTuple*nbOfComp; + for(int i=0;icopyStringInfoFrom(*a1); + return ret; +} + +DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { int nbOfComp=a1->getNumberOfComponents(); if(nbOfComp!=a2->getNumberOfComponents()) @@ -147,7 +1021,7 @@ DataArrayDouble *DataArrayDouble::add(const DataArrayDouble *a1, const DataArray return ret; } -void DataArrayDouble::addEqual(const DataArrayDouble *other) +void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { int nbOfComp=getNumberOfComponents(); if(nbOfComp!=other->getNumberOfComponents()) @@ -159,7 +1033,7 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other) declareAsNew(); } -DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const DataArrayDouble *a2) +DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { int nbOfComp=a1->getNumberOfComponents(); if(nbOfComp!=a2->getNumberOfComponents()) @@ -174,7 +1048,7 @@ DataArrayDouble *DataArrayDouble::substract(const DataArrayDouble *a1, const Dat return ret; } -void DataArrayDouble::substractEqual(const DataArrayDouble *other) +void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { int nbOfComp=getNumberOfComponents(); if(nbOfComp!=other->getNumberOfComponents()) @@ -186,7 +1060,7 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) declareAsNew(); } -DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) +DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { int nbOfTuple=a1->getNumberOfTuples(); int nbOfTuple2=a2->getNumberOfTuples(); @@ -233,7 +1107,7 @@ DataArrayDouble *DataArrayDouble::multiply(const DataArrayDouble *a1, const Data return ret; } -void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) +void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { int nbOfTuple=getNumberOfTuples(); int nbOfTuple2=other->getNumberOfTuples(); @@ -241,11 +1115,8 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) int nbOfComp2=other->getNumberOfComponents(); if(nbOfTuple!=nbOfTuple2) throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array multiplyEqual !"); - DataArrayDouble *ret=0; if(nbOfComp==nbOfComp2) { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); std::transform(getConstPointer(),getConstPointer()+nbOfTuple*nbOfComp,other->getConstPointer(),getPointer(),std::multiplies()); } else @@ -263,7 +1134,7 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) declareAsNew(); } -DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataArrayDouble *a2) +DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception) { int nbOfComp=a1->getNumberOfComponents(); if(nbOfComp!=a2->getNumberOfComponents()) @@ -278,7 +1149,7 @@ DataArrayDouble *DataArrayDouble::divide(const DataArrayDouble *a1, const DataAr return ret; } -void DataArrayDouble::divideEqual(const DataArrayDouble *other) +void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) { int nbOfComp=getNumberOfComponents(); if(nbOfComp!=other->getNumberOfComponents()) @@ -319,6 +1190,98 @@ void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) declareAsNew(); } +void DataArrayInt::fillWithZero() +{ + _mem.fillWithValue(0); + declareAsNew(); +} + +void DataArrayInt::fillWithValue(int val) +{ + _mem.fillWithValue(val); + declareAsNew(); +} + +std::string DataArrayInt::repr() const +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayInt::reprZip() const +{ + std::ostringstream ret; + reprZipStream(ret); + return ret.str(); +} + +void DataArrayInt::reprStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayInt::reprZipStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + _mem.repr(getNumberOfComponents(),stream); +} + +void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + _mem.reprZip(getNumberOfComponents(),stream); +} + +void DataArrayInt::transformWithIndArr(const int *indArr) +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component !"); + int nbOfTuples=getNumberOfTuples(); + int *pt=getPointer(); + for(int i=0;ialloc(newNbOfElem,1); + int nbOfOldNodes=getNumberOfTuples(); + const int *old2New=getConstPointer(); + int *pt=ret->getPointer(); + for(int i=0;i!=nbOfOldNodes;i++) + if(old2New[i]!=-1) + pt[old2New[i]]=i; + return ret; +} + +/*! + * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering. + */ +DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(oldNbOfElem,1); + const int *new2Old=getConstPointer(); + int *pt=ret->getPointer(); + std::fill(pt,pt+oldNbOfElem,-1); + int nbOfNewElems=getNumberOfTuples(); + for(int i=0;ialloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret; +} + +DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const +{ + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;icopyStringInfoFrom(*this); + return ret; +} + +/*! + * Idem DataArrayDouble::renumber method except that the number of tuples is reduced. + * That is to say that it is expected that newNbOfTuplegetNumberOfTuples(). + * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is + * omitted. + */ +DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const +{ + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(newNbOfTuple,nbOfCompo); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;i=0) + std::copy(iptr+i*nbOfCompo,iptr+(i+1)*nbOfCompo,optr+w*nbOfCompo); + } + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here. + * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new. + */ +DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const +{ + DataArrayInt *ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + ret->alloc(std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + int *pt=ret->getPointer(); + const int *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This method checks that 'this' is with numberofcomponents == 1 and that it is equal to + * stdext::iota() of size getNumberOfTuples. This method is particalary usefull for DataArrayInt instances + * that represents a renumbering array to check the real need in renumbering. + */ +bool DataArrayInt::isIdentity() const +{ + if(getNumberOfComponents()!=1) + return false; + int nbOfTuples=getNumberOfTuples(); + const int *pt=getConstPointer(); + for(int i=0;ialloc(getNumberOfTuples(),getNumberOfComponents()); + int nbOfVals=getNbOfElems(); + const int *src=getConstPointer(); + double *dest=ret->getPointer(); + std::copy(src,src+nbOfVals,dest); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * This methods has a similar behaviour than std::string::substr. This method returns a newly created DataArrayInt that is part of this with same number of components. + * The intervall is specified by [tupleIdBg,tupleIdEnd) except if tupleIdEnd ==-1 in this case the [tupleIdBg,this->end()) will be kept. + * This method check that interval is valid regarding this, if not an exception will be thrown. + */ +DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception) +{ + int nbt=getNumberOfTuples(); + if(tupleIdBg<0) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); + if(tupleIdBg>=nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + int trueEnd=tupleIdEnd; + if(tupleIdEnd!=-1) + { + if(tupleIdEnd>nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + } + else + trueEnd=nbt; + int nbComp=getNumberOfComponents(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(trueEnd-tupleIdBg,nbComp); + ret->copyStringInfoFrom(*this); + std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); + return ret; +} + +/*! + * This method builds a new instance of DataArrayInt (to deal with) that is reduction or an extension of 'this'. + * if 'newNbOfComp' < this->getNumberOfComponents() a reduction is done and for each tuple 'newNbOfComp' first components are kept. + * If 'newNbOfComp' > this->getNumberOfComponents() an extension is done, and for each components i such that i > getNumberOfComponents() 'dftValue' parameter is taken. + */ +DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception) +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(getNumberOfTuples(),newNbOfComp); + const int *oldc=getConstPointer(); + int *nc=ret->getPointer(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + int dim=std::min(oldNbOfComp,newNbOfComp); + for(int i=0;isetName(getName().c_str()); + for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i).c_str()); + ret->setName(getName().c_str()); + return ret; +} + void DataArrayInt::reAlloc(int nbOfTuples) { _mem.reAlloc(_info_on_compo.size()*nbOfTuples); @@ -341,6 +1494,36 @@ void DataArrayInt::reAlloc(int nbOfTuples) declareAsNew(); } +DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); + int newNbOfCompo=compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + ret->alloc(nbOfTuples,newNbOfCompo); + ret->copyPartOfStringInfoFrom(*this,compoIds); + const int *oldc=getConstPointer(); + int *nc=ret->getPointer(); + for(int i=0;iincrRef(); + return ret; +} + +void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) +{ + copyPartOfStringInfoFrom2(compoIds,*a); + int partOfCompoSz=compoIds.size(); + int nbOfCompo=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + const int *ac=a->getConstPointer(); + int *nc=getPointer(); + for(int i=0;i& groups, int newNb, std::vector< std::vector >& fidsOfGroups) +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(newNb,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+newNb,0); + int fid=1; + for(std::vector::const_iterator iter=groups.begin();iter!=groups.end();iter++) + { + const int *ptr=(*iter)->getConstPointer(); + int nbOfElem=(*iter)->getNbOfElems(); + int sfid=fid; + for(int j=0;j::const_iterator iter=groups.begin();iter!=groups.end();iter++,grId++) + { + std::set tmp; + const int *ptr=(*iter)->getConstPointer(); + int nbOfElem=(*iter)->getNbOfElems(); + for(const int *p=ptr;p!=ptr+nbOfElem;p++) + tmp.insert(retPtr[*p]); + fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end()); + } + return ret; +} + int *DataArrayInt::checkAndPreparePermutation(const int *start, const int *end) { int sz=std::distance(start,end); diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 74d165bb9..0f5d600d9 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -27,6 +27,7 @@ #include #include +#include namespace ParaMEDMEM { @@ -60,6 +61,9 @@ namespace ParaMEDMEM T operator[](int id) const { return _pointer.getConstPointer()[id]; } T& operator[](int id) { return _pointer.getPointer()[id]; } bool isEqual(const MemArray& other, T prec) const; + void repr(int sl, std::ostream& stream) const; + void reprZip(int sl, std::ostream& stream) const; + void fillWithValue(const T& val); void alloc(int nbOfElements); void reAlloc(int newNbOfElements); void useArray(const T *array, bool ownership, DeallocType type, int nbOfElem); @@ -72,7 +76,6 @@ namespace ParaMEDMEM int _nb_of_elem; bool _ownership; MEDCouplingPointer _pointer; - //T *_pointer; DeallocType _dealloc; }; @@ -81,10 +84,14 @@ namespace ParaMEDMEM public: MEDCOUPLING_EXPORT void setName(const char *name); MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const { return _info_on_compo[i]; } - MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) { _info_on_compo[i]=info; } + MEDCOUPLING_EXPORT const std::vector &getInfoOnComponent() const { return _info_on_compo; } + MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const char *info) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT int getNumberOfComponents() const { return _info_on_compo.size(); } MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; } MEDCOUPLING_EXPORT int getNbOfElems() const { return _info_on_compo.size()*_nb_of_tuples; } @@ -101,6 +108,7 @@ namespace ParaMEDMEM namespace ParaMEDMEM { + class DataArrayInt; class DataArrayDouble : public DataArray { public: @@ -108,27 +116,75 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *deepCopy() const; MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo); + MEDCOUPLING_EXPORT void fillWithZero(); + MEDCOUPLING_EXPORT void fillWithValue(double val); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const; //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); + MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); + MEDCOUPLING_EXPORT DataArrayDouble *renumber(const int *old2New) const; + MEDCOUPLING_EXPORT DataArrayDouble *renumberR(const int *new2Old) const; + MEDCOUPLING_EXPORT DataArrayDouble *renumberAndReduce(const int *old2New, int newNbOfTuple) const; + MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } MEDCOUPLING_EXPORT double *getPointer() const { return _mem.getPointer(); } MEDCOUPLING_EXPORT static void setArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet); MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); } MEDCOUPLING_EXPORT void useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void writeOnPlace(int id, double element0, const double *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT void checkNoNullValues() const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *add(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *substract(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *multiply(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *divide(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT double getAverageValue() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void accumulate(double *res) const; + MEDCOUPLING_EXPORT double accumulate(int compId) const; + MEDCOUPLING_EXPORT DataArrayDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *determinant() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *eigenValues() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *inverse() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *trace() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const char *func) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void applyFuncFast32(const char *func); + MEDCOUPLING_EXPORT void applyFuncFast64(const char *func); + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *crossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayDouble *divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); //! nothing to do here because this class does not aggregate any TimeLabel instance. MEDCOUPLING_EXPORT void updateTime() { } private: @@ -145,8 +201,32 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT bool isEqual(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT void fillWithZero(); + MEDCOUPLING_EXPORT void fillWithValue(int val); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArr); + MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; + MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; //!alloc or useArray should have been called before. MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); + MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); + MEDCOUPLING_EXPORT DataArrayInt *renumber(const int *old2New) const; + MEDCOUPLING_EXPORT DataArrayInt *renumberR(const int *new2Old) const; + MEDCOUPLING_EXPORT DataArrayInt *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; + MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT bool isIdentity() const; + MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { std::copy(_mem.getConstPointerLoc(tupleId*_info_on_compo.size()),_mem.getConstPointerLoc((tupleId+1)*_info_on_compo.size()),res); } MEDCOUPLING_EXPORT int getIJ(int tupleId, int compoId) const { return _mem[tupleId*_info_on_compo.size()+compoId]; } MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } @@ -154,6 +234,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT static void setArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet); MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); } MEDCOUPLING_EXPORT static DataArrayInt *aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); + MEDCOUPLING_EXPORT static DataArrayInt *makePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } //! nothing to do here because this class does not aggregate any TimeLabel instance. diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 476f147ae..5a1a048d5 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -87,11 +87,99 @@ namespace ParaMEDMEM return true; if(pt1==0 || pt2==0) return false; + if(pt1==pt2) + return true; for(int i=0;i<_nb_of_elem;i++) if(pt1[i]-pt2[i]<-prec || (pt1[i]-pt2[i])>prec) return false; return true; } + + /*! + * @param sl is typically the number of components [in parameter] + */ + template + void MemArray::repr(int sl, std::ostream& stream) const + { + stream << "Number of tuples : "; + if(!_pointer.isNull()) + { + if(sl!=0) + stream << _nb_of_elem/sl; + else + stream << "Empty Data"; + } + else + stream << "No data"; + stream << "\n"; + stream << "Data content :\n"; + const T *data=getConstPointer(); + if(!_pointer.isNull()) + { + if(_nb_of_elem!=0 && sl!=0) + { + int nbOfTuples=_nb_of_elem/sl; + for(int i=0;i(stream," ")); + stream << "\n"; + data+=sl; + } + } + else + stream << "Empty Data\n"; + } + else + stream << "No data !\n"; + } + + /*! + * @param sl is typically the number of components [in parameter] + */ + template + void MemArray::reprZip(int sl, std::ostream& stream) const + { + stream << "Number of tuples : "; + if(!_pointer.isNull()) + { + if(sl!=0) + stream << _nb_of_elem/sl; + else + stream << "Empty Data"; + } + else + stream << "No data"; + stream << "\n"; + stream << "Data content : "; + const T *data=getConstPointer(); + if(!_pointer.isNull()) + { + if(_nb_of_elem!=0 && sl!=0) + { + int nbOfTuples=_nb_of_elem/sl; + for(int i=0;i(stream," ")); + stream << "| "; + data+=sl; + } + stream << "\n"; + } + else + stream << "Empty Data\n"; + } + else + stream << "No data !\n"; + } + + template + void MemArray::fillWithValue(const T& val) + { + T *pt=_pointer.getPointer(); + std::fill(pt,pt+_nb_of_elem,val); + } template void MemArray::alloc(int nbOfElements) diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index a552ea588..cd3157568 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -21,15 +21,133 @@ #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" #include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "InterpKernelExprParser.hxx" - +#include #include #include using namespace ParaMEDMEM; -bool MEDCouplingMesh::areCompatible(const MEDCouplingMesh *other) const +/*! + * This method is only for ParaMEDMEM in ParaFIELD constructor. + */ +bool MEDCouplingMesh::isStructured() const +{ + return getType()==CARTESIAN; +} + +bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const +{ + return _name==other->_name; +} + +/*! + * This method checks geo equivalence between two meshes : 'this' and 'other'. + * If no exception is throw 'this' and 'other' are geometrically equivalent regarding 'levOfCheck' level. + * This method is typically used to change the mesh of a field "safely" depending the 'levOfCheck' level considered. + * + * @param levOfCheck input that specifies the level of check specified. The possible values are listed below. + * @param prec input that specifies precision for double float data used for comparison in meshes. + * @param cellCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for cells from 'other' to 'this'. + * @param nodeCor output array not always informed (depending 'levOfCheck' param) that gives the corresponding array for nodes from 'other' to 'this'. + * + * Possible values for levOfCheck : + * - 0 for strict equality. This is the strongest level. 'cellCor' and 'nodeCor' params are never informed. + * - 10,11,12 for less strict equality. Two meshes are compared geometrically. In case of success 'cellCor' and 'nodeCor' are informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) + * - 20,21,22, for less strict equality. Two meshes are compared geometrically. The difference with the previous version is that nodes(coordinates) are expected to be the same between this and other. In case of success 'cellCor' is informed. Warning ! These equivalences are CPU/Mem costly. The 3 values correspond respectively to policy used for cell comparison (see MEDCouplingUMesh::zipConnectivityTraducer to have more details) + * - 1 for fast 'equality'. This is a lazy level. Just number of cells and number of nodes are considered here and 3 cells (begin,middle,end) + * - 2 for deep 'equality' as 0 option except that no control is done on all strings in mesh. + */ +void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + cellCor=0; + nodeCor=0; + if(this==other) + return ; + switch(levOfCheck) + { + case 0: + { + if(!isEqual(other,prec)) + throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !"); + return ; + } + case 10: + case 11: + case 12: + { + checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor); + return ; + } + case 20: + case 21: + case 22: + { + checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor); + return ; + } + case 1: + { + checkFastEquivalWith(other,prec); + return; + } + case 2: + { + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !"); + return ; + } + default: + throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12."); + } +} + +/*! + * Given a nodeIds range ['partBg','partEnd'), this method returns the set of cell ids in ascendant order whose connectivity of + * these cells are fully included in the range. As a consequence the returned set of cell ids does \b not \b always fit the nodes in ['partBg','partEnd') + * This method returns the corresponding cells in a newly created array that the caller has the responsability. + */ +DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const +{ + std::vector crest; + std::set p(partBg,partEnd); + int nbOfCells=getNumberOfCells(); + for(int i=0;i conn; + getNodeIdsOfCell(i,conn); + bool cont=true; + for(std::vector::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++) + if(p.find(*iter)==p.end()) + cont=false; + if(cont) + crest.push_back(i); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(crest.size(),1); + std::copy(crest.begin(),crest.end(),ret->getPointer()); + return ret; +} + +/*! + * This method checks fastly that 'this' and 'other' are equal. All common checks are done here. + */ +void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=other->getMeshDimension()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !"); + if(getSpaceDimension()!=other->getSpaceDimension()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !"); + if(getNumberOfCells()!=other->getNumberOfCells()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !"); +} + +/*! + * This method is very poor and looks only if 'this' and 'other' are candidate for merge of fields lying repectively on them. + */ +bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const { if(getMeshDimension()!=other->getMeshDimension()) return false; @@ -51,35 +169,22 @@ bool MEDCouplingMesh::areCompatible(const MEDCouplingMesh *other) const */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const { - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(t); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); ret->setMesh(this); - DataArrayDouble *loc=ret->getDiscretization()->getLocalizationOfDiscValues(this); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfTuple=loc->getNumberOfTuples(); - int nbCompIn=loc->getNumberOfComponents(); - const double *locPtr=loc->getConstPointer(); - array->alloc(nbOfTuple,nbOfComp); - double *ptToFill=array->getPointer(); - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !"; - loc->decrRef(); - array->decrRef(); - ret->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ptToFill+=nbOfComp; - } - loc->decrRef(); - ret->setArray(array); - array->decrRef(); + ret->fillFromAnalytic(nbOfComp,func); + ret->incrRef(); return ret; } +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + _name=other->_name; +} + /*! * This method builds a field lying on 'this' with 'nbOfComp' components. * 'func' is a string that is the expression to evaluate. @@ -92,50 +197,10 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO */ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const { - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>getSpaceDimension()) - { - std::ostringstream oss; oss << "The mesh has a spaceDim==" << getSpaceDimension() << " and there are "; - oss << vars.size() << " variables : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector varsV(vars.begin(),vars.end()); - expr.prepareExprEvaluation(varsV); - // - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(t); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,NO_TIME); ret->setMesh(this); - DataArrayDouble *loc=ret->getDiscretization()->getLocalizationOfDiscValues(this); - DataArrayDouble *array=DataArrayDouble::New(); - int nbOfTuple=loc->getNumberOfTuples(); - int nbCompIn=loc->getNumberOfComponents(); - const double *locPtr=loc->getConstPointer(); - array->alloc(nbOfTuple,nbOfComp); - double *ptToFill=array->getPointer(); - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed ! " << e.what(); - loc->decrRef(); - array->decrRef(); - ret->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ptToFill+=nbOfComp; - } - loc->decrRef(); - ret->setArray(array); - array->decrRef(); + ret->fillFromAnalytic(nbOfComp,func); + ret->incrRef(); return ret; } diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx index 8d11cd573..524c23017 100644 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ b/src/MEDCoupling/MEDCouplingMesh.hxx @@ -38,6 +38,7 @@ namespace ParaMEDMEM EXTRUDED = 8 } MEDCouplingMeshType; + class DataArrayInt; class DataArrayDouble; class MEDCouplingFieldDouble; @@ -46,19 +47,35 @@ namespace ParaMEDMEM public: void setName(const char *name) { _name=name; } const char *getName() const { return _name.c_str(); } + virtual MEDCouplingMesh *deepCpy() const = 0; virtual MEDCouplingMeshType getType() const = 0; - virtual bool isEqual(const MEDCouplingMesh *other, double prec) const { return _name==other->_name; } + bool isStructured() const; + virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + // comparison methods + virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; + virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) = 0; + virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + void checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + // virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; - virtual bool isStructured() const = 0; virtual int getNumberOfCells() const = 0; virtual int getNumberOfNodes() const = 0; virtual int getSpaceDimension() const = 0; virtual int getMeshDimension() const = 0; virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; virtual DataArrayDouble *getBarycenterAndOwner() const = 0; + virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; virtual void getNodeIdsOfCell(int cellId, std::vector& conn) const = 0; + virtual DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; virtual void getCoordinatesOfNode(int nodeId, std::vector& coo) const = 0; + virtual std::string simpleRepr() const = 0; + virtual std::string advancedRepr() const = 0; // tools virtual void getBoundingBox(double *bbox) const = 0; virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; @@ -69,9 +86,19 @@ namespace ParaMEDMEM virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0; virtual void rotate(const double *center, const double *vector, double angle) = 0; virtual void translate(const double *vector) = 0; + virtual void scale(const double *point, double factor) = 0; + virtual void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) = 0; virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; - virtual bool areCompatible(const MEDCouplingMesh *other) const; + virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; + virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); + //serialisation-unserialization + virtual void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const = 0; + virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const = 0; + virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; + virtual void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings) = 0; protected: MEDCouplingMesh() { } MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name) { } diff --git a/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/src/MEDCoupling/MEDCouplingNatureOfField.cxx new file mode 100644 index 000000000..7969909f1 --- /dev/null +++ b/src/MEDCoupling/MEDCouplingNatureOfField.cxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingNatureOfField.hxx" + +#include + +namespace ParaMEDMEM +{ + const char *MEDCouplingNatureOfField::REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]= + { "NoNature", + "ConservativeVolumic", + "Integral", + "IntegralGlobConstraint", + "RevIntegral"}; + + const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37}; + + const char *MEDCouplingNatureOfField::getRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception) + { + const int *pos=std::find(POS_OF_NATUREOFFIELD,POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES,(int)nat); + if(pos==POS_OF_NATUREOFFIELD+NB_OF_POSSIBILITIES) + throw INTERP_KERNEL::Exception("MEDCouplingNatureOfField::getRepr : Unrecognized nature of field !"); + int pos2=std::distance(POS_OF_NATUREOFFIELD,pos); + return REPR_OF_NATUREOFFIELD[pos2]; + } +} + diff --git a/src/MEDCoupling/MEDCouplingNatureOfField.hxx b/src/MEDCoupling/MEDCouplingNatureOfField.hxx index bdc1c78dd..89f9125e0 100644 --- a/src/MEDCoupling/MEDCouplingNatureOfField.hxx +++ b/src/MEDCoupling/MEDCouplingNatureOfField.hxx @@ -17,8 +17,11 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __MEDCOUPLINGNATUREOFFIELD_HXX__ -#define __MEDCOUPLINGNATUREOFFIELD_HXX__ +#ifndef __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELD_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELD_HXX__ + +#include "MEDCoupling.hxx" +#include "InterpKernelException.hxx" namespace ParaMEDMEM { @@ -30,6 +33,16 @@ namespace ParaMEDMEM IntegralGlobConstraint = 35, RevIntegral = 37 } NatureOfField; + + class MEDCouplingNatureOfField + { + public: + MEDCOUPLING_EXPORT static const char *getRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception); + private: + static const int NB_OF_POSSIBILITIES=5; + static const char *REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]; + static const int POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]; + }; } #endif diff --git a/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx b/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx index ebb12e01a..c2643f327 100644 --- a/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx +++ b/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx @@ -17,8 +17,8 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __MEDCouplingNormalizedCartesianMesh_HXX__ -#define __MEDCouplingNormalizedCartesianMesh_HXX__ +#ifndef __PARAMEDMEM_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__ #include "NormalizedUnstructuredMesh.hxx" diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx index b3ebcbc7f..5ebd3ae19 100644 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx +++ b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx @@ -17,8 +17,8 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#ifndef __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ #include "NormalizedUnstructuredMesh.hxx" diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index 0c0ce1887..87964cbdf 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -73,11 +73,6 @@ void MEDCouplingPointSet::updateTime() } } -bool MEDCouplingPointSet::isStructured() const -{ - return false; -} - void MEDCouplingPointSet::setCoords(DataArrayDouble *coords) { if( coords != _coords ) @@ -98,6 +93,20 @@ DataArrayDouble *MEDCouplingPointSet::getCoordinatesAndOwner() const return _coords; } +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingPointSet::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingPointSet *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingMesh::copyTinyStringsFrom(other); + if(_coords && otherC->_coords) + _coords->copyStringInfoFrom(*otherC->_coords); +} + bool MEDCouplingPointSet::isEqual(const MEDCouplingMesh *other, double prec) const { const MEDCouplingPointSet *otherC=dynamic_cast(other); @@ -110,6 +119,16 @@ bool MEDCouplingPointSet::isEqual(const MEDCouplingMesh *other, double prec) con return true; } +bool MEDCouplingPointSet::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingPointSet *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!areCoordsEqualWithoutConsideringStr(*otherC,prec)) + return false; + return true; +} + bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, double prec) const { if(_coords==0 && other._coords==0) @@ -121,13 +140,45 @@ bool MEDCouplingPointSet::areCoordsEqual(const MEDCouplingPointSet& other, doubl return _coords->isEqual(*other._coords,prec); } +bool MEDCouplingPointSet::areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const +{ + if(_coords==0 && other._coords==0) + return true; + if(_coords==0 || other._coords==0) + return false; + if(_coords==other._coords) + return true; + return _coords->isEqualWithoutConsideringStr(*other._coords,prec); +} + +/*! + * This method is typically the base method used for implementation of mergeNodes. This method computes this permutation array using as input, + * This method is const ! So this method simply computes the array, no permutation of nodes is done. + * a precision 'precision' and a 'limitNodeId' that is the node id so that every nodes which id is strictly lower than 'limitNodeId' will not be merged. + * To desactivate this advanced feature put -1 to this argument. + * @param areNodesMerged output parameter that states if some nodes have been "merged" in returned array + * @param newNbOfNodes output parameter too this is the maximal id in returned array to avoid to recompute it. + */ +DataArrayInt *MEDCouplingPointSet::buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const +{ + DataArrayInt *comm,*commI; + findCommonNodes(limitNodeId,precision,comm,commI); + int oldNbOfNodes=getNumberOfNodes(); + DataArrayInt *ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + areNodesMerged=(oldNbOfNodes!=newNbOfNodes); + comm->decrRef(); + commI->decrRef(); + return ret; +} + /*! * This methods searches for each node n1 nodes in _coords that are less far than 'prec' from n1. if any these nodes are stored in params * comm and commIndex. + * @param limitNodeId is the limit node id. All nodes which id is strictly lower than 'limitNodeId' will not be merged. * @param comm out parameter (not inout) * @param commIndex out parameter (not inout) */ -void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const +void MEDCouplingPointSet::findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const { comm=DataArrayInt::New(); commIndex=DataArrayInt::New(); @@ -149,13 +200,13 @@ void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&co switch(spaceDim) { case 3: - findCommonNodesAlg<3>(bbox,nbNodesOld,prec,c,cI); + findCommonNodesAlg<3>(bbox,nbNodesOld,limitNodeId,prec,c,cI); break; case 2: - findCommonNodesAlg<2>(bbox,nbNodesOld,prec,c,cI); + findCommonNodesAlg<2>(bbox,nbNodesOld,limitNodeId,prec,c,cI); break; case 1: - findCommonNodesAlg<1>(bbox,nbNodesOld,prec,c,cI); + findCommonNodesAlg<1>(bbox,nbNodesOld,limitNodeId,prec,c,cI); break; default: throw INTERP_KERNEL::Exception("Unexpected spacedim of coords. Must be 1,2 or 3."); @@ -171,8 +222,8 @@ void MEDCouplingPointSet::findCommonNodes(DataArrayInt *&comm, DataArrayInt *&co * @param commI in param in the same format than one returned by findCommonNodes method. * @return the old to new correspondance array. */ -DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const +DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, + int& newNbOfNodes) const { DataArrayInt *ret=DataArrayInt::New(); int nbNodesOld=getNumberOfNodes(); @@ -272,6 +323,25 @@ void MEDCouplingPointSet::zipCoords() traducer->decrRef(); } +struct MEDCouplingCompAbs +{ + bool operator()(double x, double y) { return std::abs(x)getConstPointer(); + int nbOfValues=_coords->getNbOfElems(); + return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs())); +} + /*! * Non const method that operates a rotation of 'this'. * If spaceDim==2 'vector' parameter is ignored (and could be 0) and the rotation is done around 'center' with angle specified by 'angle'. @@ -339,7 +409,7 @@ void MEDCouplingPointSet::scale(const double *point, double factor) * - by ignoring each \f$ i^{th} \f$ components of each coord of nodes so that i >= 'newSpaceDim', 'newSpaceDim'alloc(getCoords()->getNumberOfTuples(),newSpaceDim); - const double *oldc=getCoords()->getConstPointer(); - double *nc=newCoords->getPointer(); - int nbOfNodes=getNumberOfNodes(); - int dim=std::min(oldSpaceDim,newSpaceDim); - for(int i=0;isetName(getCoords()->getName().c_str()); - for(int i=0;isetInfoOnComponent(i,getCoords()->getInfoOnComponent(i).c_str()); + DataArrayDouble *newCoords=getCoords()->changeNbOfComponents(newSpaceDim,dftValue); setCoords(newCoords); newCoords->decrRef(); + updateTime(); } /*! @@ -381,7 +436,7 @@ void MEDCouplingPointSet::tryToShareSameCoords(const MEDCouplingPointSet& other, throw INTERP_KERNEL::Exception("Current instance has no coords whereas other has !"); if(!other._coords) throw INTERP_KERNEL::Exception("Other instance has no coords whereas current has !"); - if(!_coords->isEqual(*other._coords,epsilon)) + if(!_coords->isEqualWithoutConsideringStr(*other._coords,epsilon)) throw INTERP_KERNEL::Exception("Coords are not the same !"); setCoords(other._coords); } @@ -485,7 +540,7 @@ void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) con * Second step of serialization process. * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ -void MEDCouplingPointSet::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) +void MEDCouplingPointSet::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const { if(tinyInfo[2]>=0 && tinyInfo[1]>=1) { @@ -502,7 +557,7 @@ void MEDCouplingPointSet::resizeForUnserialization(const std::vector& tinyI * Second and final unserialization process. * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ -void MEDCouplingPointSet::unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) +void MEDCouplingPointSet::unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) { if(tinyInfo[2]>=0 && tinyInfo[1]>=1) { @@ -624,6 +679,33 @@ void MEDCouplingPointSet::rotate3DAlg(const double *center, const double *vect, } } +/*! + * This method implements pure virtual method MEDCouplingMesh::buildPart. + * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end'). + * The coords are kept unchanged contrary to pure virtual method MEDCouplingMesh::buildPartAndReduceNodes. + * The returned mesh has to be managed by the caller. + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPart(const int *start, const int *end) const +{ + return buildPartOfMySelf(start,end,false); +} + +/*! + * This method implements pure virtual method MEDCouplingMesh::buildPartAndReduceNodes. + * This method build a part of 'this' by simply keeping cells whose ids are in ['start','end') \b and potentially reduces the nodes set + * behind returned mesh. This cause an overhead but it is lesser in memory. + * This method returns an array too. This array allows to the caller to know the mapping between nodeids in 'this' and nodeids in + * returned mesh. This is quite usefull for MEDCouplingFieldDouble on nodes for example... + * The returned mesh has to be managed by the caller. + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + MEDCouplingPointSet *ret=buildPartOfMySelf(start,end,true); + arr=ret->zipCoordsTraducer(); + return ret; +} + + /*! * 'This' is expected to be of spaceDim==2. Idem for 'center' and 'vect' */ diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx index 601777efc..87a4c04ec 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ b/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -43,43 +43,50 @@ namespace ParaMEDMEM ~MEDCouplingPointSet(); public: void updateTime(); - bool isStructured() const; int getNumberOfNodes() const; int getSpaceDimension() const; void setCoords(DataArrayDouble *coords); DataArrayDouble *getCoords() const { return _coords; } DataArrayDouble *getCoordinatesAndOwner() const; + void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); bool isEqual(const MEDCouplingMesh *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; - virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged) = 0; - void findCommonNodes(DataArrayInt *&comm, DataArrayInt *&commIndex, double prec) const; - DataArrayInt *buildNewNumberingFromCommNodesFrmt(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const; + bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; + virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) = 0; + DataArrayInt *buildPermArrayForMergeNode(int limitNodeId, double precision, bool& areNodesMerged, int& newNbOfNodes) const; + void findCommonNodes(int limitNodeId, double prec, DataArrayInt *&comm, DataArrayInt *&commIndex) const; + DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, + int& newNbOfNodes) const; void getBoundingBox(double *bbox) const; void zipCoords(); + double getCaracteristicDimension() const; void rotate(const double *center, const double *vector, double angle); void translate(const double *vector); void scale(const double *point, double factor); - void changeSpaceDimension(int newSpaceDim) throw(INTERP_KERNEL::Exception); + void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0; void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const throw(INTERP_KERNEL::Exception); static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type); static void rotate2DAlg(const double *center, double angle, int nbNodes, double *coords); static void rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); + MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0; virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; virtual void findBoundaryNodes(std::vector& nodes) const = 0; virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); - //! size of returned tinyInfo must be always the same. - virtual void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; - virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings); - virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - virtual void unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); + //! size of returned tinyInfo must be always the same. + void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); virtual void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems) = 0; virtual void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) = 0; virtual DataArrayInt *zipCoordsTraducer() = 0; @@ -93,7 +100,7 @@ namespace ParaMEDMEM static bool isButterfly2DCell(const std::vector& res, bool isQuad); template void findCommonNodesAlg(std::vector& bbox, - int nbNodes, double prec, std::vector& c, std::vector& cI) const; + int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const; protected: DataArrayDouble *_coords; }; diff --git a/src/MEDCoupling/MEDCouplingPointSet.txx b/src/MEDCoupling/MEDCouplingPointSet.txx index 300aab235..bae195566 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.txx +++ b/src/MEDCoupling/MEDCouplingPointSet.txx @@ -29,7 +29,7 @@ namespace ParaMEDMEM { template void MEDCouplingPointSet::findCommonNodesAlg(std::vector& bbox, - int nbNodes, double prec, + int nbNodes, int limitNodeId, double prec, std::vector& c, std::vector& cI) const { const double *coordsPtr=_coords->getConstPointer(); @@ -52,8 +52,9 @@ namespace ParaMEDMEM std::vector commonNodes; for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) if(*it!=i) - if(INTERP_KERNEL::distance2(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))=limitNodeId) + if(INTERP_KERNEL::distance2(coordsPtr+SPACEDIM*i,coordsPtr+SPACEDIM*(*it))getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); @@ -86,7 +86,7 @@ void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCo computeProduct(inputPointer,srcNbOfCompo,dftValue,resPointer); } -void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) +void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { if(_src_method!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); @@ -114,7 +114,7 @@ void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, cons computeReverseProduct(inputPointer,trgNbOfCompo,dftValue,resPointer); } -MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) +MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception) { if(_src_method!=srcField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); @@ -125,7 +125,7 @@ MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFiel return ret; } -MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) +MEDCouplingFieldDouble *MEDCouplingRemapper::reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception) { if(_target_method!=targetField->getDiscretization()->getStringRepr()) throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); @@ -146,12 +146,12 @@ bool MEDCouplingRemapper::setOptionDouble(const std::string& key, double value) return INTERP_KERNEL::InterpolationOptions::setOptionDouble(key,value); } -bool MEDCouplingRemapper::setOptionString(const std::string& key, std::string& value) +bool MEDCouplingRemapper::setOptionString(const std::string& key, const std::string& value) { return INTERP_KERNEL::InterpolationOptions::setOptionString(key,value); } -int MEDCouplingRemapper::prepareUU(const char *method) +int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exception) { MEDCouplingUMesh *src_mesh=(MEDCouplingUMesh *)_src_mesh; MEDCouplingUMesh *target_mesh=(MEDCouplingUMesh *)_target_mesh; @@ -168,7 +168,21 @@ int MEDCouplingRemapper::prepareUU(const char *method) if(trgSpaceDim!=-1 && srcSpaceDim!=-1) throw INTERP_KERNEL::Exception("Incoherent space dimension detected between target and source."); int nbCols; - if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2) + if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==1) + { + MEDCouplingNormalizedUnstructuredMesh<1,1> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<1,1> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation1D interpolation(*this); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + } + else if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==2) + { + MEDCouplingNormalizedUnstructuredMesh<2,1> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation2DCurve interpolation(*this); + nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method); + } + else if(srcMeshDim==2 && trgMeshDim==2 && srcSpaceDim==2) { MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); @@ -287,7 +301,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) return 1; } -int MEDCouplingRemapper::prepareEE(const char *method) +int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exception) { MEDCouplingExtrudedMesh *src_mesh=(MEDCouplingExtrudedMesh *)_src_mesh; MEDCouplingExtrudedMesh *target_mesh=(MEDCouplingExtrudedMesh *)_target_mesh; @@ -351,7 +365,7 @@ void MEDCouplingRemapper::computeDeno(NatureOfField nat, const MEDCouplingFieldD return computeDenoFromScratch(nat,srcField,trgField); } -void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) +void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) throw(INTERP_KERNEL::Exception) { _nature_of_deno=nat; _time_deno_update=getTimeOfThis(); @@ -364,8 +378,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case Integral: { - MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getWeightingField(srcField->getMesh(),true); - MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getWeightingField(trgField->getMesh(),true); + MEDCouplingFieldDouble *deno=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); + MEDCouplingFieldDouble *denoR=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) @@ -396,8 +410,8 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou } case RevIntegral: { - MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getWeightingField(trgField->getMesh(),true); - MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getWeightingField(srcField->getMesh(),true); + MEDCouplingFieldDouble *deno=trgField->getDiscretization()->getMeasureField(trgField->getMesh(),true); + MEDCouplingFieldDouble *denoR=srcField->getDiscretization()->getMeasureField(srcField->getMesh(),true); const double *denoPtr=deno->getArray()->getConstPointer(); const double *denoRPtr=denoR->getArray()->getConstPointer(); if(trgField->getMesh()->getMeshDimension()==-1) diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx index 5e2bd63dd..14d402d03 100644 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ b/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -24,6 +24,7 @@ #include "MEDCouplingTimeLabel.hxx" #include "InterpolationOptions.hxx" #include "MEDCouplingNatureOfField.hxx" +#include "InterpKernelException.hxx" #include #include @@ -42,23 +43,23 @@ namespace ParaMEDMEM public: MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper(); MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper(); - MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method); - MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue); + MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const char *method) throw(INTERP_KERNEL::Exception); + MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); + MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); + MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); + MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); MEDCOUPLINGREMAPPER_EXPORT bool setOptionInt(const std::string& key, int value); MEDCOUPLINGREMAPPER_EXPORT bool setOptionDouble(const std::string& key, double value); - MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, std::string& value); + MEDCOUPLINGREMAPPER_EXPORT bool setOptionString(const std::string& key, const std::string& value); public: MEDCOUPLINGREMAPPER_EXPORT static void printMatrix(const std::vector >& m); private: - int prepareUU(const char *method); - int prepareEE(const char *method); + int prepareUU(const char *method) throw(INTERP_KERNEL::Exception); + int prepareEE(const char *method) throw(INTERP_KERNEL::Exception); void updateTime(); void releaseData(bool matrixSuppression); void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); - void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); + void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) throw(INTERP_KERNEL::Exception); void computeProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer); void computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer); void buildFinalInterpolationMatrixByConvolution(const std::vector< std::map >& m1D, diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx index a030e1b4c..a150a9cd4 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -19,21 +19,31 @@ #include "MEDCouplingTimeDiscretization.hxx" #include "MEDCouplingMemArray.hxx" - -#include "InterpKernelExprParser.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include #include +#include using namespace ParaMEDMEM; +const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12; + const char MEDCouplingNoTimeLabel::EXCEPTION_MSG[]="MEDCouplingNoTimeLabel::setTime : no time info attached."; +const char MEDCouplingNoTimeLabel::REPR[]="No time label defined."; + const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time."; +const char MEDCouplingWithTimeStep::REPR[]="One time label."; + const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time."; -const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12; +const char MEDCouplingConstOnTimeInterval::REPR[]="Constant on a time interval."; + +const char MEDCouplingTwoTimeSteps::EXCEPTION_MSG[]="No data on this time."; + +const char MEDCouplingLinearTime::REPR[]="Linear time between 2 time steps."; MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDiscretization type) { @@ -45,11 +55,32 @@ MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::New(TypeOfTimeDisc return new MEDCouplingWithTimeStep; case MEDCouplingConstOnTimeInterval::DISCRETIZATION: return new MEDCouplingConstOnTimeInterval; + case MEDCouplingLinearTime::DISCRETIZATION: + return new MEDCouplingLinearTime; default: throw INTERP_KERNEL::Exception("Time discretization not implemented yet"); } } +void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + _time_tolerance=other._time_tolerance; +} + +void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +{ + if(_array && other._array) + _array->copyStringInfoFrom(*other._array); +} + +void MEDCouplingTimeDiscretization::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + if(!_array) + throw INTERP_KERNEL::Exception("Field invalid because no values set !"); + if(_time_tolerance<0.) + throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !"); +} + void MEDCouplingTimeDiscretization::updateTime() { if(_array) @@ -69,7 +100,22 @@ bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretiz return true; } -bool MEDCouplingTimeDiscretization::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) + return false; + if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const { if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) return false; @@ -87,13 +133,22 @@ bool MEDCouplingTimeDiscretization::areCompatibleForMul(const MEDCouplingTimeDis bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const { - if(!areCompatible(other)) + if(!areStrictlyCompatible(other)) return false; if(_array==other->_array) return true; return _array->isEqual(*other->_array,prec); } +bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + if(!areStrictlyCompatible(other)) + return false; + if(_array==other->_array) + return true; + return _array->isEqualWithoutConsideringStr(*other->_array,prec); +} + MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other, TypeOfTimeDiscretization type, bool deepCpy) const { @@ -190,6 +245,16 @@ void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel * } } +DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const +{ + throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); +} + +void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) +{ + throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !"); +} + void MEDCouplingTimeDiscretization::setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception) { if(arrays.size()!=1) @@ -205,122 +270,403 @@ void MEDCouplingTimeDiscretization::getArrays(std::vector& ar bool MEDCouplingTimeDiscretization::isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { - int dt,it; - double time1=getEndTime(dt,it)-_time_tolerance; - double time2=other->getStartTime(dt,it)+other->getTimeTolerance(); + int iteration,order; + double time1=getEndTime(iteration,order)-_time_tolerance; + double time2=other->getStartTime(iteration,order)+other->getTimeTolerance(); return time1<=time2; } bool MEDCouplingTimeDiscretization::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception) { - int dt,it; - double time1=getEndTime(dt,it)+_time_tolerance; - double time2=other->getStartTime(dt,it)-other->getTimeTolerance(); + int iteration,order; + double time1=getEndTime(iteration,order)+_time_tolerance; + double time2=other->getStartTime(iteration,order)-other->getTimeTolerance(); return time1getPointer()+compoId; - int nbOfComp=_array->getNumberOfComponents(); - int nbOfTuple=_array->getNumberOfTuples(); - for(int i=0;i arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->doublyContractedProduct(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + ret->setArrays(arrays3,0); + return ret; } -void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() const throw(INTERP_KERNEL::Exception) { - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=_array->getNumberOfTuples(); - int oldNbOfComp=_array->getNumberOfComponents(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=_array->getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) { - if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp)) - { - std::ostringstream oss; oss << "For tuple # " << i << " with value ("; - std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator(oss,", ")); - oss << ") : Evaluation of function failed !"; - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + if(arrays[j]) + arrays2[j]=arrays[j]->determinant(); + else + arrays2[j]=0; } - _array->decrRef(); - _array=newArr; + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; } -void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const char *func) +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->eigenValues(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->eigenVectors(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->inverse(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->trace(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->deviator(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->magnitude(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->maxPerTuple(); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->keepSelectedComponents(compoIds); + else + arrays2[j]=0; + } + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setArrays(arrays3,0); + return ret; +} + +void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception) +{ + std::vector arrays1,arrays2; + getArrays(arrays1); + other->getArrays(arrays2); + if(arrays1.size()!=arrays2.size()) + throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !"); + for(unsigned int i=0;isetSelectedComponents(arrays2[i],compoIds); + else if(arrays1[i]!=0 || arrays2[i]!=0) + throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : some time array in correspondance are not defined symetrically !"); + } +} + +void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception) { - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - int oldNbOfComp=_array->getNumberOfComponents(); - if((int)vars.size()>oldNbOfComp) + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) { - std::ostringstream oss; oss << "The field has a " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + if(arrays[j]) + arrays2[j]=arrays[j]->changeNbOfComponents(newNbOfComp,dftValue); + else + arrays2[j]=0; } - std::vector varsV(vars.begin(),vars.end()); - expr.prepareExprEvaluation(varsV); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=_array->getNumberOfTuples(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=_array->getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays[j]->sortPerTuple(asc); + } +} + +void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) { - try + if(arrays[j]) { - expr.evaluateExpr(nbOfComp,ptrToFill+i*nbOfComp,ptr+i*oldNbOfComp); + arrays[j]->incrRef(); + arrays[j]->fillWithValue(value); + arrays2[j]=arrays[j]; } - catch(INTERP_KERNEL::Exception& e) + else { - std::ostringstream oss; oss << "For tuple # " << i << " with value ("; - std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); + DataArrayDouble *tmp=DataArrayDouble::New(); + tmp->alloc(nbOfTuple,nbOfCompo); + tmp->fillWithValue(value); + arrays2[j]=tmp; } } - _array->decrRef(); - _array=newArr; + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyLin(double a, double b, int compoId) +{ + std::vector arrays; + getArrays(arrays); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyLin(a,b,compoId); + } +} + +void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) +{ + std::vector arrays; + getArrays(arrays); + std::vector arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(nbOfComp,func); + else + arrays2[j]=0; + } + setArrays(arrays2,0); + for(int j=0;j<(int)arrays.size();j++) + if(arrays2[j]) + arrays2[j]->decrRef(); +} + +void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const char *func) +{ + std::vector arrays; + getArrays(arrays); + std::vector arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(nbOfComp,func); + else + arrays2[j]=0; + } + setArrays(arrays2,0); + for(int j=0;j<(int)arrays.size();j++) + if(arrays2[j]) + arrays2[j]->decrRef(); } void MEDCouplingTimeDiscretization::applyFunc(const char *func) { - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - expr.prepareExprEvaluationVec(); - // - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=_array->getNumberOfTuples(); - int nbOfComp=_array->getNumberOfComponents(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *ptr=_array->getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i arrays; + getArrays(arrays); + std::vector arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) { - try - { - expr.evaluateExpr(nbOfComp,ptrToFill+i*nbOfComp,ptr+i*nbOfComp); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "For tuple # " << i << " with value ("; - std::copy(ptr+nbOfComp*i,ptr+nbOfComp*(i+1),std::ostream_iterator(oss,", ")); - oss << ") : Evaluation of function failed ! " << e.what(); - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(func); + else + arrays2[j]=0; + } + setArrays(arrays2,0); + for(int j=0;j<(int)arrays.size();j++) + if(arrays2[j]) + arrays2[j]->decrRef(); +} + +void MEDCouplingTimeDiscretization::applyFuncFast32(const char *func) +{ + std::vector arrays; + getArrays(arrays); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyFuncFast32(func); + } +} + +void MEDCouplingTimeDiscretization::applyFuncFast64(const char *func) +{ + std::vector arrays; + getArrays(arrays); + for(int j=0;j<(int)arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyFuncFast64(func); } - _array->decrRef(); - _array=newArr; +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays2[j]=loc->applyFunc(nbOfComp,func); + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception) +{ + std::vector arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays2[j]=loc->applyFunc(nbOfComp,func); + std::vector arrays3(arrays.size()); + for(int j=0;j<(int)arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); } MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel() @@ -331,6 +677,13 @@ MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretizati { } +std::string MEDCouplingNoTimeLabel::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR; + return stream.str(); +} + bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *other) const { if(!MEDCouplingTimeDiscretization::areCompatible(other)) @@ -339,9 +692,17 @@ bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization * return otherC!=0; } -bool MEDCouplingNoTimeLabel::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + return otherC!=0; +} + +bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const { - if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) return false; const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); return otherC!=0; @@ -355,14 +716,70 @@ bool MEDCouplingNoTimeLabel::isEqual(const MEDCouplingTimeDiscretization *other, return MEDCouplingTimeDiscretization::isEqual(other,prec); } +bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setTimeTolerance(getTimeTolerance()); - DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::dot on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::crossProduct on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setArray(arr,0); arr->decrRef(); return ret; @@ -373,8 +790,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTime const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("NoTimeLabel::add on mismatched time discretization !"); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setArray(arr,0); arr->decrRef(); return ret; @@ -393,8 +810,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCoupli const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("NoTimeLabel::substract on mismatched time discretization !"); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setArray(arr,0); arr->decrRef(); return ret; @@ -413,8 +830,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplin const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("NoTimeLabel::multiply on mismatched time discretization !"); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setArray(arr,0); arr->decrRef(); return ret; @@ -433,8 +850,8 @@ MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingT const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; ret->setArray(arr,0); arr->decrRef(); return ret; @@ -478,22 +895,22 @@ bool MEDCouplingNoTimeLabel::isStrictlyBefore(const MEDCouplingTimeDiscretizatio throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -double MEDCouplingNoTimeLabel::getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) +double MEDCouplingNoTimeLabel::getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -double MEDCouplingNoTimeLabel::getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) +double MEDCouplingNoTimeLabel::getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingNoTimeLabel::setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) +void MEDCouplingNoTimeLabel::setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingNoTimeLabel::setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) +void MEDCouplingNoTimeLabel::setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } @@ -503,25 +920,32 @@ void MEDCouplingNoTimeLabel::getValueOnTime(int eltId, double time, double *valu throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception) +void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) { throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } MEDCouplingWithTimeStep::MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), - _time(other._time),_dt(other._dt),_it(other._it) + _time(other._time),_iteration(other._iteration),_order(other._order) +{ +} + +MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_order(-1) { } -MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_dt(-1),_it(-1) +std::string MEDCouplingWithTimeStep::getStringRepr() const { + std::ostringstream stream; + stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << "."; + return stream.str(); } void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_dt); - tinyInfo.push_back(_it); + tinyInfo.push_back(_iteration); + tinyInfo.push_back(_order); } void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector& tinyInfo) const @@ -534,8 +958,8 @@ void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tiny { MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); _time=tinyInfoD[1]; - _dt=tinyInfoI[2]; - _it=tinyInfoI[3]; + _iteration=tinyInfoI[2]; + _order=tinyInfoI[3]; } bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const @@ -543,19 +967,23 @@ bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization if(!MEDCouplingTimeDiscretization::areCompatible(other)) return false; const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - return false; - return std::fabs(_time-otherC->_time)<_time_tolerance; + return otherC!=0; } -bool MEDCouplingWithTimeStep::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const { - if(!MEDCouplingTimeDiscretization::areCompatibleForMul(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) return false; const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) + return otherC!=0; +} + +bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) return false; - return std::fabs(_time-otherC->_time)<_time_tolerance; + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + return otherC!=0; } bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const @@ -563,23 +991,46 @@ bool MEDCouplingWithTimeStep::isEqual(const MEDCouplingTimeDiscretization *other const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) return false; - if(_dt!=otherC->_dt) + if(_iteration!=otherC->_iteration) return false; - if(_it!=otherC->_it) + if(_order!=otherC->_order) return false; if(std::fabs(_time-otherC->_time)>_time_tolerance) return false; return MEDCouplingTimeDiscretization::isEqual(other,prec); } +bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_iteration!=otherC->_iteration) + return false; + if(_order!=otherC->_order) + return false; + if(std::fabs(_time-otherC->_time)>_time_tolerance) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingWithTimeStep& otherC=dynamic_cast(other); + _time=otherC._time; + _iteration=otherC._iteration; + _order=otherC._order; +} + MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; ret->setTimeTolerance(getTimeTolerance()); - DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -588,39 +1039,87 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCoupl return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !"); + throw INTERP_KERNEL::Exception("WithTimeStep::dot on mismatched time discretization !"); MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray()); + DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray()); ret->setArray(arr,0); arr->decrRef(); - int tmp1,tmp2; - double tmp3=getStartTime(tmp1,tmp2); - ret->setStartTime(tmp3,tmp1,tmp2); return ret; } -void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other) +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !"); - getArray()->addEqual(other->getArray()); + throw INTERP_KERNEL::Exception("WithTimeStep::crossProduct on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); + return ret; } -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !"); + throw INTERP_KERNEL::Exception("WithTimeStep::max on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray()); MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray()); ret->setArray(arr,0); arr->decrRef(); - int tmp1,tmp2; + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::min on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); + int tmp1,tmp2; + double tmp3=getStartTime(tmp1,tmp2); + ret->setStartTime(tmp3,tmp1,tmp2); + return ret; +} + +void MEDCouplingWithTimeStep::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !"); + getArray()->addEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + arr->decrRef(); + int tmp1,tmp2; double tmp3=getStartTime(tmp1,tmp2); ret->setStartTime(tmp3,tmp1,tmp2); return ret; @@ -639,8 +1138,8 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCoupli const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("WithTimeStep::multiply on mismatched time discretization !"); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -662,8 +1161,8 @@ MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCoupling const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("WithTimeStep::divide on mismatched time discretization !"); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -728,9 +1227,9 @@ void MEDCouplingWithTimeStep::getValueOnTime(int eltId, double time, double *val throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception) +void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) { - if(_dt==dt && _it==it) + if(_iteration==iteration && _order==order) if(_array) _array->getTuple(eltId,value); else @@ -739,17 +1238,29 @@ void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int dt, int it, doub throw INTERP_KERNEL::Exception("No data on this discrete time."); } -MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_dt(-1),_end_dt(-1),_start_it(-1),_end_it(-1) +MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1) { } +void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingConstOnTimeInterval& otherC=dynamic_cast(other); + _start_time=otherC._start_time; + _end_time=otherC._end_time; + _start_iteration=otherC._start_iteration; + _end_iteration=otherC._end_iteration; + _start_order=otherC._start_order; + _end_order=otherC._end_order; +} + void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector& tinyInfo) const { MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_start_dt); - tinyInfo.push_back(_start_it); - tinyInfo.push_back(_end_dt); - tinyInfo.push_back(_end_it); + tinyInfo.push_back(_start_iteration); + tinyInfo.push_back(_start_order); + tinyInfo.push_back(_end_iteration); + tinyInfo.push_back(_end_order); } void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector& tinyInfo) const @@ -764,18 +1275,26 @@ void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector(other); - if(!otherC) - return false; - return (std::fabs(_start_time-otherC->_start_time)<_time_tolerance && std::fabs(_end_time-otherC->_end_time)<_time_tolerance); + return otherC!=0; } -bool MEDCouplingConstOnTimeInterval::areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const { - if(!MEDCouplingTimeDiscretization::areCompatible(other)) + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) return false; const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) + return otherC!=0; +} + +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) return false; - return (std::fabs(_start_time-otherC->_start_time)<_time_tolerance && std::fabs(_end_time-otherC->_end_time)<_time_tolerance); + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + return otherC!=0; } bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const @@ -823,21 +1346,41 @@ bool MEDCouplingConstOnTimeInterval::isEqual(const MEDCouplingTimeDiscretization const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) return false; - if(_start_dt!=otherC->_start_dt) + if(_start_iteration!=otherC->_start_iteration) return false; - if(_start_it!=otherC->_start_it) + if(_start_order!=otherC->_start_order) return false; if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) return false; - if(_end_dt!=otherC->_end_dt) + if(_end_iteration!=otherC->_end_iteration) return false; - if(_end_it!=otherC->_end_it) + if(_end_order!=otherC->_end_order) return false; if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) return false; return MEDCouplingTimeDiscretization::isEqual(other,prec); } +bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_start_iteration!=otherC->_start_iteration) + return false; + if(_start_order!=otherC->_start_order) + return false; + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + return false; + if(_end_iteration!=otherC->_end_iteration) + return false; + if(_end_order!=otherC->_end_order) + return false; + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception) { if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) @@ -849,9 +1392,9 @@ void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, doub throw INTERP_KERNEL::Exception(EXCEPTION_MSG); } -void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception) +void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) { - if(dt>=_start_dt && dt<=_end_dt) + if(iteration>=_start_iteration && iteration<=_end_iteration) if(_array) _array->getTuple(eltId,value); else @@ -870,7 +1413,7 @@ void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const throw( if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) { std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " with tolerance "; + stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; stream << _time_tolerance << " and trying to access on time = " << time; throw INTERP_KERNEL::Exception(stream.str().c_str()); } @@ -881,9 +1424,9 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const M const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setTimeTolerance(getTimeTolerance()); - DataArrayDouble *arr=DataArrayDouble::aggregate(getArray(),other->getArray()); ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -894,13 +1437,61 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const M return ret; } +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::dot on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::dot(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::crossProduct on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::crossProduct(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::max on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::max(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::min on mismatched time discretization !"); + DataArrayDouble *arr=DataArrayDouble::min(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + arr->decrRef(); + return ret; +} + MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const { const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("ConstOnTimeInterval::add on mismatched time discretization !"); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; DataArrayDouble *arr=DataArrayDouble::add(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -924,8 +1515,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const M const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substract on mismatched time discretization !"); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; DataArrayDouble *arr=DataArrayDouble::substract(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -949,8 +1540,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const ME const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("multiply on mismatched time discretization !"); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; DataArrayDouble *arr=DataArrayDouble::multiply(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -974,8 +1565,8 @@ MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDC const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); if(!otherC) throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; DataArrayDouble *arr=DataArrayDouble::divide(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; ret->setArray(arr,0); arr->decrRef(); int tmp1,tmp2; @@ -994,7 +1585,109 @@ void MEDCouplingConstOnTimeInterval::divideEqual(const MEDCouplingTimeDiscretiza getArray()->divideEqual(other->getArray()); } -MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_dt(-1),_end_dt(-1),_start_it(-1),_end_it(-1),_end_array(0) +MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), + _start_time(other._start_time),_end_time(other._end_time), + _start_iteration(other._start_iteration),_end_iteration(other._end_iteration), + _start_order(other._start_order),_end_order(other._end_order) +{ + if(other._end_array) + _end_array=other._end_array->performCpy(deepCpy); + else + _end_array=0; +} + +void MEDCouplingTwoTimeSteps::updateTime() +{ + MEDCouplingTimeDiscretization::updateTime(); + if(_end_array) + updateTimeWith(*_end_array); +} + +void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingTwoTimeSteps& otherC=dynamic_cast(other); + _start_time=otherC._start_time; + _end_time=otherC._end_time; + _start_iteration=otherC._start_iteration; + _end_iteration=otherC._end_iteration; + _start_order=otherC._start_order; + _end_order=otherC._end_order; +} + +void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyStringsFrom(other); + const MEDCouplingTwoTimeSteps* otherC=dynamic_cast(&other); + if(!otherC) + throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !"); + if(_end_array && otherC->_end_array) + _end_array->copyStringInfoFrom(*otherC->_end_array); +} + +DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const +{ + return _end_array; +} + +void MEDCouplingTwoTimeSteps::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTimeDiscretization::checkCoherency(); + if(!_end_array) + throw INTERP_KERNEL::Exception("No end array specified !"); + if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !"); + if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("The number of tuples mismatch between the start and the end arrays !"); +} + +bool MEDCouplingTwoTimeSteps::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_start_iteration!=otherC->_start_iteration) + return false; + if(_end_iteration!=otherC->_end_iteration) + return false; + if(_start_order!=otherC->_start_order) + return false; + if(_end_order!=otherC->_end_order) + return false; + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + return false; + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + return false; + if(_end_array!=otherC->_end_array) + if(!_end_array->isEqual(*otherC->_end_array,prec)) + return false; + return MEDCouplingTimeDiscretization::isEqual(other,prec); +} + +bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(_start_iteration!=otherC->_start_iteration) + return false; + if(_end_iteration!=otherC->_end_iteration) + return false; + if(_start_order!=otherC->_start_order) + return false; + if(_end_order!=otherC->_end_order) + return false; + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + return false; + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + return false; + if(_end_array!=otherC->_end_array) + if(!_end_array->isEqualWithoutConsideringStr(*otherC->_end_array,prec)) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1),_end_array(0) { } @@ -1014,7 +1707,7 @@ void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const throw(INTERP_ if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) { std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " with tolerance "; + stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; stream << _time_tolerance << " and trying to access on time = " << time; throw INTERP_KERNEL::Exception(stream.str().c_str()); } @@ -1027,6 +1720,55 @@ void MEDCouplingTwoTimeSteps::getArrays(std::vector& arrays) arrays[1]=_end_array; } +void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) +{ + if(array!=_end_array) + { + if(_end_array) + _end_array->decrRef(); + _end_array=array; + if(_end_array) + _end_array->incrRef(); + if(owner) + owner->declareAsNew(); + } +} + +void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); + tinyInfo.push_back(_start_iteration); + tinyInfo.push_back(_start_order); + tinyInfo.push_back(_end_iteration); + tinyInfo.push_back(_end_order); + if(_end_array) + { + tinyInfo.push_back(_end_array->getNumberOfTuples()); + tinyInfo.push_back(_end_array->getNumberOfComponents()); + } + else + { + tinyInfo.push_back(-1); + tinyInfo.push_back(-1); + } +} + +void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); + tinyInfo.push_back(_start_time); + tinyInfo.push_back(_end_time); +} + +void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const +{ + int nbOfCompo=_array->getNumberOfComponents(); + for(int i=0;igetInfoOnComponent(i)); + for(int i=0;igetInfoOnComponent(i)); +} + void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) { arrays.resize(2); @@ -1043,10 +1785,10 @@ void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& t _array=arr; arrays[0]=arr; arr=0; - if(tinyInfoI[2]!=-1 && tinyInfoI[3]!=-1) + if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) { arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[2],tinyInfoI[3]); + arr->alloc(tinyInfoI[6],tinyInfoI[7]); } _end_array=arr; arrays[1]=arr; @@ -1057,8 +1799,305 @@ void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tiny MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); _start_time=tinyInfoD[1]; _end_time=tinyInfoD[2]; - _start_dt=tinyInfoI[2]; - _end_dt=tinyInfoI[3]; - _start_it=tinyInfoI[4]; - _end_it=tinyInfoI[5]; + _start_iteration=tinyInfoI[2]; + _start_order=tinyInfoI[3]; + _end_iteration=tinyInfoI[4]; + _end_order=tinyInfoI[5]; +} + +std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const throw(INTERP_KERNEL::Exception) +{ + if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) + { + std::vector< const DataArrayDouble *> ret(2); + ret[0]=_array; + ret[1]=_end_array; + return ret; + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingTwoTimeSteps::setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception) +{ + if(arrays.size()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two."); + setArray(arrays.front(),owner); + setEndArray(arrays.back(),owner); +} + +MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy) +{ +} + +MEDCouplingLinearTime::MEDCouplingLinearTime() +{ +} + +std::string MEDCouplingLinearTime::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; + stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; + return stream.str(); +} + +void MEDCouplingLinearTime::checkCoherency() const throw(INTERP_KERNEL::Exception) +{ + MEDCouplingTwoTimeSteps::checkCoherency(); + if(std::fabs(_start_time-_end_time)<_time_tolerance) + throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance."); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const +{ + return new MEDCouplingLinearTime(*this,deepCpy); +} + +bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatible(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + return otherC!=0; +} + +bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + return otherC!=0; +} + +bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + return otherC!=0; +} + +/*! + * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples() + */ +void MEDCouplingLinearTime::getValueForTime(double time, const std::vector& vals, double *res) const +{ + double alpha=(_end_time-time)/(_end_time-_start_time); + int nbComp=vals.size()/2; + std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies(),alpha)); + std::vector tmp(nbComp); + std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),res,res,std::plus()); +} + +void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception) +{ + double alpha=(_end_time-time)/(_end_time-_start_time); + int nbComp; + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No start array existing."); + nbComp=_array->getNumberOfComponents(); + std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies(),alpha)); + std::vector tmp(nbComp); + if(_end_array) + _end_array->getTuple(eltId,&tmp[0]); + else + throw INTERP_KERNEL::Exception("No end array existing."); + std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),value,value,std::plus()); +} + +void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) +{ + if(iteration==_start_iteration && order==_start_order) + { + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("iteration order match with start time but no start array existing."); + } + if(iteration==_end_iteration && order==_end_order) + { + if(_end_array) + _end_array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("iteration order match with end time but no end array existing."); + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::aggregate(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::aggregate(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setTimeTolerance(getTimeTolerance()); + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::dot on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::dot(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::dot(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::crossProduct on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::crossProduct(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::crossProduct(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::max on mismatched time discretization !"); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + DataArrayDouble *arr1=DataArrayDouble::max(getArray(),other->getArray()); + ret->setArray(arr1,0); + arr1->decrRef(); + DataArrayDouble *arr2=DataArrayDouble::max(getEndArray(),other->getEndArray()); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::min on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::min(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::min(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::add(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::add(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + getArray()->addEqual(other->getArray()); + getEndArray()->addEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::substract(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::substract(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + getArray()->substractEqual(other->getArray()); + getEndArray()->substractEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::multiply(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::multiply(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + getArray()->multiplyEqual(other->getArray()); + getEndArray()->multiplyEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !"); + DataArrayDouble *arr1=DataArrayDouble::divide(getArray(),other->getArray()); + DataArrayDouble *arr2=DataArrayDouble::divide(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + arr1->decrRef(); + ret->setEndArray(arr2,0); + arr2->decrRef(); + return ret; +} + +void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + getArray()->divideEqual(other->getArray()); + getEndArray()->divideEqual(other->getEndArray()); } diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx index 8ea2f8c6d..e826e12ce 100644 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ b/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -17,8 +17,8 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __MEDCOUPLINGTIMEDISCRETIZATION_HXX__ -#define __MEDCOUPLINGTIMEDISCRETIZATION_HXX__ +#ifndef __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ #include "MEDCoupling.hxx" #include "MEDCouplingTimeLabel.hxx" @@ -40,13 +40,23 @@ namespace ParaMEDMEM public: void updateTime(); static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); + virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - virtual bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(const MEDCouplingTimeDiscretization *other, TypeOfTimeDiscretization type, bool deepCpy) const; + virtual std::string getStringRepr() const = 0; virtual TypeOfTimeDiscretization getEnum() const = 0; virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; + virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; + virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; + virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; + virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0; virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0; virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0; virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0; @@ -66,27 +76,46 @@ namespace ParaMEDMEM virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) = 0; virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception) = 0; virtual void setArray(DataArrayDouble *array, TimeLabel *owner); + virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner); virtual void setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); DataArrayDouble *getArray() const { return _array; } - virtual DataArrayDouble *getEndArray() const { return _array; } + virtual DataArrayDouble *getEndArray() const; virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception) = 0; virtual void getValueForTime(double time, const std::vector& vals, double *res) const = 0; virtual void getArrays(std::vector& arrays) const; virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - double getTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { return getStartTime(dt,it); } - virtual double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) = 0; - virtual double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) = 0; - void setTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { setStartTime(time,dt,it); } - virtual void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) = 0; - virtual void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) = 0; + double getTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { return getStartTime(iteration,order); } + virtual double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) = 0; + virtual double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) = 0; + void setTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { setStartTime(time,iteration,order); } + virtual void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) = 0; + virtual void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) = 0; virtual void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception) = 0; - virtual void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception) = 0; + virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception) = 0; // + virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *determinant() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *eigenValues() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *eigenVectors() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *inverse() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *trace() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *deviator() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *magnitude() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *maxPerTuple() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector& compoIds) const throw(INTERP_KERNEL::Exception); + virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); + virtual void changeNbOfComponents(int newNbOfComp, double dftValue) throw(INTERP_KERNEL::Exception); + virtual void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); + virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value); virtual void applyLin(double a, double b, int compoId); virtual void applyFunc(int nbOfComp, FunctionToEvaluate func); virtual void applyFunc(int nbOfComp, const char *func); virtual void applyFunc(const char *func); + virtual void applyFuncFast32(const char *func); + virtual void applyFuncFast64(const char *func); + virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) throw(INTERP_KERNEL::Exception); + virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); // virtual ~MEDCouplingTimeDiscretization(); protected: @@ -101,8 +130,13 @@ namespace ParaMEDMEM public: MEDCouplingNoTimeLabel(); MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); + std::string getStringRepr() const; TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; void addEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; @@ -112,8 +146,10 @@ namespace ParaMEDMEM MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; void divideEqual(const MEDCouplingTimeDiscretization *other); bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; void checkNoTimePresence() const throw(INTERP_KERNEL::Exception) { } void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); @@ -121,14 +157,15 @@ namespace ParaMEDMEM void getValueForTime(double time, const std::vector& vals, double *res) const; bool isBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception); - double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception); - void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception); - void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception); + double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); + double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); + void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); - void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception); + void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); public: static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; + static const char REPR[]; private: static const char EXCEPTION_MSG[]; }; @@ -139,8 +176,14 @@ namespace ParaMEDMEM MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy); public: MEDCouplingWithTimeStep(); + std::string getStringRepr() const; + void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; void addEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; @@ -150,31 +193,33 @@ namespace ParaMEDMEM MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; void divideEqual(const MEDCouplingTimeDiscretization *other); bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); - void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _time=time; _dt=dt; _it=it; } - void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _time=time; _dt=dt; _it=it; } - double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_dt; it=_it; return _time; } - double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_dt; it=_it; return _time; } - DataArrayDouble *getArrayOnTime(double time) const throw(INTERP_KERNEL::Exception); + void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _time=time; _iteration=iteration; _order=order; } + void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _time=time; _iteration=iteration; _order=order; } + double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_iteration; order=_order; return _time; } + double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_iteration; order=_order; return _time; } std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); void getValueForTime(double time, const std::vector& vals, double *res) const; void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); - void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception); + void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); public: static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; + static const char REPR[]; private: static const char EXCEPTION_MSG[]; protected: double _time; - int _dt; - int _it; + int _iteration; + int _order; }; class MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization @@ -183,19 +228,27 @@ namespace ParaMEDMEM MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); public: MEDCouplingConstOnTimeInterval(); + void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); void getTinySerializationIntInformation(std::vector& tinyInfo) const; void getTinySerializationDbleInformation(std::vector& tinyInfo) const; void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - bool areCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); void getValueForTime(double time, const std::vector& vals, double *res) const; void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); - void getValueOnDiscTime(int eltId, int dt, int it, double *value) const throw(INTERP_KERNEL::Exception); + void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + std::string getStringRepr() const; MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; void addEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; @@ -204,56 +257,99 @@ namespace ParaMEDMEM void multiplyEqual(const MEDCouplingTimeDiscretization *other); MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; void divideEqual(const MEDCouplingTimeDiscretization *other); - void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_dt=dt; _start_it=it; } - void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_dt=dt; _end_it=it; } - double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_start_dt; it=_start_it; return _start_time; } - double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_end_dt; it=_end_it; return _end_time; } + void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; } + void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; } + double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; } + double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_end_iteration; order=_end_order; return _end_time; } void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); public: static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; + static const char REPR[]; private: static const char EXCEPTION_MSG[]; protected: double _start_time; double _end_time; - int _start_dt; - int _end_dt; - int _start_it; - int _end_it; + int _start_iteration; + int _end_iteration; + int _start_order; + int _end_order; }; class MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization { protected: + MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy); MEDCouplingTwoTimeSteps(); ~MEDCouplingTwoTimeSteps(); public: + void updateTime(); + void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); + DataArrayDouble *getEndArray() const; + void checkCoherency() const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); void getArrays(std::vector& arrays) const; - DataArrayDouble *getEndArray() const { return _end_array; } - void setStartTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_dt=dt; _start_it=it; } - void setEndTime(double time, int dt, int it) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_dt=dt; _end_it=it; } - double getStartTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_start_dt; it=_start_it; return _start_time; } - double getEndTime(int& dt, int& it) const throw(INTERP_KERNEL::Exception) { dt=_end_dt; it=_end_it; return _end_time; } + void setEndArray(DataArrayDouble *array, TimeLabel *owner); + void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _start_time=time; _start_iteration=iteration; _start_order=order; } + void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception) { _end_time=time; _end_iteration=iteration; _end_order=order; } + double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_start_iteration; order=_start_order; return _start_time; } + double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception) { iteration=_end_iteration; order=_end_order; return _end_time; } + void getTinySerializationIntInformation(std::vector& tinyInfo) const; + void getTinySerializationDbleInformation(std::vector& tinyInfo) const; + void getTinySerializationStrInformation(std::vector& tinyInfo) const; void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); + std::vector< const DataArrayDouble *> getArraysForTime(double time) const throw(INTERP_KERNEL::Exception); + void setArrays(const std::vector& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); + protected: + static const char EXCEPTION_MSG[]; protected: double _start_time; double _end_time; - int _start_dt; - int _end_dt; - int _start_it; - int _end_it; + int _start_iteration; + int _end_iteration; + int _start_order; + int _end_order; DataArrayDouble *_end_array; }; class MEDCOUPLING_EXPORT MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps { + protected: + MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy); public: + MEDCouplingLinearTime(); + std::string getStringRepr() const; TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + void checkCoherency() const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other) const; + bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + void getValueForTime(double time, const std::vector& vals, double *res) const; + void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); + void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); + MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; + MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; + void addEqual(const MEDCouplingTimeDiscretization *other); + MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; + void substractEqual(const MEDCouplingTimeDiscretization *other); + MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; + void multiplyEqual(const MEDCouplingTimeDiscretization *other); + MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; + void divideEqual(const MEDCouplingTimeDiscretization *other); + public: static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; + static const char REPR[]; }; } diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 62e64ce7e..11f9d12ea 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -25,9 +25,12 @@ #include "PointLocatorAlgos.txx" #include "BBTree.txx" #include "DirectedBoundingBox.hxx" +#include "InterpKernelMeshQuality.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" #include #include +#include #include #include @@ -35,6 +38,8 @@ using namespace ParaMEDMEM; const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_"; +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; + MEDCouplingUMesh *MEDCouplingUMesh::New() { return new MEDCouplingUMesh; @@ -48,6 +53,11 @@ MEDCouplingUMesh *MEDCouplingUMesh::New(const char *meshName, int meshDim) return ret; } +MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const +{ + return clone(true); +} + MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const { return new MEDCouplingUMesh(*this,recDeepCpy); @@ -71,6 +81,12 @@ MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2), { } +/*! + * This method checks that this is correctly designed. For example le coordinates are set, nodal connectivity. + * When this method returns without throwing any exception, 'this' is expected to be writable, exchangeable and to be + * available for most of algorithm. When a mesh has been constructed from scratch it is a good habits to call this method to check + * that all is in order in 'this'. + */ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) { if(_mesh_dim<-1) @@ -84,6 +100,20 @@ void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception) throw INTERP_KERNEL::Exception(message.str().c_str()); } } + if(_nodal_connec) + { + if(_nodal_connec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); + if(_nodal_connec->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); + } + if(_nodal_connec_index) + { + if(_nodal_connec_index->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); + if(_nodal_connec_index->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); + } } void MEDCouplingUMesh::setMeshDimension(int meshDim) @@ -178,6 +208,150 @@ bool MEDCouplingUMesh::isEqual(const MEDCouplingMesh *other, double prec) const return true; } +bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + return false; + if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) + return false; + if(_mesh_dim!=otherC->_mesh_dim) + return false; + if(_types!=otherC->_types) + return false; + if(_nodal_connec!=0 || otherC->_nodal_connec!=0) + if(_nodal_connec==0 || otherC->_nodal_connec==0) + return false; + if(_nodal_connec!=otherC->_nodal_connec) + if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec)) + return false; + if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) + if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) + return false; + if(_nodal_connec_index!=otherC->_nodal_connec_index) + if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index)) + return false; + return true; +} + +/*! + * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one + * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. + * + * In case of success cellCor and nodeCor are informed both. + * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method. + * @param cellCor output array giving the correspondance of cells from 'other' to 'this'. + * @param nodeCor output array giving the correspondance of nodes from 'other' to 'this'. + */ +void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !"); + MEDCouplingMesh::checkFastEquivalWith(other,prec); + if(_types!=otherC->_types) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !"); + MEDCouplingAutoRefCountObjectPtr m=mergeUMeshes(this,otherC); + bool areNodesMerged; + int newNbOfNodes; + int oldNbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(oldNbOfNodes,prec,areNodesMerged,newNbOfNodes); + //mergeNodes + if(!areNodesMerged) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); + const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),oldNbOfNodes-1)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !"); + m->renumberNodes(da->getConstPointer(),newNbOfNodes); + // + nodeCor=da->substr(oldNbOfNodes); + da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); + if(nodeCor->isIdentity()) + { + nodeCor->decrRef(); + nodeCor=0; + } + // + da=m->zipConnectivityTraducer(cellCompPol); + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); + pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + nodeCor->decrRef(); nodeCor=0; + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); + } + cellCor=DataArrayInt::New(); + cellCor->alloc(otherC->getNumberOfCells(),1); + std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor->getPointer()); + if(cellCor->isIdentity()) + { + cellCor->decrRef(); + cellCor=0; + } +} + +/*! + * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one + * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. The difference with MEDCouplingUMesh::checkDeepEquivalWith method is that + * coordinates of 'this' and 'other' are expected to be the same. If not an exception will be thrown. + * + * In case of success cellCor are informed both. + * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method. + * @param cellCor output array giving the correspondance of cells from 'other' to 'this'. + */ +void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Two meshes are not not unstructured !"); + MEDCouplingMesh::checkFastEquivalWith(other,prec); + if(_types!=otherC->_types) + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Types are not equal !"); + if(_coords!=otherC->_coords) + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); + std::vector ms(2); + ms[0]=const_cast(this); + ms[1]=const_cast(otherC); + MEDCouplingAutoRefCountObjectPtr m=mergeUMeshesOnSameCoords(ms); + MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); + const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); + } + cellCor=DataArrayInt::New(); + cellCor->alloc(otherC->getNumberOfCells(),1); + std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor->getPointer()); + if(cellCor->isIdentity()) + { + cellCor->decrRef(); + cellCor=0; + } +} + +/*! + * This method checks fastly that 'this' and 'other' are equal. + */ +void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) +{ + const MEDCouplingUMesh *otherC=dynamic_cast(other); + if(!otherC) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not not unstructured !"); + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + int nbOfCells=getNumberOfCells(); + if(nbOfCells<1) + return ; + bool status=true; + status&=areCellsFrom2MeshEqual(otherC,0,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); + if(!status) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); +} + /*! * \b WARNING this method do the assumption that connectivity lies on the coordinates set. * For speed reasons no check of this will be done. @@ -386,22 +560,22 @@ void MEDCouplingUMesh::convertToPolyTypes(const std::vector& cellIdsToConve int *newConnPtr=_nodal_connec->getPointer(); std::copy(connNew.begin(),connNew.end(),newConnPtr); } + computeTypes(); } /*! - * Array returned is the correspondance old to new. + * Array returned is the correspondance new to old. * The maximum value stored in returned array is the number of nodes of 'this' minus 1 after call of this method. * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. * -1 values in returned array means that the corresponding old node is no more used. */ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() { - DataArrayInt *ret=DataArrayInt::New(); int nbOfNodes=getNumberOfNodes(); - int spaceDim=getSpaceDimension(); - int *traducer=new int[nbOfNodes]; + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); std::fill(traducer,traducer+nbOfNodes,-1); - ret->useArray(traducer,true,CPP_DEALLOC,nbOfNodes,1); int nbOfCells=getNumberOfCells(); const int *connIndex=_nodal_connec_index->getConstPointer(); int *conn=_nodal_connec->getPointer(); @@ -415,79 +589,358 @@ DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() for(int j=connIndex[i]+1;j=0) conn[j]=traducer[conn[j]]; - DataArrayDouble *newCoords=DataArrayDouble::New(); - double *newCoordsPtr=new double[newNbOfNodes*spaceDim]; - const double *oldCoordsPtr=_coords->getConstPointer(); - newCoords->useArray(newCoordsPtr,true,CPP_DEALLOC,newNbOfNodes,spaceDim); - int *work=std::find_if(traducer,traducer+nbOfNodes,std::bind2nd(std::not_equal_to(),-1)); - for(;work!=traducer+nbOfNodes;work=std::find_if(work,traducer+nbOfNodes,std::bind2nd(std::not_equal_to(),-1))) - { - newCoordsPtr=std::copy(oldCoordsPtr+spaceDim*(work-traducer),oldCoordsPtr+spaceDim*(work-traducer+1),newCoordsPtr); - work++; - } + DataArrayDouble *newCoords=_coords->renumberAndReduce(traducer,newNbOfNodes); setCoords(newCoords); newCoords->decrRef(); return ret; } +/*! + * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. + * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + */ +bool MEDCouplingUMesh::areCellsEqual(int cell1, int cell2, int compType) const +{ + switch(compType) + { + case 0: + return areCellsEqual0(cell1,cell2); + case 1: + return areCellsEqual1(cell1,cell2); + case 2: + return areCellsEqual2(cell1,cell2); + } + throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1 or 2."); +} + +/*! + * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0. + */ +bool MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const +{ + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + return std::equal(conn+connI[cell1],conn+connI[cell1+1],conn+connI[cell2]); +} + +/*! + * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1. + */ +bool MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const +{ + throw INTERP_KERNEL::Exception("Policy comparison, not implemented yet !"); +} + +/*! + * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2. + */ +bool MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const +{ + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + std::set s1(conn+connI[cell1],conn+connI[cell1+1]); + std::set s2(conn+connI[cell2],conn+connI[cell2+1]); + return s1==s2; +} + +/*! + * This method compares 2 cells coming from two unstructured meshes : 'this' and 'other'. + * This method compares 2 cells having the same id 'cellId' in 'this' and 'other'. + */ +bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const +{ + if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) + return false; + std::vector c1,c2; + getNodeIdsOfCell(cellId,c1); + other->getNodeIdsOfCell(cellId,c2); + int sz=c1.size(); + if(sz!=(int)c2.size()) + return false; + for(int i=0;i n1,n2; + getCoordinatesOfNode(c1[0],n1); + other->getCoordinatesOfNode(c2[0],n2); + std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus()); + std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun(fabs)); + if(*std::max_element(n1.begin(),n1.end())>prec) + return false; + } + return true; +} + +/*! + * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. + * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned + * and result remains unchanged. + * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method. + * If in 'candidates' pool -1 value is considered as an empty value. + * WARNING this method returns only ONE set of result ! + */ +bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const +{ + std::set cand(candidates.begin(),candidates.end()); + cand.erase(-1); + if(cand.size()<=1) + return false; + std::set::const_iterator end=cand.end(); end--; + bool ret=false; + for(std::set::const_iterator iter=cand.begin();iter!=end && !ret;iter++) + { + std::set::const_iterator begin2=iter; begin2++; + for(std::set::const_iterator iter2=begin2;iter2!=cand.end();iter2++) + { + if(areCellsEqual(*iter,*iter2,compType)) + { + if(!ret) + { + result.push_back(*iter); + ret=true; + } + result.push_back(*iter2); + } + } + } + return ret; +} + +/*! + * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details. + * This method returns 2 values 'res' and 'resI'. + * If 'res' and 'resI' are not empty before calling this method they will be cleared before set. + * The format of 'res' and 'resI' is as explained here. + * resI.size()-1 is the number of set of cells equal. + * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n +void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const +{ + res.clear(); resI.clear(); + resI.push_back(0); + std::vector bbox; + int nbOfCells=getNumberOfCells(); + getBoundingBoxForBBTree(bbox); + double bb[2*SPACEDIM]; + double eps=getCaracteristicDimension(); + eps*=1.e-12; + BBTree myTree(&bbox[0],0,0,nbOfCells,-eps); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + const double *coords=getCoords()->getConstPointer(); + std::vector isFetched(nbOfCells); + for(int k=0;k::max(); bb[2*j+1]=-std::numeric_limits::max(); } + for(const int *pt=conn+connI[k]+1;pt!=conn+connI[k+1];pt++) + if(*pt>-1) + { + for(int j=0;j candidates1; + myTree.getIntersectingElems(bb,candidates1); + std::vector candidates; + for(std::vector::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++) + if(!isFetched[*iter]) + candidates.push_back(*iter); + if(areCellsEqualInPool(candidates,compType,res)) + { + int pos=resI.back(); + resI.push_back(res.size()); + for(std::vector::const_iterator it=res.begin()+pos;it!=res.end();it++) + isFetched[*it]=true; + } + isFetched[k]=true; + } + } +} + +/*! + * This method could potentially modify 'this'. This method merges cells if there are cells equal in 'this'. The comparison is specified by 'compType'. + * This method keeps the coordiantes of 'this'. + * + * @param compType input specifying the technique used to compare cells each other. + * 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy. + * 1 : permutation. cell1 and cell2 are equal if and the connectivity of cell2 can be deduced by those of cell1 by direct permutation and their type equal. + * 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. + * @return the correspondance array old to new. + */ +DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) +{ + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells(); + std::vector commonCells; + std::vector commonCellsI; + switch(spaceDim) + { + case 3: + { + findCommonCellsBase<3>(compType,commonCells,commonCellsI); + break; + } + case 2: + { + findCommonCellsBase<2>(compType,commonCells,commonCellsI); + break; + } + case 1: + { + findCommonCellsBase<1>(compType,commonCells,commonCellsI); + break; + } + default: + throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3."); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+nbOfCells,0); + const int nbOfTupleSmCells=commonCellsI.size()-1; + int id=-1; + std::vector cellsToKeep; + for(int i=0;i::const_iterator it=commonCells.begin()+commonCellsI[i];it!=commonCells.begin()+commonCellsI[i+1];it++) + retPtr[*it]=id; + id--; + } + id=0; + std::map m; + for(int i=0;i::const_iterator iter=m.find(val); + if(iter==m.end()) + { + m[val]=id; + retPtr[i]=id++; + cellsToKeep.push_back(i); + } + else + retPtr[i]=(*iter).second; + } + } + MEDCouplingUMesh *self=(MEDCouplingUMesh *)buildPartOfMySelf(&cellsToKeep[0],&cellsToKeep[0]+cellsToKeep.size(),true); + setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true); + self->decrRef(); + return ret; +} + /*! * @param areNodesMerged if at least two nodes have been merged. * @return old to new node correspondance. */ -DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged) +DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) { - DataArrayInt *comm,*commI; - findCommonNodes(comm,commI,precision); - int newNbOfNodes; - int oldNbOfNodes=getNumberOfNodes(); - DataArrayInt *ret=buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes); - areNodesMerged=(oldNbOfNodes!=newNbOfNodes); - comm->decrRef(); - commI->decrRef(); + DataArrayInt *ret=buildPermArrayForMergeNode(-1,precision,areNodesMerged,newNbOfNodes); if(areNodesMerged) renumberNodes(ret->getConstPointer(),newNbOfNodes); return ret; } /*! - * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [start,end). - * @param start start of array containing the cell ids to keep. + * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method : + * this->_coords==other->_coords. If not a exception is thrown this remains unchanged. + */ +void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +{ + DataArrayDouble *coords=other.getCoords(); + if(!coords) + throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !"); + if(!_coords) + throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); + int otherNbOfNodes=other.getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr newCoords=mergeNodesArray(&other,this); + _coords->incrRef(); + MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; + setCoords(newCoords); + bool areNodesMerged; + int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(otherNbOfNodes,epsilon,areNodesMerged,newNbOfNodes); + if(!areNodesMerged) + { + setCoords(oldCoords); + throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !"); + } + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes); + const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + setCoords(oldCoords); + throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); + } + setCoords(oldCoords); + renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); + setCoords(coords); +} + +/*! + * build a sub part of 'this'. This sub part is defined by the cell ids contained in the array in [begin,end). + * @param begin begin of array containing the cell ids to keep. * @param end end of array of cell ids to keep. \b WARNING end param is \b not included ! Idem STL standard definitions. * @param keepCoords that specifies if you want or not to keep coords as this or zip it (see zipCoords) */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const { if(getMeshDimension()!=-1) { - MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(start,end); + MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(begin,end); if(!keepCoords) ret->zipCoords(); return ret; } else { - if(end-start!=1) + if(end-begin!=1) throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); - if(start[0]!=0) + if(begin[0]!=0) throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); incrRef(); return (MEDCouplingUMesh *)this; } } +DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const +{ + std::vector cellIdsKept; + fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(cellIdsKept.size(),1); + std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer()); + return ret; +} + /*! - * Keeps from 'this' only cells which constituing point id are in the ids specified by ['start','end'). - * The return newly allocated mesh will share the same coordinates as 'this'. + * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). + * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not. - * If 'fullyIn' is true only cells whose ids are \b fully contained in ['start','end') tab will be kept. + * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept. + * + * @param begin input start of array of node ids. + * @param end input end of array of node ids. + * @param fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in. + * @param cellIdsKept in/out array where all candidate cell ids are put at the end. */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector& cellIdsKept) const { - std::set fastFinder(start,end); + std::set fastFinder(begin,end); + int nbOfCells=getNumberOfCells(); const int *conn=getNodalConnectivity()->getConstPointer(); const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector cellIdsKept; for(int i=0;i connOfCell(conn+connIndex[i]+1,conn+connIndex[i+1]); @@ -499,22 +952,34 @@ MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *start, c if(((int)locMerge.size()==refLgth && fullyIn) || (locMerge.size()!=0 && !fullyIn)) cellIdsKept.push_back(i); } +} + +/*! + * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). + * The return newly allocated mesh will share the same coordinates as 'this'. + * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not. + * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept. + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const +{ + std::vector cellIdsKept; + fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[0]+cellIdsKept.size(),true); } /*! - * Contrary to MEDCouplingUMesh::buildPartOfMySelfNode method this method a mesh with a meshDimension equal to + * Contrary to MEDCouplingUMesh::buildPartOfMySelfNode method this method builds a mesh with a meshDimension equal to * this->getMeshDimension()-1. The return newly allocated mesh will share the same coordinates as 'this'. * Parameter 'fullyIn' specifies if a face that has part of its nodes in ids array is kept or not. - * If 'fullyIn' is true only faces whose ids are \b fully contained in ['start','end') tab will be kept. + * If 'fullyIn' is true only faces whose ids are \b fully contained in ['begin','end') tab will be kept. */ -MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const { DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx; desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); MEDCouplingUMesh *subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); desc->decrRef(); descIndx->decrRef(); revDesc->decrRef(); revDescIndx->decrRef(); - MEDCouplingUMesh *ret=(MEDCouplingUMesh *)subMesh->buildPartOfMySelfNode(start,end,fullyIn); + MEDCouplingUMesh *ret=(MEDCouplingUMesh *)subMesh->buildPartOfMySelfNode(begin,end,fullyIn); subMesh->decrRef(); return ret; } @@ -585,12 +1050,23 @@ void MEDCouplingUMesh::findBoundaryNodes(std::vector& nodes) const * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes. * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes()) * This value is asked because often known by the caller of this method. + * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after. + * * @param newNodeNumbers array specifying the new numbering. * @param newNbOfNodes the new number of nodes. */ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) { MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes); + renumberNodesInConn(newNodeNumbers); +} + +/*! + * This method renumbers nodes in connectivity only without any reference with coords. + * Use it with care ! + */ +void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbers) +{ int *conn=getNodalConnectivity()->getPointer(); const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -608,8 +1084,10 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes } /*! - * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewEnd) - * If std::distance(old2NewBg,old2NewEnd)!=this->getNumberOfCells() an INTERP_KERNEL::Exception will be thrown. + * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) + * + * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. + * After the call of this method the number of cells remains the same as before. * * If 'check' equals true the method will check that any elements in [old2NewBg;old2NewEnd) is unique ; if not * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [old2NewBg;old2NewEnd) is not expected to @@ -619,14 +1097,12 @@ void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [old2NewBg;old2NewEnd) should be unique and * should be contained in[0;this->getNumberOfCells()). */ -void MEDCouplingUMesh::renumberCells(const int *old2NewBg, const int *old2NewEnd, bool check) +void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) { int nbCells=getNumberOfCells(); const int *array=old2NewBg; - if(std::distance(old2NewBg,old2NewEnd)!=nbCells) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::renumberCells expected to take an array of size getNumberOfCells !"); if(check) - array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewEnd); + array=DataArrayInt::checkAndPreparePermutation(old2NewBg,old2NewBg+nbCells); // const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); @@ -772,8 +1248,25 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]]; } +/*! + * Returns nb of cells having the geometric type 'type'. + */ +int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + int nbOfCells=getNumberOfCells(); + int ret=0; + for(int i=0;i& conn) const { @@ -794,6 +1287,75 @@ void MEDCouplingUMesh::getCoordinatesOfNode(int nodeId, std::vector& coo coo.insert(coo.end(),cooPtr+spaceDim*nodeId,cooPtr+spaceDim*(nodeId+1)); } +std::string MEDCouplingUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Unstructured mesh with name : \"" << getName() << "\"\n"; + ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : "; + if(_coords!=0) + ret << getSpaceDimension() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of nodes : "; + if(_coords!=0) + ret << getNumberOfNodes() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of cells : "; + if(_nodal_connec!=0 && _nodal_connec_index!=0) + ret << getNumberOfCells() << "\n"; + else + ret << "No connectivity specified !" << "\n"; + ret << "Cell types present : "; + for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(*iter); + ret << cm.getRepr() << " "; + } + ret << "\n"; + return ret.str(); +} + +std::string MEDCouplingUMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << simpleRepr(); + ret << "\nCoordinates array : \n___________________\n\n"; + if(_coords) + _coords->reprWithoutNameStream(ret); + else + ret << "No array set !\n"; + ret << "\n\nConnectivity arrays : \n_____________________\n\n"; + reprConnectivityOfThisLL(ret); + return ret.str(); +} +std::string MEDCouplingUMesh::reprConnectivityOfThis() const +{ + std::ostringstream ret; + reprConnectivityOfThisLL(ret); + return ret.str(); +} + +void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const +{ + if(_nodal_connec!=0 && _nodal_connec_index!=0) + { + int nbOfCells=getNumberOfCells(); + const int *c=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i(stream," ")); + stream << "\n"; + } + } + else + stream << "Connectivity not defined !\n"; +} + int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const { const int *ptI=_nodal_connec_index->getConstPointer(); @@ -919,7 +1481,7 @@ bool MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const * Second step of serialization process. * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ -void MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) +void MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const { MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings); if(tinyInfo[5]!=-1) @@ -950,7 +1512,7 @@ void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const * Second and final unserialization process. * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. */ -void MEDCouplingUMesh::unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) +void MEDCouplingUMesh::unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) { MEDCouplingPointSet::unserialization(tinyInfo,a1,a2,littleStrings); setMeshDimension(tinyInfo[3]); @@ -972,29 +1534,38 @@ void MEDCouplingUMesh::unserialization(const std::vector& tinyInfo, DataArr /*! * This is the low algorithm of buildPartOfMySelf. - * Keeps from 'this' only cells which constituing point id are in the ids specified by ['start','end'). + * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end'). * The return newly allocated mesh will share the same coordinates as 'this'. */ -MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *start, const int *end) const +MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const { checkFullyDefined(); MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - std::ostringstream stream; stream << PART_OF_NAME << getName(); - ret->setName(stream.str().c_str()); + std::string name(getName()); + int sz=strlen(PART_OF_NAME); + if((int)name.length()>=sz) + name=name.substr(0,sz); + if(name!=PART_OF_NAME) + { + std::ostringstream stream; stream << PART_OF_NAME << getName(); + ret->setName(stream.str().c_str()); + } + else + ret->setName(getName()); ret->_mesh_dim=_mesh_dim; ret->setCoords(_coords); - int nbOfElemsRet=end-start; + int nbOfElemsRet=end-begin; int *connIndexRet=new int[nbOfElemsRet+1]; connIndexRet[0]=0; const int *conn=_nodal_connec->getConstPointer(); const int *connIndex=_nodal_connec_index->getConstPointer(); int newNbring=0; - for(const int *work=start;work!=end;work++,newNbring++) + for(const int *work=begin;work!=end;work++,newNbring++) connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work]; int *connRet=new int[connIndexRet[nbOfElemsRet]]; int *connRetWork=connRet; std::set types; - for(const int *work=start;work!=end;work++) + for(const int *work=begin;work!=end;work++) { types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]); connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork); @@ -1047,8 +1618,7 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space); } if(isAbs) - for(int iel=0;iel(fabs)); } else { @@ -1132,15 +1702,15 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const } /*! - * This methods returns a vector newly created field on cells that represents the director vector of each 1D cell of this. + * This methods returns a vector newly created field on cells that represents the direction vector of each 1D cell of this. * This method is only callable on mesh with meshdim == 1 containing only SEG2. */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildLinearField() const +MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const { if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildLinearField !"); + throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !"); if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) - throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildLinearField !"); + throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !"); MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); DataArrayDouble *array=DataArrayDouble::New(); int nbOfCells=getNumberOfCells(); @@ -1178,7 +1748,7 @@ void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !"); if(getSpaceDimension()!=3) throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !"); - MEDCouplingFieldDouble *f=buildLinearField(); + MEDCouplingFieldDouble *f=buildDirectionVectorField(); const double *fPtr=f->getArray()->getConstPointer(); double tmp[3]; for(int i=0;i& cells) const { @@ -1352,10 +1924,585 @@ void MEDCouplingUMesh::checkButterflyCells(std::vector& cells) const } /*! - * This method aggregate the bbox of each cell and put it into bbox parameter. - * @param bbox out parameter of size 2*spacedim*nbOfcells. + * This method is \b NOT const because it can modify 'this'. + * 'this' is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. + * @param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. + * @param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), + * \b 1 for translation and rotation around point of 'mesh1D'. + * @return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than 'this'. */ -void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector& bbox) const +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy) +{ + checkFullyDefined(); + mesh1D->checkFullyDefined(); + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMeshFromThis method : must be meshDim==2 and spaceDim ==3 !"); + if(mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMeshFromThis method : must be meshDim==1 and spaceDim ==3 !"); + bool isQuad=false; + if(isPresenceOfQuadratic()) + { + if(mesh1D->isFullyQuadratic()) + isQuad=true; + else + throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !"); + } + zipCoords(); + int oldNbOfNodes=getNumberOfNodes(); + DataArrayDouble *newCoords=0; + switch(policy) + { + case 0: + { + newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad); + break; + } + default: + throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !"); + } + setCoords(newCoords); + newCoords->decrRef(); + MEDCouplingUMesh *ret=buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad); + updateTime(); + return ret; +} + +/*! + * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMeshFromThis method. + * @param mesh1D is the input 1D mesh used for translation computation. + * @return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + int oldNbOfNodes=getNumberOfNodes(); + int nbOf1DCells=mesh1D->getNumberOfCells(); + DataArrayDouble *ret=DataArrayDouble::New(); + std::vector isQuads; + int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1; + ret->alloc(oldNbOfNodes*nbOfLevsInVec,3); + double *retPtr=ret->getPointer(); + const double *coords=getCoords()->getConstPointer(); + double *work=std::copy(coords,coords+3*oldNbOfNodes,retPtr); + std::vector v; + std::vector c; + double vec[3]; + v.reserve(3); + c.reserve(6); + for(int i=0;igetNodeIdsOfCell(i,v); + c.resize(0); + mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus()); + for(int j=0;j()); + if(isQuad) + { + c.resize(0); + mesh1D->getCoordinatesOfNode(v[1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+3,c.begin()+3,vec,std::minus()); + for(int j=0;j()); + } + } + ret->copyStringInfoFrom(*getCoords()); + return ret; +} + +/*! + * This method is private because not easy to use for end user. This method is const contrary to + * MEDCouplingUMesh::buildExtrudedMeshFromThis method because this->_coords are expected to contain + * the coords sorted slice by slice. + * @param isQuad specifies presence of quadratic cells. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const +{ + int nbOf1DCells=getNumberOfNodes()/nbOfNodesOf1Lev-1; + int nbOf2DCells=getNumberOfCells(); + int nbOf3DCells=nbOf2DCells*nbOf1DCells; + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("Extruded",3); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + DataArrayInt *newConn=DataArrayInt::New(); + DataArrayInt *newConnI=DataArrayInt::New(); + newConnI->alloc(nbOf3DCells+1,1); + int *newConnIPtr=newConnI->getPointer(); + *newConnIPtr++=0; + std::vector newc; + for(int j=0;jalloc(newc.size()*nbOf1DCells,1); + int *newConnPtr=newConn->getPointer(); + int deltaPerLev=isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev; + newConnIPtr=newConnI->getPointer(); + for(int iz=0;iz(),newConnIPtr[iz*nbOf2DCells])); + for(std::vector::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++) + { + int icell=iter-newc.begin(); + if(std::find(newConnIPtr,newConnIPtr+nbOf2DCells,icell)==newConnIPtr+nbOf2DCells) + { + if(*iter!=-1) + *newConnPtr=(*iter)+iz*deltaPerLev; + else + *newConnPtr=-1; + } + else + *newConnPtr=(*iter); + } + } + ret->setConnectivity(newConn,newConnI,true); + newConn->decrRef(); + newConnI->decrRef(); + ret->setCoords(getCoords()); + return ret; +} + +/*! + * This method returns if 'this' is constituted by only quadratic cells. + */ +bool MEDCouplingUMesh::isFullyQuadratic() const +{ + checkFullyDefined(); + bool ret=true; + int nbOfCells=getNumberOfCells(); + for(int i=0;i newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); + newConn->alloc(getMeshLength()-delta,1); + newConnI->alloc(nbOfCells+1,1); + const int *icptr=_nodal_connec->getConstPointer(); + const int *iciptr=_nodal_connec_index->getConstPointer(); + int *ocptr=newConn->getPointer(); + int *ociptr=newConnI->getPointer(); + *ociptr=0; + _types.clear(); + for(int i=0;i& cells) const throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + for(int i=0;igetPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + bool isModified=false; + for(int i=0;i tmp(connI[i+1]-connI[i]-2); + std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2); + } + } + if(isModified) + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * This method checks that all polyhedrons cells have correctly oriented faces. + * If not, 'cells' parameter will be appended with cellIds of incorrect cells. + * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3 + */ +void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + for(int i=0;igetPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + bool isModified=false; + for(int i=0;ideclareAsNew(); + updateTime(); +} + +/*! + * This method has a sense for meshes with spaceDim==3 and meshDim==2. + * If it is not the case an exception will be thrown. + * This method is fast because the first cell of 'this' is used to compute the plane. + * @param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. + * @param pos output of size at least 3 used to store a point owned of searched plane. + */ +void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception) +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !"); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + INTERP_KERNEL::areaVectorOfPolygon(conn+1,connI[1]-connI[0]-1,coordsPtr,vec); + std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos); +} + +/*! + * The returned newly created field has to be managed by the caller. + * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown. + * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types. + * If a cell has an another type an exception will be thrown. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !"); + if(meshDim!=2 && meshDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !"); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + arr->decrRef(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;isetName("EdgeRatio"); + ret->incrRef(); + return ret; +} + +/*! + * The returned newly created field has to be managed by the caller. + * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown. + * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types. + * If a cell has an another type an exception will be thrown. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !"); + if(meshDim!=2 && meshDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !"); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + arr->decrRef(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;isetName("AspectRatio"); + ret->incrRef(); + return ret; +} + +/*! + * The returned newly created field has to be managed by the caller. + * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown. + * This method for the moment only deals with NORM_QUAD4 geometric type. + * If a cell has an another type an exception will be thrown. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !"); + if(meshDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + arr->decrRef(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;isetName("Warp"); + ret->incrRef(); + return ret; +} + +/*! + * The returned newly created field has to be managed by the caller. + * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown. + * This method for the moment only deals with NORM_QUAD4 geometric type. + * If a cell has an another type an exception will be thrown. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERNEL::Exception) +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !"); + if(meshDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + arr->decrRef(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;isetName("Skew"); + ret->incrRef(); + return ret; +} + +/*! + * This method aggregate the bbox of each cell and put it into bbox parameter. + * @param bbox out parameter of size 2*spacedim*nbOfcells. + */ +void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector& bbox) const { int spaceDim=getSpaceDimension(); int nbOfCells=getNumberOfCells(); @@ -1398,8 +2545,13 @@ namespace ParaMEDMEMImpl }; } +/*! + * This methods checks that cells are sorted by their types. + * This method makes asumption (no check) that connectivity is correctly set before calling. + */ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const { + checkFullyDefined(); const int *conn=_nodal_connec->getConstPointer(); const int *connI=_nodal_connec_index->getConstPointer(); int nbOfCells=getNumberOfCells(); @@ -1415,6 +2567,198 @@ bool MEDCouplingUMesh::checkConsecutiveCellTypes() const return true; } +/*! + * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check + * that the order is specified in array defined by [orderBg,orderEnd). + */ +bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + int lastPos=-1; + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + int pos=std::distance(orderBg,std::find(orderBg,orderEnd,curType)); + if(pos<=lastPos) + return false; + lastPos=pos; + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + } + return true; +} + +/*! + * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [orderBg,orderEnd) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation is 'this'. + * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. + * The mesh after this call will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. + * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. + */ +DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const +{ + checkFullyDefined(); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int *tmp=new int[nbOfCells]; + int minPos=std::numeric_limits::max(); + for(const int *i=connI;i!=connI+nbOfCells;i++) + { + int pos=std::distance(orderBg,std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i])); + tmp[std::distance(connI,i)]=pos; + minPos=std::min(minPos,pos); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *optr=ret->getPointer(); + int k=0; + while(minPos!=std::numeric_limits::max()) + { + int nextMinPos=std::numeric_limits::max(); + for(int j=0;j::max(); + } + else + nextMinPos=std::min(nextMinPos,tmp[j]); + } + minPos=nextMinPos; + } + delete [] tmp; + return ret; +} + +/*! + * This method reorganize the cells of 'this' so that the cells with same geometric types are put together. + * If checkConsecutiveCellTypes() returns true, this method do not change anything of this. + * The number of cells remains unchanged after the call of this method. + * @return the array giving the correspondance old to new. + */ +DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() +{ + checkFullyDefined(); + computeTypes(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector types; + for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());) + if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end()) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + types.push_back(curType); + for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+nbOfCells,-1); + int newCellId=0; + for(std::vector::const_iterator iter=types.begin();iter!=types.end();iter++) + { + for(const int *i=connI;i!=connI+nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) + retPtr[std::distance(connI,i)]=newCellId++; + } + renumberCells(retPtr,false); + return ret; +} + +/*! + * This methods split this into as mush as untructured meshes that consecutive set of same type cells. + * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. + * This method makes asumption that connectivity is correctly set before calling. + */ +std::vector MEDCouplingUMesh::splitByType() const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector ret; + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + int beginCellId=std::distance(connI,i); + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + int endCellId=std::distance(connI,i); + int sz=endCellId-beginCellId; + int *cells=new int[sz]; + for(int j=0;jgetNumberOfTuples()getNumberOfCells(). This method makes the assumption that ids contained in 'da' + * are in [0:getNumberOfCells()) + */ +DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception) +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::set types=getAllTypes(); + int *tmp=new int[nbOfCells]; + for(std::set::const_iterator iter=types.begin();iter!=types.end();iter++) + { + int j=0; + for(const int *i=connI;i!=connI+nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) + tmp[std::distance(connI,i)]=j++; + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents()); + ret->copyStringInfoFrom(*da); + int *retPtr=ret->getPointer(); + const int *daPtr=da->getConstPointer(); + int nbOfElems=da->getNbOfElems(); + for(int k=0;k& idsPerGeoType) const +{ + std::vector idsTokeep; + int nbOfCells=getNumberOfCells(); + int j=0; + for(int i=0;i(ret); + if(!ret2) + { + ret->decrRef(); + return 0; + } + ret2->setName(getName()); + return ret2; +} + /*! * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'. */ @@ -1444,15 +2788,9 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const const double *coor=_coords->getConstPointer(); for(int i=0;i()); - nbOfPts++; - } - ptToFill=std::transform(tmp,tmp+spaceDim,ptToFill,std::bind2nd(std::divides(),(double)nbOfPts)); + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]]; + INTERP_KERNEL::computeBarycenter2(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill); + ptToFill+=spaceDim; } delete [] tmp; return ret; @@ -1460,6 +2798,7 @@ DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const /*! * Returns a newly created mesh (with ref count ==1) that contains merge of 'mesh1' and 'other'. + * The coords of 'mesh2' are added at the end of coords of 'mesh1'. */ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) { @@ -1498,3 +2837,291 @@ MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshes(const MEDCouplingUMesh *mesh1, nodal->decrRef(); return ret; } + +/*! + * Idem mergeUMeshes except that 'meshes' are expected to lyie on the same coords and 'meshes' have the same meshdim. + * 'meshes' must be a non empty vector. + */ +MEDCouplingUMesh *MEDCouplingUMesh::mergeUMeshesOnSameCoords(const std::vector& meshes) +{ + if(meshes.empty()) + throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty."); + DataArrayDouble *coords=meshes.front()->getCoords(); + int meshDim=meshes.front()->getMeshDimension(); + std::vector::const_iterator iter=meshes.begin(); + int meshLgth=0; + int meshIndexLgth=0; + for(;iter!=meshes.end();iter++) + { + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !"); + if(meshDim!=(*iter)->getMeshDimension()) + throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, fuseUMeshesOnSameCoords impossible !"); + meshLgth+=(*iter)->getMeshLength(); + meshIndexLgth+=(*iter)->getNumberOfCells(); + } + DataArrayInt *nodal=DataArrayInt::New(); + nodal->alloc(meshLgth,1); + int *nodalPtr=nodal->getPointer(); + DataArrayInt *nodalIndex=DataArrayInt::New(); + nodalIndex->alloc(meshIndexLgth+1,1); + int *nodalIndexPtr=nodalIndex->getPointer(); + int offset=0; + for(iter=meshes.begin();iter!=meshes.end();iter++) + { + const int *nod=(*iter)->getNodalConnectivity()->getConstPointer(); + const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=(*iter)->getNumberOfCells(); + int meshLgth=(*iter)->getMeshLength(); + nodalPtr=std::copy(nod,nod+meshLgth,nodalPtr); + if(iter!=meshes.begin()) + nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus(),offset)); + else + nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr); + offset+=meshLgth; + } + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName("merge"); + ret->setMeshDimension(meshDim); + ret->setConnectivity(nodal,nodalIndex,true); + ret->setCoords(coords); + nodalIndex->decrRef(); + nodal->decrRef(); + return ret; +} + +/*! + * This method fuses meshes 'meshes' and returns the fused mesh and the correspondances arrays for each mesh in 'meshes' in returned mesh. + * If a same cell is detected in several meshes in 'meshes', this cell will appear only once in returned mesh (see ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for more details) + * + * @param meshes input non empty vector containing meshes having same coordiantes array and same mesh dimension. + * @param compType see MEDCouplingUMesh::zipConnectivityTraducer + * @param corr output vector with same size as 'meshes' parameter. corr[i] is the correspondance array of mesh meshes[i] in returned mesh. + * The arrays contained in 'corr' parameter are returned with refcounter set to one. + * To avoid memory leaks the caller have to deal with each instances of DataArrayInt contained in 'corr' parameter. + * @return The mesh lying on the same coordinates than those in meshes. All cells in 'meshes' are in returned mesh with + * @exception if meshes is a empty vector or meshes are not lying on same coordinates or meshes not have the same dimension. + */ +MEDCouplingUMesh *MEDCouplingUMesh::fuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr) +{ + //All checks are delegated to mergeUMeshesOnSameCoords + MEDCouplingUMesh *ret=mergeUMeshesOnSameCoords(meshes); + DataArrayInt *o2n=ret->zipConnectivityTraducer(compType); + corr.resize(meshes.size()); + int nbOfMeshes=meshes.size(); + int offset=0; + const int *o2nPtr=o2n->getConstPointer(); + for(int i=0;igetNumberOfCells(); + tmp->alloc(curNbOfCells,1); + std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer()); + offset+=curNbOfCells; + corr[i]=tmp; + } + o2n->decrRef(); + return ret; +} + +/*! + * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [connBg,connEnd) and returns its extruded cell by inserting the result at the end of ret. + * @param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset + * @param isQuad specifies the policy of connectivity. + * @ret in/out parameter in which the result will be append + */ +void MEDCouplingUMesh::appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret) +{ + INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::getCellModel(flatType); + ret.push_back(cm.getExtrudedType()); + int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev; + switch(flatType) + { + case INTERP_KERNEL::NORM_POINT0: + { + ret.push_back(connBg[1]); + ret.push_back(connBg[1]+nbOfNodesPerLev); + break; + } + case INTERP_KERNEL::NORM_SEG2: + { + int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz}; + ret.insert(ret.end(),conn,conn+4); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_QUAD4: + { + int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_TRI3: + { + int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz}; + ret.insert(ret.end(),conn,conn+6); + break; + } + case INTERP_KERNEL::NORM_TRI6: + { + int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+15); + break; + } + case INTERP_KERNEL::NORM_QUAD8: + { + int conn[20]={ + connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz, + connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev + }; + ret.insert(ret.end(),conn,conn+20); + break; + } + case INTERP_KERNEL::NORM_POLYGON: + { + std::back_insert_iterator< std::vector > ii(ret); + std::copy(connBg+1,connEnd,ii); + *ii++=-1; + std::reverse_iterator rConnBg(connEnd); + std::reverse_iterator rConnEnd(connBg+1); + std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus(),deltaz)); + int nbOfRadFaces=std::distance(connBg+1,connEnd); + for(int i=0;i > edges; + int nbOfFaces=std::count(begin,end,-1)+1; + const int *bgFace=begin; + for(int i=0;i p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + if(std::find(edges.begin(),edges.end(),p1)!=edges.end()) + return false; + edges.push_back(p1); + } + bgFace=endFace+1; + } + return INTERP_KERNEL::calculateVolumeForPolyh2(begin,std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION; +} + +/*! + * This method tries to obtain a well oriented polyhedron. + * If the algorithm fails, an exception will be thrown. + */ +void MEDCouplingUMesh::tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception) +{ + std::vector > edges; + int nbOfFaces=std::count(begin,end,-1)+1; + int *bgFace=begin; + std::vector isPerm(nbOfFaces); + for(int i=0;i p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); + edges.push_back(p1); + } + int *bgFace2=endFace+1; + for(int k=i+1;k p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]); + if(std::find(edges.begin(),edges.end(),p2)!=edges.end()) + { + if(isPerm[k]) + throw INTERP_KERNEL::Exception("Fail to repare polyhedron ! Polyedron looks bad !"); + std::vector tmp(nbOfEdgesInFace2-1); + std::copy(bgFace2+1,endFace2,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),bgFace2+1); + isPerm[k]=true; + continue; + } + } + bgFace2=endFace2+1; + } + bgFace=endFace+1; + } + if(INTERP_KERNEL::calculateVolumeForPolyh2(begin,std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION) + {//not lucky ! The first face was not correctly oriented : reorient all faces... + bgFace=begin; + for(int i=0;i tmp(nbOfEdgesInFace-1); + std::copy(bgFace+1,endFace,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),bgFace+1); + bgFace=endFace+1; + } + } +} + +/*! + * This method put in zip format into parameter 'zipFrmt' in full interlace mode. + * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array. + */ +void MEDCouplingUMesh::fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception) +{ + double *w=zipFrmt; + if(spaceDim==3) + for(int i=0;i& conn) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const; MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; MEDCOUPLING_EXPORT int getNumberOfCells() const; MEDCOUPLING_EXPORT int getMeshDimension() const; MEDCOUPLING_EXPORT int getMeshLength() const; + MEDCOUPLING_EXPORT void computeTypes(); //! size of returned tinyInfo must be always the same. MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings); + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); + MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); //tools + MEDCOUPLING_EXPORT bool areCellsEqual(int cell1, int cell2, int compType) const; + MEDCOUPLING_EXPORT bool areCellsEqual0(int cell1, int cell2) const; + MEDCOUPLING_EXPORT bool areCellsEqual1(int cell1, int cell2) const; + MEDCOUPLING_EXPORT bool areCellsEqual2(int cell1, int cell2) const; + MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const; MEDCOUPLING_EXPORT void convertToPolyTypes(const std::vector& cellIdsToConvert); MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); + MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType); MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, const int *old2NewEnd, bool check); + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildLinearField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildDirectionVectorField() const; MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const; MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; MEDCOUPLING_EXPORT void checkButterflyCells(std::vector& cells) const; MEDCOUPLING_EXPORT void getBoundingBoxForBBTree(std::vector& bbox) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy); + MEDCOUPLING_EXPORT bool isFullyQuadratic() const; + MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; + MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector& cells) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception); + //Mesh quality + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); + //utilities for MED File RW MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; + MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); + MEDCOUPLING_EXPORT std::vector splitByType() const; + MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const std::vector& idsPerGeoType) const; + // MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *mergeUMeshesOnSameCoords(const std::vector& meshes); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *fuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); + MEDCOUPLING_EXPORT static bool isPolygonWellOriented(const double *vec, const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static bool isPolyhedronWellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static void tryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception); private: MEDCouplingUMesh(); MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCpy); ~MEDCouplingUMesh(); - void computeTypes(); void checkFullyDefined() const throw(INTERP_KERNEL::Exception); + void reprConnectivityOfThisLL(std::ostringstream& stream) const; //tools - MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *start, const int *end) const; + void renumberNodesInConn(const int *newNodeNumbers); + void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector& cellIdsKept) const; + MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; + template + void findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const; + bool areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const; + MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; template void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const; + static void fillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception); + static void appendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); private: //! this iterator stores current position in _nodal_connec array. mutable int _iterator; @@ -108,6 +164,8 @@ namespace ParaMEDMEM std::set _types; private: static const char PART_OF_NAME[]; + public: + static double EPS_FOR_POLYH_ORIENTATION; }; } diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx index 29f1e58e3..f45cd5eba 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.cxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.cxx @@ -55,6 +55,14 @@ MEDCouplingUMeshDesc *MEDCouplingUMeshDesc::New(const char *meshName, int meshDi return ret; } +/*! + * not implemented + */ +MEDCouplingMesh *MEDCouplingUMeshDesc::deepCpy() const +{ + return 0; +} + void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception) { for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) @@ -68,6 +76,18 @@ void MEDCouplingUMeshDesc::checkCoherency() const throw(INTERP_KERNEL::Exception } } +void MEDCouplingUMeshDesc::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalWith : not implemented yet !"); +} + +void MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("MEDCouplingUMeshDesc::checkDeepEquivalOnSameNodesWith : not implemented yet !"); +} + void MEDCouplingUMeshDesc::setMeshDimension(unsigned meshDim) { _mesh_dim=meshDim; @@ -107,6 +127,18 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshDesc::getTypeOfCell(int cellId return (INTERP_KERNEL::NormalizedCellType)desc_connec[desc_connec_index[cellId]+1]; } +int MEDCouplingUMeshDesc::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + const int *desc_connec=_desc_connec->getConstPointer(); + const int *desc_connec_index=_desc_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + int ret=0; + for(int i=0;i& conn) const { //not implemented yet. @@ -117,6 +149,22 @@ void MEDCouplingUMeshDesc::getCoordinatesOfNode(int nodeId, std::vector& //not implemented yet. } +std::string MEDCouplingUMeshDesc::simpleRepr() const +{ + std::string ret("Unstructured mesh with descending connectivity : "); + ret+=getName(); + ret+="\n"; + return ret; +} + +std::string MEDCouplingUMeshDesc::advancedRepr() const +{ + std::string ret("Unstructured mesh with descending connectivity : "); + ret+=getName(); + ret+="\n"; + return ret; +} + void MEDCouplingUMeshDesc::setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx) { DataArrayInt::setArrayIn(descConn,_desc_connec); @@ -283,13 +331,18 @@ void MEDCouplingUMeshDesc::giveElemsInBoundingBox(const INTERP_KERNEL::DirectedB delete [] elem_bb; } -DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged) +DataArrayInt *MEDCouplingUMeshDesc::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) { //not implemented yet. areNodesMerged=false; return 0; } +void MEDCouplingUMeshDesc::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + MEDCouplingPointSet *MEDCouplingUMeshDesc::buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const { //not implemented yet. @@ -319,6 +372,11 @@ MEDCouplingPointSet *MEDCouplingUMeshDesc::buildBoundaryMesh(bool keepCoords) co return 0; } +void MEDCouplingUMeshDesc::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception) +{ + throw INTERP_KERNEL::Exception("Available for UMesh desc but not implemented yet !"); +} + void MEDCouplingUMeshDesc::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) { MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes); diff --git a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx index 91ce649ed..7c965a31c 100644 --- a/src/MEDCoupling/MEDCouplingUMeshDesc.hxx +++ b/src/MEDCoupling/MEDCouplingUMeshDesc.hxx @@ -33,7 +33,12 @@ namespace ParaMEDMEM public: MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(); MEDCOUPLING_EXPORT static MEDCouplingUMeshDesc *New(const char *meshName, int meshDim); + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; MEDCOUPLING_EXPORT void checkCoherency() const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void setMeshDimension(unsigned meshDim); MEDCOUPLING_EXPORT int getNumberOfCells() const; MEDCOUPLING_EXPORT int getNumberOfFaces() const; @@ -41,8 +46,11 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT int getFaceMeshLength() const; MEDCOUPLING_EXPORT int getMeshDimension() const { return _mesh_dim; } MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED_DESC; } MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *descConn, DataArrayInt *descConnIndex, DataArrayInt *nodalFaceConn, DataArrayInt *nodalFaceConnIndx); //tools to overload @@ -53,12 +61,14 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems); MEDCOUPLING_EXPORT void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox &bbox, double eps, std::vector& elems); - MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged); + MEDCOUPLING_EXPORT DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; MEDCOUPLING_EXPORT void findBoundaryNodes(std::vector& nodes) const; MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; diff --git a/src/MEDCoupling/Makefile.am b/src/MEDCoupling/Makefile.am index 20117023a..28553f288 100644 --- a/src/MEDCoupling/Makefile.am +++ b/src/MEDCoupling/Makefile.am @@ -36,17 +36,19 @@ MEDCouplingCMesh.hxx MEDCouplingTimeDiscretization.hxx MEDCouplingFieldDiscretization.hxx MEDCouplingPointSet.hxx MEDCouplingPointSet.txx \ MEDCouplingUMeshDesc.hxx MEDCouplingNatureOfField.hxx \ MEDCouplingNormalizedCartesianMesh.hxx MEDCouplingNormalizedCartesianMesh.txx \ -MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx +MEDCouplingRemapper.hxx MEDCouplingExtrudedMesh.hxx MEDCouplingGaussLocalization.hxx \ +MEDCouplingAutoRefCountObjectPtr.hxx # Libraries targets dist_libmedcoupling_la_SOURCES = \ - MEDCouplingField.cxx MEDCouplingFieldDouble.cxx \ - MEDCouplingUMesh.cxx MEDCouplingMemArray.cxx MEDCouplingTimeLabel.cxx \ - MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx \ - MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx \ - MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx \ - MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx + MEDCouplingField.cxx MEDCouplingFieldDouble.cxx \ + MEDCouplingUMesh.cxx MEDCouplingMemArray.cxx MEDCouplingTimeLabel.cxx \ + MEDCouplingCMesh.cxx MEDCouplingTimeDiscretization.cxx \ + MEDCouplingFieldDiscretization.cxx MEDCouplingRefCountObject.cxx \ + MEDCouplingPointSet.cxx MEDCouplingUMeshDesc.cxx \ + MEDCouplingExtrudedMesh.cxx MEDCouplingMesh.cxx MEDCouplingGaussLocalization.cxx \ + MEDCouplingNatureOfField.cxx libmedcoupling_la_LDFLAGS= @@ -70,9 +72,6 @@ libmedcouplingremapper_la_LIBADD = libmedcoupling.la AM_CPPFLAGS += $(libinterpkernel_la_CPPFLAGS) LDADD= $(libinterpkernel_la_LDFLAGS) -if MED_ENABLE_KERNEL - LDADD+=-lSALOMEBasics -endif EXTRA_DIST += \ MEDCouplingFieldDouble.hxx \ @@ -92,4 +91,6 @@ EXTRA_DIST += \ MEDCouplingPointSet.txx \ MEDCouplingUMeshDesc.hxx \ MEDCouplingNatureOfField.hxx \ - MEDCouplingRemapper.hxx + MEDCouplingRemapper.hxx \ + MEDCouplingExtrudedMesh.hxx \ + MEDCouplingGaussLocalization.hxx diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx index 87393c8f9..569560584 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -32,7 +32,10 @@ namespace ParaMEDMEM class MEDCouplingBasicsTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest); + //MEDCouplingBasicsTest1.cxx CPPUNIT_TEST( testArray ); + CPPUNIT_TEST( testArray2 ); + CPPUNIT_TEST( testArray3 ); CPPUNIT_TEST( testMesh ); CPPUNIT_TEST( testMeshPointsCloud ); CPPUNIT_TEST( testMeshM1D ); @@ -46,15 +49,19 @@ namespace ParaMEDMEM CPPUNIT_TEST( testBuildPartOfMySelf ); CPPUNIT_TEST( testBuildPartOfMySelfNode ); CPPUNIT_TEST( testZipCoords ); + CPPUNIT_TEST( testZipConnectivity ); CPPUNIT_TEST( testEqualMesh ); CPPUNIT_TEST( testEqualFieldDouble ); CPPUNIT_TEST( testNatureChecking ); CPPUNIT_TEST( testBuildSubMeshData ); CPPUNIT_TEST( testExtrudedMesh1 ); CPPUNIT_TEST( testExtrudedMesh2 ); + CPPUNIT_TEST( testExtrudedMesh3 ); + CPPUNIT_TEST( testExtrudedMesh4 ); CPPUNIT_TEST( testFindCommonNodes ); CPPUNIT_TEST( testCheckButterflyCells ); CPPUNIT_TEST( testMergeMesh1 ); + CPPUNIT_TEST( testMergeMeshOnSameCoords1 ); CPPUNIT_TEST( testMergeField1 ); CPPUNIT_TEST( testFillFromAnalytic ); CPPUNIT_TEST( testFillFromAnalytic2 ); @@ -63,8 +70,13 @@ namespace ParaMEDMEM CPPUNIT_TEST( testOperationsOnFields ); CPPUNIT_TEST( testOperationsOnFields2 ); CPPUNIT_TEST( testOperationsOnFields3 ); + CPPUNIT_TEST( testOperationsOnFields4 ); CPPUNIT_TEST( testMergeNodesOnField ); CPPUNIT_TEST( testCheckConsecutiveCellTypes ); + CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes ); + CPPUNIT_TEST( testSplitByType ); + CPPUNIT_TEST( testFuseUMeshesOnSameCoords ); + CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 ); CPPUNIT_TEST( testBuildOrthogonalField ); CPPUNIT_TEST( testGetCellsContainingPoint ); CPPUNIT_TEST( testGetValueOn1 ); @@ -74,6 +86,64 @@ namespace ParaMEDMEM CPPUNIT_TEST( testFindNodeOnPlane ); CPPUNIT_TEST( testRenumberCells ); CPPUNIT_TEST( testChangeSpaceDimension ); + //MEDCouplingBasicsTest2.cxx + CPPUNIT_TEST( testGaussPointField1 ); + CPPUNIT_TEST( testGaussPointNEField1 ); + CPPUNIT_TEST( testCellOrientation1 ); + CPPUNIT_TEST( testCellOrientation2 ); + CPPUNIT_TEST( testPolyhedronBarycenter ); + CPPUNIT_TEST( testNormL12Integ1D ); + CPPUNIT_TEST( testAreaBary2D ); + CPPUNIT_TEST( testAreaBary3D ); + CPPUNIT_TEST( testRenumberCellsForFields ); + CPPUNIT_TEST( testRenumberNodesForFields ); + CPPUNIT_TEST( testConvertQuadraticCellsToLinear ); + CPPUNIT_TEST( testCheckGeoEquivalWith ); + CPPUNIT_TEST( testCheckGeoEquivalWith2 ); + CPPUNIT_TEST( testCopyTinyStringsFromOnFields ); + CPPUNIT_TEST( testTryToShareSameCoordsPermute ); + CPPUNIT_TEST( testTryToShareSameCoordsPermute2 ); + CPPUNIT_TEST( testChangeUnderlyingMesh1 ); + CPPUNIT_TEST( testGetMaxValue1 ); + CPPUNIT_TEST( testSubstractInPlaceDM1 ); + CPPUNIT_TEST( testDotCrossProduct1 ); + CPPUNIT_TEST( testMinMaxFields1 ); + CPPUNIT_TEST( testApplyLin1 ); + CPPUNIT_TEST( testGetIdsInRange1 ); + CPPUNIT_TEST( testBuildSubPart1 ); + CPPUNIT_TEST( testDoublyContractedProduct1 ); + CPPUNIT_TEST( testDeterminant1 ); + CPPUNIT_TEST( testEigenValues1 ); + CPPUNIT_TEST( testEigenVectors1 ); + CPPUNIT_TEST( testInverse1 ); + CPPUNIT_TEST( testTrace1 ); + CPPUNIT_TEST( testDeviator1 ); + CPPUNIT_TEST( testMagnitude1 ); + CPPUNIT_TEST( testMaxPerTuple1 ); + CPPUNIT_TEST( testChangeNbOfComponents ); + CPPUNIT_TEST( testSortPerTuple1 ); + CPPUNIT_TEST( testIsEqualWithoutConsideringStr1 ); + CPPUNIT_TEST( testGetNodeIdsOfCell1 ); + CPPUNIT_TEST( testGetEdgeRatioField1 ); + CPPUNIT_TEST( testFillFromAnalytic3 ); + CPPUNIT_TEST( testFieldDoubleOpEqual1 ); + CPPUNIT_TEST( testAreaBary3D2 ); + CPPUNIT_TEST( testGetMeasureFieldCMesh1 ); + CPPUNIT_TEST( testFieldDoubleZipCoords1 ); + CPPUNIT_TEST( testFieldDoubleZipConnectivity1 ); + CPPUNIT_TEST( testDaDoubleRenumber1 ); + CPPUNIT_TEST( testDaDoubleRenumberAndReduce1 ); + CPPUNIT_TEST( testDaDoubleRenumberInPlace1 ); + CPPUNIT_TEST( testDaDoubleSelectByTupleId1 ); + CPPUNIT_TEST( testDaDoubleRenumberR1 ); + CPPUNIT_TEST( testDaDoubleRenumberInPlaceR1 ); + CPPUNIT_TEST( testDaDoubleGetMinMaxValues1 ); + CPPUNIT_TEST( testFieldDoubleGetMinMaxValues2 ); + CPPUNIT_TEST( testBuildUnstructuredCMesh1 ); + CPPUNIT_TEST( testDataArrayIntInvertO2NNO21 ); + CPPUNIT_TEST( testKeepSetSelectedComponent1 ); + CPPUNIT_TEST( testKeepSetSelectedComponent2 ); + //MEDCouplingBasicsTestInterp.cxx CPPUNIT_TEST( test2DInterpP0P0_1 ); CPPUNIT_TEST( test2DInterpP0P0PL_1 ); CPPUNIT_TEST( test2DInterpP0P0PL_2 ); @@ -131,10 +201,12 @@ namespace ParaMEDMEM CPPUNIT_TEST( test2DCurveInterpP0P1_1 ); CPPUNIT_TEST( test2DCurveInterpP1P0_1 ); CPPUNIT_TEST( test2DCurveInterpP1P1_1 ); - CPPUNIT_TEST_SUITE_END(); public: + //MEDCouplingBasicsTest1.cxx void testArray(); + void testArray2(); + void testArray3(); void testMesh(); void testMeshPointsCloud(); void testMeshM1D(); @@ -148,15 +220,19 @@ namespace ParaMEDMEM void testBuildPartOfMySelf(); void testBuildPartOfMySelfNode(); void testZipCoords(); + void testZipConnectivity(); void testEqualMesh(); void testEqualFieldDouble(); void testNatureChecking(); void testBuildSubMeshData(); void testExtrudedMesh1(); void testExtrudedMesh2(); + void testExtrudedMesh3(); + void testExtrudedMesh4(); void testFindCommonNodes(); void testCheckButterflyCells(); void testMergeMesh1(); + void testMergeMeshOnSameCoords1(); void testMergeField1(); void testFillFromAnalytic(); void testFillFromAnalytic2(); @@ -165,8 +241,13 @@ namespace ParaMEDMEM void testOperationsOnFields(); void testOperationsOnFields2(); void testOperationsOnFields3(); + void testOperationsOnFields4(); void testMergeNodesOnField(); void testCheckConsecutiveCellTypes(); + void testRearrange2ConsecutiveCellTypes(); + void testSplitByType(); + void testFuseUMeshesOnSameCoords(); + void testFuseUMeshesOnSameCoords2(); void testBuildOrthogonalField(); void testGetCellsContainingPoint(); void testGetValueOn1(); @@ -176,6 +257,64 @@ namespace ParaMEDMEM void testFindNodeOnPlane(); void testRenumberCells(); void testChangeSpaceDimension(); + //MEDCouplingBasicsTest2.cxx + void testGaussPointField1(); + void testGaussPointNEField1(); + void testCellOrientation1(); + void testCellOrientation2(); + void testPolyhedronBarycenter(); + void testNormL12Integ1D(); + void testAreaBary2D(); + void testAreaBary3D(); + void testRenumberCellsForFields(); + void testRenumberNodesForFields(); + void testConvertQuadraticCellsToLinear(); + void testCheckGeoEquivalWith(); + void testCheckGeoEquivalWith2(); + void testCopyTinyStringsFromOnFields(); + void testTryToShareSameCoordsPermute(); + void testTryToShareSameCoordsPermute2(); + void testChangeUnderlyingMesh1(); + void testGetMaxValue1(); + void testSubstractInPlaceDM1(); + void testDotCrossProduct1(); + void testMinMaxFields1(); + void testApplyLin1(); + void testGetIdsInRange1(); + void testBuildSubPart1(); + void testDoublyContractedProduct1(); + void testDeterminant1(); + void testEigenValues1(); + void testEigenVectors1(); + void testInverse1(); + void testTrace1(); + void testDeviator1(); + void testMagnitude1(); + void testMaxPerTuple1(); + void testChangeNbOfComponents(); + void testSortPerTuple1(); + void testIsEqualWithoutConsideringStr1(); + void testGetNodeIdsOfCell1(); + void testGetEdgeRatioField1(); + void testFillFromAnalytic3(); + void testFieldDoubleOpEqual1(); + void testAreaBary3D2(); + void testGetMeasureFieldCMesh1(); + void testFieldDoubleZipCoords1(); + void testFieldDoubleZipConnectivity1(); + void testDaDoubleRenumber1(); + void testDaDoubleRenumberAndReduce1(); + void testDaDoubleRenumberInPlace1(); + void testDaDoubleSelectByTupleId1(); + void testDaDoubleRenumberR1(); + void testDaDoubleRenumberInPlaceR1(); + void testDaDoubleGetMinMaxValues1(); + void testFieldDoubleGetMinMaxValues2(); + void testBuildUnstructuredCMesh1(); + void testDataArrayIntInvertO2NNO21(); + void testKeepSetSelectedComponent1(); + void testKeepSetSelectedComponent2(); + //MEDCouplingBasicsTestInterp.cxx void test2DInterpP0P0_1(); void test2DInterpP0P0PL_1(); void test2DInterpP0P0PL_2(); @@ -259,6 +398,15 @@ namespace ParaMEDMEM static MEDCouplingUMesh *build2DTargetMeshMerged_1(); static MEDCouplingUMesh *build2DCurveMesh(double dx, double dy); static MEDCouplingUMesh *build1DMesh(double dx); + static MEDCouplingUMesh *build1DSourceMesh_2(); + static MEDCouplingUMesh *build1DTargetMesh_2(); + static MEDCouplingUMesh *build2DCurveSourceMesh_2(); + static MEDCouplingUMesh *build2DCurveTargetMesh_2(); + static MEDCouplingUMesh *build1DTargetMesh_3(); + static MEDCouplingUMesh *build2DCurveTargetMesh_3(); + static MEDCouplingUMesh *build2DTargetMesh_3(); + static MEDCouplingUMesh *build3DTargetMesh_3(); + static MEDCouplingUMesh *build2DTargetMesh_4(); static double sumAll(const std::vector< std::map >& matrix); }; } diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx index 959a8c2c3..3f7adf58a 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx @@ -678,6 +678,170 @@ MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMesh(double dx) return targetMesh; } +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DSourceMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); + ret->allocateCells(4); + int conn[8]={0,1,2,3,1,2,3,4}; + for(int i=0;i<4;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[5]={0.3,0.7,0.9,1.0,1.12}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,1); + std::copy(coords,coords+5,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); + ret->allocateCells(2); + int conn[4]={1,2,0,1}; + for(int i=0;i<2;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[3]={0.5,0.75,1.2}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,1); + std::copy(coords,coords+3,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveSourceMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); + ret->allocateCells(4); + int conn[8]={0,1,2,3,1,2,3,4}; + for(int i=0;i<4;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[10]={0.3,0.3,0.7,0.7,0.9,0.9,1.0,1.0,1.12,1.12}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,2); + std::copy(coords,coords+10,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); + ret->allocateCells(2); + int conn[4]={1,2,0,1}; + for(int i=0;i<2;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[6]={0.5,0.5,0.75,0.75,1.2,1.2}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(coords,coords+6,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DMesh_3",1); + ret->allocateCells(4); + int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); + ret->finishInsertingCells(); + double coords[10]={0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,1); + std::copy(coords,coords+10,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DCurveMesh_3",1); + ret->allocateCells(4); + int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); + ret->finishInsertingCells(); + double coords[20]={0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(coords,coords+20,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DMesh_3",2); + ret->allocateCells(10); + int conn[52]={ + 0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, + 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6 + }; + ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+7); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+12); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+18); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+26); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+29); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+33); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+38); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+44); + ret->finishInsertingCells(); + double coords[22]={0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(11,2); + std::copy(coords,coords+22,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + ret->checkCoherency(); + return ret; +} + +/*! + * Same as build2DTargetMesh_1 but with more nodes than needed. To check tryToShareSameCoordsPermute method. + */ +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_4() +{ + double targetCoords[20]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_3() +{ + return 0; +} + double MEDCouplingBasicsTest::sumAll(const std::vector< std::map >& matrix) { double ret=0.; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx index dbd2a6ff9..ffa8b6a75 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -59,6 +59,68 @@ void MEDCouplingBasicsTest::testArray() } } +void MEDCouplingBasicsTest::testArray2() +{ + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(3,4); + double *tmp=arr->getPointer(); + const double arrRef[12]={12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.}; + std::copy(arrRef,arrRef+12,tmp); + arr->setInfoOnComponent(0,"ggg"); + arr->setInfoOnComponent(1,"hhhh"); + arr->setInfoOnComponent(2,"jj"); + arr->setInfoOnComponent(3,"kkkkkk"); + DataArrayInt *arr2=arr->convertToIntArr(); + DataArrayDouble *arr3=arr2->convertToDblArr(); + arr2->decrRef(); + CPPUNIT_ASSERT(arr->isEqual(*arr3,1e-14)); + arr3->decrRef(); + arr->decrRef(); +} + +void MEDCouplingBasicsTest::testArray3() +{ + DataArrayInt *arr1=DataArrayInt::New(); + arr1->alloc(7,2); + int *tmp=arr1->getPointer(); + const int arr1Ref[14]={0,10,1,11,2,12,3,13,4,14,5,15,6,16}; + std::copy(arr1Ref,arr1Ref+14,tmp); + CPPUNIT_ASSERT_EQUAL(7,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref,arr1Ref+14,arr1->getConstPointer())); + DataArrayInt *arr2=arr1->substr(3); + CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr2->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref+6,arr1Ref+14,arr2->getConstPointer())); + arr2->decrRef(); + DataArrayInt *arr3=arr1->substr(2,5); + CPPUNIT_ASSERT_EQUAL(3,arr3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr3->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref+4,arr1Ref+10,arr3->getConstPointer())); + arr1->decrRef(); + arr3->decrRef(); + // + DataArrayDouble *arr4=DataArrayDouble::New(); + arr4->alloc(7,2); + double *tmp2=arr4->getPointer(); + const int arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5}; + std::copy(arr4Ref,arr4Ref+14,tmp2); + CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref,arr4Ref+14,arr4->getConstPointer())); + DataArrayDouble *arr5=arr4->substr(3); + CPPUNIT_ASSERT_EQUAL(4,arr5->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr5->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref+6,arr4Ref+14,arr5->getConstPointer())); + arr5->decrRef(); + DataArrayDouble *arr6=arr4->substr(2,5); + CPPUNIT_ASSERT_EQUAL(3,arr6->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr6->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref+4,arr4Ref+10,arr6->getConstPointer())); + arr4->decrRef(); + arr6->decrRef(); +} + void MEDCouplingBasicsTest::testMesh() { const int nbOfCells=6; @@ -542,7 +604,12 @@ void MEDCouplingBasicsTest::testBuildPartOfMySelf() CPPUNIT_ASSERT_EQUAL(4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); + const int tab3[3]={0,1,2}; + MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true); subMesh->decrRef(); + name=subMeshSimple2->getName(); + CPPUNIT_ASSERT(name=="PartOf_Toto"); + subMeshSimple2->decrRef(); // mesh->decrRef(); } @@ -653,6 +720,47 @@ void MEDCouplingBasicsTest::testZipCoords() mesh->decrRef(); } +void MEDCouplingBasicsTest::testZipConnectivity() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast(m3_1); + CPPUNIT_ASSERT(m3); + m2->decrRef(); + MEDCouplingUMesh *m4=build2DSourceMesh_1(); + MEDCouplingUMesh *m5=MEDCouplingUMesh::mergeUMeshes(m1,m3); + m1->decrRef(); + m3->decrRef(); + MEDCouplingUMesh *m6=MEDCouplingUMesh::mergeUMeshes(m5,m4); + m4->decrRef(); + m5->decrRef(); + // + bool areNodesMerged; + int newNbOfNodes; + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); + DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); + arr->decrRef(); + CPPUNIT_ASSERT(areNodesMerged); + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(9,newNbOfNodes); + // + arr=m6->zipConnectivityTraducer(0); + CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); + arr->decrRef(); + MEDCouplingUMesh *m7=m6->clone(true); + arr=m6->zipConnectivityTraducer(0); + CPPUNIT_ASSERT(m7->isEqual(m6,1e-12)); + CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); + arr->decrRef(); + // + m7->decrRef(); + m6->decrRef(); +} + void MEDCouplingBasicsTest::testEqualMesh() { MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); @@ -887,7 +995,8 @@ void MEDCouplingBasicsTest::testExtrudedMesh2() build3DExtrudedUMesh_2(mN,mTT,mTF); // bool b=false; - DataArrayInt *da=mTT->mergeNodes(1e-12,b); + int newNbOfNodes; + DataArrayInt *da=mTT->mergeNodes(1e-12,b,newNbOfNodes); CPPUNIT_ASSERT(b); da->decrRef(); std::vector n; @@ -903,7 +1012,7 @@ void MEDCouplingBasicsTest::testExtrudedMesh2() mTT3dSurf->decrRef(); // b=false; - da=mN->mergeNodes(1e-12,b); + da=mN->mergeNodes(1e-12,b,newNbOfNodes); da->decrRef(); CPPUNIT_ASSERT(!b); n.clear(); @@ -917,7 +1026,7 @@ void MEDCouplingBasicsTest::testExtrudedMesh2() mN3dSurf->decrRef(); // b=false; - da=mTF->mergeNodes(1e-12,b); + da=mTF->mergeNodes(1e-12,b,newNbOfNodes); da->decrRef(); CPPUNIT_ASSERT(!b); n.clear(); @@ -939,15 +1048,122 @@ void MEDCouplingBasicsTest::testExtrudedMesh2() mTF->decrRef(); } +/*! + * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method. + */ +void MEDCouplingBasicsTest::testExtrudedMesh3() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->changeSpaceDimension(3); + MEDCouplingUMesh *m2=buildCU1DMesh_U(); + m2->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0,1,0}; + m2->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0); + // + MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + const int *m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]); + m4->decrRef(); + //some random in cells to check that extrusion alg find it correctly + const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; + m3->renumberCells(expected1,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + //play with polygons and polyedrons + std::vector cells(2); cells[0]=2; cells[1]=3; + m1->convertToPolyTypes(cells); + m3=m1->buildExtrudedMeshFromThis(m2,0); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4)); + m3->renumberCells(expected1,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + // + m2->decrRef(); + m1->decrRef(); +} + +/*! + * This test check MEDCouplingUMesh::buildExtrudedMeshFromThis method, but also, MEDCouplingExtrudedMesh following methods : + * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh. + */ +void MEDCouplingBasicsTest::testExtrudedMesh4() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + std::vector cells(2); cells[0]=2; cells[1]=4; + m1->convertToPolyTypes(cells); + m1->changeSpaceDimension(3); + MEDCouplingUMesh *m2=buildCU1DMesh_U(); + m2->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0.,1.,0.}; + m2->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m3=m1->buildExtrudedMeshFromThis(m2,0); + const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; + const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12}; + m3->renumberCells(expected1,false); + MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7)); + MEDCouplingFieldDouble *f=m4->getMeasureField(true); + DataArrayDouble *arr=f->getArray(); + CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + const double *arrPtr=arr->getConstPointer(); + const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); + f->decrRef(); + MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh(); + CPPUNIT_ASSERT(m5->isEqual(m3,1e-12)); + f=m5->getMeasureField(true); + arr=f->getArray(); + arrPtr=arr->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); + f->decrRef(); + m5->decrRef(); + // + m4->decrRef(); + m3->decrRef(); + m2->decrRef(); + m1->decrRef(); +} + void MEDCouplingBasicsTest::testFindCommonNodes() { DataArrayInt *comm,*commI; MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - targetMesh->findCommonNodes(comm,commI,1e-10); + targetMesh->findCommonNodes(-1,1e-10,comm,commI); CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples()); CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples()); int newNbOfNodes; - DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes); + DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples()); const int o2nExp1[27]= @@ -963,14 +1179,14 @@ void MEDCouplingBasicsTest::testFindCommonNodes() // targetMesh=build3DTargetMeshMergeNode_1(); CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes()); - targetMesh->findCommonNodes(comm,commI,1e-10); + targetMesh->findCommonNodes(-1,1e-10,comm,commI); CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples()); CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples()); const int commExpected[6]={1,27,28,29,23,30}; const int commIExpected[3]={0,4,6}; CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer())); CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer())); - o2n=targetMesh->buildNewNumberingFromCommNodesFrmt(comm,commI,newNbOfNodes); + o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples()); CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); const int o2nExp2[31]= @@ -987,7 +1203,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes() targetMesh=build3DTargetMesh_1(); bool areNodesMerged; unsigned int time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); targetMesh->updateTime(); CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis()); CPPUNIT_ASSERT(!areNodesMerged); @@ -996,7 +1212,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes() // targetMesh=build3DTargetMeshMergeNode_1(); time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); targetMesh->updateTime(); CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); CPPUNIT_ASSERT(areNodesMerged); @@ -1021,7 +1237,7 @@ void MEDCouplingBasicsTest::testFindCommonNodes() targetMesh=build2DTargetMeshMergeNode_1(); CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes()); time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); CPPUNIT_ASSERT(areNodesMerged); CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); @@ -1081,8 +1297,10 @@ void MEDCouplingBasicsTest::testMergeMesh1() CPPUNIT_ASSERT(m3->isEqual(m4,1.e-12)); m4->decrRef(); bool isMerged; - DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged); + int newNbOfNodes; + DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged,newNbOfNodes); CPPUNIT_ASSERT_EQUAL(11,m3C->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(11,newNbOfNodes); CPPUNIT_ASSERT(isMerged); da->decrRef(); m3->decrRef(); @@ -1090,6 +1308,43 @@ void MEDCouplingBasicsTest::testMergeMesh1() m2->decrRef(); } +void MEDCouplingBasicsTest::testMergeMeshOnSameCoords1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + std::vector cells(5); + for(int i=0;i<5;i++) + cells[i]=i; + m2->convertToPolyTypes(cells); + m1->tryToShareSameCoords(*m2,1e-12); + MEDCouplingUMesh *m3=build2DTargetMesh_1(); + m3->tryToShareSameCoords(*m2,1e-12); + std::vector meshes; + meshes.push_back(m1); meshes.push_back(m2); meshes.push_back(m3); + MEDCouplingUMesh *m4=MEDCouplingUMesh::mergeUMeshesOnSameCoords(meshes); + m4->checkCoherency(); + CPPUNIT_ASSERT(m4->getCoords()==m1->getCoords()); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + const int cells1[5]={0,1,2,3,4}; + MEDCouplingPointSet *m1_1=m4->buildPartOfMySelf(cells1,cells1+5,true); + m1_1->setName(m1->getName()); + CPPUNIT_ASSERT(m1->isEqual(m1_1,1e-12)); + const int cells2[5]={5,6,7,8,9}; + MEDCouplingPointSet *m2_1=m4->buildPartOfMySelf(cells2,cells2+5,true); + m2_1->setName(m2->getName()); + CPPUNIT_ASSERT(m2->isEqual(m2_1,1e-12)); + const int cells3[5]={10,11,12,13,14}; + MEDCouplingPointSet *m3_1=m4->buildPartOfMySelf(cells3,cells3+5,true); + m3_1->setName(m3->getName()); + CPPUNIT_ASSERT(m3->isEqual(m3_1,1e-12)); + m1_1->decrRef(); m2_1->decrRef(); m3_1->decrRef(); + // + m4->decrRef(); + m1->decrRef(); + m2->decrRef(); + m3->decrRef(); +} + void MEDCouplingBasicsTest::testMergeField1() { MEDCouplingUMesh *m1=build2DTargetMesh_1(); @@ -1195,7 +1450,7 @@ void MEDCouplingBasicsTest::testFillFromAnalytic() f1->accumulate(values4); CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->measureAccumulate(true,values4); + f1->integral(true,values4); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); f1->decrRef(); @@ -1265,7 +1520,7 @@ void MEDCouplingBasicsTest::testFillFromAnalytic2() f1->accumulate(values4); CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->measureAccumulate(true,values4); + f1->integral(true,values4); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); f1->decrRef(); @@ -1525,6 +1780,105 @@ void MEDCouplingBasicsTest::testOperationsOnFields3() m->decrRef(); } +/*! + * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies + */ +void MEDCouplingBasicsTest::testOperationsOnFields4() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,3); + f1->setArray(array); + CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.}; + const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.}; + std::copy(arr1,arr1+15,tmp); + f1->setStartTime(2.,0,0); + f1->setEndTime(3.,0,0); + f1->checkCoherency(); + double res[3]; + const double pos[2]={0.3,-0.2}; + f1->getValueOn(pos,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); + std::fill(res,res+3,0.); + f1->getValueOn(pos,2.2,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); + std::fill(res,res+3,0.); + CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f2->setMesh(m); + f2->setArray(f1->getArray()); + f2->setStartTime(2.,3,0); + f2->setEndTime(4.,13,0); + CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception); + DataArrayDouble *array2=DataArrayDouble::New(); + array2->alloc(nbOfCells,3); + tmp=array2->getPointer(); + std::copy(arr2,arr2+15,tmp); + f2->setEndArray(array2); + array2->decrRef(); + f2->checkCoherency(); + // + std::fill(res,res+3,0.); + f2->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12); + MEDCouplingFieldDouble *f3=f2->clone(true); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12)); + f3->getEndArray()->getPointer()[0]=5.001; + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12)); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.1,3,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,4,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,1); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.1,13,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,14,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,1); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->decrRef(); + MEDCouplingFieldDouble *f4=(*f2)+(*f2); + std::fill(res,res+3,0.); + f4->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12); + (*f4)+=*f2; + std::fill(res,res+3,0.); + f4->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + m->decrRef(); +} + bool func4(const double *pt, double *res) { res[0]=pt[0]+pt[1]+pt[2]; @@ -1562,11 +1916,178 @@ void MEDCouplingBasicsTest::testCheckConsecutiveCellTypes() MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); CPPUNIT_ASSERT(sourceMesh->checkConsecutiveCellTypes()); + const INTERP_KERNEL::NormalizedCellType order1[]={INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; + const INTERP_KERNEL::NormalizedCellType order2[]={INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI3}; CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypes()); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); + DataArrayInt *da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order1,order1+2); + CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + const int expected1[5]={2,0,1,3,4}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); + da->decrRef(); + da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order2,order2+2); + CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + const int expected2[5]={0,3,4,1,2}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,da->getConstPointer())); + da->decrRef(); + const int renumber1[5]={4,0,1,2,3}; + targetMesh->renumberCells(renumber1,false); + CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypes()); + CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); targetMesh->decrRef(); sourceMesh->decrRef(); } +void MEDCouplingBasicsTest::testRearrange2ConsecutiveCellTypes() +{ + MEDCouplingUMesh *m1_1=build2DSourceMesh_1(); + MEDCouplingUMesh *m2_1=build2DTargetMesh_1(); + DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes(); + MEDCouplingUMesh *m1_2=build2DSourceMesh_1(); + CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12)); + const int expected1[2]={0,1}; + CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer())); + arr1->decrRef(); + const int expected2[5]={0,3,4,1,2}; + arr1=m2_1->rearrange2ConsecutiveCellTypes(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + MEDCouplingUMesh *m2_2=build2DTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12)); + m2_2->renumberCells(expected2,false); + CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12)); + arr1->decrRef(); + m1_1->decrRef(); + m1_2->decrRef(); + m2_1->decrRef(); + m2_2->decrRef(); +} + +void MEDCouplingBasicsTest::testSplitByType() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + std::vector v=m1->splitByType(); + CPPUNIT_ASSERT_EQUAL(3,(int)v.size()); + MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshesOnSameCoords(v); + m2->setName(m1->getName()); + CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12)); + for(std::vector::const_iterator iter=v.begin();iter!=v.end();iter++) + (*iter)->decrRef(); + m2->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords() +{ + std::vector meshes; + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast(m3_1); + CPPUNIT_ASSERT(m3); + meshes.push_back(m3); + int cells2[3]={1,2,4}; + MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true); + MEDCouplingUMesh *m4=dynamic_cast(m4_1); + CPPUNIT_ASSERT(m4); + meshes.push_back(m4); + int cells3[2]={1,2}; + MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true); + MEDCouplingUMesh *m5=dynamic_cast(m5_1); + CPPUNIT_ASSERT(m5); + meshes.push_back(m5); + m2->decrRef(); + // + std::vector corr; + MEDCouplingUMesh *m7=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,(int)corr.size()); + const int expectedVals1[3]={3,3,2}; + const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}}; + for(int i=0;i<3;i++) + { + DataArrayInt *arr=corr[i]; + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + int nbOfVals=expectedVals1[i]; + CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples()); + const int *vals=arr->getConstPointer(); + for(int j=0;j > fidsOfGroups; + DataArrayInt *arr2=DataArrayInt::makePartition(corr,m7->getNumberOfCells(),fidsOfGroups); + const int fidExp[4]={5,1,3,4}; + const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}}; + CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size()); + CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer())); + for(int i=0;i<3;i++) + { + int nbOfVals=expectedVals1[i]; + CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size()); + CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i])); + } + for(std::vector::iterator iter=corr.begin();iter!=corr.end();iter++) + (*iter)->decrRef(); + arr2->decrRef(); + m7->decrRef(); + // + m3->decrRef(); + m4->decrRef(); + m5->decrRef(); +} + +void MEDCouplingBasicsTest::testFuseUMeshesOnSameCoords2() +{ + MEDCouplingUMesh *m2; + MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2); + m2->decrRef(); + const int part1[5]={2,3,6,4,10}; + MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true); + const int part2[4]={5,6,4,7}; + MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true); + std::vector meshes; + meshes.push_back(m1); + meshes.push_back(m3); + meshes.push_back(m3); + meshes.push_back(m4); + std::vector corr; + MEDCouplingUMesh *m5=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells()); + std::vector::iterator it=corr.begin(); + const int exp1[4]={18,5,5,4}; + const int exp2[4][18]={ + {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} + }; + int i=0; + for(;it!=corr.end();it++,i++) + { + int sz=(*it)->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(exp1[i],sz); + CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer())); + } + for(it=corr.begin();it!=corr.end();it++) + (*it)->decrRef(); + m5->decrRef(); + m4->decrRef(); + m3->decrRef(); + m1->decrRef(); +} + void MEDCouplingBasicsTest::testBuildOrthogonalField() { MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); @@ -1845,7 +2366,7 @@ void MEDCouplingBasicsTest::testRenumberCells() MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); CPPUNIT_ASSERT(m->isEqual(m2,0)); const int arr[5]={12,3,25,2,26}; - m->renumberCells(arr,arr+5,true); + m->renumberCells(arr,true); CPPUNIT_ASSERT(!m->isEqual(m2,0)); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(0)); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); @@ -1853,7 +2374,7 @@ void MEDCouplingBasicsTest::testRenumberCells() CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(4)); const int arr2[5]={5,-1,-5,4,8}; - m->renumberCells(arr2,arr2+5,true); + m->renumberCells(arr2,true); CPPUNIT_ASSERT(m->isEqual(m2,0)); m->decrRef(); m2->decrRef(); diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx new file mode 100644 index 000000000..0c36bdbad --- /dev/null +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -0,0 +1,3007 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingBasicsTest.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingGaussLocalization.hxx" + +#include +#include +#include + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest::testGaussPointField1() +{ + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector _refCoo1(refCoo1,refCoo1+6); + std::vector _gsCoo1(gsCoo1,gsCoo1+12); + std::vector _wg1(wg1,wg1+6); + // + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); + f->setMesh(m); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); + const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector _refCoo2(refCoo2,refCoo2+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(18,2); + double *ptr=array->getPointer(); + for(int i=0;i<18*2;i++) + ptr[i]=(double)(i+1); + f->setArray(array); + f->setName("MyFirstFieldOnGaussPoint"); + array->decrRef(); + f->checkCoherency(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(27.,f->getIJK(2,5,0),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(16.,f->getIJK(1,5,1),1e-14); + // + f->clearGaussLocalizations(); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception); + int ids1[4]={0,1,3,4}; + CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnCells(ids1,ids1+4,_refCoo2,_gsCoo1,_wg1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + int ids2[2]={0,4}; + f->setGaussLocalizationOnCells(ids2,ids2+2,_refCoo2,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); + CPPUNIT_ASSERT_THROW(f->getGaussLocalizationIdOfOneCell(1),INTERP_KERNEL::Exception); + int ids3[2]={1,2}; + f->setGaussLocalizationOnCells(ids3,ids3+2,_refCoo1,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); + CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(1)); + CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(2)); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- cell 3 has no localization + int ids4[1]={3}; + std::vector _gsCoo2(_gsCoo1); + std::vector _wg2(_wg1); + _gsCoo2[0]=0.8888777776666; _wg2[0]=0.1234567892377; + f->setGaussLocalizationOnCells(ids4,ids4+1,_refCoo2,_gsCoo2,_wg2); + CPPUNIT_ASSERT_EQUAL(3,f->getNbOfGaussLocalization()); + std::vector tmpIds; + f->getCellIdsHavingGaussLocalization(0,tmpIds); + CPPUNIT_ASSERT_EQUAL(2,(int)tmpIds.size()); + CPPUNIT_ASSERT(std::equal(ids2,ids2+2,tmpIds.begin())); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- it's always not ok because undelying array not with the good size. + DataArrayDouble *array2=f->getArray()->substr(0,10); + f->setArray(array2); + array2->decrRef(); + f->checkCoherency();//<- here it is OK + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + MEDCouplingGaussLocalization& gl1=f2->getGaussLocalization(0); + double tmp=gl1.getGaussCoord(1,1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.07*_b-1,tmp,1e-14); + gl1.setGaussCoord(1,1,0.07); + CPPUNIT_ASSERT(!f->isEqual(f2,1e-14,1e-14)); + gl1.setGaussCoord(1,1,tmp); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + f->decrRef(); + f2->checkCoherency(); + // + f2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testGaussPointNEField1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); + f->setMesh(m); + f->setName("MyFirstFieldOnNE"); + f->setDescription("MyDescriptionNE"); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(18,2); + double *ptr=array->getPointer(); + for(int i=0;i<18*2;i++) + ptr[i]=(double)(i+7); + f->setArray(array); + array->decrRef(); + // + f->checkCoherency(); + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,f->getIJK(2,0,0),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,f->getIJK(1,1,1),1e-14); + f2->decrRef(); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testCellOrientation1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + double vec[3]={0.,0.,1.}; + std::vector res1; + CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception); + m->changeSpaceDimension(3); + res1.clear(); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + vec[2]=-1; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(5,(int)res1.size()); + res1.clear(); + // + vec[2]=1.; + // connectivity inversion + int *conn=m->getNodalConnectivity()->getPointer(); + int tmp=conn[11]; + conn[11]=conn[12]; + conn[12]=tmp; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); + CPPUNIT_ASSERT_EQUAL(2,res1[0]); + res1.clear(); + m->orientCorrectly2DCells(vec,false); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + m2->changeSpaceDimension(3); + CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); + m2->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest::testCellOrientation2() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); + m1->decrRef(); + std::vector res1; + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT_EQUAL(6,(int)res1.size()); + m2->orientCorrectlyPolyhedrons(); + res1.clear(); + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + m2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); + int cellIds[3]={0,6,12}; + std::vector cellIds2(cellIds,cellIds+3); + m2->convertToPolyTypes(cellIds2); + m2->orientCorrectlyPolyhedrons(); + res1.clear(); + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation + MEDCouplingUMesh *m3=build2DTargetMesh_1(); + double vec[3]={0.,0.,-1.};//<- important for the test + m3->changeSpaceDimension(3); + const int ids1[5]={0,1,2,3,4}; + std::vector ids2(ids1,ids1+5); + m3->convertToPolyTypes(ids2); + m3->orientCorrectly2DCells(vec,false); + MEDCouplingUMesh *m4=buildCU1DMesh_U(); + m4->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0.,1.,0.}; + m4->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m5=m3->buildExtrudedMeshFromThis(m4,0); + res1.clear(); + m5->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT_EQUAL(15,(int)res1.size()); + m5->orientCorrectlyPolyhedrons(); + res1.clear(); + m5->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingFieldDouble *f3=m5->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(15,f3->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + const double *f3Ptr=f3->getArray()->getConstPointer(); + const double expected1[15]={ + 0.075,0.0375,0.0375,0.075,0.075, + 0.1125,0.05625,0.05625,0.1125,0.1125, + 0.0625,0.03125,0.03125,0.0625,0.0625 + }; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),f3Ptr[i],1e-12); + f3->decrRef(); + DataArrayDouble *f4=m5->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(15,f4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f4->getNumberOfComponents()); + const double *f4Ptr=f4->getConstPointer(); + const double expected2[45]={ + -0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15, + -0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525, + -0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875 + }; + for(int i=0;i<45;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4Ptr[i],1e-12); + f4->decrRef(); + m5->decrRef(); + m3->decrRef(); + m4->decrRef(); + // + f2->decrRef(); + m2->decrRef(); +} + +/*! + * This test check polyhedron true barycenter computation. + */ +void MEDCouplingBasicsTest::testPolyhedronBarycenter() +{ + int connN[]={0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0}; + double coords[]={0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5}; + MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); + meshN->setName("ForBary"); + meshN->setMeshDimension(3); + meshN->allocateCells(4); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,29,connN); + meshN->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(coords,coords+27,myCoords->getPointer()); + meshN->setCoords(myCoords); + myCoords->decrRef(); + meshN->checkCoherency(); + // + std::vector res1; + meshN->arePolyhedronsNotCorrectlyOriented(res1); + meshN->orientCorrectlyPolyhedrons(); + CPPUNIT_ASSERT(res1.empty()); + const double *ref,*daPtr; + DataArrayDouble *da=meshN->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + const double center[]={0.,0.,0.}; + const double vec[]={0.,2.78,0.}; + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + meshN->rotate(center,vec,M_PI/7.); + meshN->translate(vec); + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + const double center2[]={1.12,3.45,6.78}; + const double vec2[]={4.5,9.3,2.8}; + meshN->rotate(center2,vec2,M_E); + meshN->translate(vec2); + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-10); + da->decrRef(); + // + meshN->decrRef(); +} + +void MEDCouplingBasicsTest::testNormL12Integ1D() +{ + MEDCouplingUMesh *m1=build1DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(m1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m1->getNumberOfCells(),3); + const double arr[12]={-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72}; + std::copy(arr,arr+12,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const double *ptr; + DataArrayDouble *f3=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + double expected9[4]={0.75,5.105,0.8,5.155}; + ptr=f3->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],ptr[i],1e-12); + f3->decrRef(); + // + MEDCouplingFieldDouble *f2=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + double expected1[4]={0.5,0.21,-0.6,-0.31}; + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + f2->decrRef(); + double expected2[4]={0.5,0.21,0.6,0.31}; + f2=m1->getMeasureField(true); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + f2->decrRef(); + //integral + double res[3]; + f1->integral(false,res); + double expected3[3]={0.9866,-0.3615,0.4217}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f1->integral(0,false),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f1->integral(1,false),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f1->integral(2,false),1e-12); + f1->integral(true,res); + double expected4[3]={-3.4152,8.7639,-14.6879}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],res[i],1e-12); + //normL1 + f1->normL1(res); + double expected5[3]={11.3068,27.3621,43.7881}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[0],f1->normL1(0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[1],f1->normL1(1),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[2],f1->normL1(2),1e-12); + //normL2 + f1->normL2(res); + double expected7[3]={9.0252562290496776, 21.545259176904789, 34.433193070059595}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[0],f1->normL2(0),1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[1],f1->normL2(1),1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[2],f1->normL2(2),1e-9); + //buildMeasureField + MEDCouplingFieldDouble *f4=f1->buildMeasureField(false); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2,f4->accumulate(0),1e-12); + f4->decrRef(); + f4=f1->buildMeasureField(true); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.62,f4->accumulate(0),1e-12); + f4->decrRef(); + // + f1->decrRef(); + m1->decrRef(); + // Testing with 2D Curve + m1=build2DCurveTargetMesh_3(); + f2=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected2[i],ptr[i],1e-12); + f2->decrRef(); + f2=m1->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i]*sqrt(2.),ptr[i],1e-12); + f2->decrRef(); + //bary + f3=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f3->getNumberOfComponents()); + double expected10[8]={0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155}; + ptr=f3->getConstPointer(); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected10[i],ptr[i],1e-12); + f3->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(m1); + array=DataArrayDouble::New(); + array->alloc(m1->getNumberOfCells(),3); + std::copy(arr,arr+12,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->integral(false,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); + f1->integral(true,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); + f1->normL1(res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected5[i],res[i],1e-12); + f1->normL2(res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(sqrt(2.))*expected7[i],res[i],1e-12); + // + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest::testAreaBary2D() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + double expected1[10]={-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1}; + const double *ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + f1->decrRef(); + f1=m1->getMeasureField(true); + ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); + f1->decrRef(); + DataArrayDouble *f2=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + double expected2[20]={ + 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, + 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, + }; + ptr=f2->getConstPointer(); + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + f2->decrRef(); + m1->changeSpaceDimension(3); + f1=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); + f1->decrRef(); + f2=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); + ptr=f2->getConstPointer(); + double expected3[30]={ + 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., + 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0. + }; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); + f2->decrRef(); + m1->decrRef(); +} + +/*! + * This test check polyhedron true barycenter computation 2. + */ +void MEDCouplingBasicsTest::testAreaBary3D() +{ + double coords [] = { 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , + 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , + 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , + 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , + -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , + -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , + 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , + 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , + -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , + 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , + -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , + -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , + -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , + -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , + -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , + -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , + 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , + 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , + 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , + -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , + -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , + -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , + -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , + 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , + 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , + 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , + -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , + -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , + 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , + 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , + -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , + 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , + 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , + 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , + -0.0372812069535 , -0.286740286332 , 0.00963701291166 }; + + int connN [] = { /*polyhedron 0*/ + 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 + , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 + , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 + , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, + /* polyhedron 1*/ + 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 + , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 + , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 + , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, + /* polyhedron 2*/ + 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 + , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, + /*polyhedron 3*/ + 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 + , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 + , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 + , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65}; + + double barys[]={ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , + 0.0287618656076 , 0.135874379934 , -0.14601588119 , + -0.147128055553 , 0.0465995097041 , -0.049391174453 , + -0.00142506732317 , -0.0996953090351 , -0.115159183132 }; + MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); + meshN->setName("ForBary"); + meshN->setMeshDimension(3); + meshN->allocateCells(4); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,113,connN); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,99,connN+113); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,connN+212); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,92,connN+255); + meshN->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(69,3); + std::copy(coords,coords+207,myCoords->getPointer()); + meshN->setCoords(myCoords); + myCoords->decrRef(); + meshN->checkCoherency(); + std::vector res1; + meshN->arePolyhedronsNotCorrectlyOriented(res1); + meshN->orientCorrectlyPolyhedrons(); + res1.clear(); + meshN->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + // + DataArrayDouble *da=meshN->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); + const double *daPtr=da->getConstPointer(); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(barys[i],daPtr[i],1e-12); + da->decrRef(); + // + meshN->decrRef(); +} + +void MEDCouplingBasicsTest::testRenumberCellsForFields() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + int nbOfCells=m->getNumberOfCells(); + arr->alloc(nbOfCells,3); + f->setArray(arr); + arr->decrRef(); + const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; + std::copy(values1,values1+15,arr->getPointer()); + const int renumber1[5]={3,1,0,4,2}; + double res[3]; + const double loc[]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; + for(int j=0;j<5;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); + } + f->renumberCells(renumber1,false); + const double *ptr=f->getArray()->getConstPointer(); + const double expected1[15]={9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + //check that fields remains the same geometrically + for(int j=0;j<5;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); + } + f->decrRef(); + //On gauss + f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); + f->setMesh(m); + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector _refCoo1(refCoo1,refCoo1+6); + std::vector _gsCoo1(gsCoo1,gsCoo1+12); + std::vector _wg1(wg1,wg1+6); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector _refCoo2(refCoo2,refCoo2+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + arr=DataArrayDouble::New(); + arr->alloc(18,2); + const double values2[36]={1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.}; + std::copy(values2,values2+36,arr->getPointer()); + f->setArray(arr); + arr->decrRef(); + f->checkCoherency(); + MEDCouplingFieldDouble *fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberCells(renumber1,false); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + double expected2[36]={21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.}; + ptr=f->getArray()->getConstPointer(); + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + const int renumber2[5]={2,1,4,0,3};//reverse renumber1 + f->renumberCells(renumber2,false); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + f->decrRef(); + //GaussNE + f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); + f->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(18,2); + const double values3[36]={1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.}; + std::copy(values3,values3+36,arr->getPointer()); + f->setArray(arr); + arr->decrRef(); + f->checkCoherency(); + fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberCells(renumber1,false); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + double expected3[36]={21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.}; + ptr=f->getArray()->getConstPointer(); + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); + f->renumberCells(renumber2,false);//perform reverse operation of renumbering to check that the resulting field is equal. + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + f->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest::testRenumberNodesForFields() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + int nbOfNodes=m->getNumberOfNodes(); + arr->alloc(nbOfNodes,3); + f->setArray(arr); + arr->decrRef(); + const double values1[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; + std::copy(values1,values1+27,arr->getPointer()); + f->checkCoherency(); + const int renumber1[9]={0,4,1,3,5,2,6,7,8}; + double res[3]; + const double loc[]={0.5432,-0.2432, 0.5478,0.1528}; + const double expected1[6]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124}; + for(int j=0;j<2;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); + } + MEDCouplingFieldDouble *fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberNodes(renumber1); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + for(int j=0;j<2;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); + } + const double expected2[27]={7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; + for(int i=0;i<27;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getArray()->getConstPointer()[i],1e-12); + const int renumber2[9]={0,2,5,3,1,4,6,7,8};//reverse of renumber2 + f->renumberNodes(renumber2); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest::testConvertQuadraticCellsToLinear() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_3(); + mesh->checkCoherency(); + const std::set& types=mesh->getAllTypes(); + CPPUNIT_ASSERT_EQUAL(5,(int)types.size()); + INTERP_KERNEL::NormalizedCellType expected1[5]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8}; + std::set expected1Bis(expected1,expected1+5); + CPPUNIT_ASSERT(expected1Bis==types); + CPPUNIT_ASSERT(mesh->isPresenceOfQuadratic()); + CPPUNIT_ASSERT_EQUAL(62,mesh->getMeshLength()); + MEDCouplingFieldDouble *f1=mesh->getMeasureField(false); + // + mesh->convertQuadraticCellsToLinear(); + CPPUNIT_ASSERT(!mesh->isPresenceOfQuadratic()); + // + mesh->checkCoherency(); + MEDCouplingFieldDouble *f2=mesh->getMeasureField(false); + CPPUNIT_ASSERT(f1->getArray()->isEqual(*f2->getArray(),1e-12)); + CPPUNIT_ASSERT_EQUAL(48,mesh->getMeshLength()); + const std::set& types2=mesh->getAllTypes(); + CPPUNIT_ASSERT_EQUAL(3,(int)types.size()); + INTERP_KERNEL::NormalizedCellType expected2[3]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; + std::set expected2Bis(expected2,expected2+3); + CPPUNIT_ASSERT(expected2Bis==types2); + // + f1->decrRef(); + f2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest::testCheckGeoEquivalWith() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + DataArrayInt *cellCor,*nodeCor; + //First test mesh1 + mesh1->checkGeoEquivalWith(mesh1,0,1e-12,cellCor,nodeCor);//deepEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh1,1,1e-12,cellCor,nodeCor);//fastEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + //Second test mesh1 and mesh2 are 2 different meshes instance + mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + //Third test : cell permutation by keeping the first the middle and the last as it is. + const int renum[]={0,2,1,3,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor==0); + cellCor->decrRef(); + cellCor=0; + CPPUNIT_ASSERT(nodeCor==0); + //4th test : cell and node permutation by keeping the first the middle and the last as it is. + mesh2->decrRef(); + mesh2=build2DTargetMesh_3(); + const int renum2[]={0,2,1,3,4,5,6,8,7,9,10}; + mesh2->renumberCells(renum,false); + mesh2->renumberNodes(renum2,11); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor); + CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); + cellCor->decrRef(); + cellCor=0; + nodeCor->decrRef(); + nodeCor=0; + //5th test : modification of the last cell to check fastCheck detection. + mesh2->decrRef(); + mesh2=build2DTargetMesh_3(); + const int renum3[]={0,2,1,3,4,5,6,8,9,7}; + mesh2->renumberCells(renum3,false); + mesh2->renumberNodes(renum2,11); + bool isExcep=false; + try { mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual fails + } + catch(INTERP_KERNEL::Exception& e) { isExcep=true; } + CPPUNIT_ASSERT(isExcep); isExcep=false; + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + try { mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual has detected something + } + catch(INTERP_KERNEL::Exception& e) { isExcep=true; } + CPPUNIT_ASSERT(isExcep); isExcep=false; + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh2->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum3,renum3+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor); + CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); + cellCor->decrRef(); + cellCor=0; + nodeCor->decrRef(); + nodeCor=0; + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest::testCheckGeoEquivalWith2() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_4(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + DataArrayInt *cellCor,*nodeCor; + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor); + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor!=0); + const int expected1[9]={0, 1, 3, 4, 5, 6, 7, 8, 9}; + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],nodeCor->getIJ(i,0)); + nodeCor->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest::testCopyTinyStringsFromOnFields() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f->setMesh(m); + f->setName("a"); + f->setDescription("b"); + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(nbOfCells,2); + a1->fillWithZero(); + a1->setInfoOnComponent(0,"c"); + a1->setInfoOnComponent(1,"d"); + DataArrayDouble *a2=a1->deepCopy(); + a2->setInfoOnComponent(0,"e"); + a2->setInfoOnComponent(1,"f"); + f->setArray(a1); + f->setEndArray(a2); + f->setEndTime(3.,3,4); + a2->decrRef(); + a1->decrRef(); + m->setName("g"); + m->getCoords()->setInfoOnComponent(0,"h"); + m->getCoords()->setInfoOnComponent(1,"i"); + m->getCoords()->setInfoOnComponent(2,"j"); + // + f->checkCoherency(); + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->setName("smth"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->setDescription("GGG"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->getArray()->setInfoOnComponent(0,"mmmm"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->getEndArray()->setInfoOnComponent(1,"mmmm"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->decrRef(); + MEDCouplingUMesh *m2=m->clone(true); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->setName("123"); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m2->copyTinyStringsFrom(m); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->getCoords()->setInfoOnComponent(1,"eee"); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m2->copyTinyStringsFrom(m); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->decrRef(); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testTryToShareSameCoordsPermute() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); + CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); + m->tryToShareSameCoordsPermute(*m2,1e-12); + CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + const int renum1[9]={1,2,0,5,8,7,4,3,6}; + m->renumberNodes(renum1,9); + CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m->tryToShareSameCoordsPermute(*m2,1e-12); + CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testTryToShareSameCoordsPermute2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_4(); + double targetCoords[8]={-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 }; + int targetConn[4]={0,2,3,1}; + MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); + m2->setMeshDimension(2); + m2->allocateCells(1); + m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + m2->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); + m2->setCoords(myCoords); + myCoords->decrRef(); + m2->checkCoherency(); + m1->checkCoherency(); + // + const double expected1[5]={0.25,0.125,0.125,0.25,0.25}; + MEDCouplingFieldDouble *f1=m1->getMeasureField(false); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); + f2->decrRef(); + f1->decrRef(); + CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoordsPermute(*m2,1e-12),INTERP_KERNEL::Exception);// <- here in this order the sharing is impossible. + // Let's go for deeper test of tryToShareSameCoordsPermute + m2->tryToShareSameCoordsPermute(*m1,1e-12); + f1=m1->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); + // + f2->decrRef(); + f1->decrRef(); + // + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest::testChangeUnderlyingMesh1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int renum[]={0,2,1,3,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh1,10,1e-12);// nothing done only to check that nothing done. + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh2,10,1e-12); + CPPUNIT_ASSERT(f1->getMesh()==mesh2); + const double expected1[20]={7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),2); + const double arr2[22]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.}; + std::copy(arr2,arr2+22,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int renum2[]={0,2,10,3,4,5,6,8,7,9,1}; + mesh2->renumberNodes(renum2,11); + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh2,10,1e-12); + CPPUNIT_ASSERT(f1->getMesh()==mesh2); + const double expected2[22]={7.,107.,9.,109.,17.,117.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,8.,108.}; + for(int i=0;i<22;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest::testGetMaxValue1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f->setMesh(m); + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(nbOfCells,1); + const double val1[5]={3.,4.,5.,6.,7.}; + std::copy(val1,val1+5,a1->getPointer()); + DataArrayDouble *a2=DataArrayDouble::New(); + a2->alloc(nbOfCells,1); + const double val2[5]={0.,1.,2.,8.,7.}; + std::copy(val2,val2+5,a2->getPointer()); + f->setArray(a1); + f->setEndArray(a2); + f->setEndTime(3.,3,4); + f->checkCoherency(); + // + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(),1e-14); + a1->setIJ(0,2,9.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); + a2->setIJ(0,0,9.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,f->getMinValue(),1e-14); + // + a2->decrRef(); + a1->decrRef(); + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest::testSubstractInPlaceDM1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(10,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(20,f1->getNumberOfValues()); + // + const int renum[]={0,2,1,3,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + // + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f2->setMesh(mesh2); + array=DataArrayDouble::New(); + array->alloc(mesh2->getNumberOfCells(),2); + const double arr2[20]={7.1,107.1,9.1,109.1,8.1,108.1,10.1,110.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1}; + std::copy(arr2,arr2+20,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + f1->substractInPlaceDM(f2,10,1e-12); + f1->applyFunc(1,"abs(x+y+0.2)"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f1->getMaxValue(),1e-14); + // + f1->decrRef(); + f2->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest::testDotCrossProduct1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setTime(7.8,4,5); + f2->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr2[30]={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.}; + std::copy(arr2,arr2+30,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + MEDCouplingFieldDouble *f3=f1->dot(*f2); + const double expected1[10]={842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(i,0),1e-9); + f3->decrRef(); + // + MEDCouplingFieldDouble *f4=f1->crossProduct(*f2); + const double expected2[30]={-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest::testMinMaxFields1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setTime(7.8,4,5); + f2->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr2[30]={6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.}; + std::copy(arr2,arr2+30,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + MEDCouplingFieldDouble *f3=f1->max(*f2); + const double expected1[30]={7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-9); + f3->decrRef(); + // + MEDCouplingFieldDouble *f4=f1->min(*f2); + const double expected2[30]={6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest::testApplyLin1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->applyLin(2.,3.,0); + const double expected1[20]={17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-9); + // + const double arr2[20]={2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + std::copy(arr2,arr2+20,array->getPointer()); + f1->setEndArray(array); + array->decrRef(); + // + f1->applyLin(4.,5.,1); + // + const double expected2[20]={17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-9); + const double expected3[20]={2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f1->getEndArray()->getIJ(0,i),1e-9); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testGetIdsInRange1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),1); + const double arr1[10]={2.,8.,6.,5.,11.,7.,9.,3.,10.,4.}; + std::copy(arr1,arr1+10,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->checkCoherency(); + DataArrayInt *da=f1->getIdsInRange(2.9,7.1); + CPPUNIT_ASSERT_EQUAL(5,da->getNbOfElems()); + const int expected1[5]={2,3,5,7,9}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); + da->decrRef(); + da=f1->getIdsInRange(8.,12.); + CPPUNIT_ASSERT_EQUAL(4,da->getNbOfElems()); + const int expected2[4]={1,4,6,8}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+4,da->getConstPointer())); + da->decrRef(); + // + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest::testBuildSubPart1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; + std::copy(arr1,arr1+10,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int part1[3]={2,1,4}; + MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected1[6]={5.,105.,4.,104.,7.,107.}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected1[i],1e-12); + CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + MEDCouplingUMesh *m2C=dynamic_cast(const_cast(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); + const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); + const double expected4[4]={0,4,8,13}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + f1->decrRef(); + // Test with field on nodes. + f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),2); + const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; + std::copy(arr2,arr2+18,array->getPointer()); + f1->setArray(array); + array->decrRef(); + const int part2[4]={1,4,2,5}; + f2=f1->buildSubPart(part2,part2+4); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected5[8]={4.,104.,5.,105.,7.,107.,8.,108.}; + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast(const_cast(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); + for(int i=0;i<8;i++)//8 is not an error + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + //idem previous because nodes of cell#4 are not fully present in part3 + const int part3[5]={1,4,2,5,7}; + DataArrayInt *arrr=DataArrayInt::New(); + arrr->alloc(5,1); + std::copy(part3,part3+5,arrr->getPointer()); + f2=f1->buildSubPart(arrr); + arrr->decrRef(); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast(const_cast(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); + for(int i=0;i<8;i++)//8 is not an error + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + // + const int part4[6]={1,4,2,5,7,8}; + f2=f1->buildSubPart(part4,part4+6); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected6[12]={4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected6[i],1e-12); + CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast(const_cast(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3+8,expected3+13,m2C->getNodalConnectivity()->getConstPointer()+8)); + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + // + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest::testDoublyContractedProduct1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->doublyContractedProduct(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(3906.56,f2->getIJ(i,0),1e-9); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testDeterminant1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1->setTime(2.3,5,6); + f1->setEndTime(3.8,7,3); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr1[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr1,arr1+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + //4 components + f1->checkCoherency(); + MEDCouplingFieldDouble *f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(CONST_ON_TIME_INTERVAL,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfValues()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.42,f2->getIJ(i,0),1e-13); + f2->decrRef(); + f1->decrRef(); + //6 components multi arrays with end array not defined + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setTime(2.3,5,6); + f1->setEndTime(3.8,7,3); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),6); + const double arr2[54]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, + 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr2,arr2+54,array->getPointer()); + f1->setArray(array); + array->decrRef(); + CPPUNIT_ASSERT_THROW(f1->checkCoherency(),INTERP_KERNEL::Exception);//no end array specified ! + // + f2=f1->determinant(); + CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); + f2->decrRef(); + //6 components multi arrays with end array defined + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),6); + const double arr3[54]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, + 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+54,array->getPointer()); + f1->setEndArray(array); + array->decrRef(); + f1->checkCoherency(); + f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + int it,order; + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(5,it); CPPUNIT_ASSERT_EQUAL(6,order); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.8,f2->getEndTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(7,it); CPPUNIT_ASSERT_EQUAL(3,order); + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1289.685,f2->getEndArray()->getIJ(i,0),1e-9); + } + f2->decrRef(); + f1->decrRef(); + //9 components + f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(7.8,10,2); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr4[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr4,arr4+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->checkCoherency(); + f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(ONE_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f2->getTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(10,it); CPPUNIT_ASSERT_EQUAL(2,order); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.267,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testEigenValues1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->eigenValues(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[3]={13.638813677891717,-4.502313844635971,-2.2364998332557486}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testEigenVectors1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->eigenVectors(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[9]={ + 0.5424262364180696, 0.5351201064614425, 0.6476266283176001,//eigenvect 0 + 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,//eigenvect 1 + -0.4012053603397987, 0.8423032781211455, -0.3599436712889738//eigenvect 2 + }; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testInverse1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr1,arr1+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[9]={-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); + } + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected3[6]={-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[5],f2->getIJ(i,5),1e-13); + } + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr2,arr2+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected2[4]={-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[3],f2->getIJ(i,3),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testTrace1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr1,arr1+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.9,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.8,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr2,arr2+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testDeviator1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->deviator(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[6]={-1.1,0.,1.1,4.5,5.6,6.7}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testMagnitude1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->magnitude(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.3606219864313918,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testMaxPerTuple1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->maxPerTuple(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testChangeNbOfComponents() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f1->changeNbOfComponents(3,7.77); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + const double expected1[15]={1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-13); + f1->changeNbOfComponents(4,7.77); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + const double expected2[20]={1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-13); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testSortPerTuple1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f1->sortPerTuple(true); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,4),1e-13); + } + // + f1->sortPerTuple(false); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,4),1e-13); + } + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testIsEqualWithoutConsideringStr1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + DataArrayInt *da1,*da2; + // + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->setName("rr"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh1->checkDeepEquivalWith(mesh2,2,1e-12,da1,da2); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,da1,da2),INTERP_KERNEL::Exception); + mesh2->setName(""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(0,"tty"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(0,""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(1,"tty"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(1,""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + double tmp=mesh2->getCoords()->getIJ(0,3); + mesh2->getCoords()->setIJ(0,3,9999.); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setIJ(0,3,tmp); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + int tmp2=mesh2->getNodalConnectivity()->getIJ(0,4); + mesh2->getNodalConnectivity()->setIJ(0,4,0); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getNodalConnectivity()->setIJ(0,4,tmp2); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + // + MEDCouplingFieldDouble *f1=mesh1->getMeasureField(true); + MEDCouplingFieldDouble *f2=mesh2->getMeasureField(true); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->setName("ftest"); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f1->setName("ftest"); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f2->getArray()->setInfoOnComponent(0,"eee"); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->getArray()->setInfoOnComponent(0,""); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f2->getArray()->setIJ(1,0,0.123); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(!f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->getArray()->setIJ(1,0,0.125); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f1->decrRef(); + f2->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest::testGetNodeIdsOfCell1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + std::vector nodeIds; + mesh1->getNodeIdsOfCell(1,nodeIds); + CPPUNIT_ASSERT_EQUAL(3,(int)nodeIds.size()); + CPPUNIT_ASSERT_EQUAL(1,nodeIds[0]); + CPPUNIT_ASSERT_EQUAL(4,nodeIds[1]); + CPPUNIT_ASSERT_EQUAL(2,nodeIds[2]); + std::vector coords; + mesh1->getCoordinatesOfNode(4,coords); + CPPUNIT_ASSERT_EQUAL(2,(int)coords.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[1],1e-13); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest::testGetEdgeRatioField1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m1->getEdgeRatioField(); + CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + const double expected1[5]={1.,1.4142135623730951, 1.4142135623730951,1.,1.}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-14); + f1->decrRef(); + m1->decrRef(); + // + m1=build3DSurfTargetMesh_1(); + f1=m1->getEdgeRatioField(); + CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + const double expected2[5]={1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(i,0),1e-14); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest::testFillFromAnalytic3() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"y+x"),INTERP_KERNEL::Exception); + f1->setMesh(m); + f1->setName("myField"); + f1->fillFromAnalytic(1,"y+x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(std::string(f1->getName())=="myField"); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; + const double *tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+5,values1,values1,std::minus()); + std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); + double max=*std::max_element(values1,values1+5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,CONST_ON_TIME_INTERVAL); + f1->setMesh(m); + f1->setEndTime(1.2,3,4); + f1->fillFromAnalytic(1,"y+2*x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==CONST_ON_TIME_INTERVAL); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2,values2,std::minus()); + std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); + max=*std::max_element(values2,values2+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setMesh(m); + f1->setEndTime(1.2,3,4); + f1->fillFromAnalytic(1,"2.*x+y"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==LINEAR_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + tmp=f1->getArray()->getConstPointer(); + double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + double values2BisBis[9]; + std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); + std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); + max=*std::max_element(values2BisBis,values2BisBis+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + tmp=f1->getEndArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); + std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); + max=*std::max_element(values2BisBis,values2BisBis+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(m); + f1->fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+18,values3,values3,std::minus()); + std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); + max=*std::max_element(values3,values3+18); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + double values4[2]; + f1->accumulate(values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); + f1->integral(true,values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(m); + CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"1./(x-0.2)"),INTERP_KERNEL::Exception); + // + m->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest::testFieldDoubleOpEqual1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT_THROW((*f1)=0.07,INTERP_KERNEL::Exception); + f1->setMesh(m); + (*f1)=0.07; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,f1->getIJ(i,0),1e-16); + (*f1)=0.09; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09,f1->getIJ(i,0),1e-16); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setEndTime(4.5,2,3); + f1->setMesh(m); + (*f1)=0.08; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getIJ(i,0),1e-16); + CPPUNIT_ASSERT_EQUAL(1,f1->getEndArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getEndArray()->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getEndArray()->getIJ(i,0),1e-16); + f1->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest::testAreaBary3D2() +{ + const double coordsForHexa8[24]={ + -75.45749305371, 180.95495078401, 39.515472018008, + -9.755591679144, 23.394927935279, 5.108794294848, + 14.337630157832, 61.705351002702, 160.42422501908, + -27.273893776752, 167.567731083961, 192.830034145464, + // + 99.857193154796,264.499264735586,-8.287335493412, + 144.939882761126,156.38626563134,-31.896173894226, + 161.34096835726,182.4654895809,73.832387065572, + 132.680430393685,255.37973247196,96.15235602819 + }; + const double volHexa8=3258520.29637466; + const double baryHexa8[3]={43.925705821778, 155.31893955289, 65.874418109644}; + + const double coordsForPenta6[18]={ + -68.199829618726,178.938498373416,62.608505919588, + 8.461744647847,76.653979804423,165.00018874933, + -27.273893776752,167.567731083961,192.830034145464, + // + 106.586501038965,262.629609408327,13.124533008813, + 155.465082847275,197.414118382622,78.408350795821, + 132.680430393685,255.37973247196,96.15235602819 + }; + const double volPenta6=944849.868507338; + const double baryPenta6[3]={39.631002313543,182.692711783428,106.98540473964}; + + const double coordsForPyra5[15]={ + 132.680430393685,255.37973247196,96.15235602819, + -27.273893776752,167.567731083961,192.830034145464, + 8.461744647847,76.653979804423,165.00018874933, + 155.465082847275,197.414118382622,78.408350795821, + // + -68.199829618726,178.938498373416,62.608505919588 + }; + const double volPyra5=756943.92980254; + const double baryPyra5[3]={29.204294116618,172.540129749156,118.01035951483}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Bary3D2",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(19,3); + double *tmp=std::copy(coordsForHexa8,coordsForHexa8+24,coo->getPointer()); + tmp=std::copy(coordsForPenta6,coordsForPenta6+18,tmp); + std::copy(coordsForPyra5,coordsForPyra5+15,tmp); + mesh->setCoords(coo); + coo->decrRef(); + // + int tmpConn[8]={0,1,2,3,4,5,6,7}; + mesh->allocateCells(3); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,tmpConn); + std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),8)); + mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,tmpConn); + std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),6)); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,tmpConn); + mesh->finishInsertingCells(); + mesh->checkCoherency(); + bool isMerged; + int newNebOfNodes; + DataArrayInt *da=mesh->mergeNodes(1e-7,isMerged,newNebOfNodes); + da->decrRef(); + CPPUNIT_ASSERT_EQUAL(12,newNebOfNodes); + MEDCouplingFieldDouble *vols=mesh->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(3,vols->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volHexa8,vols->getIJ(0,0),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volPenta6,vols->getIJ(1,0),1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volPyra5,vols->getIJ(2,0),1e-7); + vols->decrRef(); + DataArrayDouble *bary=mesh->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[0],bary->getIJ(0,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[1],bary->getIJ(0,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[2],bary->getIJ(0,2),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[0],bary->getIJ(1,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[1],bary->getIJ(1,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[2],bary->getIJ(1,2),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[0],bary->getIJ(2,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[1],bary->getIJ(2,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[2],bary->getIJ(2,2),1e-11); + bary->decrRef(); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest::testGetMeasureFieldCMesh1() +{ + MEDCouplingCMesh *m=MEDCouplingCMesh::New(); + DataArrayDouble *da=DataArrayDouble::New(); + const double discX[4]={2.3,3.4,5.8,10.2}; + const double discY[3]={12.3,23.4,45.8}; + const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; + da->alloc(4,1); + std::copy(discX,discX+4,da->getPointer()); + m->setCoordsAt(0,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(1,m->getSpaceDimension()); + MEDCouplingFieldDouble *f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(3,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected1[3]={1.1,2.4,4.4}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(i,0),1e-12); + f->decrRef(); + DataArrayDouble *coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(discX[i],coords->getIJ(i,0),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); + const double expected1_3[3]={2.85,4.6,8.}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1_3[i],coords->getIJ(i,0),1e-12); + coords->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(3,1); + std::copy(discY,discY+3,da->getPointer()); + m->setCoordsAt(1,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(12,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(6,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(2,m->getSpaceDimension()); + f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(6,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected2[6]={12.21,26.64,48.84,24.64,53.76,98.56}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(i,0),1e-12); + f->decrRef(); + coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(12,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); + const double expected2_2[24]={2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8}; + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_2[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(6,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); + const double expected2_3[12]={2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_3[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(5,1); + std::copy(discZ,discZ+5,da->getPointer()); + m->setCoordsAt(2,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(60,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(24,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); + f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(24,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected3[24]={23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224}; + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f->getIJ(i,0),1e-12); + f->decrRef(); + coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(60,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); + const double expected3_2[180]={ + 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, + 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, + 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, + 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, + 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67 + }; + for(int i=0;i<180;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_2[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(24,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); + const double expected3_3[72]={ + 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, + 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, + 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, + 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4 + }; + for(int i=0;i<72;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_3[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest::testFieldDoubleZipCoords1() +{ + MEDCouplingUMesh *m=build2DTargetMeshMergeNode_1(); + MEDCouplingFieldDouble *f=m->fillFromAnalytic(ON_NODES,2,"x*2."); + f->getArray()->setInfoOnComponent(0,"titi"); + f->getArray()->setInfoOnComponent(1,"tutu"); + f->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(18,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + const double expected1[36]={-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(f->zipCoords()); + f->checkCoherency(); + const double expected2[30]={-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(!f->zipCoords()); + f->checkCoherency(); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest::testFieldDoubleZipConnectivity1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + const int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast(m3_1); + CPPUNIT_ASSERT(m3); + m2->decrRef(); + MEDCouplingUMesh *m4=build2DSourceMesh_1(); + MEDCouplingUMesh *m5=MEDCouplingUMesh::mergeUMeshes(m1,m3); + m1->decrRef(); + m3->decrRef(); + MEDCouplingUMesh *m6=MEDCouplingUMesh::mergeUMeshes(m5,m4); + m4->decrRef(); + m5->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); + bool areNodesMerged; + int newNbOfNodes; + DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); + arr->decrRef(); + MEDCouplingFieldDouble *f=m6->fillFromAnalytic(ON_CELLS,2,"x"); + MEDCouplingFieldDouble *f2=m6->fillFromAnalytic(ON_NODES,2,"x"); + CPPUNIT_ASSERT_EQUAL(10,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + const double expected1[20]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, + 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); + f->getArray()->setInfoOnComponent(0,"titi"); + f->getArray()->setInfoOnComponent(1,"tutu"); + f->checkCoherency(); + CPPUNIT_ASSERT(f->zipConnectivity(0)); + const double expected2[14]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; + CPPUNIT_ASSERT_EQUAL(7,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); + CPPUNIT_ASSERT(!f->zipConnectivity(0)); + f->decrRef(); + // + const double expected3[18]={-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, + -0.3, -0.3, 0.2, 0.2, 0.7, 0.7}; + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(f2->zipConnectivity(0)); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); + f2->decrRef(); + // + m6->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleRenumber1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + DataArrayDouble *b=a->renumber(arr2); + CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumber(arr2); + CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleRenumberAndReduce1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={2,-1,1,-1,0,4,3}; + DataArrayDouble *b=a->renumberAndReduce(arr2,5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumberAndReduce(arr2,5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleRenumberInPlace1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + a->renumberInPlace(arr2); + CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); + const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + c->renumberInPlace(arr2); + CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); + const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); + c->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleRenumberR1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + DataArrayDouble *b=a->renumberR(arr2); + CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumberR(arr2); + CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleRenumberInPlaceR1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + a->renumberInPlaceR(arr2); + CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); + const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + c->renumberInPlaceR(arr2); + CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); + const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); + c->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleSelectByTupleId1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={4,2,0,6,5}; + DataArrayDouble *b=a->selectByTupleId(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->selectByTupleId(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest::testDaDoubleGetMinMaxValues1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(9,1); + const double arr1[9]={2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56}; + std::copy(arr1,arr1+9,a->getPointer()); + int where; + double m=a->getMaxValue(where); + CPPUNIT_ASSERT_EQUAL(1,where); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); + DataArrayInt *ws; + m=a->getMaxValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); + CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + const int expected1[3]={1,4,8}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + a->decrRef(); + a=DataArrayDouble::New(); + const double arr2[9]={-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56}; + a->alloc(9,1); + std::copy(arr2,arr2+9,a->getPointer()); + where=-2; + m=a->getMinValue(where); + CPPUNIT_ASSERT_EQUAL(1,where); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); + m=a->getMinValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); + CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest::testFieldDoubleGetMinMaxValues2() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); + m1->decrRef(); + CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); + const double arr1[18]={8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71}; + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(18,1); + std::copy(arr1,arr1+18,a->getPointer()); + f->setArray(a); + a->decrRef(); + f->setMesh(m2); + // + f->checkCoherency(); + double m=f->getMaxValue(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); + DataArrayInt *ws; + m=f->getMaxValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); + CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + const int expected1[4]={0,3,7,17}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + // + const double arr2[18]={-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71}; + std::copy(arr2,arr2+18,a->getPointer()); + f->checkCoherency(); + m=f->getMinValue(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); + m=f->getMinValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); + CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + // + f->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest::testBuildUnstructuredCMesh1() +{ + MEDCouplingCMesh *m=MEDCouplingCMesh::New(); + DataArrayDouble *da=DataArrayDouble::New(); + const double discX[4]={2.3,3.4,5.8,10.2}; + const double discY[3]={12.3,23.4,45.8}; + const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; + da->alloc(4,1); + std::copy(discX,discX+4,da->getPointer()); + m->setCoordsAt(0,da); + da->decrRef(); + m->checkCoherency(); + double pos=2.4; + CPPUNIT_ASSERT_EQUAL(0,m->getCellContainingPoint(&pos,1e-12)); + pos=3.7; + CPPUNIT_ASSERT_EQUAL(1,m->getCellContainingPoint(&pos,1e-12)); + pos=5.9; + CPPUNIT_ASSERT_EQUAL(2,m->getCellContainingPoint(&pos,1e-12)); + pos=10.3; + CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); + pos=1.3; + CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); + // + MEDCouplingUMesh *m2=m->buildUnstructured(); + m2->checkCoherency(); + MEDCouplingFieldDouble *f1=m->getMeasureField(false); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),3); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),3); + CPPUNIT_ASSERT_EQUAL(1,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(1,m2->getSpaceDimension()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + da=DataArrayDouble::New(); + da->alloc(3,1); + std::copy(discY,discY+3,da->getPointer()); + m->setCoordsAt(1,da); + da->decrRef(); + m2->decrRef(); + f1->decrRef(); + f2->decrRef(); + // + m2=m->buildUnstructured(); + m2->checkCoherency(); + f1=m->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),6); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),6); + CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(2,m2->getSpaceDimension()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + f1->decrRef(); + f2->decrRef(); + m2->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(5,1); + std::copy(discZ,discZ+5,da->getPointer()); + m->setCoordsAt(2,da); + da->decrRef(); + m2=m->buildUnstructured(); + m2->checkCoherency(); + f1=m->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),24); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),24); + CPPUNIT_ASSERT_EQUAL(3,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + f1->decrRef(); + f2->decrRef(); + // + double pos1[3]={5.,30.,2.}; + CPPUNIT_ASSERT_EQUAL(16,m->getCellContainingPoint(pos1,1e-12)); + // + const double pt[3]={2.4,12.7,-3.4}; + m->scale(pt,3.7); + MEDCouplingUMesh *m3=m->buildUnstructured(); + m2->scale(pt,3.7); + CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); + m2->decrRef(); + m3->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest::testDataArrayIntInvertO2NNO21() +{ + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayO2N2N2O(6); + CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + DataArrayInt *da3=da2->invertArrayN2O2O2N(6); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(arr1[i],da3->getIJ(i,0)); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); + // + const int arr2[10]={3,-1,5,4,-1,0,-1,1,2,-1}; + da=DataArrayInt::New(); + da->alloc(10,1); + std::copy(arr2,arr2+10,da->getPointer()); + da2=da->invertArrayO2N2N2O(6); + CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected2[10]={5,7,8,0,3,2}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da2->getIJ(i,0)); + da3=da2->invertArrayN2O2O2N(10); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(arr2[i],da3->getIJ(i,0)); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest::testKeepSetSelectedComponent1() +{ + const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(5,4); + std::copy(arr1,arr1+20,a1->getPointer()); + a1->setInfoOnComponent(0,"aaaa"); + a1->setInfoOnComponent(1,"bbbb"); + a1->setInfoOnComponent(2,"cccc"); + a1->setInfoOnComponent(3,"dddd"); + const int arr2[6]={1,2,1,2,0,0}; + std::vector arr2V(arr2,arr2+6); + DataArrayDouble *a2=a1->keepSelectedComponents(arr2V); + CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); + const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a2->getIJ(0,i),1e-14); + DataArrayInt *a3=a1->convertToIntArr(); + DataArrayInt *a4=a3->keepSelectedComponents(arr2V); + CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_EQUAL(int(expected1[i]),a4->getIJ(0,i)); + // setSelectedComponents + const int arr3[2]={3,2}; + std::vector arr3V(arr3,arr3+2); + DataArrayDouble *a5=a1->keepSelectedComponents(arr3V); + a5->setInfoOnComponent(0,"eeee"); + a5->setInfoOnComponent(1,"ffff"); + const int arr4[2]={1,2}; + std::vector arr4V(arr4,arr4+2); + a2->setSelectedComponents(a5,arr4V); + CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); + const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],a2->getIJ(0,i),1e-14); + DataArrayInt *a6=a5->convertToIntArr(); + a6->setInfoOnComponent(0,"eeee"); + a6->setInfoOnComponent(1,"ffff"); + a4->setSelectedComponents(a6,arr4V); + CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_EQUAL(int(expected2[i]),a4->getIJ(0,i)); + // test of throw + const int arr5[3]={2,3,6}; + const int arr6[3]={2,7,5}; + const int arr7[4]={2,1,4,6}; + std::vector arr5V(arr5,arr5+3); + std::vector arr6V(arr6,arr6+3); + std::vector arr7V(arr7,arr7+4); + CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr5V),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr6V),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); + arr7V.resize(3); + CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); + // + a6->decrRef(); + a5->decrRef(); + a4->decrRef(); + a3->decrRef(); + a2->decrRef(); + a1->decrRef(); +} + +void MEDCouplingBasicsTest::testKeepSetSelectedComponent2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(5,4); + std::copy(arr1,arr1+20,a1->getPointer()); + a1->setInfoOnComponent(0,"aaaa"); + a1->setInfoOnComponent(1,"bbbb"); + a1->setInfoOnComponent(2,"cccc"); + a1->setInfoOnComponent(3,"dddd"); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,4,5); + f1->setMesh(m1); + f1->setName("f1"); + f1->setArray(a1); + f1->checkCoherency(); + // + const int arr2[6]={1,2,1,2,0,0}; + std::vector arr2V(arr2,arr2+6); + MEDCouplingFieldDouble *f2=f1->keepSelectedComponents(arr2V); + CPPUNIT_ASSERT(f2->getMesh()==f1->getMesh()); + CPPUNIT_ASSERT(f2->getTimeDiscretization()==ONE_TIME); + int dt,it; + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); + CPPUNIT_ASSERT_EQUAL(4,dt); + CPPUNIT_ASSERT_EQUAL(5,it); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); + const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f2->getIJ(0,i),1e-14); + //setSelectedComponents + const int arr3[2]={3,2}; + std::vector arr3V(arr3,arr3+2); + MEDCouplingFieldDouble *f5=f1->keepSelectedComponents(arr3V); + f5->setTime(6.7,8,9); + f5->getArray()->setInfoOnComponent(0,"eeee"); + f5->getArray()->setInfoOnComponent(1,"ffff"); + f5->checkCoherency(); + const int arr4[2]={1,2}; + std::vector arr4V(arr4,arr4+2); + f2->setSelectedComponents(f5,arr4V); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + f2->checkCoherency(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); + CPPUNIT_ASSERT_EQUAL(4,dt); + CPPUNIT_ASSERT_EQUAL(5,it); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); + const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-14); + f5->decrRef(); + f1->decrRef(); + f2->decrRef(); + a1->decrRef(); + m1->decrRef(); +} diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx index b7c30b712..1050f75ce 100644 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx +++ b/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx @@ -158,6 +158,119 @@ void MEDCouplingRemapperTest::test2DInterpP0P0R_1() targetMesh->decrRef(); } +void MEDCouplingRemapperTest::test1DInterp_1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build1DSourceMesh_2(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_2(); + // + MEDCouplingRemapper remapper; + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;igetNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + // + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected1[2]={9.0540540540540526,7.4}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); + trgfield->decrRef(); + const double valuesExpected2[2]={24.75,5.75}; + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + const double valuesExpected3[2]={24.75,9.25}; + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + // + const double valuesExpected4[2]={7.4444444444444446,7.4}; + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + //2D Curve + sourceMesh=MEDCouplingBasicsTest::build2DCurveSourceMesh_2(); + targetMesh=MEDCouplingBasicsTest::build2DCurveTargetMesh_2(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;igetNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + // + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + void MEDCouplingRemapperTest::test2DInterpMultiMethods() { MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); @@ -709,7 +822,8 @@ void MEDCouplingRemapperTest::testExtruded2() MEDCouplingUMesh *meshN2D=(MEDCouplingUMesh *)meshN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); n.clear(); bool b=false; - DataArrayInt *da=meshTT->mergeNodes(1e-12,b); + int newNbOfNodes; + DataArrayInt *da=meshTT->mergeNodes(1e-12,b,newNbOfNodes); CPPUNIT_ASSERT(b); da->decrRef(); meshTT->findNodesOnPlane(pt,v,1e-12,n); diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx index 61dc0e701..2b45b4b06 100644 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx +++ b/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx @@ -34,6 +34,7 @@ namespace ParaMEDMEM CPPUNIT_TEST_SUITE(MEDCouplingRemapperTest); CPPUNIT_TEST( test2DInterpP0P0_1 ); CPPUNIT_TEST( test2DInterpP0P0R_1 ); + CPPUNIT_TEST( test1DInterp_1 ); CPPUNIT_TEST( test2DInterpMultiMethods ); CPPUNIT_TEST( testMultiDimCombi ); CPPUNIT_TEST( testNatureOfField ); @@ -43,6 +44,7 @@ namespace ParaMEDMEM public: void test2DInterpP0P0_1(); void test2DInterpP0P0R_1(); + void test1DInterp_1(); void test2DInterpMultiMethods(); void testMultiDimCombi(); void testNatureOfField(); diff --git a/src/MEDCoupling/Test/Makefile.am b/src/MEDCoupling/Test/Makefile.am index 045a74953..875fcf4ae 100755 --- a/src/MEDCoupling/Test/Makefile.am +++ b/src/MEDCoupling/Test/Makefile.am @@ -26,10 +26,17 @@ TestMEDCoupling_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$( TestMEDCoupling_LDFLAGS = @CPPUNIT_LIBS@ ../libmedcoupling.la ../../INTERP_KERNEL/libinterpkernel.la dist_TestMEDCoupling_SOURCES = TestMEDCoupling.cxx MEDCouplingBasicsTest.hxx MEDCouplingBasicsTest0.cxx MEDCouplingBasicsTest1.cxx \ - MEDCouplingBasicsTestInterp.cxx MEDCouplingBasicsTestData1.hxx + MEDCouplingBasicsTest2.cxx MEDCouplingBasicsTestInterp.cxx MEDCouplingBasicsTestData1.hxx TestMEDCouplingRemapper_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../../INTERP_KERNEL/Bases -I$(srcdir)/../../INTERP_KERNELTest -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Geometric2D TestMEDCouplingRemapper_LDFLAGS = @CPPUNIT_LIBS@ ../libmedcouplingremapper.la ../../INTERP_KERNEL/libinterpkernel.la ../libmedcoupling.la dist_TestMEDCouplingRemapper_SOURCES = TestMEDCouplingRemapper.cxx MEDCouplingRemapperTest.hxx MEDCouplingRemapperTest.cxx MEDCouplingBasicsTest0.cxx + +UNIT_TEST_PROG = TestMEDCoupling TestMEDCouplingRemapper + +check : tests + +CLEANFILES = \ + UnitTestsResult diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py index 98db6b0d5..a8e328c08 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -20,8 +20,63 @@ from libMEDCoupling_Swig import * import unittest +from math import pi,e,sqrt +from MEDCouplingDataForTest import MEDCouplingDataForTest class MEDCouplingBasicsTest(unittest.TestCase): + def testArray2(self): + arr=DataArrayDouble.New() + arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4) + arr.setInfoOnComponent(0,"ggg"); + arr.setInfoOnComponent(1,"hhhh"); + arr.setInfoOnComponent(2,"jj"); + arr.setInfoOnComponent(3,"kkkkkk"); + arr2=arr.convertToIntArr(); + arr3=arr2.convertToDblArr(); + self.assertTrue(arr.isEqual(arr3,1e-14)) + pass + + def testArray3(self): + arr1=DataArrayInt.New(); + arr1Ref=[0,10,1,11,2,12,3,13,4,14,5,15,6,16] + arr1.setValues(arr1Ref,7,2); + self.assertEqual(7,arr1.getNumberOfTuples()); + self.assertEqual(2,arr1.getNumberOfComponents()); + self.assertEqual(arr1Ref,list(arr1.getValues())); + arr2=arr1.substr(3); + self.assertEqual(4,arr2.getNumberOfTuples()); + self.assertEqual(2,arr2.getNumberOfComponents()); + self.assertEqual(arr1Ref[6:],list(arr2.getValues())); + arr3=arr1.substr(2,5); + self.assertEqual(3,arr3.getNumberOfTuples()); + self.assertEqual(2,arr3.getNumberOfComponents()); + self.assertEqual(arr1Ref[4:10],list(arr3.getValues())); + # + arr4=DataArrayDouble.New(); + arr4Ref=[0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5] + arr4.setValues(arr4Ref,7,2); + self.assertEqual(7,arr4.getNumberOfTuples()); + self.assertEqual(2,arr4.getNumberOfComponents()); + tmp=arr4.getValues() + for i in xrange(14): + self.assertTrue(abs(arr4Ref[i]-tmp[i])<1e-14); + pass + arr5=arr4.substr(3); + self.assertEqual(4,arr5.getNumberOfTuples()); + self.assertEqual(2,arr5.getNumberOfComponents()); + tmp=arr5.getValues() + for i in xrange(8): + self.assertTrue(abs(arr4Ref[6+i]-tmp[i])<1e-14); + pass + arr6=arr4.substr(2,5); + self.assertEqual(3,arr6.getNumberOfTuples()); + self.assertEqual(2,arr6.getNumberOfComponents()); + tmp=arr6.getValues() + for i in xrange(6): + self.assertTrue(abs(arr4Ref[4+i]-tmp[i])<1e-14); + pass + pass + def testMesh(self): tab4=[1, 2, 8, 7, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, @@ -38,23 +93,23 @@ class MEDCouplingBasicsTest(unittest.TestCase): mesh.setMeshDimension(2) mesh.allocateCells(8); mesh.setName("mesh1") - self.failUnless(mesh.getName()=="mesh1") + self.assertTrue(mesh.getName()=="mesh1") for i in range(nbOfCells): mesh.insertNextCell(NORM_QUAD4,4,tab4[4*i:4*(i+1)]); pass mesh.finishInsertingCells() - self.failUnless(mesh.getNumberOfCells()==nbOfCells) - self.failUnless(mesh.getNodalConnectivity().getNbOfElems()==30) - self.failUnless(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1) + self.assertTrue(mesh.getNumberOfCells()==nbOfCells) + self.assertTrue(mesh.getNodalConnectivity().getNbOfElems()==30) + self.assertTrue(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1) myCoords=DataArrayDouble.New() myCoords.setValues(coords,nbOfNodes,3); - self.failUnless(myCoords.getIJ(3,2)==-0.305) + self.assertTrue(myCoords.getIJ(3,2)==-0.305) mesh.setCoords(myCoords); mesh.checkCoherency(); - self.failUnless(mesh.getAllTypes()==[4]) + self.assertTrue(mesh.getAllTypes()==[4]) myFalseConn=DataArrayInt.New() myFalseConn.setValues(tab4,6,4) - self.failUnless(myFalseConn.getIJ(1,1)==3) + self.assertTrue(myFalseConn.getIJ(1,1)==3) # field=MEDCouplingFieldDouble.New(ON_CELLS) field.setMesh(mesh) @@ -65,7 +120,7 @@ class MEDCouplingBasicsTest(unittest.TestCase): sampleTab.append(float(i)) myCoords.setValues(sampleTab,nbOfCells,9); field.setArray(myCoords) - self.failUnless(3==mesh.getSpaceDimension()) + self.assertTrue(3==mesh.getSpaceDimension()) field.checkCoherency() mesh2=mesh.clone(False) mesh3=mesh.clone(True) @@ -78,6 +133,4552 @@ class MEDCouplingBasicsTest(unittest.TestCase): field3=mesh3.fillFromAnalytic(ON_CELLS,2,"x*IVec+(y+z)*JVec") field3.applyFunc("u*u*u+cos(u)") pass + def testMeshPointsCloud(self): + targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, + -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(0); + targetMesh.allocateCells(8); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.insertNextCell(NORM_POINT0,0,[]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,3); + targetMesh.setCoords(myCoords); + self.assertEqual(targetMesh.getSpaceDimension(),3) + self.assertEqual(targetMesh.getNumberOfCells(),8) + self.assertEqual(targetMesh.getNumberOfNodes(),9) + self.assertEqual(targetMesh.getMeshDimension(),0) + pass + def testMeshM1D(self): + meshM1D=MEDCouplingUMesh.New(); + self.assertRaises(Exception,meshM1D.getMeshDimension); + self.assertRaises(Exception,meshM1D.getNumberOfNodes); + self.assertRaises(Exception,meshM1D.getNumberOfCells); + self.assertRaises(Exception,meshM1D.setMeshDimension,-2) + self.assertRaises(Exception,meshM1D.setMeshDimension,-10) + meshM1D.setMeshDimension(-1); + meshM1D.checkCoherency(); + self.assertEqual(meshM1D.getMeshDimension(),-1); + self.assertEqual(meshM1D.getNumberOfCells(),1); + self.assertRaises(Exception,meshM1D.getNumberOfNodes); + self.assertRaises(Exception,meshM1D.getSpaceDimension); + cpy=meshM1D.clone(True); + self.assertTrue(cpy.isEqual(meshM1D,1e-12)); + fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); + fieldOnCells.setMesh(meshM1D); + array=DataArrayDouble.New(); + array.setValues(6*[7.],1,6); + fieldOnCells.setArray(array); + fieldOnCells.checkCoherency(); + pass + def testDeepCopy(self): + array=DataArrayDouble.New(); + array.setValues(5*3*[7.],5,3); + self.assertEqual(array.getIJ(3,2),7.); + array2=array.deepCopy(); + self.assertEqual(array2.getIJ(3,2),7.) + # + array3=DataArrayInt.New(); + array3.setValues(5*3*[17],5,3); + self.assertEqual(array3.getIJ(3,2),17); + array4=array3.deepCopy(); + self.assertEqual(array4.getIJ(3,2),17); + pass + def testRevNodal(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1() + revNodal=DataArrayInt.New(); + revNodalIndx=DataArrayInt.New(); + mesh.getReverseNodalConnectivity(revNodal,revNodalIndx); + revNodalExpected=[0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]; + revNodalIndexExpected=[0,1,3,5,7,12,14,15,17,18]; + self.assertEqual(revNodal.getNbOfElems(),18) + self.assertEqual(revNodalIndx.getNbOfElems(),10) + self.assertEqual(list(revNodal.getValues()),revNodalExpected) + self.assertEqual(list(revNodalIndx.getValues()),revNodalIndexExpected) + pass + def testConvertToPolyTypes(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + elts=[1,3]; + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(5,mesh.getNumberOfCells()); + self.assertEqual(23,mesh.getNodalConnectivity().getNumberOfTuples()); + expected1=[4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4] + self.assertEqual(expected1,list(mesh.getNodalConnectivity().getValues())); + # + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(8,mesh.getNumberOfCells()); + self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(8,mesh.getNumberOfCells()); + self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); + pass + def testDescConn2D(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(1,mesh2.getMeshDimension()); + self.assertEqual(13,mesh2.getNumberOfCells()); + self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); + self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); + self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); + self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); + expected1=[0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]; + self.assertEqual(expected1,list(desc.getValues())); + expected2=[0,4,7,10,14,18]; + self.assertEqual(expected2,list(descIndx.getValues())); + expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18]; + self.assertEqual(expected3,list(revDescIndx.getValues())); + expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]; + self.assertEqual(expected4,list(revDesc.getValues())); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39]; + self.assertEqual(expected5,list(connIndex.getValues())); + expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5]; + self.assertEqual(expected6,list(conn.getValues())); + # + eltsV=[1,3]; + mesh.convertToPolyTypes(eltsV); + mesh.checkCoherency(); + # + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + # + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(1,mesh2.getMeshDimension()); + self.assertEqual(13,mesh2.getNumberOfCells()); + self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); + self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); + self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); + self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); + self.assertEqual(expected1,list(desc.getValues())); + self.assertEqual(expected2,list(descIndx.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + self.assertEqual(expected5,list(connIndex.getValues())); + self.assertEqual(expected6,list(conn.getValues())); + pass + def testDescConn3D(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + # + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(2,mesh2.getMeshDimension()); + self.assertEqual(36,mesh2.getNumberOfCells()); + self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); + self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); + self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); + self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); + expected1=[0, 6, 12, 18, 24, 30, 36, 42, 48] + expected2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30] + expected3=[0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48] + expected4=[0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7] + expected5=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180] + expected6=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, + 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] + expected7=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, + 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] + + self.assertEqual(expected1,list(descIndx.getValues())); + self.assertEqual(expected2,list(desc.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); + self.assertEqual(expected6,list(mesh2.getNodalConnectivity().getValues())); + # + eltsV=[1,3] + mesh.convertToPolyTypes(eltsV); + mesh.checkCoherency(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(2,mesh2.getMeshDimension()); + self.assertEqual(36,mesh2.getNumberOfCells()); + self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); + self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); + self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); + self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); + self.assertEqual(expected1,list(descIndx.getValues())); + self.assertEqual(expected2,list(desc.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); + self.assertEqual(expected7,list(mesh2.getNodalConnectivity().getValues())); + pass + def testFindBoundaryNodes(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + boundaryNodes=mesh.findBoundaryNodes(); + expected1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; + self.assertEqual(expected1,list(boundaryNodes)); + pass + def testBoundaryMesh(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh2=mesh.buildBoundaryMesh(False); + self.assertEqual(24,mesh2.getNumberOfCells()); + self.assertEqual(26,mesh2.getNumberOfNodes()); + pass + def testBuildPartOfMySelf(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh.setName("Toto"); + tab1=[0,4] + tab2=[0,2,3] + # + subMesh=mesh.buildPartOfMySelf(tab1,True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + name=subMesh.getName(); + self.assertEqual(2,len(mesh.getAllTypes())); + self.assertEqual(NORM_TRI3,mesh.getAllTypes()[0]); + self.assertEqual(NORM_QUAD4,mesh.getAllTypes()[1]); + self.assertEqual(1,len(subMesh.getAllTypes())); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]); + self.assertEqual(name,"PartOf_Toto"); + self.assertEqual(2,subMesh.getNumberOfCells()); + subConn=[4,0,3,4,1,4,7,8,5,4]; + subConnIndex=[0,5,10]; + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn[0:10],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex[0:3],list(subMesh.getNodalConnectivityIndex().getValues())); + # + subMesh=mesh.buildPartOfMySelf(tab2[0:3],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)); + name=subMesh.getName(); + self.assertEqual(2,len(subMesh.getAllTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]); + self.assertEqual(name,"PartOf_Toto"); + self.assertEqual(3,subMesh.getNumberOfCells()); + subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3] + subConnIndex2=[0,5,9,14] + self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); + subMesh=subMesh.buildPartOfMySelf(range(3),True); + self.assertEqual("PartOf_Toto",subMesh.getName()); + pass + def testBuildPartOfMySelfNode(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + tab1=[5,7] + subMesh=mesh.buildPartOfMySelfNode(tab1[0:2],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(1,len(subMesh.getAllTypes())); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]); + self.assertEqual(1,subMesh.getNumberOfCells()); + self.assertEqual(5,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(2,subMesh.getNodalConnectivityIndex().getNbOfElems()); + subConn=[4,7,8,5,4] + subConnIndex=[0,5] + self.assertEqual(subConn[0:5],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex[0:2],list(subMesh.getNodalConnectivityIndex().getValues())); + # + subMesh=mesh.buildPartOfMySelfNode(tab1[0:2],False); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(2,len(subMesh.getAllTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]); + self.assertEqual(3,subMesh.getNumberOfCells()); + self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); + subConn2=[3,4,5,2,4,6,7,4,3,4,7,8,5,4] + subConnIndex2=[0,4,9,14] + self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); + #testing the case where length of tab2 is greater than max number of node per cell. + tab2=[0,3,2,1,4,5,6] + subMesh=mesh.buildPartOfMySelfNode(tab2[0:7],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(2,len(subMesh.getAllTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[1]); + self.assertEqual(3,subMesh.getNumberOfCells()); + pass + def testZipCoords(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertEqual(2,len(mesh.getAllTypes())); + self.assertEqual(2,mesh.getSpaceDimension()); + self.assertEqual(9,mesh.getNumberOfNodes()); + self.assertEqual(5,mesh.getNumberOfCells()); + oldConn=mesh.getNodalConnectivity().getValues()[0:mesh.getNodalConnectivity().getNbOfElems()]; + oldConnIndex=mesh.getNodalConnectivityIndex().getValues()[0:mesh.getNumberOfCells()+1] + oldCoords=mesh.getCoords(); + mesh.zipCoords(); + self.assertEqual(2,len(mesh.getAllTypes())); + self.assertEqual(2,mesh.getSpaceDimension()); + self.assertEqual(9,mesh.getNumberOfNodes()); + self.assertEqual(5,mesh.getNumberOfCells()); + self.assertEqual(mesh.getCoords().getValues()[0:2*9],oldCoords.getValues()); + self.assertEqual(list(oldConn),list(mesh.getNodalConnectivity().getValues())); + self.assertEqual(list(oldConnIndex),list(mesh.getNodalConnectivityIndex().getValues())); + # + tab1=[0,4] + subMesh=mesh.buildPartOfMySelf(tab1,True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + traducer=subMesh.zipCoordsTraducer(); + expectedTraducer=[0, 1, -1, 2, 3, 4, -1, 5, 6] + self.assertEqual(expectedTraducer,list(traducer.getValues())); + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]); + self.assertEqual(2,subMesh.getNumberOfCells()); + subConn=[4,0,2,3,1,4,5,6,4,3] + subConnIndex=[0,5,10] + self.assertEqual(7,subMesh.getNumberOfNodes()); + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); + # + subMesh=mesh.buildPartOfMySelf(tab1,False); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(NORM_QUAD4,subMesh.getAllTypes()[0]); + self.assertEqual(2,subMesh.getNumberOfCells()); + self.assertEqual(7,subMesh.getNumberOfNodes()); + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); + pass + def testZipConnectivity(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3=m2.buildPartOfMySelf(cells1,True); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)) + m4=MEDCouplingDataForTest.build2DSourceMesh_1(); + m5=MEDCouplingUMesh.mergeUMeshes(m1,m3); + m6=MEDCouplingUMesh.mergeUMeshes(m5,m4); + # + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(22,m6.getNumberOfNodes()); + (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13); + self.assertTrue(areNodesMerged); + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(9,m6.getNumberOfNodes()); + # + arr=m6.zipConnectivityTraducer(0); + self.assertEqual(7,m6.getNumberOfCells()); + m7=m6.clone(True); + arr=m6.zipConnectivityTraducer(0); + self.assertTrue(m7.isEqual(m6,1e-12)); + self.assertEqual(7,m6.getNumberOfCells()); + pass + def testEqualMesh(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertTrue(mesh1.isEqual(mesh1,1e-12)); + # + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + pt=mesh2.getCoords().getValues(); + tmp=pt[1] + mesh2.getCoords().setIJ(0,1,5.999); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh2.getCoords().setIJ(0,1,tmp); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + pt2=mesh1.getNodalConnectivity().getValues(); + mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])+1); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + pt2=mesh1.getNodalConnectivityIndex().getValues(); + mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]+1)); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1])); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + tmp3=mesh1.getName(); + mesh1.setName("lllll"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.setName(tmp3); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + tmp3=mesh2.getCoords().getInfoOnComponent(1); + mesh2.getCoords().setInfoOnComponent(1,"kkkkkk"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,tmp3); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + pass + def testEqualFieldDouble(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldOnCells1.setMesh(mesh1); + fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldOnCells2.setMesh(mesh2); + # + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnNodes1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnNodes1,1e-12,1e-15)); + self.assertTrue(not fieldOnNodes1.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1.setTime(4.,6,7); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setTime(4.,6,7); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1.setName("Power"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setName("Power"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnCells1.setMesh(mesh1); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setMesh(mesh1); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr=DataArrayDouble.New(); + arr.setName("popo"); + arr.setValues(mesh1.getNumberOfCells()*3*[6.],mesh1.getNumberOfCells(),3); + fieldOnCells1.setArray(arr); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setArray(arr); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2=arr.deepCopy(); + fieldOnCells2.setArray(arr2); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setIJ(1,2,6.1); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setIJ(1,2,6.); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr2.setName("popo2"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2.setName("popo"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2.setInfoOnComponent(2,"jjj"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setInfoOnComponent(2,"jjj"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + pass + + def testNatureChecking(self): + field=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + field.setNature(Integral); + field.setNature(ConservativeVolumic); + field.setNature(IntegralGlobConstraint); + field=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + field.setNature(ConservativeVolumic); + self.assertRaises(Exception,field.setNature,Integral); + self.assertRaises(Exception,field.setNature,IntegralGlobConstraint); + pass + + def testBuildSubMeshData(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1() + #check buildSubMesh on field on cells + fieldCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldCells.setMesh(targetMesh); + elts=[1,2,4] + ret1,di=fieldCells.buildSubMeshData(elts); + self.assertTrue(isinstance(ret1,MEDCouplingUMesh)) + self.assertEqual(3,ret1.getNumberOfCells()); + self.assertEqual(6,ret1.getNumberOfNodes()); + self.assertEqual(3,di.getNumberOfTuples()); + self.assertEqual(1,di.getNumberOfComponents()); + toCheck=di.getValues(); + self.assertTrue(elts,toCheck); + #check buildSubMesh on field on nodes + fieldNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + fieldNodes.setMesh(targetMesh); + ret2,di=fieldNodes.buildSubMeshData(elts); + self.assertTrue(isinstance(ret2,MEDCouplingUMesh)) + self.assertEqual(3,ret2.getNumberOfCells()); + self.assertEqual(6,ret2.getNumberOfNodes()); + self.assertEqual(6,di.getNumberOfTuples()); + self.assertEqual(1,di.getNumberOfComponents()); + toCheck=di.getValues(); + expected=[1,2,4,5,7,8] + self.assertEqual(expected,list(toCheck)); + pass + def testExtrudedMesh1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + ext=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,1); + self.assertEqual(18,ext.getNumberOfCells()); + self.assertEqual(60,ext.getNumberOfNodes()); + ids3D=ext.getMesh3DIds(); + ids3DExpected=[5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12] + self.assertEqual(18,ids3D.getNumberOfTuples()); + self.assertEqual(1,ids3D.getNumberOfComponents()); + self.assertEqual(ids3DExpected,list(ids3D.getValues())); + mesh1D=ext.getMesh1D(); + self.assertEqual(4,mesh1D.getNumberOfNodes()); + self.assertEqual(3,mesh1D.getNumberOfCells()); + mesh1DExpected=[0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, + 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, + 2, 0.66666666666666663, 1.4583333333333333, 3] + mesh1DCoords=mesh1D.getCoords(); + self.assertEqual(4,mesh1DCoords.getNumberOfTuples()); + self.assertEqual(3,mesh1DCoords.getNumberOfComponents()); + self.assertEqual(mesh1DExpected,mesh1DCoords.getValues()); + conn1D=mesh1D.getNodalConnectivity(); + self.assertEqual(9,conn1D.getNumberOfTuples()); + self.assertEqual(1,conn1D.getNumberOfComponents()); + conn1DExpected=[1,0,1,1,1,2,1,2,3] + self.assertEqual(conn1DExpected,list(conn1D.getValues())); + pass + + def testExtrudedMesh3(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.changeSpaceDimension(3); + m2=MEDCouplingDataForTest.buildCU1DMesh_U(); + m2.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m2.rotate(center,vector,-pi/2.); + m3=m1.buildExtrudedMeshFromThis(m2,0); + # + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(range(15),list(m3DIds)); + #some random in cells to check that extrusion alg find it correctly + expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(expected1,list(m3DIds)); + #play with polygons and polyedrons + cells=[2,3] + m1.convertToPolyTypes(cells); + m3=m1.buildExtrudedMeshFromThis(m2,0); + self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(0)); + self.assertEqual(NORM_PENTA6,m3.getTypeOfCell(1)); + self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(2)); + self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(3)); + self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(4)); + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(expected1,list(m3DIds)); + pass + + def testExtrudedMesh4(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=[2,4]; + m1.convertToPolyTypes(cells); + m1.changeSpaceDimension(3); + m2=MEDCouplingDataForTest.buildCU1DMesh_U(); + m2.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m2.rotate(center,vector,-pi/2.); + m3=m1.buildExtrudedMeshFromThis(m2,0); + expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] + rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12] + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0)); + self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1)); + self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2)); + self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7)); + f=m4.getMeasureField(True); + arr=f.getArray(); + self.assertEqual(15,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + arrPtr=arr.getValues(); + expected2=[0.075,0.0375,0.0375,0.075,0.075, + 0.1125,0.05625,0.05625,0.1125,0.1125, + 0.0625,0.03125,0.03125,0.0625,0.0625] + for i in xrange(15): + self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16); + pass + m5=m4.build3DUnstructuredMesh(); + self.assertTrue(m5.isEqual(m3,1e-12)); + f=m5.getMeasureField(True); + f.setMesh(m4) + self.assertTrue(isinstance(f.getMesh(),MEDCouplingExtrudedMesh)) + arr=f.getArray(); + arrPtr=arr.getValues(); + for i in xrange(15): + self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],15); + pass + pass + + def testFindCommonNodes(self): + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + comm,commI=targetMesh.findCommonNodes(-1,1e-10); + self.assertEqual(1,commI.getNumberOfTuples()); + self.assertEqual(0,comm.getNumberOfTuples()); + o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); + self.assertEqual(27,newNbOfNodes); + self.assertEqual(27,o2n.getNumberOfTuples()); + o2nExp1=range(27) + self.assertEqual(o2nExp1,list(o2n.getValues())); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + self.assertEqual(31,targetMesh.getNumberOfNodes()); + comm,commI=targetMesh.findCommonNodes(-1,1e-10); + self.assertEqual(3,commI.getNumberOfTuples()); + self.assertEqual(6,comm.getNumberOfTuples()); + commExpected=[1,27,28,29,23,30] + commIExpected=[0,4,6] + self.assertEqual(commExpected,list(comm.getValues())); + self.assertEqual(commIExpected,list(commI.getValues())); + o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); + self.assertEqual(31,o2n.getNumberOfTuples()); + self.assertEqual(27,newNbOfNodes); + o2nExp2=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, + 21,22,23,24,25,26,1,1,1,23] + self.assertEqual(o2nExp2,list(o2n.getValues())); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + targetMesh.updateTime(); + self.assertEqual(time,targetMesh.getTimeOfThis()); + self.assertTrue(not areNodesMerged); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + targetMesh.updateTime(); + self.assertTrue(time!=targetMesh.getTimeOfThis()); + self.assertTrue(areNodesMerged); + connExp=[18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, + 18,4,5,8,7,13,14,17,16, + 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, + 18,13,14,17,16,22,23,26,25] + self.assertEqual(72,targetMesh.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(connExp,list(targetMesh.getNodalConnectivity().getValues())); + self.assertEqual(27,targetMesh.getCoords().getNumberOfTuples()); + coordsExp=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , + 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., + 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , + 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. + , 0., 50., 200., 50., 50., 200. , 200., 50., 200., + 0., 200., 200., 50., 200., 200. , 200., 200., 200. ] + self.assertEqual(coordsExp,targetMesh.getCoords().getValues()); + # 2D + targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); + self.assertEqual(18,targetMesh.getNumberOfNodes()); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + self.assertTrue(time!=targetMesh.getTimeOfThis()); + self.assertTrue(areNodesMerged); + self.assertEqual(9,targetMesh.getNumberOfNodes()); + connExp2=[4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3] + self.assertEqual(23,targetMesh.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(connExp2,list(targetMesh.getNodalConnectivity().getValues())); + coordsExp2=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7] + self.assertEqual(9,targetMesh.getCoords().getNumberOfTuples()); + self.assertEqual(coordsExp2,targetMesh.getCoords().getValues()); + pass + + def testCheckButterflyCells(self): + sourceMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + conn=sourceMesh.getNodalConnectivity() + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(1,len(cells)); + self.assertEqual(3,cells[0]); + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + # 3D surf + sourceMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + conn=sourceMesh.getNodalConnectivity() + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(1,len(cells)); + self.assertEqual(3,cells[0]); + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + pass + + def testMergeMesh1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + vec=[1.,0.] + m2.translate(vec); + m3=m1.mergeMyselfWith(m2); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)); + m3.checkCoherency(); + m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); + self.assertTrue(m3.isEqual(m4,1.e-12)); + da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12); + self.assertEqual(11,m3.getNumberOfNodes()); + self.assertTrue(isMerged); + pass + + def testMergeMeshOnSameCoords1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=range(5); + m2.convertToPolyTypes(cells); + m1.tryToShareSameCoords(m2,1e-12); + m3=MEDCouplingDataForTest.build2DTargetMesh_1(); + m3.tryToShareSameCoords(m2,1e-12); + meshes=[m1,m2,m3] + m4=MEDCouplingUMesh.mergeUMeshesOnSameCoords(meshes); + m4.checkCoherency(); + self.assertEqual(15,m4.getNumberOfCells()); + cells1=[0,1,2,3,4] + m1_1=m4.buildPartOfMySelf(cells1,True); + m1_1.setName(m1.getName()); + self.assertTrue(m1.isEqual(m1_1,1e-12)); + cells2=[5,6,7,8,9] + m2_1=m4.buildPartOfMySelf(cells2,True); + m2_1.setName(m2.getName()); + self.assertTrue(m2.isEqual(m2_1,1e-12)); + cells3=[10,11,12,13,14] + m3_1=m4.buildPartOfMySelf(cells3,True); + m3_1.setName(m3.getName()); + self.assertTrue(m3.isEqual(m3_1,1e-12)); + pass + + def testMergeField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + vec=[1.,0.] + m2.translate(vec); + f1=m1.getMeasureField(True); + f2=m2.getMeasureField(True); + f3=MEDCouplingFieldDouble.mergeFields(f1,f2); + f3.checkCoherency(); + m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); + self.assertTrue(f3.getMesh().isEqual(m4,1.e-12)); + name=f3.getName(); + self.assertEqual(name,"MeasureOfMesh_"); + self.assertEqual(f3.getTypeOfField(),ON_CELLS); + self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f3.getNumberOfComponents()); + self.assertEqual(7,f3.getNumberOfTuples()); + values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values),len(tmp)) + for i in xrange(7): + self.assertTrue(abs(values[i]-tmp[i])<1e-12) + pass + pass + + def testFillFromAnalytic(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_CELLS,1,"x+y"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + # + f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) + pass + values4=f1.accumulate(); + self.assertEqual(2,len(values4)) + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertEqual(2,len(values4)) + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + # + self.assertRaises(Exception,m.fillFromAnalytic,ON_NODES,1,"1./(x-0.2)"); + pass + + def testFillFromAnalytic2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_CELLS,1,"y+x"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(values1)): + self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); + pass + # + f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(values2)): + self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); + pass + f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + tmp=f1.getArray().getValues(); + values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + # + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(values3)): + self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); + pass + values4=f1.accumulate(); + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + pass + + def testApplyFunc(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + f1.applyFunc(1,"x+y"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + pass + + def testApplyFunc2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + # + f2=f1.clone(True); + f2.applyFunc("abs(u)^2.4+2*u"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 5.0423700574830965, 17.435300118916864] + tmp=f2.getArray().getValues(); + self.assertEqual(len(tmp),len(values2)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f1.applyFunc(1,"x+y"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] + tmp=f1.getArray().getValues(); + self.assertEqual(len(tmp),len(values1)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + pass + + def testOperationsOnFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f2=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f1.checkCoherency(); + f2.checkCoherency(); + f3=f1+f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + # + f3=f1*f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f3=f1+f2; + f4=f1-f3; + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4] + tmp=f4.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) + pass + # + f3=f1+f2; + f4=f3/f2; + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + tmp=f4.getArray().getValues(); + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-2.)<1.e-12) + pass + # + f4=f2.buildNewTimeReprFromThis(ONE_TIME,False); + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + self.assertRaises(Exception,f1.__add__,f4); + f5=f4.buildNewTimeReprFromThis(NO_TIME,False); + self.assertEqual(f5.getTypeOfField(),ON_NODES); + self.assertEqual(f5.getTimeDiscretization(),NO_TIME); + f3=f1+f5; + tmp=f3.getArray().getValues(); + values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values4[i])<1.e-12) + pass + # + f4=f2.buildNewTimeReprFromThis(ONE_TIME,True); + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + self.assertRaises(Exception,f1.__add__,f4); + f5=f4.buildNewTimeReprFromThis(NO_TIME,True); + self.assertEqual(f5.getTypeOfField(),ON_NODES); + self.assertEqual(f5.getTimeDiscretization(),NO_TIME); + f3=f1+f5; + tmp=f3.getArray().getValues(); + values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + self.assertEqual(len(values5),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values5[i])<1.e-12) + pass + pass + + def testOperationsOnFields2(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + f3=f1/f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),NO_TIME); + expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] + self.assertEqual(1,f3.getNumberOfComponents()); + self.assertEqual(9,f3.getNumberOfTuples()); + val=f3.getArray().getValues(); + for i in xrange(9): + self.assertTrue(abs(expected1[i]-val[i])<1.e-12); + # + f1=m.buildOrthogonalField(); + f2=m.fillFromAnalytic(ON_CELLS,1,"x"); + f3=f1*f2; + expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] + val=f3.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + # + f3=f2*f1; + val=f3.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + pass + + def testOperationsOnFields3(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + f1/=f2 + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),NO_TIME); + expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + val=f1.getArray().getValues(); + for i in xrange(9): + self.assertTrue(abs(expected1[i]-val[i])<1.e-12); + pass + # + f1=m.buildOrthogonalField(); + f2=m.fillFromAnalytic(ON_CELLS,1,"x"); + f1*=f2 + expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] + val=f1.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + # + f1=m.buildOrthogonalField(); + # to avoid valgrind leaks + # self.assertRaises(Exception,f2.__imul__,f1); + pass + + def testOperationsOnFields4(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setMesh(m); + array=DataArrayDouble.New(); + f1.setArray(array); + self.assertRaises(Exception,f1.setEndArray,array); + self.assertRaises(Exception,f1.getEndArray); + arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] + arr2=[5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.] + array.setValues(arr1,nbOfCells,3); + f1.setStartTime(2.,0,0); + f1.setEndTime(3.,0,0); + f1.checkCoherency(); + pos=[0.3,-0.2] + res=f1.getValueOn(pos); + self.assertTrue(abs(arr1[3]-res[0])<1.e-12); + self.assertTrue(abs(arr1[4]-res[1])<1.e-12); + self.assertTrue(abs(arr1[5]-res[2])<1.e-12); + res=None + res=f1.getValueOn(pos,2.2); + self.assertTrue(abs(arr1[3]-res[0])<1.e-12); + self.assertTrue(abs(arr1[4]-res[1])<1.e-12); + self.assertTrue(abs(arr1[5]-res[2])<1.e-12); + res=None + self.assertRaises(Exception,f1.getValueOn,pos,3.2) + f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f2.setMesh(m); + f2.setArray(f1.getArray()); + f2.setStartTime(2.,3,0); + f2.setEndTime(4.,13,0); + self.assertRaises(Exception,f2.checkCoherency) + array2=DataArrayDouble.New(); + array2.setValues(arr2,nbOfCells,3); + f2.setEndArray(array2); + f2.checkCoherency(); + # + res=None + res=f2.getValueOn(pos,3.21); + self.assertTrue(abs(4.025-res[0])<1.e-12); + self.assertTrue(abs(14.025-res[1])<1.e-12); + self.assertTrue(abs(24.025-res[2])<1.e-12); + f3=f2.clone(True); + self.assertTrue(f2.isEqual(f3,1e-12,1e-12)); + f3.getEndArray().setIJ(0,0,5.001); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-12)); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.1,3,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,4,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,1); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.1,13,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,14,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,1); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f4=f2+f2 + res=None + res=f4.getValueOn(pos,3.21); + self.assertTrue(abs(8.05-res[0])<1.e-12); + self.assertTrue(abs(28.05-res[1])<1.e-12); + self.assertTrue(abs(48.05-res[2])<1.e-12); + f4+=f2; + res=None + res=f4.getValueOn(pos,3.21); + self.assertTrue(abs(12.075-res[0])<1.e-12); + self.assertTrue(abs(42.075-res[1])<1.e-12); + self.assertTrue(abs(72.075-res[2])<1.e-12); + pass + + def testMergeNodesOnField(self): + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f1.mergeNodes(1e-10); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + tmp=f1.getArray() + tmp.setIJ(0,0,1000.); + f1.mergeNodes(1e-10); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + tmp=f1.getArray() + tmp.setIJ(1,0,1000.); + self.assertRaises(Exception,f1.mergeNodes,1.e-10) + pass + + def testCheckConsecutiveCellTypes(self): + sourceMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertTrue(sourceMesh.checkConsecutiveCellTypes()); + order1=[NORM_TRI3,NORM_QUAD4] + order2=[NORM_QUAD4,NORM_TRI3] + self.assertTrue(not targetMesh.checkConsecutiveCellTypes()); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order1)); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); + da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order1); + self.assertEqual(5,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + expected1=[2,0,1,3,4] + self.assertTrue(expected1==list(da.getValues())); + da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order2); + self.assertEqual(5,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + expected2=[0,3,4,1,2] + self.assertTrue(expected2==list(da.getValues())); + renumber1=[4,0,1,2,3] + targetMesh.renumberCells(renumber1,False); + self.assertTrue(targetMesh.checkConsecutiveCellTypes()); + self.assertTrue(targetMesh.checkConsecutiveCellTypesAndOrder(order1)); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); + pass + + def testRearrange2ConsecutiveCellTypes(self): + m1_1=MEDCouplingDataForTest.build2DSourceMesh_1(); + m2_1=MEDCouplingDataForTest.build2DTargetMesh_1(); + arr1=m1_1.rearrange2ConsecutiveCellTypes(); + m1_2=MEDCouplingDataForTest.build2DSourceMesh_1(); + self.assertTrue(m1_2.isEqual(m1_1,1e-12)); + expected1=[0,1] + self.assertEqual(2,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertTrue(expected1,arr1.getValues()); + expected2=[0,3,4,1,2] + arr1=m2_1.rearrange2ConsecutiveCellTypes(); + self.assertEqual(5,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected2,list(arr1.getValues())); + m2_2=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertEqual(5,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected2,list(arr1.getValues())); + self.assertTrue(not m2_2.isEqual(m2_1,1e-12)); + m2_2.renumberCells(expected2,False); + self.assertTrue(m2_2.isEqual(m2_1,1e-12)); + pass + + def testSplitByType(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + v=m1.splitByType(); + self.assertEqual(3,len(v)); + m2=MEDCouplingUMesh.mergeUMeshesOnSameCoords(v); + m2.setName(m1.getName()); + self.assertTrue(m1.isEqual(m2,1.e-12)); + pass + + def testFuseUMeshesOnSameCoords(self): + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3=m2.buildPartOfMySelf(cells1,True); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)) + cells2=[1,2,4] + m4=m2.buildPartOfMySelf(cells2,True); + self.assertTrue(isinstance(m4,MEDCouplingUMesh)) + cells3=[1,2] + m5=m2.buildPartOfMySelf(cells3,True); + self.assertTrue(isinstance(m5,MEDCouplingUMesh)) + meshes=[m3,m4,m5] + # + m7,corr=MEDCouplingUMesh.fuseUMeshesOnSameCoords(meshes,0); + self.assertEqual(4,m7.getNumberOfCells()); + self.assertEqual(3,len(corr)); + expectedVals1=[3,3,2] + expectedVals2=[[0,1,2],[3,0,2],[3,0]] + for i in xrange(3): + arr=corr[i]; + self.assertEqual(1,arr.getNumberOfComponents()); + nbOfVals=expectedVals1[i]; + self.assertEqual(nbOfVals,arr.getNumberOfTuples()); + vals=arr.getValues(); + self.assertEqual(expectedVals2[i],list(vals)); + pass + arr2,fidsOfGroups=DataArrayInt.makePartition(corr,m7.getNumberOfCells()); + fidExp=[5,1,3,4] + fidsGrp=[[1,3,5],[3,4,5],[4,5]] + self.assertEqual(3,len(fidsOfGroups)); + self.assertEqual(1,arr2.getNumberOfComponents()); + self.assertEqual(4,arr2.getNumberOfTuples()); + self.assertEqual(fidExp,list(arr2.getValues())); + for i in xrange(3): + nbOfVals=expectedVals1[i]; + self.assertEqual(list(fidsOfGroups[i]),fidsGrp[i]); + pass + pass + + def testFuseUMeshesOnSameCoords2(self): + m1,m2=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + part1=[2,3,6,4,10] + m3=m1.buildPartOfMySelf(part1,True); + part2=[5,6,4,7] + m4=m1.buildPartOfMySelf(part2,True); + meshes=[m1,m3,m3,m4] + m5,corr=MEDCouplingUMesh.fuseUMeshesOnSameCoords(meshes,0); + self.assertEqual(18,m5.getNumberOfCells()); + exp2=[ + [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], + [2,3,6,4,10], + [2,3,6,4,10], + [5,6,4,7]] + i=0; + for it in corr: + self.assertEqual(exp2[i],list(it.getValues())); + i+=1 + pass + pass + + def testBuildOrthogonalField(self): + targetMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + field=targetMesh.buildOrthogonalField(); + expected=[0.70710678118654746,0.,-0.70710678118654746] + self.assertEqual(5,field.getNumberOfTuples()); + self.assertEqual(3,field.getNumberOfComponents()); + vals=field.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected[i%3]-vals[i])<1e-12); + # testing + targetCoords=[0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.] + targetConn=[0,1,2,3] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(1); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,4,3); + targetMesh.setCoords(myCoords); + field=targetMesh.buildOrthogonalField(); + self.assertEqual(1,field.getNumberOfTuples()); + self.assertEqual(3,field.getNumberOfComponents()); + vals=field.getArray().getValues(); + self.assertTrue(abs(-0.70710678118654746-vals[0])<1e-12); + self.assertTrue(abs(0.-vals[1])<1e-12); + self.assertTrue(abs(0.70710678118654746-vals[2])<1e-12); + pass + + def testGetCellsContainingPoint(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos=[0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.] + #2D basic + t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12); + self.assertEqual(6,len(t1)); + self.assertEqual(7,len(t2)); + expectedValues1=[0,4,3,0,1,2] + expectedValues2=[0,1,2,3,4,5,6] + self.assertEqual(list(t1),expectedValues1); + self.assertEqual(list(t2),expectedValues2); + #2D with no help of bounding box. + center=[0.2,0.2] + MEDCouplingPointSet.rotate2DAlg(center,0.78539816339744830962,6,pos); + targetMesh.rotate(center,[],0.78539816339744830962); + t1=None + t2=None + t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12); + self.assertEqual(6,len(t1)); + self.assertEqual(7,len(t2)); + self.assertEqual(list(t1),expectedValues1); + self.assertEqual(list(t2),expectedValues2); + #2D outside + pos1bis=[-0.3303300858899107,-0.11819805153394641] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos1bis,1e-12)); + #test limits 2D + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos2=[0.2,-0.05] + t1=None + t1=targetMesh.getCellsContainingPoint(pos2,1e-12) + self.assertEqual(2,len(t1)); + expectedValues3=[0,1] + self.assertEqual(list(t1),expectedValues3); + pos3=[0.2,0.2] + t1=None + t1=targetMesh.getCellsContainingPoint(pos3,1e-12); + self.assertEqual(5,len(t1)); + expectedValues4=[0,1,2,3,4] + self.assertEqual(list(t1),expectedValues4); + self.assertEqual(0,targetMesh.getCellContainingPoint(pos3,1e-12)); + #3D + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + pos4=[25.,25.,25.] + self.assertEqual(0,targetMesh.getCellContainingPoint(pos4,1e-12)); + pos5=[50.,50.,50.] + t1=None + t1=targetMesh.getCellsContainingPoint(pos5,1e-12); + self.assertEqual(8,len(t1)); + expectedValues5=[0,1,2,3,4,5,6,7] + self.assertEqual(list(t1),expectedValues5); + pos6=[0., 50., 0.] + t1=None + t1=targetMesh.getCellsContainingPoint(pos6,1e-12); + self.assertEqual(2,len(t1)); + expectedValues6=[0,2] + self.assertEqual(list(t1),expectedValues6); + #3D outside + pos7=[-1.0,-1.0,0.] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos7,1e-12)); + #3D outside 2 + center2=[0.,0.,0.] + vec2=[0.,-1.,0.] + targetMesh.rotate(center2,vec2,0.78539816339744830962); + pos8=[-25.,25.,12.] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos8,1e-12)); + pass + + def testGetValueOn1(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); + nbOfCells=targetMesh.getNumberOfCells(); + fieldOnCells.setMesh(targetMesh); + array=DataArrayDouble.New(); + tmp=2*nbOfCells*[None] + for i in xrange(nbOfCells): + tmp[2*i]=7.+float(i); + tmp[2*i+1]=17.+float(i) + pass + array.setValues(tmp,nbOfCells,2); + fieldOnCells.setArray(array); + # + pos1=[0.25,0.] + res=fieldOnCells.getValueOn(pos1); + self.assertEqual(2,len(res)) + self.assertTrue(abs(8.-res[0])<1e-12); + self.assertTrue(abs(18.-res[1])<1e-12); + # + # + targetMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); + fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES); + nbOfNodes=targetMesh.getNumberOfNodes(); + fieldOnNodes.setMesh(targetMesh); + array=DataArrayDouble.New(); + tmp=2*nbOfNodes*[None] + for i in xrange(nbOfNodes): + tmp[2*i]=17.+float(i); + tmp[2*i+1]=27.+float(i) + pass + array.setValues(tmp,nbOfNodes,2); + fieldOnNodes.setArray(array); + # + pos2=[-0.13333333333333333,-0.13333333333333333] + res=None + res=fieldOnNodes.getValueOn(pos2); + self.assertEqual(2,len(res)) + self.assertTrue(abs(17.5-res[0])<1e-12); + self.assertTrue(abs(27.5-res[1])<1e-12); + pos3=[0.033333333333333326,0.36666666666666664] + res=None + res=fieldOnNodes.getValueOn(pos3); + self.assertEqual(2,len(res)) + self.assertTrue(abs(18.666666666666667-res[0])<1e-12); + self.assertTrue(abs(28.666666666666667-res[1])<1e-12); + pass + + def testCMesh0(self): + mesh=MEDCouplingCMesh.New(); + coordsX=DataArrayDouble.New(); + arrX=[ -1., 1., 2., 4. ] + coordsX.setValues(arrX,4,1); + coordsY=DataArrayDouble.New(); + arrY=[ -2., 2., 4., 8. ] + coordsY.setValues(arrY,4,1); + coordsZ=DataArrayDouble.New(); + arrZ=[ -3., 3., 6., 12. ] + coordsZ.setValues(arrZ,4,1); + mesh.setCoords(coordsX,coordsY,coordsZ); + pass + + def testScale(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos=[0.2,0.2] + mesh.scale(pos,0.5); + expected1=[-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, + -0.05,0.45, 0.2,0.45, 0.45,0.45] + val=mesh.getCoords().getValues(); + self.assertEqual(18,len(val)) + for i in xrange(18): + self.assertTrue(abs(expected1[i]-val[i])<1e-12); + pass + pass + + def testTryToShareSameCoords(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + #self.assertEqual(m1.getCoords()!=m2.getCoords()); + m1.tryToShareSameCoords(m2,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + m1.tryToShareSameCoords(m2,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + m2.tryToShareSameCoords(m1,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + # + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_2(); + #self.assertEqual(m1.getCoords()!=m2.getCoords()); + m1.tryToShareSameCoords(m2,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + m1.tryToShareSameCoords(m2,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + m2.tryToShareSameCoords(m1,1e-12); + #self.assertEqual(m1.getCoords()==m2.getCoords()); + # + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + #self.assertEqual(m1.getCoords()!=m2.getCoords()); + self.assertRaises(Exception,m1.tryToShareSameCoords,m2,1e-12) + pass + + def testFindNodeOnPlane(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + pt=[300.,300.,0.] + v=[0.,0.,2.] + n=mesh.findNodesOnPlane(pt,v,1e-12); + self.assertEqual(9,len(n)); + m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); + self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) + me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); + da=me.getMesh3DIds(); + self.assertEqual(8,me.getNumberOfCells()); + expected=[0,1,2,3,4,5,6,7] + val=da.getValues(); + self.assertEqual(expected,list(val)); + pass + + def testRenumberCells(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + self.assertTrue(m.isEqual(m2,0)); + arr=[12,3,25,2,26] + m.renumberCells(arr,True); + self.assertTrue(not m.isEqual(m2,0)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(0)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(2)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(4)); + arr2=[5,-1,-5,4,8] + m.renumberCells(arr2,True); + self.assertTrue(m.isEqual(m2,0)); + pass + + def testChangeSpaceDimension(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertEqual(3,m1.getSpaceDimension()); + m1.changeSpaceDimension(2); + self.assertEqual(2,m1.getSpaceDimension()); + m1.setName(m2.getName()); + self.assertTrue(m1.isEqual(m2,1e-12)); + m1.changeSpaceDimension(3); + self.assertEqual(3,m1.getSpaceDimension()); + expected=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.] + val=m1.getCoords().getValues(); + for i in xrange(27): + self.assertTrue(abs(expected[i]-val[i])<1e-14); + pass + pass + + def testGaussPointField1(self): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1 + _gsCoo1=gsCoo1 + _wg1=wg1 + # + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); + f.setMesh(m); + self.assertEqual(0,f.getNbOfGaussLocalization()); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + self.assertRaises(Exception,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) + self.assertEqual(1,f.getNbOfGaussLocalization()); + refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo2=refCoo2 + _gsCoo1=_gsCoo1[0:4] + _wg1=_wg1[0:2] + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + array=DataArrayDouble.New(); + ptr=18*2*[None] + for i in xrange(18*2): + ptr[i]=float(i+1) + array.setValues(ptr,18,2); + ptr=array.getPointer(); + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + f.checkCoherency(); + self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); + self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); + # + f.clearGaussLocalizations(); + self.assertEqual(0,f.getNbOfGaussLocalization()); + self.assertRaises(Exception,f.checkCoherency); + ids1=[0,1,3,4] + self.assertRaises(Exception,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(0,f.getNbOfGaussLocalization()); + ids2=[0,4] + f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(1,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertRaises(Exception,f.getGaussLocalizationIdOfOneCell,1); + ids3=[1,2] + f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); + self.assertRaises(Exception,f.checkCoherency);#<- cell 3 has no localization + ids4=[3] + _gsCoo2=_gsCoo1; + _wg2=_wg1; + _gsCoo2[0]=0.8888777776666; + _wg2[0]=0.1234567892377; + f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); + self.assertEqual(3,f.getNbOfGaussLocalization()); + tmpIds=f.getCellIdsHavingGaussLocalization(0); + self.assertEqual(ids2,list(tmpIds)); + self.assertRaises(Exception,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. + array2=f.getArray().substr(0,10); + f.setArray(array2); + f.checkCoherency();#<- here it is OK + f2=f.clone(True); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + gl1=f2.getGaussLocalization(0); + tmp=gl1.getGaussCoord(1,1); + self.assertAlmostEqual(2.07*_b-1,tmp,14); + gl1.setGaussCoord(1,1,0.07); + self.assertTrue(not f.isEqual(f2,1e-14,1e-14)); + gl1.setGaussCoord(1,1,tmp); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + f2.checkCoherency(); + pass + + def testGaussPointNEField1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); + f.setMesh(m); + f.setName("MyFirstFieldOnNE"); + f.setDescription("MyDescriptionNE"); + array=DataArrayDouble.New(); + tmp=18*2*[None] + for i in xrange(18*2): + tmp[i]=float(i+7) + pass + array.setValues(tmp,18,2); + ptr=array.getPointer(); + f.setArray(array); + # + f.checkCoherency(); + f2=f.clone(True); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + self.assertAlmostEqual(21.,f.getIJK(2,0,0),14); + self.assertAlmostEqual(18.,f.getIJK(1,1,1),14); + pass + + def testCellOrientation1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + vec=[0.,0.,1.] + self.assertRaises(Exception,m.are2DCellsNotCorrectlyOriented,vec,False); + m.changeSpaceDimension(3); + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertTrue(len(res1)==0); + vec[2]=-1.; + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertEqual(5,len(res1)); + # + vec[2]=1.; + # connectivity inversion + conn=m.getNodalConnectivity().getValues(); + tmp=conn[11]; + conn[11]=conn[12]; + conn[12]=tmp; + m.getNodalConnectivity().setValues(conn,len(conn),1) + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertEqual(1,len(res1)); + self.assertEqual(2,res1[0]); + m.orientCorrectly2DCells(vec,False); + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertTrue(len(res1)==0); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2.changeSpaceDimension(3); + self.assertTrue(m.isEqual(m2,1e-12)); + pass + + def testCellOrientation2(self): + m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertEqual(6,len(res1)); + m2.orientCorrectlyPolyhedrons(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + m2.checkCoherency(); + self.assertEqual(18,m2.getNumberOfCells()); + cellIds2=[0,6,12] + m2.convertToPolyTypes(cellIds2); + m2.orientCorrectlyPolyhedrons(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + f2=m2.getMeasureField(False); + f2Ptr=f2.getArray().getValues(); + #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation + m3=MEDCouplingDataForTest.build2DTargetMesh_1(); + vec=[0.,0.,-1.] + m3.changeSpaceDimension(3); + ids2=[0,1,2,3,4] + m3.convertToPolyTypes(ids2); + m3.orientCorrectly2DCells(vec,False); + m4=MEDCouplingDataForTest.buildCU1DMesh_U(); + m4.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m4.rotate(center,vector,-pi/2.); + m5=m3.buildExtrudedMeshFromThis(m4,0); + res1=m5.arePolyhedronsNotCorrectlyOriented(); + self.assertEqual(15,len(res1)); + m5.orientCorrectlyPolyhedrons(); + res1=m5.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + f3=m5.getMeasureField(False); + self.assertEqual(15,f3.getArray().getNumberOfTuples()); + self.assertEqual(1,f3.getNumberOfComponents()); + f3Ptr=f3.getArray().getValues(); + expected1=[0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625]; + for i in xrange(15): + self.assertTrue(abs(expected1[i]-f3Ptr[i])<1e-12); + pass + f4=m5.getBarycenterAndOwner(); + self.assertEqual(15,f4.getNumberOfTuples()); + self.assertEqual(3,f4.getNumberOfComponents()); + f4Ptr=f4.getValues(); + expected2=[-0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,-0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,-0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875]; + for i in xrange(45): + self.assertTrue(abs(expected2[i]-f4Ptr[i])<1e-12); + pass + pass + + def testPolyhedronBarycenter(self): + connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0]; + coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5]; + meshN=MEDCouplingUMesh.New(); + meshN.setName("ForBary"); + meshN.setMeshDimension(3); + meshN.allocateCells(4); + meshN.insertNextCell(NORM_POLYHED,29,connN[0:29]) + meshN.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,9,3); + meshN.setCoords(myCoords); + meshN.checkCoherency(); + # + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + meshN.orientCorrectlyPolyhedrons(); + self.assertTrue(len(res1)==0); + da=meshN.getBarycenterAndOwner(); + self.assertEqual(1,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + center=[0.,0.,0.] + vec=[0.,2.78,0.] + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + meshN.rotate(center,vec,pi/7.); + meshN.translate(vec); + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + center2=[1.12,3.45,6.78] + vec2=[4.5,9.3,2.8] + meshN.rotate(center2,vec2,e); + meshN.translate(vec2); + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-10); + pass + pass + + def testNormL12Integ1D(self): + m1=MEDCouplingDataForTest.build1DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(m1); + array=DataArrayDouble.New(); + arr=[-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72] + array.setValues(arr,m1.getNumberOfCells(),3); + f1.setArray(array); + # + f3=m1.getBarycenterAndOwner(); + self.assertEqual(4,f3.getNumberOfTuples()); + self.assertEqual(1,f3.getNumberOfComponents()); + expected9=[0.75,5.105,0.8,5.155] + ptr=f3.getValues(); + for i in xrange(4): + self.assertTrue(abs(expected9[i]-ptr[i])<1e-12); + pass + # + f2=m1.getMeasureField(False); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + expected1=[0.5,0.21,-0.6,-0.31] + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + expected2=[0.5,0.21,0.6,0.31] + f2=m1.getMeasureField(True); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + #integral + self.assertTrue(4,f1.getNumberOfTuples()) + res=f1.integral(False); + self.assertTrue(3,len(res)) + expected3=[0.9866,-0.3615,0.4217] + for i in xrange(3): + self.assertTrue(abs(expected3[i]-res[i])<1e-12); + pass + self.assertTrue(abs(expected3[0]-f1.integral(0,False))<1e-12); + self.assertTrue(abs(expected3[1]-f1.integral(1,False))<1e-12); + self.assertTrue(abs(expected3[2]-f1.integral(2,False))<1e-12); + res=f1.integral(True); + expected4=[-3.4152,8.7639,-14.6879] + for i in xrange(3): + self.assertTrue(abs(expected4[i]-res[i])<1e-12); + pass + #normL1 + res=f1.normL1(); + self.assertTrue(3,len(res)) + expected5=[11.3068,27.3621,43.7881] + for i in xrange(3): + self.assertTrue(abs(expected5[i]-res[i])<1e-12); + pass + self.assertTrue(abs(expected5[0]-f1.normL1(0))<1e-12); + self.assertTrue(abs(expected5[1]-f1.normL1(1))<1e-12); + self.assertTrue(abs(expected5[2]-f1.normL1(2))<1e-12); + #normL2 + res=f1.normL2(); + self.assertTrue(3,len(res)) + expected7=[9.0252562290496776, 21.545259176904789, 34.433193070059595] + for i in xrange(3): + self.assertTrue(abs(expected7[i]-res[i])<1e-9); + pass + self.assertTrue(abs(expected7[0]-f1.normL2(0))<1e-9); + self.assertTrue(abs(expected7[1]-f1.normL2(1))<1e-9); + self.assertTrue(abs(expected7[2]-f1.normL2(2))<1e-9); + #buildMeasureField + f4=f1.buildMeasureField(False); + self.assertTrue(abs(-0.2-f4.accumulate(0))<1e-12); + f4=f1.buildMeasureField(True); + self.assertTrue(abs(1.62-f4.accumulate(0))<1e-12); + # Testing with 2D Curve + m1=MEDCouplingDataForTest.build2DCurveTargetMesh_3(); + f2=m1.getMeasureField(False); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(sqrt(2.)*expected2[i]-ptr[i])<1e-12); + pass + f2=m1.getMeasureField(True); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected2[i]*sqrt(2.)-ptr[i])<1e-12); + pass + #bary + f3=m1.getBarycenterAndOwner(); + self.assertEqual(4,f3.getNumberOfTuples()); + self.assertEqual(2,f3.getNumberOfComponents()); + expected10=[0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155] + ptr=f3.getValues(); + for i in xrange(8): + self.assertTrue(abs(expected10[i]-ptr[i])<1e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(m1); + array=DataArrayDouble.New(); + array.setValues(arr,m1.getNumberOfCells(),3); + f1.setArray(array); + res=f1.integral(False); + for i in xrange(3): + self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); + pass + res=f1.integral(True); + for i in xrange(3): + self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); + pass + res=f1.normL1(); + for i in xrange(3): + self.assertTrue(abs(sqrt(2.)*expected5[i]-res[i])<1e-12); + pass + res=f1.normL2(); + for i in xrange(3): + self.assertTrue(abs(sqrt(sqrt(2.))*expected7[i]-res[i])<1e-12); + pass + pass + + def testAreaBary2D(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=m1.getMeasureField(False); + self.assertEqual(10,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected1=[-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1] + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + f1=m1.getMeasureField(True); + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); + pass + f2=m1.getBarycenterAndOwner(); + self.assertEqual(10,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + expected2=[0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5] + ptr=f2.getValues(); + for i in xrange(20): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + m1.changeSpaceDimension(3); + f1=m1.getMeasureField(False); + self.assertEqual(10,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); + pass + f2=m1.getBarycenterAndOwner(); + self.assertEqual(10,f2.getNumberOfTuples()); + self.assertEqual(3,f2.getNumberOfComponents()); + ptr=f2.getValues(); + expected3=[0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.] + for i in xrange(30): + self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); + pass + pass + + def testAreaBary3D(self): + coords=[ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , + 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , + 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , + 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , + -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , + -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , + 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , + 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , + -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , + 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , + -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , + -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , + -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , + -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , + -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , + -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , + 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , + 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , + 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , + -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , + -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , + -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , + -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , + 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , + 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , + 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , + -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , + -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , + 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , + 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , + -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , + 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , + 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , + 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , + -0.0372812069535 , -0.286740286332 , 0.00963701291166 ] + + connN = [ #polyhedron 0 + 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 + , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 + , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 + , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, + # polyhedron 1 + 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 + , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 + , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 + , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, + # polyhedron 2 + 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 + , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, + # polyhedron 3 + 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 + , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 + , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 + , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65] + + barys = [ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , + 0.0287618656076 , 0.135874379934 , -0.14601588119 , + -0.147128055553 , 0.0465995097041 , -0.049391174453 , + -0.00142506732317 , -0.0996953090351 , -0.115159183132 ] + meshN=MEDCouplingUMesh.New(); + meshN.setName("ForBary"); + meshN.setMeshDimension(3); + meshN.allocateCells(4); + meshN.insertNextCell(NORM_POLYHED,113,connN); + meshN.insertNextCell(NORM_POLYHED,99,connN[113:]); + meshN.insertNextCell(NORM_POLYHED,43,connN[212:]); + meshN.insertNextCell(NORM_POLYHED,92,connN[255:]); + meshN.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,69,3); + meshN.setCoords(myCoords); + meshN.checkCoherency(); + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + meshN.orientCorrectlyPolyhedrons(); + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + # + da=meshN.getBarycenterAndOwner(); + self.assertEqual(4,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + daPtr=da.getValues(); + for i in xrange(12): + self.assertTrue(abs(barys[i]-daPtr[i])<1e-12); + pass + pass + + def testRenumberCellsForFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + nbOfCells=m.getNumberOfCells(); + values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] + arr.setValues(values1,nbOfCells,3); + f.setArray(arr); + renumber1=[3,1,0,4,2] + loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] + for j in xrange(5): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); + pass + pass + f.renumberCells(renumber1,False); + ptr=f.getArray().getValues(); + expected1=[9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.] + for i in xrange(15): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + #check that fields remains the same geometrically + for j in xrange(5): + res=f.getValueOn(loc[2*j:2*(j+1)]); + for i in xrange(3): + self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); + pass + pass + #On gauss + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); + f.setMesh(m); + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1[0:6]; + _gsCoo1=gsCoo1[0:12]; + _wg1=wg1[0:6]; + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo2=refCoo2[0:8]; + _gsCoo1=_gsCoo1[0:4] + _wg1=_wg1[0:2] + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + arr=DataArrayDouble.New(); + values2=[1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.] + arr.setValues(values2,18,2); + f.setArray(arr); + f.checkCoherency(); + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberCells(renumber1,False); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + expected2=[21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.] + ptr=f.getArray().getValues(); + for i in xrange(36): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + renumber2=[2,1,4,0,3] + f.renumberCells(renumber2,False); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + #GaussNE + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + values3=[1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.] + arr.setValues(values3,18,2); + f.setArray(arr); + f.checkCoherency(); + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberCells(renumber1,False); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + expected3=[21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.] + ptr=f.getArray().getValues(); + for i in xrange(36): + self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); + pass + f.renumberCells(renumber2,False);#perform reverse operation of renumbering to check that the resulting field is equal. + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + # + pass + + def testRenumberNodesForFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + nbOfNodes=m.getNumberOfNodes(); + values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] + arr.setValues(values1,nbOfNodes,3); + f.setArray(arr); + f.checkCoherency(); + renumber1=[0,4,1,3,5,2,6,7,8] + loc=[0.5432,-0.2432, 0.5478,0.1528] + expected1=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124] + for j in xrange(2): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); + pass + pass + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberNodes(renumber1); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + for j in xrange(2): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); + pass + pass + expected2=[7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] + for i in xrange(27): + self.assertTrue(abs(expected2[i]-f.getArray().getValues()[i])<1e-12); + pass + renumber2=[0,2,5,3,1,4,6,7,8] + f.renumberNodes(renumber2); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + pass + + def testConvertQuadraticCellsToLinear(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh.checkCoherency(); + types=mesh.getAllTypes(); + types.sort() + self.assertEqual(5,len(types)); + expected1=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4, NORM_TRI6, NORM_QUAD8] + expected1.sort() + self.assertTrue(expected1==types); + self.assertTrue(mesh.isPresenceOfQuadratic()); + self.assertEqual(62,mesh.getMeshLength()); + f1=mesh.getMeasureField(False); + # + mesh.convertQuadraticCellsToLinear(); + self.assertTrue(not mesh.isPresenceOfQuadratic()); + # + mesh.checkCoherency(); + f2=mesh.getMeasureField(False); + self.assertTrue(f1.getArray().isEqual(f2.getArray(),1e-12)); + self.assertEqual(48,mesh.getMeshLength()); + types2=mesh.getAllTypes(); + types2.sort() + self.assertEqual(3,len(types2)); + expected2=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4] + expected2.sort() + self.assertTrue(expected2==types2); + pass + + def testCheckGeoEquivalWith(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + #First test mesh1 + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + #Second test mesh1 and mesh2 are 2 different meshes instance + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + #Third test : cell permutation by keeping the first the middle and the last as it is. + renum=[0,2,1,3,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum,list(cellCor.getValues())) + self.assertTrue(nodeCor==None); + cellCor=0; + self.assertTrue(nodeCor==None); + #4th test : cell and node permutation by keeping the first the middle and the last as it is. + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + renum2=[0,2,1,3,4,5,6,8,7,9,10] + mesh2.renumberCells(renum,False); + mesh2.renumberNodes(renum2,11); + cellCor=None + nodeCor=None + self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum,list(cellCor.getValues())) + self.assertTrue(nodeCor); + self.assertEqual(11,nodeCor.getNumberOfTuples()); + self.assertEqual(1,nodeCor.getNumberOfComponents()); + self.assertEqual(renum2,list(nodeCor.getValues())) + cellCor=0; + nodeCor=0; + #5th test : modification of the last cell to check fastCheck detection. + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + renum3=[0,2,1,3,4,5,6,8,9,7] + mesh2.renumberCells(renum3,False); + mesh2.renumberNodes(renum2,11); + cellCor=None + nodeCor=None + self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12) + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,1,1e-12) + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor!=None); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum3,list(cellCor.getValues())) + self.assertTrue(nodeCor!=None); + self.assertEqual(11,nodeCor.getNumberOfTuples()); + self.assertEqual(1,nodeCor.getNumberOfComponents()); + self.assertEqual(renum2,list(nodeCor.getValues())); + pass + + def testCheckGeoEquivalWith2(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_4(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12); + self.assertEqual(None,cellCor); + self.assertNotEqual(None,nodeCor); + expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9] + for i in xrange(9): + self.assertEqual(expected1[i],nodeCor.getIJ(i,0)); + pass + pass + + def testCopyTinyStringsFromOnFields(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f.setMesh(m); + f.setName("a"); + f.setDescription("b"); + a1=DataArrayDouble.New(); + a1.alloc(nbOfCells,2); + a1.fillWithZero(); + a1.setInfoOnComponent(0,"c"); + a1.setInfoOnComponent(1,"d"); + a2=a1.deepCopy(); + a2.setInfoOnComponent(0,"e"); + a2.setInfoOnComponent(1,"f"); + f.setArray(a1); + f.setEndArray(a2); + f.setEndTime(3.,3,4); + m.setName("g"); + m.getCoords().setInfoOnComponent(0,"h"); + m.getCoords().setInfoOnComponent(1,"i"); + m.getCoords().setInfoOnComponent(2,"j"); + # + f.checkCoherency(); + f2=f.clone(True); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.setName("smth"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.setDescription("GGG"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.getArray().setInfoOnComponent(0,"mmmm"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.getEndArray().setInfoOnComponent(1,"mmmm"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + m2=m.clone(True); + self.assertTrue(m2.isEqual(m,1e-12)); + m2.setName("123"); + self.assertTrue(not m2.isEqual(m,1e-12)); + m2.copyTinyStringsFrom(m); + self.assertTrue(m2.isEqual(m,1e-12)); + m2.getCoords().setInfoOnComponent(1,"eee"); + self.assertTrue(not m2.isEqual(m,1e-12)); + m2.copyTinyStringsFrom(m); + self.assertTrue(m2.isEqual(m,1e-12)); + pass + + def testTryToShareSameCoordsPermute(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + #self.assertTrue(m.getCoords()!=m2.getCoords()); + m.tryToShareSameCoordsPermute(m2,1e-12); + #self.assertTrue(m.getCoords()==m2.getCoords()); + self.assertTrue(m2.isEqual(m,1e-12)); + renum1=[1,2,0,5,8,7,4,3,6] + m.renumberNodes(renum1,9); + #self.assertTrue(m.getCoords()!=m2.getCoords()); + self.assertTrue(not m2.isEqual(m,1e-12)); + m.tryToShareSameCoordsPermute(m2,1e-12); + #self.assertTrue(m.getCoords()==m2.getCoords()); + self.assertTrue(m2.isEqual(m,1e-12)); + pass + + def testTryToShareSameCoordsPermute2(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_4(); + targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ] + targetConn=[0,2,3,1] + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(2); + m2.allocateCells(1); + m2.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + m2.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,4,2); + m2.setCoords(myCoords); + m2.checkCoherency(); + m1.checkCoherency(); + # + expected1=[0.25,0.125,0.125,0.25,0.25] + f1=m1.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(5,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getArray().getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); + pass + self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); + self.assertRaises(Exception,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible. + # Let's go for deeper test of tryToShareSameCoordsPermute + m2.tryToShareSameCoordsPermute(m1,1e-12); + f1=m1.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(5,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getArray().getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); + pass + self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); + pass + + def testChangeUnderlyingMesh1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7., 107., 8., 108., 9., 109., 10., 110., 11., 111., 12., 112., 13., 113., 14., 114., 15., 115., 16., 116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + renum=[0,2,1,3,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh1,10,1e-12);# nothing done only to check that nothing done. + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh2,10,1e-12); + #self.assertTrue(f1.getMesh()==mesh2); + expected1=[7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.] + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.] + array.setValues(arr2,mesh1.getNumberOfNodes(),2); + f1.setArray(array); + # + renum2=[0,2,10,3,4,5,6,8,7,9,1] + mesh2.renumberNodes(renum2,11); + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh2,10,1e-12); + #self.assertTrue(f1.getMesh()==mesh2); + expected2=[7.,107.,9.,109.,17.,117.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,8.,108.] + for i in xrange(22): + self.assertAlmostEqual(expected2[i],f1.getArray().getIJ(0,i),12); + pass + pass + + def testGetMaxValue1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f.setMesh(m); + a1=DataArrayDouble.New(); + val1=[3.,4.,5.,6.,7.] + a1.setValues(val1,nbOfCells,1); + a2=DataArrayDouble.New(); + val2=[0.,1.,2.,8.,7.] + a2.setValues(val2,nbOfCells,1); + f.setArray(a1); + f.setEndArray(a2); + f.setEndTime(3.,3,4); + f.checkCoherency(); + # + self.assertAlmostEqual(8.,f.getMaxValue(),14); + self.assertAlmostEqual(0.,f.getMinValue(),14); + self.assertAlmostEqual(5.,f.getAverageValue(),14); + self.assertAlmostEqual(5.125,f.getWeightedAverageValue(),14); + a1.setIJ(0,2,9.5); + self.assertAlmostEqual(9.5,f.getMaxValue(),14); + self.assertAlmostEqual(0.,f.getMinValue(),14); + a2.setIJ(0,0,9.); + self.assertAlmostEqual(9.5,f.getMaxValue(),14); + self.assertAlmostEqual(1.,f.getMinValue(),14); + pass + + def testSubstractInPlaceDM1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + self.assertEqual(10,f1.getNumberOfTuples()); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(20,f1.getNumberOfValues()); + # + renum=[0,2,1,3,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + # + f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f2.setMesh(mesh2); + array=DataArrayDouble.New(); + arr2=[7.1,107.1,9.1,109.1,8.1,108.1,10.1,110.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1] + array.setValues(arr2,mesh2.getNumberOfCells(),2); + f2.setArray(array); + # + f1.substractInPlaceDM(f2,10,1e-12); + f1.applyFunc(1,"abs(x+y+0.2)"); + self.assertAlmostEqual(0.,f1.getMaxValue(),13); + pass + + def testDotCrossProduct1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] + array.setValues(arr1,mesh1.getNumberOfCells(),3); + f1.setArray(array); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setTime(7.8,4,5); + f2.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.] + array.setValues(arr2,mesh1.getNumberOfCells(),3); + f2.setArray(array); + # + f3=f1.dot(f2); + expected1=[842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],f3.getIJ(i,0),9); + pass + # + f4=f1.crossProduct(f2); + expected2=[-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); + pass + pass + + def testMinMaxFields1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] + array.setValues(arr1,mesh1.getNumberOfCells(),3); + f1.setArray(array); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setTime(7.8,4,5); + f2.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.] + array.setValues(arr2,mesh1.getNumberOfCells(),3); + f2.setArray(array); + # + f3=f1.max(f2); + expected1=[7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),9); + pass + # + f4=f1.min(f2); + expected2=[6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); + pass + # + pass + + def testApplyLin1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + f1.applyLin(2.,3.,0); + expected1=[17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.] + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),9); + pass + # + arr2=[2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] + array=DataArrayDouble.New(); + array.setValues(arr2,mesh1.getNumberOfCells(),2); + f1.setEndArray(array); + # + f1.applyLin(4.,5.,1); + # + expected2=[17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.] + for i in xrange(20): + self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),9); + pass + expected3=[2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.] + for i in xrange(20): + self.assertAlmostEqual(expected3[i],f1.getEndArray().getIJ(0,i),9); + pass + # + pass + + def testGetIdsInRange1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[2.,8.,6.,5.,11.,7.,9.,3.,10.,4.] + array.setValues(arr1,mesh1.getNumberOfCells(),1); + f1.setArray(array); + # + f1.checkCoherency(); + da=f1.getIdsInRange(2.9,7.1); + self.failUnlessEqual(5,da.getNbOfElems()); + expected1=[2,3,5,7,9] + self.failUnlessEqual(expected1,list(da.getValues())); + da=f1.getIdsInRange(8.,12.); + self.failUnlessEqual(4,da.getNbOfElems()); + expected2=[1,4,6,8] + self.failUnlessEqual(expected2,list(da.getValues())); + # + pass + + def testBuildSubPart1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] + array.setValues(arr1,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + part1=[2,1,4] + f2=f1.buildSubPart(part1); + self.failUnlessEqual(3,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected1=[5.,105.,4.,104.,7.,107.] + for i in xrange(6): + self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12); + pass + self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(13,m2C.getMeshLength()); + expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] + self.failUnlessEqual(expected3,list(m2C.getNodalConnectivity().getValues())); + expected4=[0,4,8,13] + self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); + # Test with field on nodes. + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] + array.setValues(arr2,mesh1.getNumberOfNodes(),2); + f1.setArray(array); + part2=[1,4,2,5] + f2=f1.buildSubPart(part2); + self.failUnlessEqual(4,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected5=[4.,104.,5.,105.,7.,107.,8.,108.] + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); + pass + self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(8,m2C.getMeshLength()); + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); + self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); + #idem previous because nodes of cell#4 are not fully present in part3 + part3=[1,4,2,5,7] + arrr=DataArrayInt.New(); + arrr.setValues(part3,5,1); + f2=f1.buildSubPart(arrr); + self.failUnlessEqual(4,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); + pass + self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(8,m2C.getMeshLength()); + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); + self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); + # + part4=[1,4,2,5,7,8] + f2=f1.buildSubPart(part4); + self.failUnlessEqual(6,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] + for i in xrange(12): + self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12); + pass + self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(13,m2C.getMeshLength()); + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4]); + self.failUnlessEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13]); + self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); + pass + + def testDoublyContractedProduct1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.doublyContractedProduct(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9); + pass + # + pass + + def testDeterminant1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr1,mesh1.getNumberOfCells(),4); + f1.setArray(array); + #4 components + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfValues()); + for i in xrange(5): + self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13); + pass + #6 components multi arrays with end array not defined + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, + 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr2,mesh1.getNumberOfNodes(),6); + f1.setArray(array); + self.assertRaises(Exception,f1.checkCoherency);#no end array specified ! + # + f2=f1.determinant(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getArray().getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + pass + #6 components multi arrays with end array defined + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, + 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfNodes(),6); + f1.setEndArray(array); + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(2.3,time2,12); + self.assertEqual(5,it); + self.assertEqual(6,order); + time2,it,order=f2.getEndTime() + self.assertAlmostEqual(3.8,time2,12); + self.assertEqual(7,it); + self.assertEqual(3,order); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9); + pass + #9 components + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(7.8,10,2); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr4,mesh1.getNumberOfCells(),9); + f1.setArray(array); + # + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(ONE_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(7.8,time2,12); + self.assertEqual(10,it); + self.assertEqual(2,order); + for i in xrange(5): + self.assertAlmostEqual(3.267,f2.getIJ(i,0),13); + pass + pass + + def testEigenValues1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenValues(); + f2.checkCoherency(); + self.assertEqual(3,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + pass + pass + + def testEigenVectors1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenVectors(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0 + 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1 + -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2 + ] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); + pass + # + pass + + def testInverse1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887] + for i in xrange(5): + self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(4,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156] + for i in xrange(5): + self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13); + pass + # + pass + + def testTrace1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(15.9,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(25.8,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.7,f2.getIJ(i,0),13); + pass + # + pass + + def testDeviator1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.deviator(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-1.1,0.,1.1,4.5,5.6,6.7] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + pass + # + pass + + def testMagnitude1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.magnitude(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13); + pass + # + pass + + def testMaxPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.maxPerTuple(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.6,f2.getIJ(i,0),13); + pass + # + pass + + def testChangeNbOfComponents(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.changeNbOfComponents(3,7.77); + f1.checkCoherency(); + self.assertEqual(3,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2] + for i in xrange(15): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13); + pass + f1.changeNbOfComponents(4,7.77); + f1.checkCoherency(); + self.assertEqual(4,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77] + for i in xrange(20): + self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13); + pass + # + pass + + def testSortPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.sortPerTuple(True); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13); + pass + # + f1.sortPerTuple(False); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13); + pass + # + pass + + def testIsEqualWithoutConsideringStr1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.setName("rr"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + da1,da2=mesh1.checkGeoEquivalWith(mesh2,2,1e-12); + self.assertRaises(Exception,mesh1.checkGeoEquivalWith,mesh2,0,1e-12); + mesh2.setName(""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(0,"tty"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(0,""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,"tty"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + tmp=mesh2.getCoords().getIJ(0,3); + mesh2.getCoords().setIJ(0,3,9999.); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setIJ(0,3,tmp); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + tmp2=mesh2.getNodalConnectivity().getIJ(0,4); + mesh2.getNodalConnectivity().setIJ(0,4,0); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getNodalConnectivity().setIJ(0,4,tmp2); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + # + f1=mesh1.getMeasureField(True); + f2=mesh2.getMeasureField(True); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.setName("ftest"); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f1.setName("ftest"); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + f2.getArray().setInfoOnComponent(0,"eee"); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.getArray().setInfoOnComponent(0,""); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + f2.getArray().setIJ(1,0,0.123); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(not f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.getArray().setIJ(1,0,0.125); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + pass + def testGetNodeIdsOfCell1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + li=mesh1.getNodeIdsOfCell(1) + expected1=[1, 4, 2] + self.assertEqual(expected1,list(li)) + li=mesh1.getCoordinatesOfNode(4) + self.assertEqual(2,len(li)) + self.assertAlmostEqual(0.2,li[0],13); + self.assertAlmostEqual(0.2,li[1],13); + li=mesh1.getCoords().getValuesAsTuple() + self.assertEqual(9,len(li)) + li2=mesh1.getNodalConnectivityIndex().getValuesAsTuple() + self.assertEqual(6,len(li2)) + pass + + def testGetEdgeRatioField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m1.getEdgeRatioField(); + self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); + self.assertEqual(5,f1.getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected1=[1.,1.4142135623730951, 1.4142135623730951,1.,1.] + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),14); + pass + # + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=m1.getEdgeRatioField(); + self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); + self.assertEqual(5,f1.getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected2=[1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951] + for i in xrange(5): + self.assertAlmostEqual(expected2[i],f1.getIJ(i,0),14); + pass + pass + + def testFillFromAnalytic3(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) + self.assertRaises(Exception,f1.fillFromAnalytic,1,"y+x"); + f1.setMesh(m) + f1.setName("myField"); + f1.fillFromAnalytic(1,"y+x"); + f1.checkCoherency(); + self.assertEqual(f1.getName(),"myField"); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(values1)): + self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL) + f1.setMesh(m) + f1.fillFromAnalytic(1,"y+2*x"); + f1.setEndTime(1.2,3,4); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),CONST_ON_TIME_INTERVAL); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(values2)): + self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); + pass + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setMesh(m) + f1.fillFromAnalytic(1,"2.*x+y"); + f1.setEndTime(1.2,3,4); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),LINEAR_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + tmp=f1.getArray().getValues(); + values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + tmp=f1.getEndArray().getValues(); + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setMesh(m) + f1.fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(values3)): + self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); + pass + values4=f1.accumulate(); + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + # + f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f1.setMesh(m); + self.assertRaises(Exception,f1.fillFromAnalytic,1,"1./(x-0.2)"); + pass + + def testFieldDoubleOpEqual1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertRaises(Exception,f1.assign,0.07); + f1.setMesh(m); + f1.assign(0.07); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(0.07,f1.getIJ(i,0),16); + pass + f1.assign(0.09); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(0.09,f1.getIJ(i,0),16); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setEndTime(4.5,2,3); + f1.setMesh(m); + f1.assign(0.08); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(0.08,f1.getIJ(i,0),16); + pass + self.assertEqual(1,f1.getEndArray().getNumberOfComponents()); + self.assertEqual(9,f1.getEndArray().getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(0.08,f1.getEndArray().getIJ(i,0),16); + pass + pass + + def testAreaBary3D2(self): + coordsForHexa8=[-75.45749305371, 180.95495078401, 39.515472018008, + -9.755591679144, 23.394927935279, 5.108794294848, + 14.337630157832, 61.705351002702, 160.42422501908, + -27.273893776752, 167.567731083961, 192.830034145464, + 99.857193154796,264.499264735586,-8.287335493412, + 144.939882761126,156.38626563134,-31.896173894226, + 161.34096835726,182.4654895809,73.832387065572, + 132.680430393685,255.37973247196,96.15235602819]; + volHexa8=3258520.29637466; + baryHexa8=[43.925705821778, 155.31893955289, 65.874418109644] + + coordsForPenta6=[-68.199829618726,178.938498373416,62.608505919588, + 8.461744647847,76.653979804423,165.00018874933, + -27.273893776752,167.567731083961,192.830034145464, + 106.586501038965,262.629609408327,13.124533008813, + 155.465082847275,197.414118382622,78.408350795821, + 132.680430393685,255.37973247196,96.15235602819]; + volPenta6=944849.868507338; + baryPenta6=[39.631002313543,182.692711783428,106.98540473964] + + coordsForPyra5=[132.680430393685,255.37973247196,96.15235602819, + -27.273893776752,167.567731083961,192.830034145464, + 8.461744647847,76.653979804423,165.00018874933, + 155.465082847275,197.414118382622,78.408350795821, + -68.199829618726,178.938498373416,62.608505919588]; + volPyra5=756943.92980254; + baryPyra5=[29.204294116618,172.540129749156,118.01035951483] + mesh=MEDCouplingUMesh.New("Bary3D2",3); + coo=DataArrayDouble.New(); + tmp=coordsForHexa8+coordsForPenta6+coordsForPyra5 + coo.setValues(tmp,19,3); + mesh.setCoords(coo); + # + tmpConn=[0,1,2,3,4,5,6,7] + mesh.allocateCells(3); + mesh.insertNextCell(NORM_HEXA8,8,tmpConn[0:8]) + mesh.insertNextCell(NORM_PENTA6,6,[i+8 for i in tmpConn]) + mesh.insertNextCell(NORM_PYRA5,5,[i+14 for i in tmpConn]) + mesh.finishInsertingCells(); + mesh.checkCoherency(); + mesh.mergeNodes(1e-7) + self.assertEqual(12,mesh.getNumberOfNodes()); + vols=mesh.getMeasureField(True); + self.assertEqual(3,vols.getNumberOfTuples()); + self.assertEqual(1,vols.getNumberOfComponents()); + self.assertAlmostEqual(volHexa8,vols.getIJ(0,0),6); + self.assertAlmostEqual(volPenta6,vols.getIJ(1,0),7); + self.assertAlmostEqual(volPyra5,vols.getIJ(2,0),7); + bary=mesh.getBarycenterAndOwner(); + self.assertEqual(3,bary.getNumberOfTuples()); + self.assertEqual(3,bary.getNumberOfComponents()); + self.assertAlmostEqual(baryHexa8[0],bary.getIJ(0,0),11); + self.assertAlmostEqual(baryHexa8[1],bary.getIJ(0,1),11); + self.assertAlmostEqual(baryHexa8[2],bary.getIJ(0,2),11); + self.assertAlmostEqual(baryPenta6[0],bary.getIJ(1,0),11); + self.assertAlmostEqual(baryPenta6[1],bary.getIJ(1,1),11); + self.assertAlmostEqual(baryPenta6[2],bary.getIJ(1,2),11); + self.assertAlmostEqual(baryPyra5[0],bary.getIJ(2,0),11); + self.assertAlmostEqual(baryPyra5[1],bary.getIJ(2,1),11); + self.assertAlmostEqual(baryPyra5[2],bary.getIJ(2,2),11); + pass + + def testGetMeasureFieldCMesh1(self): + m=MEDCouplingCMesh.New(); + da=DataArrayDouble.New(); + discX=[2.3,3.4,5.8,10.2] + discY=[12.3,23.4,45.8] + discZ=[-0.7,1.2,1.25,2.13,2.67] + da.setValues(discX,4,1); + m.setCoordsAt(0,da); + m.checkCoherency(); + self.assertEqual(4,m.getNumberOfNodes()); + self.assertEqual(3,m.getNumberOfCells()); + self.assertEqual(1,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(3,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected1=[1.1,2.4,4.4] + for i in xrange(3): + self.assertAlmostEqual(expected1[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(4,coords.getNumberOfTuples()); + self.assertEqual(1,coords.getNumberOfComponents()); + for i in xrange(4): + self.assertAlmostEqual(discX[i],coords.getIJ(i,0),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(3,coords.getNumberOfTuples()); + self.assertEqual(1,coords.getNumberOfComponents()); + expected1_3=[2.85,4.6,8.] + for i in xrange(3): + self.assertAlmostEqual(expected1_3[i],coords.getIJ(i,0),12); + pass + # + da=DataArrayDouble.New(); + da.setValues(discY,3,1); + m.setCoordsAt(1,da); + m.checkCoherency(); + self.assertEqual(12,m.getNumberOfNodes()); + self.assertEqual(6,m.getNumberOfCells()); + self.assertEqual(2,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(6,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected2=[12.21,26.64,48.84,24.64,53.76,98.56] + for i in xrange(6): + self.assertAlmostEqual(expected2[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(12,coords.getNumberOfTuples()); + self.assertEqual(2,coords.getNumberOfComponents()); + expected2_2=[2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8] + for i in xrange(24): + self.assertAlmostEqual(expected2_2[i],coords.getIJ(0,i),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(6,coords.getNumberOfTuples()); + self.assertEqual(2,coords.getNumberOfComponents()); + expected2_3=[2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6] + for i in xrange(12): + self.assertAlmostEqual(expected2_3[i],coords.getIJ(0,i),12); + pass + # + da=DataArrayDouble.New(); + da.setValues(discZ,5,1); + m.setCoordsAt(2,da); + m.checkCoherency(); + self.assertEqual(60,m.getNumberOfNodes()); + self.assertEqual(24,m.getNumberOfCells()); + self.assertEqual(3,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(24,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected3=[23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224] + for i in xrange(24): + self.assertAlmostEqual(expected3[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(60,coords.getNumberOfTuples()); + self.assertEqual(3,coords.getNumberOfComponents()); + expected3_2=[ + 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, + 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, + 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, + 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, + 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67]; + for i in xrange(180): + self.assertAlmostEqual(expected3_2[i],coords.getIJ(0,i),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(24,coords.getNumberOfTuples()); + self.assertEqual(3,coords.getNumberOfComponents()); + expected3_3=[ + 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, + 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, + 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, + 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4]; + for i in xrange(72): + self.assertAlmostEqual(expected3_3[i],coords.getIJ(0,i),12); + pass + pass + + def testFieldDoubleZipCoords1(self): + m=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); + f=m.fillFromAnalytic(ON_NODES,2,"x*2."); + f.getArray().setInfoOnComponent(0,"titi"); + f.getArray().setInfoOnComponent(1,"tutu"); + f.checkCoherency(); + self.assertEqual(18,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + expected1=[-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] + for i in xrange(36): + self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.zipCoords()); + f.checkCoherency(); + expected2=[-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(not f.zipCoords()); + f.checkCoherency(); + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); + self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); + pass + + def testFieldDoubleZipConnectivity1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3_1=m2.buildPartOfMySelf(cells1,True); + m3=m3_1; + m4=MEDCouplingDataForTest.build2DSourceMesh_1(); + m5=MEDCouplingUMesh.mergeUMeshes(m1,m3); + m6=MEDCouplingUMesh.mergeUMeshes(m5,m4); + # + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(22,m6.getNumberOfNodes()); + arr,areNodesMerged,newNbOfNodes=m6.mergeNodes(1e-13); + self.assertEqual(9,m6.getNumberOfNodes()); + f=m6.fillFromAnalytic(ON_CELLS,2,"x"); + f2=m6.fillFromAnalytic(ON_NODES,2,"x"); + self.assertEqual(10,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + expected1=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, + 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); + pass + f.getArray().setInfoOnComponent(0,"titi"); + f.getArray().setInfoOnComponent(1,"tutu"); + f.checkCoherency(); + self.assertTrue(f.zipConnectivity(0)); + expected2=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; + self.assertEqual(7,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + for i in xrange(14): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); + self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); + self.assertTrue(not f.zipConnectivity(0)); + # + expected3=[-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, + -0.3, -0.3, 0.2, 0.2, 0.7, 0.7]; + self.assertEqual(9,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + for i in xrange(18): + self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); + pass + self.assertTrue(f2.zipConnectivity(0)); + self.assertEqual(9,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + for i in xrange(18): + self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); + pass + pass + + def testDaDoubleRenumber1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[3,1,0,6,5,4,2] + b=a.renumber(arr2); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumber(arr2); + self.assertEqual(7,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] + for i in xrange(14): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberAndReduce1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[2,-1,1,-1,0,4,3] + b=a.renumberAndReduce(arr2,5); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumberAndReduce(arr2,5); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberInPlace1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + # + arr2=[3,1,0,6,5,4,2] + a.renumberInPlace(arr2); + self.assertEqual(7,a.getNumberOfTuples()); + self.assertEqual(2,a.getNumberOfComponents()); + expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.renumberInPlace(arr2); + self.assertEqual(7,c.getNumberOfTuples()); + self.assertEqual(2,c.getNumberOfComponents()); + expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] + for i in xrange(14): + self.assertEqual(expected2[i],c.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberR1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[3,1,0,6,5,4,2] + b=a.renumberR(arr2); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumberR(arr2); + self.assertEqual(7,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] + for i in xrange(14): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberInPlaceR1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + # + arr2=[3,1,0,6,5,4,2] + a.renumberInPlaceR(arr2); + self.assertEqual(7,a.getNumberOfTuples()); + self.assertEqual(2,a.getNumberOfComponents()); + expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.renumberInPlaceR(arr2); + self.assertEqual(7,c.getNumberOfTuples()); + self.assertEqual(2,c.getNumberOfComponents()); + expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] + for i in xrange(14): + self.assertEqual(expected2[i],c.getIJ(0,i)); + pass + pass + + def testDaDoubleSelectByTupleId1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[4,2,0,6,5] + b=a.selectByTupleId(arr2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.selectByTupleId(arr2); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleGetMinMaxValues1(self): + a=DataArrayDouble.New(); + arr1=[2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56] + a.setValues(arr1,9,1); + m,where=a.getMaxValue(); + self.assertEqual(1,where); + self.assertAlmostEqual(4.56,m,12); + m,ws=a.getMaxValue2(); + self.assertAlmostEqual(4.56,m,12); + self.assertEqual(3,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + expected1=[1,4,8] + for i in xrange(3): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + a=DataArrayDouble.New(); + arr2=[-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56] + a.setValues(arr2,9,1); + m,where=a.getMinValue(); + self.assertEqual(1,where); + self.assertAlmostEqual(-4.56,m,12); + m,ws=a.getMinValue2(); + self.assertAlmostEqual(-4.56,m,12); + self.assertEqual(3,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + for i in xrange(3): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + pass + + def testFieldDoubleGetMinMaxValues2(self): + m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + self.assertEqual(18,m2.getNumberOfCells()); + arr1=[8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71] + f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + a=DataArrayDouble.New(); + a.setValues(arr1,18,1); + f.setArray(a); + f.setMesh(m2); + # + f.checkCoherency(); + m=f.getMaxValue(); + self.assertAlmostEqual(8.71,m,12); + m,ws=f.getMaxValue2(); + self.assertAlmostEqual(8.71,m,12); + self.assertEqual(4,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + expected1=[0,3,7,17] + for i in xrange(4): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + # + arr2=[-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71] + a.setValues(arr2,18,1); + f.checkCoherency(); + m=f.getMinValue(); + self.assertAlmostEqual(-8.71,m,12); + m,ws=f.getMinValue2(); + self.assertAlmostEqual(-8.71,m,12); + self.assertEqual(4,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + for i in xrange(4): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + pass + + def testBuildUnstructuredCMesh1(self): + m=MEDCouplingCMesh.New(); + da=DataArrayDouble.New(); + discX=[2.3,3.4,5.8,10.2] + discY=[12.3,23.4,45.8] + discZ=[-0.7,1.2,1.25,2.13,2.67] + da.setValues(discX,4,1); + m.setCoordsAt(0,da); + m.checkCoherency(); + self.assertEqual(0,m.getCellContainingPoint([2.4],12)); + self.assertEqual(1,m.getCellContainingPoint([3.7],12)); + self.assertEqual(2,m.getCellContainingPoint([5.9],12)); + self.assertEqual(-1,m.getCellContainingPoint([10.3],12)); + self.assertEqual(-1,m.getCellContainingPoint([1.3],12)); + # + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertTrue(isinstance(f1.getMesh(),MEDCouplingCMesh)) + self.assertEqual(f1.getNumberOfTuples(),3); + self.assertEqual(f2.getNumberOfTuples(),3); + self.assertEqual(1,m2.getMeshDimension()); + self.assertEqual(1,m2.getSpaceDimension()); + for i in xrange(3): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + da=DataArrayDouble.New(); + da.setValues(discY,3,1); + m.setCoordsAt(1,da); + # + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(f1.getNumberOfTuples(),6); + self.assertEqual(f2.getNumberOfTuples(),6); + self.assertEqual(2,m2.getMeshDimension()); + self.assertEqual(2,m2.getSpaceDimension()); + for i in xrange(6): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + # + da=DataArrayDouble.New(); + da.setValues(discZ,5,1); + m.setCoordsAt(2,da); + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(f1.getNumberOfTuples(),24); + self.assertEqual(f2.getNumberOfTuples(),24); + self.assertEqual(3,m2.getMeshDimension()); + self.assertEqual(3,m2.getSpaceDimension()); + for i in xrange(24): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + # + pos1=[5.,30.,2.] + self.assertEqual(16,m.getCellContainingPoint(pos1,1e-12)); + # + pt=[2.4,12.7,-3.4] + m.scale(pt,3.7); + m3=m.buildUnstructured(); + m2.scale(pt,3.7); + self.assertTrue(m3.isEqual(m2,1e-12)); + pass + + def testDataArrayIntInvertO2NNO21(self): + arr1=[2,0,4,1,5,3] + da=DataArrayInt.New(); + da.setValues(arr1,6,1); + da2=da.invertArrayO2N2N2O(6); + self.assertEqual(6,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected1=[1,3,0,5,2,4] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass + da3=da2.invertArrayN2O2O2N(6); + for i in xrange(6): + self.assertEqual(arr1[i],da3.getIJ(i,0)); + pass + # + arr2=[3,-1,5,4,-1,0,-1,1,2,-1] + da=DataArrayInt.New(); + da.setValues(arr2,10,1); + da2=da.invertArrayO2N2N2O(6); + self.assertEqual(6,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected2=[5,7,8,0,3,2] + for i in xrange(6): + self.assertEqual(expected2[i],da2.getIJ(i,0)); + pass + da3=da2.invertArrayN2O2O2N(10); + for i in xrange(10): + self.assertEqual(arr2[i],da3.getIJ(i,0)); + pass + pass + + def testDoublyContractedProduct1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.doublyContractedProduct(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9); + pass + # + pass + + def testDeterminant1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr1,mesh1.getNumberOfCells(),4); + f1.setArray(array); + #4 components + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfValues()); + for i in xrange(5): + self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13); + pass + #6 components multi arrays with end array not defined + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, + 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr2,mesh1.getNumberOfNodes(),6); + f1.setArray(array); + self.assertRaises(Exception,f1.checkCoherency);#no end array specified ! + # + f2=f1.determinant(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getArray().getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + pass + #6 components multi arrays with end array defined + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, + 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfNodes(),6); + f1.setEndArray(array); + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(2.3,time2,12); + self.assertEqual(5,it); + self.assertEqual(6,order); + time2,it,order=f2.getEndTime() + self.assertAlmostEqual(3.8,time2,12); + self.assertEqual(7,it); + self.assertEqual(3,order); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9); + pass + #9 components + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(7.8,10,2); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr4,mesh1.getNumberOfCells(),9); + f1.setArray(array); + # + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(ONE_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(7.8,time2,12); + self.assertEqual(10,it); + self.assertEqual(2,order); + for i in xrange(5): + self.assertAlmostEqual(3.267,f2.getIJ(i,0),13); + pass + pass + + def testEigenValues1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenValues(); + f2.checkCoherency(); + self.assertEqual(3,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + pass + pass + + def testEigenVectors1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenVectors(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0 + 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1 + -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2 + ] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),1e-13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),1e-13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),1e-13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),1e-13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),1e-13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),1e-13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),1e-13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),1e-13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),1e-13); + pass + # + pass + + def testInverse1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887] + for i in xrange(5): + self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(4,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156] + for i in xrange(5): + self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13); + pass + # + pass + + def testTrace1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(15.9,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(25.8,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.7,f2.getIJ(i,0),13); + pass + # + pass + + def testDeviator1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.deviator(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-1.1,0.,1.1,4.5,5.6,6.7] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + pass + # + pass + + def testMagnitude1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.magnitude(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13); + pass + # + pass + + def testMaxPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.maxPerTuple(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.6,f2.getIJ(i,0),13); + pass + # + pass + + def testChangeNbOfComponents(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.changeNbOfComponents(3,7.77); + f1.checkCoherency(); + self.assertEqual(3,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2] + for i in xrange(15): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13); + pass + f1.changeNbOfComponents(4,7.77); + f1.checkCoherency(); + self.assertEqual(4,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77] + for i in xrange(20): + self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13); + pass + # + pass + + def testSortPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.sortPerTuple(True); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13); + pass + # + f1.sortPerTuple(False); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13); + pass + # + pass + + def testKeepSetSelectedComponent1(self): + arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] + a1=DataArrayDouble.New(); + a1.setValues(arr1,5,4); + a1.setInfoOnComponent(0,"aaaa"); + a1.setInfoOnComponent(1,"bbbb"); + a1.setInfoOnComponent(2,"cccc"); + a1.setInfoOnComponent(3,"dddd"); + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V); + self.assertEqual(6,a2.getNumberOfComponents()); + self.assertEqual(5,a2.getNumberOfTuples()); + self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(1)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(2)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); + expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14); + pass + a3=a1.convertToIntArr(); + a4=a3.keepSelectedComponents(arr2V); + self.assertEqual(6,a4.getNumberOfComponents()); + self.assertEqual(5,a4.getNumberOfTuples()); + self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(1)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(2)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); + for i in xrange(30): + self.assertEqual(int(expected1[i]),a4.getIJ(0,i)); + pass + # setSelectedComponents + arr3V=[3,2] + a5=a1.keepSelectedComponents(arr3V); + a5.setInfoOnComponent(0,"eeee"); + a5.setInfoOnComponent(1,"ffff"); + arr4V=[1,2] + a2.setSelectedComponents(a5,arr4V); + self.assertEqual(6,a2.getNumberOfComponents()); + self.assertEqual(5,a2.getNumberOfTuples()); + self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(1)=="eeee"); + self.assertTrue(a2.getInfoOnComponent(2)=="ffff"); + self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); + expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],a2.getIJ(0,i),14); + pass + a6=a5.convertToIntArr(); + a6.setInfoOnComponent(0,"eeee"); + a6.setInfoOnComponent(1,"ffff"); + a4.setSelectedComponents(a6,arr4V); + self.assertEqual(6,a4.getNumberOfComponents()); + self.assertEqual(5,a4.getNumberOfTuples()); + self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(1)=="eeee"); + self.assertTrue(a4.getInfoOnComponent(2)=="ffff"); + self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); + for i in xrange(30): + self.assertEqual(int(expected2[i]),a4.getIJ(0,i)); + pass + # test of throw + arr5V=[2,3,6] + arr6V=[2,7,5] + arr7V=[2,1,4,6] + self.assertRaises(Exception,a2.keepSelectedComponents,arr5V); + self.assertRaises(Exception,a2.keepSelectedComponents,arr6V); + self.assertRaises(Exception,a2.setSelectedComponents,a1,arr7V); + arr7V=arr7V[0:3] + self.assertRaises(Exception,a2.setSelectedComponents,a1,arr7V); + # + pass + + def testKeepSetSelectedComponent2(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] + a1=DataArrayDouble.New(); + a1.setValues(arr1,5,4); + a1.setInfoOnComponent(0,"aaaa"); + a1.setInfoOnComponent(1,"bbbb"); + a1.setInfoOnComponent(2,"cccc"); + a1.setInfoOnComponent(3,"dddd"); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,4,5); + f1.setMesh(m1); + f1.setName("f1"); + f1.setArray(a1); + f1.checkCoherency(); + # + arr2V=[1,2,1,2,0,0] + f2=f1.keepSelectedComponents(arr2V); + self.assertTrue(f2.getTimeDiscretization()==ONE_TIME); + t,dt,it=f2.getTime() + self.assertAlmostEqual(2.3,t,13); + self.assertEqual(4,dt); + self.assertEqual(5,it); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(1)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(2)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); + self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); + expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],f2.getIJ(0,i),14); + pass + #setSelectedComponents + arr3V=[3,2] + f5=f1.keepSelectedComponents(arr3V); + f5.setTime(6.7,8,9); + f5.getArray().setInfoOnComponent(0,"eeee"); + f5.getArray().setInfoOnComponent(1,"ffff"); + f5.checkCoherency(); + arr4V=[1,2] + f2.setSelectedComponents(f5,arr4V); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + f2.checkCoherency(); + t,dt,it=f2.getTime() + self.assertAlmostEqual(2.3,t,13); + self.assertEqual(4,dt); + self.assertEqual(5,it); + self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(1)=="eeee"); + self.assertTrue(f2.getArray().getInfoOnComponent(2)=="ffff"); + self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); + self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); + expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),14); + pass + # + pass + def setUp(self): pass pass diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py new file mode 100644 index 000000000..d152e2a4b --- /dev/null +++ b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -0,0 +1,338 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D +# +# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from libMEDCoupling_Swig import * + +class MEDCouplingDataForTest: + def build2DTargetMesh_1(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + return targetMesh; + def build2DSourceMesh_1(cls): + sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] + sourceConn=[0,3,1,0,2,3] + sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2); + sourceMesh.allocateCells(2); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); + sourceMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(sourceCoords,4,2); + sourceMesh.setCoords(myCoords); + return sourceMesh; + + def build3DTargetMesh_1(cls): + targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. ]; + targetConn=[0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25]; + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(3); + targetMesh.allocateCells(12); + for i in xrange(8): + targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*i+8]); + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,27,3); + targetMesh.setCoords(myCoords); + return targetMesh + + def build3DSurfTargetMesh_1(self): + targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,3); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DExtrudedUMesh_1(self): + coords=[ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] + + conn=[ + # 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + # 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + # 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58] + conn2=[7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3] + # + ret=MEDCouplingUMesh.New(); + ret.setMeshDimension(3); + ret.allocateCells(18); + # + ret.insertNextCell(NORM_HEXA8,8,conn[0:8]); + ret.insertNextCell(NORM_POLYHED,43,conn[8:51]); + ret.insertNextCell(NORM_HEXA8,8,conn[51:59]); + ret.insertNextCell(NORM_HEXA8,8,conn[59:67]); + ret.insertNextCell(NORM_POLYHED,43,conn[67:110]); + ret.insertNextCell(NORM_HEXA8,8,conn[110:118]); + # + ret.insertNextCell(NORM_HEXA8,8,conn[118:126]); + ret.insertNextCell(NORM_POLYHED,43,conn[126:169]); + ret.insertNextCell(NORM_HEXA8,8,conn[169:177]); + ret.insertNextCell(NORM_HEXA8,8,conn[177:185]); + ret.insertNextCell(NORM_POLYHED,43,conn[185:228]); + ret.insertNextCell(NORM_HEXA8,8,conn[228:236]); + # + ret.insertNextCell(NORM_HEXA8,8,conn[236:244]); + ret.insertNextCell(NORM_POLYHED,43,conn[244:287]); + ret.insertNextCell(NORM_HEXA8,8,conn[287:295]); + ret.insertNextCell(NORM_HEXA8,8,conn[295:303]); + ret.insertNextCell(NORM_POLYHED,43,conn[303:346]); + ret.insertNextCell(NORM_HEXA8,8,conn[346:354]); + # + ret.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,60,3); + ret.setCoords(myCoords); + # + mesh2D=MEDCouplingUMesh.New(); + mesh2D.setMeshDimension(2); + mesh2D.allocateCells(6); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[0:4]); + mesh2D.insertNextCell(NORM_POLYGON,6,conn2[4:10]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[10:14]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[14:18]); + mesh2D.insertNextCell(NORM_POLYGON,6,conn2[18:24]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[24:28]); + mesh2D.setCoords(myCoords); + return ret,mesh2D + + def buildCU1DMesh_U(self): + coords=[ 0.0, 0.3, 0.75, 1.0 ] + conn=[ 0,1, 1,2, 2,3 ] + mesh=MEDCouplingUMesh.New(); + mesh.setMeshDimension(1); + mesh.allocateCells(3); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]); + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]); + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]); + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,4,1); + mesh.setCoords(myCoords); + return mesh; + + def build2DTargetMeshMergeNode_1(self): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 ] + targetConn=[0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,18,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DTargetMeshMergeNode_1(self): + targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.] + targetConn=[0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(3); + targetMesh.allocateCells(12); + for i in xrange(8): + targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*(i+1)]); + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,31,3); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DTargetMeshMerged_1(self): + targetCoords=[ + -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 + ] + targetConn=[ + 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, + 9,12,10,9,11,12 + ] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setName("merge"); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(10); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,13,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DTargetMesh_2(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 ] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(8); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[6:9]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[9:12]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[12:15]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[15:18]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build1DTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("1DMesh_3",1); + ret.allocateCells(4); + conn=[0,1,2, 3,4, 6,5,7 ,9,8] + ret.insertNextCell(NORM_SEG3,3,conn[0:3]) + ret.insertNextCell(NORM_SEG2,2,conn[3:5]) + ret.insertNextCell(NORM_SEG3,3,conn[5:8]) + ret.insertNextCell(NORM_SEG2,2,conn[8:10]) + ret.finishInsertingCells(); + coords=[0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,10,1); + ret.setCoords(myCoords); + return ret; + + def build2DCurveTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("2DCurveMesh_3",1); + ret.allocateCells(4); + conn=[0,1,2, 3,4, 6,5,7 ,9,8] + ret.insertNextCell(NORM_SEG3,3,conn[0:3]) + ret.insertNextCell(NORM_SEG2,2,conn[3:5]) + ret.insertNextCell(NORM_SEG3,3,conn[5:8]) + ret.insertNextCell(NORM_SEG2,2,conn[8:10]) + ret.finishInsertingCells(); + coords=[0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,10,2); + ret.setCoords(myCoords); + return ret; + + def build2DTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("2DMesh_3",2); + ret.allocateCells(10); + conn=[0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6] + ret.insertNextCell(NORM_TRI3,3,conn[0:3]) + ret.insertNextCell(NORM_QUAD4,4,conn[3:7]) + ret.insertNextCell(NORM_POLYGON,5,conn[7:12]) + ret.insertNextCell(NORM_TRI6,6,conn[12:18]) + ret.insertNextCell(NORM_QUAD8,8,conn[18:26]) + ret.insertNextCell(NORM_TRI3,3,conn[26:29]) + ret.insertNextCell(NORM_QUAD4,4,conn[29:33]) + ret.insertNextCell(NORM_POLYGON,5,conn[33:38]) + ret.insertNextCell(NORM_TRI6,6,conn[38:44]) + ret.insertNextCell(NORM_QUAD8,8,conn[44:52]) + ret.finishInsertingCells(); + coords=[0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,11,2); + ret.setCoords(myCoords); + ret.checkCoherency(); + return ret; + + def build2DTargetMesh_4(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,10,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + build2DTargetMesh_1=classmethod(build2DTargetMesh_1) + build2DSourceMesh_1=classmethod(build2DSourceMesh_1) + build3DTargetMesh_1=classmethod(build3DTargetMesh_1) + build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1) + build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1) + buildCU1DMesh_U=classmethod(buildCU1DMesh_U) + build2DTargetMeshMergeNode_1=classmethod(build2DTargetMeshMergeNode_1) + build3DTargetMeshMergeNode_1=classmethod(build3DTargetMeshMergeNode_1) + build2DTargetMeshMerged_1=classmethod(build2DTargetMeshMerged_1) + build2DTargetMesh_2=classmethod(build2DTargetMesh_2) + build1DTargetMesh_3=classmethod(build1DTargetMesh_3) + build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3) + build2DTargetMesh_3=classmethod(build2DTargetMesh_3) + build2DTargetMesh_4=classmethod(build2DTargetMesh_4) + pass diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i index 4b8e950b2..d1af65ba8 100644 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -17,28 +17,78 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +#ifdef WITH_NUMPY2 +#include +#endif + static PyObject* convertMesh(ParaMEDMEM::MEDCouplingMesh* mesh, int owner) { - PyObject *ret; + PyObject *ret=0; if(dynamic_cast(mesh)) ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner); + if(dynamic_cast(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); + if(dynamic_cast(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner); + if(!ret) + { + PyErr_SetString(PyExc_TypeError,"Not recognized type of mesh on downcast !"); + PyErr_Print(); + } return ret; } static PyObject *convertIntArrToPyList(const int *ptr, int size) { +#ifndef WITH_NUMPY2 PyObject *ret=PyList_New(size); for(int i=0;i(tmp)); +#endif +} + +static PyObject *convertIntArrToPyList2(const std::vector& v) +{ +#ifndef WITH_NUMPY2 + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i& arr) { if(PyList_Check(pyLi)) { int size=PyList_Size(pyLi); - int *tmp=new int[size]; + arr.resize(size); for(int i=0;i& v) +{ + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i& v) +{ + if(PyList_Check(ms)) + { + int size=PyList_Size(ms); + v.resize(size); + for(int i=0;i(argp); + v[i]=arg; + } + } + else + { + PyErr_SetString(PyExc_TypeError,"convertPyObjToVecUMeshes : not a list"); + PyErr_Print(); + } +} + +void convertPyObjToVecDataArrayInt(PyObject *ms, std::vector& v) +{ + if(PyList_Check(ms)) + { + int size=PyList_Size(ms); + v.resize(size); + for(int i=0;i(argp); + v[i]=arg; + } + } + else + { + PyErr_SetString(PyExc_TypeError,"convertPyObjToVecDataArrayInt : not a list"); + PyErr_Print(); + } +} diff --git a/src/MEDCoupling_Swig/Makefile.am b/src/MEDCoupling_Swig/Makefile.am index 483a7e8e1..fd14551f1 100644 --- a/src/MEDCoupling_Swig/Makefile.am +++ b/src/MEDCoupling_Swig/Makefile.am @@ -58,4 +58,8 @@ _libMEDCouplingRemapper_Swig_la_LDFLAGS = -module $(PYTHON_LIBS) \ CLEANFILES = libMEDCoupling_SwigWRAP.cxx libMEDCoupling_Swig.py libMEDCouplingRemapper_SwigWRAP.cxx libMEDCouplingRemapper_Swig.py -dist_salomescript_DATA= MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py libMEDCoupling_Swig.py libMEDCouplingRemapper_Swig.py +dist_salomescript_DATA= MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py libMEDCoupling_Swig.py libMEDCouplingRemapper_Swig.py MEDCouplingDataForTest.py + +UNIT_TEST_PROG = MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py + +#check : tests diff --git a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i index ec02326ac..d6b35f447 100644 --- a/src/MEDCoupling_Swig/libMEDCoupling_Swig.i +++ b/src/MEDCoupling_Swig/libMEDCoupling_Swig.i @@ -21,61 +21,459 @@ #define MEDCOUPLING_EXPORT +%include std_vector.i +%include std_string.i + %{ #include "MEDCouplingMemArray.hxx" #include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingCMesh.hxx" #include "MEDCouplingField.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingGaussLocalization.hxx" #include "MEDCouplingTypemaps.i" using namespace ParaMEDMEM; using namespace INTERP_KERNEL; %} +%template(ivec) std::vector; +%template(dvec) std::vector; +%template(svec) std::vector; + %typemap(out) ParaMEDMEM::MEDCouplingMesh* { $result=convertMesh($1,$owner); } +%typemap(out) ParaMEDMEM::MEDCouplingPointSet* +{ + $result=convertMesh($1,$owner); +} + +#ifdef WITH_NUMPY2 +%init %{ import_array(); %} +#endif + +%feature("autodoc", "1"); +%feature("docstring"); + %newobject ParaMEDMEM::DataArrayDouble::New; %newobject ParaMEDMEM::DataArrayInt::New; +%newobject ParaMEDMEM::DataArrayDouble::convertToIntArr; +%newobject ParaMEDMEM::DataArrayInt::convertToDblArr; %newobject ParaMEDMEM::MEDCouplingUMesh::New; +%newobject ParaMEDMEM::MEDCouplingField::buildMeasureField; %newobject ParaMEDMEM::MEDCouplingFieldDouble::New; %newobject ParaMEDMEM::MEDCouplingFieldDouble::mergeFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::doublyContractedProduct; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::determinant; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenValues; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenVectors; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::inverse; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::trace; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::deviator; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::magnitude; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxPerTuple; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::keepSelectedComponents; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::dotFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::dot; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProductFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProduct; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::max; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::minFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::min; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::getIdsInRange; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator+; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator-; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator*; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::operator/; %newobject ParaMEDMEM::MEDCouplingUMesh::clone; %newobject ParaMEDMEM::DataArrayDouble::deepCopy; %newobject ParaMEDMEM::DataArrayDouble::performCpy; %newobject ParaMEDMEM::DataArrayInt::deepCopy; %newobject ParaMEDMEM::DataArrayInt::performCpy; +%newobject ParaMEDMEM::DataArrayInt::substr; +%newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents; +%newobject ParaMEDMEM::DataArrayInt::keepSelectedComponents; +%newobject ParaMEDMEM::DataArrayInt::selectByTupleId; +%newobject ParaMEDMEM::DataArrayInt::renumber; +%newobject ParaMEDMEM::DataArrayInt::renumberR; +%newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; +%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O; +%newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N; +%newobject ParaMEDMEM::DataArrayDouble::aggregate; +%newobject ParaMEDMEM::DataArrayDouble::dot; +%newobject ParaMEDMEM::DataArrayDouble::crossProduct; +%newobject ParaMEDMEM::DataArrayDouble::add; +%newobject ParaMEDMEM::DataArrayDouble::substract; +%newobject ParaMEDMEM::DataArrayDouble::multiply; +%newobject ParaMEDMEM::DataArrayDouble::divide; +%newobject ParaMEDMEM::DataArrayDouble::substr; +%newobject ParaMEDMEM::DataArrayDouble::changeNbOfComponents; +%newobject ParaMEDMEM::DataArrayDouble::keepSelectedComponents; +%newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; +%newobject ParaMEDMEM::DataArrayDouble::selectByTupleId; +%newobject ParaMEDMEM::DataArrayDouble::applyFunc; +%newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct; +%newobject ParaMEDMEM::DataArrayDouble::determinant; +%newobject ParaMEDMEM::DataArrayDouble::eigenValues; +%newobject ParaMEDMEM::DataArrayDouble::eigenVectors; +%newobject ParaMEDMEM::DataArrayDouble::inverse; +%newobject ParaMEDMEM::DataArrayDouble::trace; +%newobject ParaMEDMEM::DataArrayDouble::deviator; +%newobject ParaMEDMEM::DataArrayDouble::magnitude; +%newobject ParaMEDMEM::DataArrayDouble::maxPerTuple; +%newobject ParaMEDMEM::DataArrayDouble::renumber; +%newobject ParaMEDMEM::DataArrayDouble::renumberR; +%newobject ParaMEDMEM::DataArrayDouble::renumberAndReduce; %newobject ParaMEDMEM::MEDCouplingFieldDouble::clone; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis; +%newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner; +%newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner; +%newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField; +%newobject ParaMEDMEM::MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds; +%newobject ParaMEDMEM::MEDCouplingMesh::buildPart; %newobject ParaMEDMEM::MEDCouplingMesh::mergeMyselfWith; %newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOfMySelf; %newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer; -%newobject ParaMEDMEM::MEDCouplingUMesh::getMeasureField; +%newobject ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; +%newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; +%newobject ParaMEDMEM::MEDCouplingMesh::getMeasureField; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMeshFromThis; %newobject ParaMEDMEM::MEDCouplingUMesh::mergeUMeshes; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; +%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType; +%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getEdgeRatioField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getAspectRatioField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getWarpField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getSkewField; +%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; +%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; +%newobject ParaMEDMEM::MEDCouplingCMesh::New; +%newobject ParaMEDMEM::MEDCouplingCMesh::buildUnstructured; %feature("unref") DataArrayDouble "$this->decrRef();" +%feature("unref") MEDCouplingPointSet "$this->decrRef();" +%feature("unref") MEDCouplingMesh "$this->decrRef();" %feature("unref") MEDCouplingUMesh "$this->decrRef();" +%feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" +%feature("unref") MEDCouplingCMesh "$this->decrRef();" %feature("unref") DataArrayInt "$this->decrRef();" +%feature("unref") MEDCouplingField "$this->decrRef();" %feature("unref") MEDCouplingFieldDouble "$this->decrRef();" -%ignore ParaMEDMEM::TimeLabel::operator=; +%rename(assign) *::operator=; %ignore ParaMEDMEM::MemArray::operator=; %ignore ParaMEDMEM::MemArray::operator[]; +%ignore ParaMEDMEM::MEDCouplingPointSet::getCoords(); +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo; +%rename (Exception) InterpKernelException; %nodefaultctor; + +namespace INTERP_KERNEL +{ + class Exception + { + public: + Exception(const char* what); + ~Exception() throw (); + const char *what() const throw (); + }; +} + %include "MEDCouplingTimeLabel.hxx" %include "MEDCouplingRefCountObject.hxx" -%include "MEDCouplingMesh.hxx" -%include "MEDCouplingPointSet.hxx" + +namespace ParaMEDMEM +{ + typedef enum + { + UNSTRUCTURED = 5, + UNSTRUCTURED_DESC = 6, + CARTESIAN = 7, + EXTRUDED = 8 + } MEDCouplingMeshType; + + class DataArrayInt; + class DataArrayDouble; + class MEDCouplingFieldDouble; + + class MEDCouplingMesh : public RefCountObject, public TimeLabel + { + public: + void setName(const char *name) { _name=name; } + const char *getName() const { return _name.c_str(); } + virtual MEDCouplingMeshType getType() const = 0; + bool isStructured() const; + virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; + virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception) = 0; + virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception) = 0; + virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; + virtual DataArrayDouble *getBarycenterAndOwner() const = 0; + virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; + virtual std::string simpleRepr() const = 0; + virtual std::string advancedRepr() const = 0; + // tools + virtual void getBoundingBox(double *bbox) const = 0; + virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; + virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0; + virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0; + virtual void rotate(const double *center, const double *vector, double angle) = 0; + virtual void translate(const double *vector) = 0; + virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; + virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception) = 0; + virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; + static MEDCouplingMesh *mergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); + %extend + { + std::string __str__() const + { + return self->simpleRepr(); + } + + int getCellContainingPoint(PyObject *p, double eps) const + { + int sz; + double *pos=convertPyToNewDblArr2(p,&sz); + int ret=self->getCellContainingPoint(pos,eps); + delete [] pos; + return ret; + } + + void renumberCells(PyObject *li, bool check) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + self->renumberCells(tmp,check); + delete [] tmp; + } + + PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellCor, *nodeCor; + self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); + return res; + } + DataArrayInt *getCellIdsFullyIncludedInNodeIds(PyObject *li) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + DataArrayInt *ret=self->getCellIdsFullyIncludedInNodeIds(tmp,tmp+size); + delete [] tmp; + return ret; + } + PyObject *getNodeIdsOfCell(int cellId) const + { + std::vector conn; + self->getNodeIdsOfCell(cellId,conn); + return convertIntArrToPyList2(conn); + } + + PyObject *getCoordinatesOfNode(int nodeId) const + { + std::vector coo; + self->getCoordinatesOfNode(nodeId,coo); + return convertDblArrToPyList2(coo); + } + + void scale(PyObject *point, double factor) + { + int sz; + double *p=convertPyToNewDblArr2(point,&sz); + self->scale(p,factor); + delete [] p; + } + } + }; +} + %include "MEDCouplingMemArray.hxx" -%include "MEDCouplingMesh.hxx" %include "NormalizedUnstructuredMesh.hxx" -%include "MEDCouplingField.hxx" %include "MEDCouplingNatureOfField.hxx" +%include "MEDCouplingTimeDiscretization.hxx" +%include "MEDCouplingGaussLocalization.hxx" namespace ParaMEDMEM { + class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh + { + public: + void updateTime(); + void setCoords(DataArrayDouble *coords); + DataArrayDouble *getCoordinatesAndOwner() const; + bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; + void getBoundingBox(double *bbox) const; + void zipCoords(); + double getCaracteristicDimension() const; + void translate(const double *vector); + void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); + void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception) = 0; + static DataArrayDouble *mergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); + static MEDCouplingPointSet *buildInstanceFromMeshType(MEDCouplingMeshType type); + virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords) const = 0; + virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; + virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; + virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; + virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); + virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; + //! size of returned tinyInfo must be always the same. + void getTinySerializationInformation(std::vector& tinyInfo, std::vector& littleStrings) const; + void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; + void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + void unserialization(const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector& littleStrings); + virtual void giveElemsInBoundingBox(const double *bbox, double eps, std::vector& elems) = 0; + virtual void giveElemsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector& elems) = 0; + virtual DataArrayInt *zipCoordsTraducer() = 0; + %extend + { + std::string __str__() const + { + return self->simpleRepr(); + } + + PyObject *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex) const + { + int newNbOfNodes; + DataArrayInt *ret0=self->buildNewNumberingFromCommonNodesFormat(comm,commIndex,newNbOfNodes); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_From_int(newNbOfNodes)); + return res; + } + + PyObject *findCommonNodes(int limitNodeId, double prec) const + { + DataArrayInt *comm, *commIndex; + self->findCommonNodes(limitNodeId,prec,comm,commIndex); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + PyObject *getCoords() const + { + DataArrayDouble *ret1=self->getCoords(); + ret1->incrRef(); + return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0); + } + PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+size,keepCoords); + delete [] tmp; + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+size,fullyIn); + delete [] tmp; + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+size,fullyIn); + delete [] tmp; + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *findBoundaryNodes() const + { + std::vector nodes; + self->findBoundaryNodes(nodes); + return convertIntArrToPyList2(nodes); + } + void rotate(PyObject *center, PyObject *vector, double alpha) + { + int sz; + double *c=convertPyToNewDblArr2(center,&sz); + if(!c) + return ; + double *v=convertPyToNewDblArr2(vector,&sz); + if(!v) + { delete [] c; return ; } + self->rotate(c,v,alpha); + delete [] c; + delete [] v; + } + void translate(PyObject *vector) + { + int sz; + double *v=convertPyToNewDblArr2(vector,&sz); + self->translate(v); + delete [] v; + } + void renumberNodes(PyObject *li, int newNbOfNodes) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + self->renumberNodes(tmp,newNbOfNodes); + delete [] tmp; + } + PyObject *findNodesOnPlane(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + std::vector nodes; + int sz; + double *p=convertPyToNewDblArr2(pt,&sz); + double *v=convertPyToNewDblArr2(vec,&sz); + self->findNodesOnPlane(p,v,eps,nodes); + delete [] v; + delete [] p; + return convertIntArrToPyList2(nodes); + } + static void rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords) + { + int sz; + double *c=convertPyToNewDblArr2(center,&sz); + double *coo=convertPyToNewDblArr2(coords,&sz); + ParaMEDMEM::MEDCouplingPointSet::rotate2DAlg(c,angle,nbNodes,coo); + for(int i=0;isimpleRepr(); + } void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) { - int *tmp=convertPyToNewIntArr(li,size); + int sz; + int *tmp=convertPyToNewIntArr2(li,&sz); self->insertNextCell(type,size,tmp); delete [] tmp; } @@ -124,23 +532,256 @@ namespace ParaMEDMEM PyObject *mergeNodes(double precision) { bool ret1; - DataArrayInt *ret0=self->mergeNodes(precision,ret1); - PyObject *res = PyList_New(2); + int ret2; + DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2); + PyObject *res = PyList_New(3); PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); PyList_SetItem(res,1,SWIG_From_bool(ret1)); + PyList_SetItem(res,2,SWIG_From_int(ret2)); return res; } + PyObject *checkButterflyCells() + { + std::vector cells; + self->checkButterflyCells(cells); + return convertIntArrToPyList2(cells); + } + + PyObject *splitByType() const + { + std::vector ms=self->splitByType(); + int sz=ms.size(); + PyObject *ret = PyList_New(sz); + for(int i=0;i idsPerGeoType; + convertPyToNewIntArr3(ids,idsPerGeoType); + MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,idsPerGeoType); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ); + } + + bool checkConsecutiveCellTypesAndOrder(PyObject *li) const + { + int sz; + INTERP_KERNEL::NormalizedCellType *order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); + bool ret=self->checkConsecutiveCellTypesAndOrder(order,order+sz); + delete [] order; + return ret; + } + + DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(PyObject *li) const + { + int sz; + INTERP_KERNEL::NormalizedCellType *order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); + DataArrayInt *ret=self->getRenumArrForConsecutiveCellTypesSpec(order,order+sz); + delete [] order; + return ret; + } + + PyObject *getCellsContainingPoints(PyObject *p, int nbOfPoints, double eps) const + { + int sz; + double *pos=convertPyToNewDblArr2(p,&sz); + std::vector elts,eltsIndex; + self->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex); + delete [] pos; + PyObject *ret=PyList_New(2); + PyList_SetItem(ret,0,convertIntArrToPyList2(elts)); + PyList_SetItem(ret,1,convertIntArrToPyList2(eltsIndex)); + return ret; + } + + PyObject *getCellsContainingPoint(PyObject *p, double eps) const + { + int sz; + double *pos=convertPyToNewDblArr2(p,&sz); + std::vector elts; + self->getCellsContainingPoint(pos,eps,elts); + delete [] pos; + return convertIntArrToPyList2(elts); + } + + static PyObject *mergeUMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) + { + std::vector meshes; + if(PyList_Check(ms)) + { + int sz=PyList_Size(ms); + meshes.resize(sz); + for(int i=0;i(arg); + } + } + else + { + PyErr_SetString(PyExc_TypeError,"mergeUMeshesOnSameCoords : not a list as first parameter"); + PyErr_Print(); + return 0; + } + MEDCouplingUMesh *ret=MEDCouplingUMesh::mergeUMeshesOnSameCoords(meshes); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + static PyObject *fuseUMeshesOnSameCoords(PyObject *ms, int compType) + { + int sz; + std::vector meshes; + convertPyObjToVecUMeshes(ms,meshes); + std::vector corr; + MEDCouplingUMesh *um=MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,compType,corr); + sz=corr.size(); + PyObject *ret1=PyList_New(sz); + for(int i=0;i cells; + int sz; + double *v=convertPyToNewDblArr2(vec,&sz); + try + { + self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] v; + throw e; + } + delete [] v; + return convertIntArrToPyList2(cells); + } + + void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception) + { + int sz; + double *v=convertPyToNewDblArr2(vec,&sz); + try + { + self->orientCorrectly2DCells(v,polyOnly); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] v; + throw e; + } + delete [] v; + } + + PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception) + { + std::vector cells; + self->arePolyhedronsNotCorrectlyOriented(cells); + return convertIntArrToPyList2(cells); + } + + PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception) + { + double vec[3]; + double pos[3]; + self->getFastAveragePlaneOfThis(vec,pos); + double vals[6]; + std::copy(vec,vec+3,vals); + std::copy(pos,pos+3,vals+3); + return convertDblArrToPyListOfTuple(vals,3,2); + } + } + void convertToPolyTypes(const std::vector& cellIdsToConvert); + MEDCouplingUMesh *buildExtrudedMeshFromThis(const MEDCouplingUMesh *mesh1D, int policy); + static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); + }; + + class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh + { + public: + static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *build3DUnstructuredMesh() const; + %extend { + std::string __str__() const + { + return self->simpleRepr(); + } + PyObject *getMesh2D() const + { + MEDCouplingUMesh *ret=self->getMesh2D(); + ret->incrRef(); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *getMesh1D() const + { + MEDCouplingUMesh *ret=self->getMesh1D(); + ret->incrRef(); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *getMesh3DIds() const + { + DataArrayInt *ret=self->getMesh3DIds(); + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + } + }; + + class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingMesh + { + public: + static MEDCouplingCMesh *New(); + void setCoords(DataArrayDouble *coordsX, + DataArrayDouble *coordsY=0, + DataArrayDouble *coordsZ=0); + void setCoordsAt(int i, DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildUnstructured() const; + %extend { + std::string __str__() const + { + return self->simpleRepr(); + } } - MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - static MEDCouplingUMesh *mergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); }; } +%extend ParaMEDMEM::DataArray +{ + void copyPartOfStringInfoFrom(const DataArray& other, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + self->copyPartOfStringInfoFrom(other,tmp); + } + + void copyPartOfStringInfoFrom2(PyObject *li, const DataArray& other) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + self->copyPartOfStringInfoFrom2(tmp,other); + } +} + %extend ParaMEDMEM::DataArrayDouble { + std::string __str__() const + { + return self->repr(); + } + void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) { - double *tmp=convertPyToNewDblArr2(li); + int sz; + double *tmp=convertPyToNewDblArr2(li,&sz); self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple); } @@ -149,13 +790,158 @@ namespace ParaMEDMEM const double *vals=self->getPointer(); return convertDblArrToPyList(vals,self->getNbOfElems()); } + + PyObject *getValuesAsTuple() + { + const double *vals=self->getPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayDouble *ret=self->renumber(tmp); + delete [] tmp; + return ret; + } + + DataArrayDouble *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayDouble *ret=self->renumberR(tmp); + delete [] tmp; + return ret; + } + + DataArrayDouble *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayDouble *ret=self->renumberAndReduce(tmp,newNbOfTuple); + delete [] tmp; + return ret; + } + + void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + self->renumberInPlace(tmp); + delete [] tmp; + } + + void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + self->renumberInPlaceR(tmp); + delete [] tmp; + } + + DataArrayDouble *selectByTupleId(PyObject *li) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + DataArrayDouble *ret=self->selectByTupleId(tmp,tmp+size); + delete [] tmp; + return ret; + } + + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + double r1=self->getMaxValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMaxValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + double r1=self->getMinValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMinValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + return self->keepSelectedComponents(tmp); + } + + void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(a,tmp); + } }; %extend ParaMEDMEM::DataArrayInt { + std::string __str__() const + { + return self->repr(); + } + void setValues(PyObject *li, int nbOfTuples, int nbOfElsPerTuple) { - int *tmp=convertPyToNewIntArr2(li); + int size; + int *tmp=convertPyToNewIntArr2(li,&size); self->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfElsPerTuple); } @@ -164,40 +950,323 @@ namespace ParaMEDMEM const int *vals=self->getPointer(); return convertIntArrToPyList(vals,self->getNbOfElems()); } - }; -%include "MEDCouplingField.hxx" + PyObject *getValuesAsTuple() + { + const int *vals=self->getPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertIntArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + static PyObject *makePartition(PyObject *gps, int newNb) + { + std::vector groups; + std::vector< std::vector > fidsOfGroups; + convertPyObjToVecDataArrayInt(gps,groups); + ParaMEDMEM::DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::makePartition(groups,newNb,fidsOfGroups); + PyObject *ret = PyList_New(2); + PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + int sz=fidsOfGroups.size(); + PyObject *ret1 = PyList_New(sz); + for(int i=0;igetNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + self->renumberInPlace(tmp); + delete [] tmp; + } + + void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + self->renumberInPlaceR(tmp); + delete [] tmp; + } + + DataArrayInt *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayInt *ret=self->renumberAndReduce(tmp,newNbOfTuple); + delete [] tmp; + return ret; + } + + DataArrayInt *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayInt *ret=self->renumber(tmp); + delete [] tmp; + return ret; + } + + DataArrayInt *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + delete [] tmp; + } + DataArrayInt *ret=self->renumberR(tmp); + delete [] tmp; + return ret; + } + + DataArrayInt *selectByTupleId(PyObject *li) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + DataArrayInt *ret=self->selectByTupleId(tmp,tmp+size); + delete [] tmp; + return ret; + } + + DataArrayInt *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + return self->keepSelectedComponents(tmp); + } + + void setSelectedComponents(const DataArrayInt *a, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(a,tmp); + } + }; namespace ParaMEDMEM { + class MEDCouplingField : public ParaMEDMEM::RefCountObject, public ParaMEDMEM::TimeLabel + { + public: + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); + virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; + virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); + void setName(const char *name); + const char *getDescription() const; + void setDescription(const char *desc); + const char *getName() const; + TypeOfField getTypeOfField() const; + MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDiscretization *getDiscretization() const; + void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); + void clearGaussLocalizations(); + MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); + int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); + const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); + %extend { + PyObject *getMesh() const + { + MEDCouplingMesh *ret1=(MEDCouplingMesh *)self->getMesh(); + ret1->incrRef(); + return convertMesh(ret1, SWIG_POINTER_OWN | 0 ); + } + + PyObject *buildSubMeshData(PyObject *li) const + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + DataArrayInt *ret1; + MEDCouplingMesh *ret0=self->buildSubMeshData(tmp,tmp+size,ret1); + delete [] tmp; + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + return res; + } + void setGaussLocalizationOnCells(PyObject *li, const std::vector& refCoo, + const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + try + { + self->setGaussLocalizationOnCells(tmp,tmp+size,refCoo,gsCoo,wg); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] tmp; + throw e; + } + delete [] tmp; + } + PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + self->getCellIdsHavingGaussLocalization(locId,tmp); + return convertIntArrToPyList2(tmp); + } + } + }; + class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField { public: static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=NO_TIME); + void copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + std::string advancedRepr() const; MEDCouplingFieldDouble *clone(bool recDeepCpy) const; + MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; + MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const; + TypeOfTimeDiscretization getTimeDiscretization() const; void checkCoherency() const throw(INTERP_KERNEL::Exception); double getIJ(int tupleId, int compoId) const; - void setArray(DataArrayDouble *array); - void setTime(double val, int dt, int it); - void setStartTime(double val, int dt, int it); - void setEndTime(double val, int dt, int it); - DataArrayDouble *getArray() const { return _array; } - void applyLin(double a, double b, int compoId); - int getNumberOfComponents() const; + double getIJK(int cellId, int nodeIdInCell, int compoId) const; + void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); + void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); + void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setStartTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setEndTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getEndArray() const throw(INTERP_KERNEL::Exception); + void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); + int getNumberOfValues() const throw(INTERP_KERNEL::Exception); NatureOfField getNature() const { return _nature; } void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception); void updateTime(); - bool mergeNodes(double eps); - void applyFunc(int nbOfComp, const char *func); - void applyFunc(const char *func); - static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double prec) throw(INTERP_KERNEL::Exception); + bool mergeNodes(double eps) throw(INTERP_KERNEL::Exception); + bool zipCoords() throw(INTERP_KERNEL::Exception); + bool zipConnectivity(int compType) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception); + void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); + void applyFunc(int nbOfComp, const char *func) throw(INTERP_KERNEL::Exception); + void applyFunc(int nbOfComp, double val) throw(INTERP_KERNEL::Exception); + void applyFunc(const char *func) throw(INTERP_KERNEL::Exception); + void applyFuncFast32(const char *func) throw(INTERP_KERNEL::Exception); + void applyFuncFast64(const char *func) throw(INTERP_KERNEL::Exception); + double accumulate(int compId) const throw(INTERP_KERNEL::Exception); + double getMaxValue() const throw(INTERP_KERNEL::Exception); + double getMinValue() const throw(INTERP_KERNEL::Exception); + double getAverageValue() const throw(INTERP_KERNEL::Exception); + double getWeightedAverageValue() const throw(INTERP_KERNEL::Exception); + double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); + double normL1(int compId) const throw(INTERP_KERNEL::Exception); + double normL2(int compId) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *mergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *dotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const; + static MEDCouplingFieldDouble *crossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const; + static MEDCouplingFieldDouble *maxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const; + static MEDCouplingFieldDouble *minFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const; + MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other) throw(INTERP_KERNEL::Exception); %extend { + std::string __str__() const + { + return self->simpleRepr(); + } + PyObject *getValueOn(PyObject *sl) const throw(INTERP_KERNEL::Exception) + { + int sz; + double *spaceLoc=convertPyToNewDblArr2(sl,&sz); + sz=self->getNumberOfComponents(); + double *res=new double[sz]; + try + { + self->getValueOn(spaceLoc,res); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] spaceLoc; + delete [] res; + throw e; + } + delete [] spaceLoc; + PyObject *ret=convertDblArrToPyList(res,sz); + delete [] res; + return ret; + } + PyObject *getValueOn(PyObject *sl, double time) const throw(INTERP_KERNEL::Exception) + { + int sz; + double *spaceLoc=convertPyToNewDblArr2(sl,&sz); + sz=self->getNumberOfComponents(); + double *res=new double[sz]; + try + { + self->getValueOn(spaceLoc,time,res); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] spaceLoc; + delete [] res; + throw e; + } + delete [] spaceLoc; + PyObject *ret=convertDblArrToPyList(res,sz); + delete [] res; + return ret; + } void setValues(PyObject *li) { if(self->getArray()!=0) { - double *tmp=convertPyToNewDblArr2(li); + int sz; + double *tmp=convertPyToNewDblArr2(li,&sz); int nbTuples=self->getArray()->getNumberOfTuples(); int nbOfCompo=self->getArray()->getNumberOfComponents(); self->getArray()->useArray(tmp,true,CPP_DEALLOC,nbTuples,nbOfCompo); @@ -237,6 +1306,125 @@ namespace ParaMEDMEM PyList_SetItem(res,2,SWIG_From_int(tmp2)); return res; } + PyObject *accumulate() const + { + int sz=self->getNumberOfComponents(); + double *tmp=new double[sz]; + self->accumulate(tmp); + PyObject *ret=convertDblArrToPyList(tmp,sz); + delete [] tmp; + return ret; + } + PyObject *integral(bool isWAbs) const + { + int sz=self->getNumberOfComponents(); + double *tmp=new double[sz]; + self->integral(isWAbs,tmp); + PyObject *ret=convertDblArrToPyList(tmp,sz); + delete [] tmp; + return ret; + } + PyObject *normL1() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + double *tmp=new double[sz]; + self->normL1(tmp); + PyObject *ret=convertDblArrToPyList(tmp,sz); + delete [] tmp; + return ret; + } + PyObject *normL2() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + double *tmp=new double[sz]; + self->normL2(tmp); + PyObject *ret=convertDblArrToPyList(tmp,sz); + delete [] tmp; + return ret; + } + + void renumberCells(PyObject *li, bool check) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + try + { + self->renumberCells(tmp,check); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] tmp; + throw e; + } + delete [] tmp; + } + void renumberNodes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + try + { + self->renumberNodes(tmp); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] tmp; + throw e; + } + delete [] tmp; + } + + MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int size; + int *tmp=convertPyToNewIntArr2(li,&size); + MEDCouplingFieldDouble *ret=0; + try + { + ret=self->buildSubPart(tmp,tmp+size); + } + catch(INTERP_KERNEL::Exception& e) + { + delete [] tmp; + throw e; + } + delete [] tmp; + return ret; + } + + PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMaxValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMinValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + MEDCouplingFieldDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + return self->keepSelectedComponents(tmp); + } + + void setSelectedComponents(const MEDCouplingFieldDouble *f, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(f,tmp); + } } }; } diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx index f68192850..cde077cee 100644 --- a/src/MEDLoader/MEDLoader.cxx +++ b/src/MEDLoader/MEDLoader.cxx @@ -23,6 +23,7 @@ #include "MEDCouplingUMesh.hxx" #include "MEDCouplingMemArray.hxx" #include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingGaussLocalization.hxx" extern "C" { @@ -57,7 +58,7 @@ med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE+2] = { MED_POINT1, med_geometrie_element typmainoeud[1] = { MED_NONE }; -INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_ERROR, +INTERP_KERNEL::NormalizedCellType typmai2[MED_NBR_GEOMETRIE_MAILLE+2] = { INTERP_KERNEL::NORM_POINT0, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_TRI3, @@ -109,6 +110,12 @@ med_geometrie_element typmai3[32] = { MED_POINT1,//0 MED_POLYEDRE//31 }; +double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; + +int MEDLoader::_COMP_FOR_CELL=0; + +int MEDLoader::_TOO_LONG_STR=0; + using namespace ParaMEDMEM; namespace MEDLoaderNS @@ -132,37 +139,77 @@ namespace MEDLoaderNS int _val; }; - std::string buildStringFromFortran(const char *expr, int lgth); std::vector getMeshNamesFid(med_idt fid); - void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, std::list& field, - int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time); + void readFieldDoubleDataInMedFile(const char *fileName, const char *meshName, const char *fieldName, + int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, + std::list& field, + double& time, std::vector& infos); std::vector getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams); std::vector getIdsFromGroups(const char *fileName, const char *meshName, const std::vector& grps); med_int getIdFromMeshName(med_idt fid, const char *meshName, std::string& trueMeshName) throw(INTERP_KERNEL::Exception); void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entite_maillage& whichEntity); - void readUMeshDataInMedFile(med_idt fid, med_int meshId, double *&coords, int& nCoords, int& spaceDim, std::list& conn); - int buildMEDSubConnectivityOfOneType(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile); + int readUMeshDimFromFile(const char *fileName, const char *meshName, std::vector& possibilities); + void readUMeshDataInMedFile(med_idt fid, med_int meshId, DataArrayDouble *&coords, std::list& conn); + int buildMEDSubConnectivityOfOneType(const std::vector& conn, const std::vector& connIndex, const std::vector& families, INTERP_KERNEL::NormalizedCellType type, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + std::vector& fam4MEDFile, std::vector& renumber); MEDCouplingUMesh *readUMeshFromFileLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& ids, - const std::vector& typesToKeep, unsigned& meshDimExtract) throw(INTERP_KERNEL::Exception); + const std::vector& typesToKeep, unsigned& meshDimExtract, int *&cellRenum) throw(INTERP_KERNEL::Exception); void tradMEDFileCoreFrmt2MEDCouplingUMesh(const std::list& medConnFrmt, + const std::vector& familiesToKeep, DataArrayInt* &conn, DataArrayInt* &connIndex, - const std::vector& familiesToKeep); - ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list& fieldPerType); - int buildMEDSubConnectivityOfOneTypesPolyg(DataArrayInt *conn, DataArrayInt *connIndex, std::vector& conn4MEDFile, std::vector& connIndex4MEDFile); - int buildMEDSubConnectivityOfOneTypesPolyh(DataArrayInt *conn, DataArrayInt *connIndex, std::vector& conn4MEDFile, - std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile); - int buildMEDSubConnectivityOfOneTypeStaticTypes(DataArrayInt *conn, DataArrayInt *connIndex, INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile); + int *&cellRenum); + ParaMEDMEM::DataArrayDouble *buildArrayFromRawData(const std::list& fieldPerType, + const std::vector& infos); + int buildMEDSubConnectivityOfOneTypesPolyg(const std::vector& conn, const std::vector& connIndex, const std::vector& families, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); + int buildMEDSubConnectivityOfOneTypesPolyh(const std::vector&conn, const std::vector& connIndex, const std::vector& families, + std::vector& conn4MEDFile, std::vector& connIndex4MEDFile, std::vector& connIndexRk24MEDFile, + std::vector& fam4MEDFile, std::vector& renumber); + int buildMEDSubConnectivityOfOneTypeStaticTypes(const std::vector& conn, const std::vector& connIndex, const std::vector& families, + INTERP_KERNEL::NormalizedCellType type, std::vector& conn4MEDFile, std::vector& fam4MEDFile, std::vector& renumber); ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev1(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField); - void appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f); - void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, std::list& split); - void writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch); - void writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch); + ParaMEDMEM::MEDCouplingFieldDouble *readFieldDoubleLev2(const char *fileName, ParaMEDMEM::TypeOfField typeOfOutField, unsigned meshDim, const int *renumCell, const ParaMEDMEM::MEDCouplingUMesh *mesh, + const std::vector& infos, const char *fieldName, int iteration, int order, double time, + std::list& fieldPerCellType); + med_idt appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt); + void appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); + void appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds); + void appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIds); + void prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIds, std::list& split); + void fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f); + void writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering); + void writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch); + void writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch); + void writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); +} + +/*! + * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. + */ +void MEDLoader::setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception) +{ + _EPS_FOR_NODE_COMP=val; } -const char WHITE_SPACES[]=" \n"; +/*! + * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. + */ +void MEDLoader::setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception) +{ + _COMP_FOR_CELL=val; +} + +/*! + * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. + * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. + */ +void MEDLoader::setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception) +{ + _TOO_LONG_STR=val; +} /*! * @param lgth is the size of fam tab. For classical types conn is size of 'lgth'*number_of_nodes_in_type. @@ -171,8 +218,8 @@ const char WHITE_SPACES[]=" \n"; */ MEDLoader::MEDConnOfOneElemType::MEDConnOfOneElemType(INTERP_KERNEL::NormalizedCellType type, int *conn, int *index, int *fam, int lgth, int connLgth):_lgth(lgth),_fam(fam), _conn(conn),_index(index), - _global(0),_type(type), - _conn_lgth(connLgth) + _global(0),_conn_lgth(connLgth), + _type(type) { } @@ -194,8 +241,13 @@ void MEDLoader::MEDConnOfOneElemType::releaseArray() delete [] _global; } -MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type) +MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple, + const int *cellIdPerType, const char *locName):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type) { + if(cellIdPerType) + _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+ntuple); + if(locName) + _loc_name=locName; } void MEDLoader::MEDFieldDoublePerCellType::releaseArray() @@ -203,21 +255,6 @@ void MEDLoader::MEDFieldDoublePerCellType::releaseArray() delete [] _values; } - -std::string MEDLoaderNS::buildStringFromFortran(const char *expr, int lgth) -{ - std::string ret(expr,lgth); - std::string whiteSpaces(WHITE_SPACES); - std::size_t lgthReal=strlen(ret.c_str()); - std::string ret2=ret.substr(0,lgthReal); - std::size_t found=ret2.find_last_not_of(whiteSpaces); - if (found!=std::string::npos) - ret2.erase(found+1); - else - ret2.clear();//ret is all whitespace - return ret2; -} - std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) { med_maillage type_maillage; @@ -229,22 +266,150 @@ std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) for(int i=0;i MEDLoader::GetMeshNames(const char *fileName) +void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list& data, MEDCouplingFieldDouble *f) +{ + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + char locName[MED_TAILLE_NOM+1]; + int nloc=MEDnGauss(fid); + med_geometrie_element typeGeo; + for(std::list::const_iterator iter=data.begin();iter!=data.end();iter++) + { + const std::string& loc=(*iter).getLocName(); + int idLoc=1; + int nbOfGaussPt=-1; + for(;idLoc<=nloc;idLoc++) + { + MEDgaussInfo(fid,idLoc,locName,&typeGeo,&nbOfGaussPt); + if(loc==locName) + break; + } + int dim=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getDimension(); + int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes(); + std::vector refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt); + MEDgaussLire(fid,(med_float *)&refcoo[0],(med_float *)&gscoo[0],(med_float *)&w[0],MED_FULL_INTERLACE,(char *)(*iter).getLocName().c_str()); + f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w); + } + MEDfermer(fid); +} + +void MEDLoader::CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + int status=MEDLoaderBase::getStatusOfFile(fileName); + std::ostringstream oss; + oss << " File : \"" << fileName << "\""; + switch(status) + { + case MEDLoaderBase::DIR_LOCKED: + { + oss << " has been detected as unreadable : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + case MEDLoaderBase::NOT_EXIST: + { + oss << " has been detected as NOT EXISTING : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + case MEDLoaderBase::EXIST_WRONLY: + { + oss << " has been detected as WRITE ONLY : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int fid=MEDouvrir((char *)fileName,MED_LECTURE); + if(fid<0) + { + oss << " has been detected as unreadable by MED file : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + oss << " has been detected readable but "; + int major,minor,release; + MEDversionLire(fid,&major,&minor,&release); + if(major<2 || (major==2 && minor<2)) + { + oss << "version of MED file is < 2.2 : impossible to read anything !"; + MEDfermer(fid); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDfermer(fid); +} + +std::vector MEDLoader::GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); MEDfermer(fid); return ret; } -std::vector MEDLoader::GetMeshFamilyNames(const char *fileName, const char *meshName) +std::vector MEDLoader::GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + //med_int nbpdtnor=0,pflsize,*pflval,lnsize; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + //char pflname[MED_TAILLE_NOM+1]=""; + //char locname[MED_TAILLE_NOM+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + // + for(int i=0;i MEDLoader::GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nfam=MEDnFam(fid,(char *)meshName); std::vector ret(nfam); @@ -259,7 +424,7 @@ std::vector MEDLoader::GetMeshFamilyNames(const char *fileName, con char *attdes=new char[MED_TAILLE_DESC*natt+1]; char *gro=new char[MED_TAILLE_LNOM*ngro+1]; MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro); - std::string cur=MEDLoaderNS::buildStringFromFortran(nomfam,sizeof(nomfam)); + std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); ret[i]=cur; delete [] attdes; delete [] gro; @@ -270,8 +435,9 @@ std::vector MEDLoader::GetMeshFamilyNames(const char *fileName, con return ret; } -std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) +std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nfam=MEDnFam(fid,(char *)meshName); std::vector ret; @@ -288,7 +454,7 @@ std::vector MEDLoader::GetMeshGroupsNames(const char *fileName, con MEDfamInfo(fid,(char *)meshName,i+1,nomfam,&numfam,attide,attval,attdes,&natt,gro,&ngro); for(int j=0;j MEDLoader::GetMeshGroupsNames(const char *fileName, con MEDfermer(fid); return ret; } - -std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) +std::vector MEDLoader::GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception) { - std::vector ret; + CheckFileForRead(fileName); + std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); // @@ -315,9 +481,9 @@ std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName med_booleen local; //char pflname[MED_TAILLE_NOM+1]=""; //char locname[MED_TAILLE_NOM+1]=""; - char maa_ass[MED_TAILLE_NOM+1]=""; - char dt_unit[MED_TAILLE_PNOM+1]=""; - char nomcha[MED_TAILLE_NOM+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); // for(int i=0;i MEDLoader::GetCellFieldNamesOnMesh(const char *fileName char *comp=new char[ncomp*MED_TAILLE_PNOM+1]; char *unit=new char[ncomp*MED_TAILLE_PNOM+1]; MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); - std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); delete [] comp; delete [] unit; - bool found=false; - for(int j=0;j0) { - MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); - std::string curMeshName=MEDLoaderNS::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); - if(curMeshName==meshName) + bool found=false; + for(int i=0;i0) + { + MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); + if(curMeshName==meshName) + { + found=true; + ret.push_back(ON_CELLS); + } } } } } + delete [] maa_ass; + delete [] dt_unit; + delete [] nomcha; + MEDfermer(fid); + return ret; +} + +std::vector MEDLoader::GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + std::vector ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + med_type_champ typcha; + for(int i=0;i MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) +std::vector MEDLoader::GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { + CheckFileForRead(fileName); std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); // med_type_champ typcha; + //med_int nbpdtnor=0,pflsize,*pflval,lnsize; med_int ngauss=0; med_int numdt=0,numo=0,nbrefmaa; med_float dt=0.0; med_booleen local; - char maa_ass[MED_TAILLE_NOM+1]=""; - char dt_unit[MED_TAILLE_PNOM+1]=""; - char nomcha[MED_TAILLE_NOM+1]=""; + //char pflname[MED_TAILLE_NOM+1]=""; + //char locname[MED_TAILLE_NOM+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); // for(int i=0;i MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName char *comp=new char[ncomp*MED_TAILLE_PNOM+1]; char *unit=new char[ncomp*MED_TAILLE_PNOM+1]; MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); - std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); delete [] comp; delete [] unit; - bool found=false; + // med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); + bool found=false; if(nbPdt>0) + { + for(int i=0;i0) { - found=true; - ret.push_back(curFieldName); + MEDpasdetempsInfo(fid,nomcha,MED_MAILLE,typmai[j],1, &ngauss, &numdt, &numo, dt_unit,&dt, maa_ass, &local, &nbrefmaa); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_TAILLE_NOM+1); + if(curMeshName==meshName) + { + found=true; + ret.push_back(curFieldName); + } } } } + delete [] maa_ass; + delete [] dt_unit; + delete [] nomcha; MEDfermer(fid); return ret; } -std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char *fileName, const char *fieldName) +std::vector MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { - std::vector< std::pair > ret; + CheckFileForRead(fileName); + switch(type) + { + case ON_CELLS: + return GetCellFieldNamesOnMesh(fileName,meshName); + case ON_NODES: + return GetNodeFieldNamesOnMesh(fileName,meshName); + default: + throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); + } +} + +std::vector MEDLoader::GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); // med_type_champ typcha; + //med_int nbpdtnor=0,pflsize,*pflval,lnsize; med_int ngauss=0; med_int numdt=0,numo=0,nbrefmaa; med_float dt=0.0; med_booleen local; - char maa_ass[MED_TAILLE_NOM+1]=""; - char dt_unit[MED_TAILLE_PNOM+1]=""; - char nomcha[MED_TAILLE_NOM+1]=""; + //char pflname[MED_TAILLE_NOM+1]=""; + //char locname[MED_TAILLE_NOM+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); // for(int i=0;i > MEDLoader::GetCellFieldIterations(const char * char *comp=new char[ncomp*MED_TAILLE_PNOM+1]; char *unit=new char[ncomp*MED_TAILLE_PNOM+1]; MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); - std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); delete [] comp; delete [] unit; - if(curFieldName==fieldName) + bool found=false; + for(int j=0;j0) { - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]); - for(int k=0;k > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *fieldName) +std::vector MEDLoader::GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception) { - std::vector< std::pair > ret; + CheckFileForRead(fileName); + std::vector ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); // @@ -443,9 +702,9 @@ std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const char * med_int numdt=0,numo=0,nbrefmaa; med_float dt=0.0; med_booleen local; - char maa_ass[MED_TAILLE_NOM+1]=""; - char dt_unit[MED_TAILLE_PNOM+1]=""; - char nomcha[MED_TAILLE_NOM+1]=""; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); // for(int i=0;i > MEDLoader::GetNodeFieldIterations(const char * char *comp=new char[ncomp*MED_TAILLE_PNOM+1]; char *unit=new char[ncomp*MED_TAILLE_PNOM+1]; MEDchampInfo(fid,i+1,nomcha,&typcha,comp,unit,ncomp); - std::string curFieldName=MEDLoaderNS::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_TAILLE_NOM+1); delete [] comp; delete [] unit; - if(curFieldName==fieldName) + bool found=false; + med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); + if(nbPdt>0) { - med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_NOEUD,MED_NONE); - for(int k=0;k& field, - int iteration, int order, ParaMEDMEM::TypeOfField typeOfOutField, double& time) +std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { - time=0.; + CheckFileForRead(fileName); + std::string meshNameCpp(meshName); + std::vector< std::pair< std::pair, double> > ret; med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); med_int nbFields=MEDnChamp(fid,0); // med_type_champ typcha; - char nomcha[MED_TAILLE_NOM+1]=""; - char pflname [MED_TAILLE_NOM+1]=""; - char locname [MED_TAILLE_NOM+1]=""; - std::map tabEnt; - std::map tabType; - std::map tabTypeLgth; - tabEnt[ON_CELLS]=MED_MAILLE; - tabType[ON_CELLS]=typmai; - tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2; - tabEnt[ON_NODES]=MED_NOEUD; - tabType[ON_NODES]=typmainoeud; - tabTypeLgth[ON_NODES]=1; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); // for(int i=0;i0) + med_int nbPdt=MEDnPasdetemps(fid,nomcha,MED_MAILLE,typmai[j]); + for(int k=0;k MEDLoaderNS::getIdsFromFamilies(const char *fileName, const char *meshName, const std::vector& fams) +double MEDLoader::GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { - std::vector ret; + CheckFileForRead(fileName); med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); - med_int nfam=MEDnFam(fid,(char *)meshName); - char nomfam[MED_TAILLE_NOM+1]; - med_int numfam; - for(int i=0;i > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + switch(type) + { + case ON_CELLS: + return GetCellFieldIterations(fileName,meshName,fieldName); + case ON_NODES: + return GetNodeFieldIterations(fileName,meshName,fieldName); + default: + throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); + } +} + +std::vector< std::pair > MEDLoader::GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + std::string meshNameCpp(meshName); + std::vector< std::pair > ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + // + for(int i=0;i > MEDLoader::GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) +{ + CheckFileForRead(fileName); + std::string meshNameCpp(meshName); + std::vector< std::pair > ret; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + med_float dt=0.0; + med_booleen local; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + // + for(int i=0;i& field, + double& time, std::vector& infos) +{ + time=0.; + med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE); + med_int nbFields=MEDnChamp(fid,0); + // + med_type_champ typcha; + char nomcha[MED_TAILLE_NOM+1]=""; + char pflname [MED_TAILLE_NOM+1]=""; + char locname [MED_TAILLE_NOM+1]=""; + std::map tabEnt; + std::map tabType; + std::map tabTypeLgth; + tabEnt[ON_CELLS]=MED_MAILLE; + tabType[ON_CELLS]=typmai; + tabTypeLgth[ON_CELLS]=MED_NBR_GEOMETRIE_MAILLE+2; + tabEnt[ON_NODES]=MED_NOEUD; + tabType[ON_NODES]=typmainoeud; + tabTypeLgth[ON_NODES]=1; + tabEnt[ON_GAUSS_PT]=MED_MAILLE; + tabType[ON_GAUSS_PT]=typmai; + tabTypeLgth[ON_GAUSS_PT]=MED_NBR_GEOMETRIE_MAILLE+2; + tabEnt[ON_GAUSS_NE]=MED_MAILLE; + tabType[ON_GAUSS_NE]=typmai; + tabTypeLgth[ON_GAUSS_NE]=MED_NBR_GEOMETRIE_MAILLE+2; + // + for(int i=0;i0) + { + int nval=MEDnVal(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j],iteration,order,(char *)meshName,MED_COMPACT); + double *valr=new double[ncomp*nval]; + // + med_int ngauss=0; + med_int numdt=0,numo=0,nbrefmaa; + char *dt_unit=MEDLoaderBase::buildEmptyString(MED_TAILLE_PNOM); + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + med_float dt=0.0; + med_booleen local; + med_int nbPdt=MEDnPasdetemps(fid,(char *)fieldName,tabEnt[typeOfOutField],tabType[typeOfOutField][j]); + bool found2=false; + for(int k=0;k MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception) +{ + if(its.empty()) + return std::vector(); + CheckFileForRead(fileName); + std::vector ret(its.size()); + if(its.empty()) + return ret; + //Retrieving mesh of rank 0 and field on rank 0 too. + std::list fieldPerCellType; + double time; + std::vector infos; + MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[0].first,its[0].second,type,fieldPerCellType,time,infos); + std::vector familiesToKeep; + std::vector typesToKeep; + if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE) + for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) + typesToKeep.push_back((*iter).getType()); + unsigned meshDim; + int *cellRenum; + ParaMEDMEM::MEDCouplingUMesh *m1=MEDLoaderNS::readUMeshFromFileLev1(fileName,meshName,meshDimRelToMax,familiesToKeep,typesToKeep,meshDim,cellRenum); + ret[0]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[0].first,its[0].second,time,fieldPerCellType); + if(cellRenum) + m1->renumberCells(cellRenum,true); + MEDLoaderNS::releaseMEDFileCoreFrmt(fieldPerCellType); + // + for(int itId=1;itId<(int)its.size();itId++) + { + std::list fieldPerCellType; + double time; + std::vector infos; + MEDLoaderNS::readFieldDoubleDataInMedFile(fileName,meshName,fieldName,its[itId].first,its[itId].second,type,fieldPerCellType,time,infos); + std::vector familiesToKeep; + std::vector typesToKeep; + if(type==ON_CELLS || type==ON_GAUSS_PT || type==ON_GAUSS_NE) + for(std::list::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++) + typesToKeep.push_back((*iter).getType()); + ret[itId]=MEDLoaderNS::readFieldDoubleLev2(fileName,type,meshDim,cellRenum,m1,infos,fieldName,its[itId].first,its[itId].second,time,fieldPerCellType); + //clean-up + MEDLoaderNS::releaseMEDFileCoreFrmt(fieldPerCellType); + } + m1->decrRef(); + delete [] cellRenum; + return ret; +} + +std::vector MEDLoader::ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception) +{ + return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector MEDLoader::ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception) +{ + return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector MEDLoader::ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception) +{ + return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector MEDLoader::ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception) +{ + return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its); } -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_CELLS); } -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) { return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_NODES); } -void MEDLoaderNS::writeUMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool forceFromScratch) +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) +{ + return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_PT); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception) +{ + return MEDLoaderNS::readFieldDoubleLev1(fileName,meshName,meshDimRelToMax,fieldName,iteration,order,ON_GAUSS_NE); +} + +/*! + * @param families input parameter that specifies the field on int on each cells of 'mesh'. + * @param isRenumbering output parameter that specifies if a renumbering of mesh has been needed. + */ +void MEDLoaderNS::writeUMeshesDirectly(const char *fileName, const std::vector& mesh, const std::vector& families, bool forceFromScratch, bool &isRenumbering) { med_idt fid=MEDouvrir((char *)fileName,forceFromScratch?MED_CREATION:MED_LECTURE_ECRITURE); - std::string meshName(mesh->getName()); + std::string meshName(mesh[0]->getName()); if(meshName=="") { MEDfermer(fid); throw INTERP_KERNEL::Exception("MEDCouplingMesh must have a not null name !"); } - char maa[MED_TAILLE_NOM+1]; - strcpy(maa,meshName.c_str()); - MEDmaaCr(fid,maa,mesh->getSpaceDimension(),MED_NON_STRUCTURE,maa); - std::set allTypes(mesh->getAllTypes()); - DataArrayInt *conn=mesh->getNodalConnectivity(); - DataArrayInt *connIndex=mesh->getNodalConnectivityIndex(); - char familyName[MED_TAILLE_NOM+1]; - std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); - const char DftFamilyName[]="DftFamily"; - std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); - for(int i=0;i conn; + std::vector connIndex; + std::set allTypes; + for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) { - med_geometrie_element curMedType=typmai[i]; - INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; - if(allTypes.find(curType)!=allTypes.end()) + isRenumbering|=!(*iter)->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + isFamilies&=(families[std::distance(mesh.begin(),iter)]!=0); + conn.push_back((*iter)->getNodalConnectivity()); + connIndex.push_back((*iter)->getNodalConnectivityIndex()); + const std::set& curTypes=(*iter)->getAllTypes(); + allTypes.insert(curTypes.begin(),curTypes.end()); + } + char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + char *desc=MEDLoaderBase::buildEmptyString(MED_TAILLE_DESC); + MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(meshName.c_str(),MED_TAILLE_DESC,desc,MEDLoader::_TOO_LONG_STR); + const int spaceDim=mesh[0]->getSpaceDimension(); + MEDmaaCr(fid,maa,spaceDim,MED_NON_STRUCTURE,desc); + MEDdimEspaceCr(fid,maa,spaceDim); + for(std::vector::const_iterator iter=mesh.begin();iter!=mesh.end();iter++) + { + for(int i=0;i medConn; - std::vector medConnIndex; - std::vector medConnIndex2; - int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,curType,medConn,medConnIndex,medConnIndex2); - if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) - MEDconnEcr(fid,maa,mesh->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); - else + med_geometrie_element curMedType=typmai[i]; + INTERP_KERNEL::NormalizedCellType curType=typmai2[i]; + if(allTypes.find(curType)!=allTypes.end()) { - if(curMedType==MED_POLYGONE) - MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); + std::vector medConn; + std::vector medConnIndex; + std::vector medConnIndex2; + std::vector fam; + std::vector renumber; + int nbOfElt=MEDLoaderNS::buildMEDSubConnectivityOfOneType(conn,connIndex,families,curType,medConn,medConnIndex,medConnIndex2,fam,renumber); + if(curMedType!=MED_POLYGONE && curMedType!=MED_POLYEDRE) + MEDconnEcr(fid,maa,(*iter)->getMeshDimension(),&medConn[0],MED_FULL_INTERLACE,nbOfElt,MED_MAILLE,curMedType,MED_NOD); + else + { + if(curMedType==MED_POLYGONE) + MEDpolygoneConnEcr(fid,maa,&medConnIndex[0],medConnIndex.size(),&medConn[0],MED_MAILLE,MED_NOD); + if(curMedType==MED_POLYEDRE) + { + MEDpolyedreConnEcr(fid,maa,&medConnIndex2[0],medConnIndex2.size(),&medConnIndex[0],medConnIndex.size(), + &medConn[0],MED_NOD); + } + } + if(isFamilies) + MEDfamEcr(fid,maa,&fam[0],nbOfElt,MED_MAILLE,curMedType); + if(isRenumbering) + MEDnumEcr(fid,maa,&renumber[0],nbOfElt,MED_MAILLE,curMedType); } } } + char familyName[MED_TAILLE_NOM+1]; + std::fill(familyName,familyName+MED_TAILLE_NOM+1,'\0'); + const char DftFamilyName[]="DftFamily"; + std::copy(DftFamilyName,DftFamilyName+sizeof(DftFamilyName),familyName); MEDfamCr(fid,maa,familyName,0,0,0,0,0,0,0); - DataArrayDouble *arr=mesh->getCoords(); - char comp[2*MED_TAILLE_PNOM+1]; - char unit[2*MED_TAILLE_PNOM+1]; - std::fill(comp,comp+2*MED_TAILLE_PNOM,' '); - comp[2*MED_TAILLE_PNOM]='\0'; - char *work=comp; - for(int i=0;igetSpaceDimension();i++,work+=3) - *work='X'+i; - std::fill(unit,unit+2*MED_TAILLE_PNOM+1,'\0'); - MEDcoordEcr(fid,maa,mesh->getSpaceDimension(),arr->getPointer(),MED_FULL_INTERLACE,mesh->getNumberOfNodes(),MED_CART,comp,unit); + DataArrayDouble *arr=mesh[0]->getCoords(); + char *comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); + char *unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_TAILLE_PNOM); + for(int i=0;igetInfoOnComponent(i); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDcoordEcr(fid,maa,spaceDim,arr->getPointer(),MED_FULL_INTERLACE,mesh[0]->getNumberOfNodes(),MED_CART,comp,unit); + delete [] comp; + delete [] unit; + delete [] maa; + delete [] desc; MEDfermer(fid); } -void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f) +/*! + * In this method meshes are assumed to shared the same coords. + * This method makes the assumption that 'meshes' is not empty, no check on that is done (responsability of the caller) + */ +void MEDLoaderNS::writeUMeshesPartitionDirectly(const char *fileName, const char *meshName, const std::vector& meshes, bool forceFromScratch) +{ + std::string meshNameCpp(meshName); + char *maa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(meshName,MED_TAILLE_NOM,maa,MEDLoader::_TOO_LONG_STR); + if(meshNameCpp=="") + throw INTERP_KERNEL::Exception("writeUMeshesPartitionDirectly : Invalid meshName : Must be different from \"\" !"); + std::vector< DataArrayInt * > corr; + MEDCouplingUMesh *m=ParaMEDMEM::MEDCouplingUMesh::fuseUMeshesOnSameCoords(meshes,0,corr); + m->setName(meshName); + std::vector< std::vector > fidsOfGroups; + DataArrayInt *arr2=DataArrayInt::makePartition(corr,m->getNumberOfCells(),fidsOfGroups); + for(std::vector< DataArrayInt * >::iterator it=corr.begin();it!=corr.end();it++) + (*it)->decrRef(); + bool isRenumbering; + std::vector mv(1); mv[0]=m; + std::vector famv(1); famv[0]=arr2; + writeUMeshesDirectly(fileName,mv,famv,forceFromScratch,isRenumbering); + // families creation + std::set familyIds; + for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + familyIds.insert(*it2); + std::vector< std::vector > gidsOfFamilies(familyIds.size()); + int fid=0; + for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) + { + int gid=0; + for(std::vector< std::vector >::const_iterator it1=fidsOfGroups.begin();it1!=fidsOfGroups.end();it1++,gid++) + for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + if(*it2==*it) + gidsOfFamilies[fid].push_back(gid); + } + fid=0; + med_idt fid2=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE); + for(std::set::const_iterator it=familyIds.begin();it!=familyIds.end();it++,fid++) + { + int ngro=gidsOfFamilies[fid].size(); + char *groName=MEDLoaderBase::buildEmptyString(MED_TAILLE_LNOM*ngro); + for(int i=0;igetName(),MED_TAILLE_LNOM-1,groName+i*MED_TAILLE_LNOM,MEDLoader::_TOO_LONG_STR);//MED_TAILLE_LNOM-1 to avoid to write '\0' on next compo + std::ostringstream oss; oss << "Family_" << *it; + char *famName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,famName,MEDLoader::_TOO_LONG_STR); + MEDfamCr(fid2,maa,famName,*it,0,0,0,0,groName,ngro); + delete [] famName; + delete [] groName; + } + MEDfermer(fid2); + // end families creation + delete [] maa; + arr2->decrRef(); + m->decrRef(); +} + +/*! + * This method makes the assumption that f->getMesh() nodes are fully included in already written mesh in 'fileName'. + * @param thisMeshNodeIds points to a tab of size f->getMesh()->getNumberOfNodes() that says for a node i in f->getMesh() that its id is thisMeshNodeIds[i] is already written mesh. + */ +void MEDLoaderNS::appendNodeProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshNodeIds) +{ + med_int numdt,numo; + med_float dt; + char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); + med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); + int nbOfNodes=f->getMesh()->getNumberOfNodes(); + const double *pt=f->getArray()->getConstPointer(); + int *profile=new int[nbOfNodes]; + std::ostringstream oss; oss << "Pfln" << f->getName(); + char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR); + std::transform(thisMeshNodeIds,thisMeshNodeIds+nbOfNodes,profile,std::bind2nd(std::plus(),1)); + MEDprofilEcr(fid,profile,nbOfNodes,profileName); + delete [] profile; + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfNodes, + (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_NOEUD, + MED_NONE,numdt,(char *)"",dt,numo); + delete [] profileName; + delete [] nommaa; + MEDfermer(fid); +} + +/*! + * This method makes the assumption that f->getMesh() cells are fully included in already written mesh in 'fileName'. + * @param thisMeshCellIdsPerType points to a tab of size f->getMesh()->getNumberOfCells() that says for a cell i in f->getMesh() that its id is thisMeshCellIds[i] of corresponding type is already written mesh. + */ +void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *thisMeshCellIdsPerType) +{ + med_int numdt,numo; + med_float dt; + int nbComp=f->getNumberOfComponents(); + med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); + std::list split; + prepareCellFieldDoubleForWriting(f,thisMeshCellIdsPerType,split); + const double *pt=f->getArray()->getConstPointer(); + int number=0; + for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) + { + char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); + char *profileName=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++; + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,profileName,MEDLoader::_TOO_LONG_STR); + const std::vector& ids=(*iter).getCellIdPerType(); + int *profile=new int [ids.size()]; + std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus(),1)); + MEDprofilEcr(fid,profile,ids.size(),profileName); + delete [] profile; + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(), + (char *)MED_NOGAUSS,MED_ALL,profileName,MED_COMPACT,MED_MAILLE, + typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + delete [] profileName; + delete [] nommaa; + pt+=(*iter).getNbOfTuple()*nbComp; + } + MEDfermer(fid); +} + +/*! + * This method performs the classical job for fields before any values setting. + */ +med_idt MEDLoaderNS::appendFieldSimpleAtt(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, med_int& numdt, med_int& numo, med_float& dt) { med_idt fid=MEDouvrir((char *)fileName,MED_LECTURE_ECRITURE); int nbComp=f->getNumberOfComponents(); - char *comp=new char[nbComp*MED_TAILLE_PNOM+1]; - std::fill(comp,comp+nbComp*MED_TAILLE_PNOM,' '); - comp[nbComp*MED_TAILLE_PNOM]='\0'; - char *unit=new char[nbComp*MED_TAILLE_PNOM+1]; - std::fill(unit,unit+nbComp*MED_TAILLE_PNOM,' '); - unit[nbComp*MED_TAILLE_PNOM]='\0'; + char *comp=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM); + char *unit=MEDLoaderBase::buildEmptyString(nbComp*MED_TAILLE_PNOM); + for(int i=0;igetArray()->getInfoOnComponent(i); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy(c.c_str(),MED_TAILLE_PNOM-1,comp+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR); + MEDLoaderBase::safeStrCpy(u.c_str(),MED_TAILLE_PNOM-1,unit+i*MED_TAILLE_PNOM,MEDLoader::_TOO_LONG_STR); + } MEDchampCr(fid,(char *)f->getName(),MED_FLOAT64,comp,unit,nbComp); - med_int numdt,numo; - med_float dt; ParaMEDMEM::TypeOfTimeDiscretization td=f->getTimeDiscretization(); if(td==ParaMEDMEM::NO_TIME) { @@ -1196,19 +2327,45 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCoupl numdt=(med_int)tmp1; numo=(med_int)tmp2; dt=(med_float)tmp0; } + delete [] comp; + delete [] unit; + return fid; +} + +void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f2) +{ + med_int numdt,numo; + med_float dt; + //renumbering + const ParaMEDMEM::MEDCouplingFieldDouble *f=f2; + const MEDCouplingMesh *mesh=f->getMesh(); + const MEDCouplingUMesh *meshC=dynamic_cast(mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); + bool renum=!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + if(renum) + { + ParaMEDMEM::MEDCouplingFieldDouble *f3=f2->clone(true); + DataArrayInt *da=meshC->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + f3->renumberCells(da->getConstPointer(),false); + da->decrRef(); + f=f3; + } + //end renumbering + int nbComp=f->getNumberOfComponents(); + med_idt fid=appendFieldSimpleAtt(fileName,f,numdt,numo,dt); const double *pt=f->getArray()->getConstPointer(); + char *nommaa=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + MEDLoaderBase::safeStrCpy(f->getMesh()->getName(),MED_TAILLE_NOM,nommaa,MEDLoader::_TOO_LONG_STR); switch(f->getTypeOfField()) { case ParaMEDMEM::ON_CELLS: { std::list split; - prepareCellFieldDoubleForWriting(f,split); + prepareCellFieldDoubleForWriting(f,0,split); for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) { - char nommaa[MED_TAILLE_NOM+1]; - std::fill(nommaa,nommaa+MED_TAILLE_NOM,' '); nommaa[MED_TAILLE_NOM]='\0'; - strcpy(nommaa,f->getMesh()->getName()); - MEDchampEcr(fid,(char *)nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(), + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,(*iter).getNbOfTuple(), (char *)MED_NOGAUSS,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); pt+=(*iter).getNbOfTuple()*nbComp; @@ -1218,42 +2375,94 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, ParaMEDMEM::MEDCoupl case ParaMEDMEM::ON_NODES: { int nbOfTuples=f->getArray()->getNumberOfTuples(); - MEDchampEcr(fid,(char *)f->getMesh()->getName(),(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfTuples,(char *)MED_NOGAUSS, + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfTuples,(char *)MED_NOGAUSS, MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_NOEUD,MED_NONE,numdt,(char *)"",dt,numo); break; } + case ParaMEDMEM::ON_GAUSS_PT: + { + std::list split; + prepareCellFieldDoubleForWriting(f,0,split); + int idGp=0; + for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) + { + char *nomGauss=MEDLoaderBase::buildEmptyString(MED_TAILLE_NOM); + std::ostringstream oss; oss << "GP_" << f->getName() << idGp++; + MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_TAILLE_NOM,nomGauss,MEDLoader::_TOO_LONG_STR); + int id=f->getGaussLocalizationIdOfOneType((*iter).getType()); + const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id); + MEDgaussEcr(fid,typmai3[(int)(*iter).getType()],(med_float*)&gl.getRefCoords()[0],MED_FULL_INTERLACE,gl.getNumberOfGaussPt(), + (med_float*)&gl.getGaussCoords()[0], + (med_float*)&gl.getWeights()[0],nomGauss); + int nbOfValues=gl.getNumberOfGaussPt()*f->getMesh()->getNumberOfCellsWithType((*iter).getType()); + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues, + nomGauss,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, + typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + pt+=nbOfValues*nbComp; + delete [] nomGauss; + } + break; + } + case ParaMEDMEM::ON_GAUSS_NE: + { + std::list split; + prepareCellFieldDoubleForWriting(f,0,split); + for(std::list::const_iterator iter=split.begin();iter!=split.end();iter++) + { + int nbPtPerCell=(int)INTERP_KERNEL::CellModel::getCellModel((*iter).getType()).getNumberOfNodes(); + int nbOfValues=nbPtPerCell*f->getMesh()->getNumberOfCellsWithType((*iter).getType()); + MEDchampEcr(fid,nommaa,(char *)f->getName(),(unsigned char*)pt,MED_FULL_INTERLACE,nbOfValues, + (char *)MED_GAUSS_ELNO,MED_ALL,(char *)MED_NOPFL,MED_NO_PFLMOD,MED_MAILLE, + typmai3[(int)(*iter).getType()],numdt,(char *)"",dt,numo); + pt+=nbOfValues*nbComp; + } + break; + } default: throw INTERP_KERNEL::Exception("Not managed this type of FIELD !"); } - delete [] comp; - delete [] unit; + delete [] nommaa; MEDfermer(fid); + if(renum) + ((ParaMEDMEM::MEDCouplingFieldDouble *)f)->decrRef(); } -void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, std::list& split) +/*! + * This method splits field 'f' into types to be ready for writing. + * @param cellIdsPerType this parameter can be 0 if not in profile mode. If it is != 0 this array is of size f->getMesh()->getNumberOfCells(). + */ +void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCouplingFieldDouble *f, const int *cellIdsPerType, std::list& split) { int nbComp=f->getNumberOfComponents(); const MEDCouplingMesh *mesh=f->getMesh(); const MEDCouplingUMesh *meshC=dynamic_cast(mesh); if(!meshC) throw INTERP_KERNEL::Exception("Not implemented yet for not unstructured mesh !"); - if(!meshC->checkConsecutiveCellTypes()) + if(!meshC->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2)) throw INTERP_KERNEL::Exception("Unstructuded mesh has not consecutive cell types !"); const int *connI=meshC->getNodalConnectivityIndex()->getConstPointer(); const int *conn=meshC->getNodalConnectivity()->getConstPointer(); int nbOfCells=meshC->getNumberOfCells(); INTERP_KERNEL::NormalizedCellType curType; + const int *wCellIdsPT=cellIdsPerType; for(const int *pt=connI;pt!=connI+nbOfCells;) { curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt]; const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType)); - split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt)); + if(!cellIdsPerType) + split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,0,0)); + else + { + split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,wCellIdsPT,0)); + wCellIdsPT+=std::distance(pt,pt2); + } pt=pt2; } } -void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch) +void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool forceFromScratch) { + f->checkCoherency(); std::string meshName(f->getMesh()->getName()); if(meshName.empty()) throw INTERP_KERNEL::Exception("Trying to write a mesh (f->getMesh()) with no name ! MED file format needs a not empty mesh name !"); @@ -1261,47 +2470,304 @@ void MEDLoaderNS::writeFieldAndMeshDirectly(const char *fileName, ParaMEDMEM::ME if(fieldName.empty()) throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !"); MEDCouplingUMesh *mesh=dynamic_cast((MEDCouplingMesh *)f->getMesh()); - writeUMeshDirectly(fileName,mesh,forceFromScratch); - appendFieldDirectly(fileName,f); + if(mesh) + { + bool isRenumbering; + std::vector meshV(1); meshV[0]=mesh; + std::vector famV(1); famV[0]=0; + writeUMeshesDirectly(fileName,meshV,famV,forceFromScratch,isRenumbering); + if(isRenumbering) + { + ParaMEDMEM::MEDCouplingFieldDouble *f2=f->clone(true); + DataArrayInt *da=mesh->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_NBR_GEOMETRIE_MAILLE+2); + f2->renumberCells(da->getConstPointer(),false); + da->decrRef(); + appendFieldDirectly(fileName,f2); + f2->decrRef(); + } + else + appendFieldDirectly(fileName,f); + return ; + } + throw INTERP_KERNEL::Exception("The mesh underlying field is not unstructured ! Only unstructured mesh supported for writting now !"); } -void MEDLoader::WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) +/*! + * When called this method expectes that file 'fileName' is already existing and has a mesh with name equal to + * f->getMesh()->getName(). If not the behaviour of this method is not warranted. + * This method reads the corresponding mesh into the file and try to fit it with f->getMesh(). + * If it appears that f->getMesh() equals exactly mesh into the file + */ +void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) +{ + std::vector poss; + int mDimInFile=MEDLoaderNS::readUMeshDimFromFile(fileName,f->getMesh()->getName(),poss); + int mdim=f->getMesh()->getMeshDimension(); + int f2=mdim-mDimInFile; + if(std::find(poss.begin(),poss.end(),f2)==poss.end()) + { + std::ostringstream oss; oss << "Trying to fit with the existing \"" << f->getMesh()->getName() << "mesh in file \"" << fileName; + oss << "\" but meshdimension does not match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingUMesh *m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2); + MEDCouplingUMesh *m2=MEDCouplingUMesh::mergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh()); + bool areNodesMerged; + int newNbOfNodes; + DataArrayInt *da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes); + if(!areNodesMerged || newNbOfNodes!=m->getNumberOfNodes()) + { + da->decrRef(); + m2->decrRef(); + m->decrRef(); + std::ostringstream oss; oss << "Nodes in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit coordinates of unstructured grid f->getMesh() !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + switch(f->getTypeOfField()) + { + case ParaMEDMEM::ON_CELLS: + { + da->decrRef(); + DataArrayInt *da2=m2->zipConnectivityTraducer(MEDLoader::_COMP_FOR_CELL); + if(m2->getNumberOfCells()!=m->getNumberOfCells()) + { + da2->decrRef(); + m2->decrRef(); + m->decrRef(); + std::ostringstream oss1; oss1 << "Cells in already written mesh \"" << f->getMesh()->getName() << "\" in file \"" << fileName << "\" does not fit connectivity of unstructured grid f->getMesh() !"; + throw INTERP_KERNEL::Exception(oss1.str().c_str()); + } + da=m2->convertCellArrayPerGeoType(da2); + DataArrayInt *da3=da->substr(m2->getNumberOfCells()); + da2->decrRef(); + da2=m2->convertCellArrayPerGeoType(da3); + da3->decrRef(); + appendCellProfileField(fileName,f,da2->getConstPointer()); + da2->decrRef(); + break; + } + case ParaMEDMEM::ON_NODES: + { + appendNodeProfileField(fileName,f,da->getConstPointer()+m->getNumberOfNodes()); + break; + } + default: + { + da->decrRef(); + m2->decrRef(); + m->decrRef(); + throw INTERP_KERNEL::Exception("Not implemented other profile fitting from already written mesh for fields than on NODES and on CELLS."); + } + } + da->decrRef(); + m2->decrRef(); + m->decrRef(); +} + +void MEDLoader::WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { std::string meshName(mesh->getName()); if(meshName.empty()) throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !"); int status=MEDLoaderBase::getStatusOfFile(fileName); + bool isRenumbering; if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) { std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + std::vector meshV(1); meshV[0]=mesh; + std::vector famV(1); famV[0]=0; if(writeFromScratch) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true); + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); return ; } if(status==MEDLoaderBase::NOT_EXIST) { - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,true); + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); return; } else { std::vector meshNames=GetMeshNames(fileName); - std::string fileNameCpp(mesh->getName()); - if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) - MEDLoaderNS::writeUMeshDirectly(fileName,mesh,false); + if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering); + else + { + std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; + oss << meshName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDLoader::WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + std::string meshName(mesh->getName()); + if(meshName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name !"); + int status=MEDLoaderBase::getStatusOfFile(fileName); + bool isRenumbering; + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector meshV(1); meshV[0]=mesh; + std::vector famV(1); famV[0]=0; + if(writeFromScratch) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); + return ; + } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,true,isRenumbering); + return; + } + else + MEDLoaderNS::writeUMeshesDirectly(fileName,meshV,famV,false,isRenumbering); +} + +void MEDLoader::WriteUMeshesPartition(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + std::string meshName(meshNameC); + if(meshName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !"); + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshes.empty()) + throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); + DataArrayDouble *coords=meshes.front()->getCoords(); + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); + std::set tmp; + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + { + if(tmp.find((*iter)->getName())==tmp.end()) + tmp.insert((*iter)->getName()); + else + throw INTERP_KERNEL::Exception("The names of meshes must be different each other !"); + } + tmp.clear(); + if(writeFromScratch) + { + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); + return ; + } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); + return; + } + else + { + std::vector meshNames=GetMeshNames(fileName); + if(std::find(meshNames.begin(),meshNames.end(),meshName)==meshNames.end()) + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false); else { std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; - oss << fileNameCpp << "\" !"; + oss << meshName << "\" !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } } } -void MEDLoader::WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) +void MEDLoader::WriteUMeshesPartitionDep(const char *fileName, const char *meshNameC, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + std::string meshName(meshNameC); + if(meshName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !"); + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshes.empty()) + throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); + DataArrayDouble *coords=meshes.front()->getCoords(); + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); + std::set tmp; + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + { + if(tmp.find((*iter)->getName())==tmp.end()) + tmp.insert((*iter)->getName()); + else + throw INTERP_KERNEL::Exception("The names of meshes must be different each other !"); + } + tmp.clear(); + if(writeFromScratch) + { + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); + return ; + } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,true); + return; + } + else + { + MEDLoaderNS::writeUMeshesPartitionDirectly(fileName,meshNameC,meshes,false); + } +} + +void MEDLoader::WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshes.empty()) + throw INTERP_KERNEL::Exception("List of meshes must be not empty !"); + std::string meshName(meshes[0]->getName()); + if(meshName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change name of first element of 2nd parameter !"); + DataArrayDouble *coords=meshes.front()->getCoords(); + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("Meshes does not not share the same coordinates : try method MEDCouplingPointSet::tryToShareSameCoords !"); + std::set tmp; + for(std::vector::const_iterator iter=meshes.begin();iter!=meshes.end();iter++) + { + if(tmp.find((*iter)->getMeshDimension())==tmp.end()) + tmp.insert((*iter)->getMeshDimension()); + else + throw INTERP_KERNEL::Exception("The mesh dimension of meshes must be different each other !"); + } + tmp.clear(); + bool isRenumbering; + std::vector families(meshes.size()); + if(writeFromScratch) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); + return ; + } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,true,isRenumbering); + return; + } + else + { + MEDLoaderNS::writeUMeshesDirectly(fileName,meshes,families,false,isRenumbering); + return; + } +} + +void MEDLoader::WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception) { int status=MEDLoaderBase::getStatusOfFile(fileName); if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) @@ -1326,15 +2792,33 @@ void MEDLoader::WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDou if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); else - { - std::ostringstream oss; oss << "File \'" << fileName << "\' already exists and has already a mesh called \""; - oss << fileNameCpp << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } + MEDLoaderNS::writeFieldTryingToFitExistingMesh(fileName,f); + } +} + +void MEDLoader::WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception) +{ + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(writeFromScratch) + { + MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); + return ; } + if(status==MEDLoaderBase::NOT_EXIST) + { + MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,true); + return ; + } + else + MEDLoaderNS::writeFieldAndMeshDirectly(fileName,f,false); } -void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f) +void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception) { f->checkCoherency(); int status=MEDLoaderBase::getStatusOfFile(fileName); @@ -1343,5 +2827,8 @@ void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDM std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + std::string fieldName(f->getName()); + if(fieldName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a field with no name ! MED file format needs a not empty field name !"); MEDLoaderNS::appendFieldDirectly(fileName,f); } diff --git a/src/MEDLoader/MEDLoader.hxx b/src/MEDLoader/MEDLoader.hxx index cb2f74381..b90cad0f7 100644 --- a/src/MEDLoader/MEDLoader.hxx +++ b/src/MEDLoader/MEDLoader.hxx @@ -20,7 +20,9 @@ #ifndef __MEDLOADER_HXX__ #define __MEDLOADER_HXX__ +#include "MEDLoaderDefines.hxx" #include "InterpKernelException.hxx" +#include "MEDCouplingRefCountObject.hxx" #include "NormalizedUnstructuredMesh.hxx" #include @@ -33,9 +35,9 @@ namespace ParaMEDMEM class MEDCouplingFieldDouble; } -class MEDLoader +class MEDLOADER_EXPORT MEDLoader { -public: + public: class MEDConnOfOneElemType { public: @@ -47,6 +49,7 @@ public: int *getIndex() const { return _index; } int *getFam() const { return _fam; } void setGlobal(int *global); + const int *getGlobal() const { return _global; } void releaseArray(); private: int _lgth; @@ -61,38 +64,77 @@ public: class MEDFieldDoublePerCellType { public: - MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple); + MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple, const int *cellIdPerType, const char *locName); INTERP_KERNEL::NormalizedCellType getType() const { return _type; } int getNbComp() const { return _ncomp; } int getNbOfTuple() const { return _ntuple; } int getNbOfValues() const { return _ncomp*_ntuple; } double *getArray() const { return _values; } + const std::string& getLocName() const { return _loc_name; } + const std::vector& getCellIdPerType() const { return _cell_id_per_type; } void releaseArray(); private: int _ntuple; int _ncomp; double *_values; + std::string _loc_name; + std::vector _cell_id_per_type; INTERP_KERNEL::NormalizedCellType _type; }; // - static std::vector GetMeshNames(const char *fileName); - static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName); - static std::vector GetMeshFamilyNames(const char *fileName, const char *meshName); - static std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName); - static std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName); - static std::vector< std::pair > GetCellFieldIterations(const char *fileName, const char *fieldName); - static std::vector< std::pair > GetNodeFieldIterations(const char *fileName, const char *fieldName); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps); + static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); + static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); + static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); + static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector< std::pair > GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static std::vector< std::pair > GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static std::vector< std::pair > GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static std::vector< std::pair< std::pair, double> > GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static double GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); - static void WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f); -private: + static int ReadUMeshDimFromFile(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static std::vector ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception); + static std::vector ReadFieldsCellOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception); + static std::vector ReadFieldsNodeOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception); + static std::vector ReadFieldsGaussOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception); + static std::vector ReadFieldsGaussNEOnSameMesh(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, + const std::vector >& its) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static void WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshesPartition(const char *fileName, const char *meshName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshesPartitionDep(const char *fileName, const char *meshName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshes(const char *fileName, const std::vector& meshes, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); + private: MEDLoader(); + public: + static double _EPS_FOR_NODE_COMP; + static int _COMP_FOR_CELL; + static int _TOO_LONG_STR; }; #endif diff --git a/src/MEDLoader/MEDLoaderBase.cxx b/src/MEDLoader/MEDLoaderBase.cxx index ec50466fd..14c33ac1e 100644 --- a/src/MEDLoader/MEDLoaderBase.cxx +++ b/src/MEDLoader/MEDLoaderBase.cxx @@ -20,42 +20,154 @@ #include "MEDLoaderBase.hxx" #include "InterpKernelException.hxx" +#include #include +#include +#include + +const char MEDLoaderBase::WHITE_SPACES[]=" \n"; int MEDLoaderBase::getStatusOfFile(const char *fileName) { std::ifstream ifs; ifs.open(fileName); - unsigned int res=0; if((ifs.rdstate() & std::ifstream::failbit)!=0) { - res+=1; ifs.close(); + return NOT_EXIST; } std::ofstream ofs(fileName,std::ios_base::app); if((ofs.rdstate() & std::ofstream::failbit)!=0) { - ofs.close(); - res+=2; + return EXIST_RDONLY; } - switch(res) + return EXIST_RW; +} + +char *MEDLoaderBase::buildEmptyString(int lgth) +{ + char *ret=new char[lgth+1]; + std::fill(ret,ret+lgth,' '); + ret[lgth]='\0'; + return ret; +} + +std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth) +{ + std::string ret(buildStringFromFortran(name,nameLgth)); + std::string unitCpp(buildStringFromFortran(unit,unitLgth)); + if(unitCpp[0]=='\0') + return ret; + ret+=" ("; + ret+=unitCpp; + ret+=")"; + return ret; +} + +void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit) +{ + std::string::size_type f1=s.find_first_of('('); + std::string::size_type f2=s.find_last_of(')'); + if(f1!=std::string::npos && f2!=std::string::npos) { - case 0: - return EXIST_RW; - case 1: - { - std::ifstream ifs2; - ifs2.open(fileName); - if((ifs2.rdstate() & std::ifstream::failbit)!=0) - return EXIST_WRONLY; - else - return NOT_EXIST; - } - case 2: - return EXIST_RDONLY; - case 3: - return DIR_LOCKED; - default: - throw INTERP_KERNEL::Exception("Internal error !"); + if(f1maxLgth) + { + if(behaviour==0 || behaviour>1) + { + std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else if(behaviour==1) + { + std::string s=zipString(src,maxLgth); + std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; + std::cerr << "zipping to : " << s << "\n"; + strcpy(dest,s.c_str()); + return ; + } + } + strcpy(dest,src); +} + +std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth) +{ + std::string ret(expr,lgth); + std::string whiteSpaces(WHITE_SPACES); + std::size_t lgthReal=strlen(ret.c_str()); + std::string ret2=ret.substr(0,lgthReal); + std::size_t found=ret2.find_last_not_of(whiteSpaces); + if (found!=std::string::npos) + ret2.erase(found+1); + else + ret2.clear();//ret is all whitespace + return ret2; +} + +/*! + * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string. + * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed. + */ +std::string MEDLoaderBase::zipString(const char *src, int sizeToRespect) +{ + std::string s(src); + strip(s); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + zipEqualConsChar(s,3); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + zipEqualConsChar(s,2); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + return s.substr(0,sizeToRespect); +} + +/*! + * This method see if there is in 's' more than 'minConsSmChar' consecutive same character. + * If yes, the group will be zipped using only one character for this group. + * If no such group is found, s remains unchanged. + */ +void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar) +{ + for(std::string::iterator it=s.begin();it!=s.end();it++) + { + char tmp=*it; + int sz=1; + for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++) + sz++; + if(sz>=minConsSmChar) + s.erase(it+1,it+sz); } } + diff --git a/src/MEDLoader/MEDLoaderBase.hxx b/src/MEDLoader/MEDLoaderBase.hxx index 06df9422b..09e0c5850 100644 --- a/src/MEDLoader/MEDLoaderBase.hxx +++ b/src/MEDLoader/MEDLoaderBase.hxx @@ -20,16 +20,30 @@ #ifndef __MEDLOADERBASE_HXX__ #define __MEDLOADERBASE_HXX__ -class MEDLoaderBase +#include "MEDLoaderDefines.hxx" +#include "InterpKernelException.hxx" + +#include + +class MEDLOADER_EXPORT MEDLoaderBase { public: static int getStatusOfFile(const char *fileName); + static char *buildEmptyString(int lgth); + static std::string buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth); + static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit); + static void strip(std::string& s); + static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour) throw(INTERP_KERNEL::Exception); + static std::string buildStringFromFortran(const char *expr, int lgth); + static void zipEqualConsChar(std::string& s, int minConsSmChar); + static std::string zipString(const char *src, int sizeToRespect); public: static const int EXIST_RW=0; static const int NOT_EXIST=1; static const int EXIST_RDONLY=2; static const int EXIST_WRONLY=3; static const int DIR_LOCKED=4; + static const char WHITE_SPACES[]; }; #endif diff --git a/src/MEDLoader/MEDLoaderDefines.hxx b/src/MEDLoader/MEDLoaderDefines.hxx new file mode 100644 index 000000000..656caa4d5 --- /dev/null +++ b/src/MEDLoader/MEDLoaderDefines.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDLOADERDEFINES_HXX__ +#define __MEDLOADERDEFINES_HXX__ + +#ifdef WIN32 +# if defined medloader_EXPORTS +# define MEDLOADER_EXPORT __declspec(dllexport) +# else +# define MEDLOADER_EXPORT __declspec(dllimport) +# endif +#else +# define MEDLOADER_EXPORT +#endif + +#endif diff --git a/src/MEDLoader/Makefile.am b/src/MEDLoader/Makefile.am index bc5acc7e0..3a2fbb760 100755 --- a/src/MEDLoader/Makefile.am +++ b/src/MEDLoader/Makefile.am @@ -19,26 +19,33 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am +MEDLOADER_SUBDIRS = + if !MED_ENABLE_MICROMED - SUBDIRS = . Swig + MEDLOADER_SUBDIRS += . Swig +if CPPUNIT_IS_OK + MEDLOADER_SUBDIRS += Test +endif endif +SUBDIRS = $(MEDLOADER_SUBDIRS) + #DIST_SUBDIRS = Swig lib_LTLIBRARIES = libmedloader.la salomeinclude_HEADERS= \ +MEDLoaderDefines.hxx \ MEDLoader.hxx MEDLoaderBase.hxx dist_libmedloader_la_SOURCES= \ MEDLoader.cxx MEDLoaderBase.cxx -libmedloader_la_CPPFLAGS= $(MPI_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ +libmedloader_la_CPPFLAGS= $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ -I$(srcdir)/../INTERP_KERNEL \ -I$(srcdir)/../INTERP_KERNEL/Geometric2D \ -I$(srcdir)/../INTERP_KERNEL/Bases \ -I$(srcdir)/../MEDCoupling -# change motivated by the bug KERNEL4778. libmedloader_la_LDFLAGS= ../MEDCoupling/libmedcoupling.la \ -../INTERP_KERNEL/libinterpkernel.la $(MPI_LIBS) $(MED2_LIBS) $(HDF5_LIBS) +../INTERP_KERNEL/libinterpkernel.la $(MED2_LIBS) $(HDF5_LIBS) diff --git a/src/MEDLoader/Swig/MEDLoaderDataForTest.py b/src/MEDLoader/Swig/MEDLoaderDataForTest.py new file mode 100644 index 000000000..2ec4ac837 --- /dev/null +++ b/src/MEDLoader/Swig/MEDLoaderDataForTest.py @@ -0,0 +1,304 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D +# +# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from libMEDLoader_Swig import * +from math import pi,e,sqrt + +class MEDLoaderDataForTest: + def build1DMesh_1(cls): + coords=[ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 ] + conn=[ 0,1, 1,2, 2,3 , 3,4,5] + mesh=MEDCouplingUMesh.New(); + mesh.setName("1DMesh_1"); + mesh.setMeshDimension(1); + mesh.allocateCells(4); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) + mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,6,1); + myCoords.setInfoOnComponent(0,"tototototototot (m*m*m*m*m*m*m*m)"); + mesh.setCoords(myCoords); + return mesh; + + def build2DCurveMesh_1(cls): + coords=[ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 ] + conn=[ 0,1, 1,2, 2,3 , 3,4,5] + mesh=MEDCouplingUMesh.New(); + mesh.setName("2DCurveMesh_1"); + mesh.setMeshDimension(1); + mesh.allocateCells(4); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) + mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,6,2); + mesh.setCoords(myCoords); + return mesh; + + def build2DMesh_1(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(6); + targetMesh.setName("2DMesh_1"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,2); + myCoords.setInfoOnComponent(0,"tototototototot (m)"); + myCoords.setInfoOnComponent(1,"energie (kW)"); + targetMesh.setCoords(myCoords) + return targetMesh; + + def build2DMesh_2(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.setName("2DMesh_2"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,2); + myCoords.setInfoOnComponent(0,"toto (m)"); + myCoords.setInfoOnComponent(1,"energie (kW)"); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DMesh_1(cls): + coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] + conn=[ + # 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + # 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + # 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58] + # + ret=MEDCouplingUMesh.New(); + ret.setName("3DMesh_1"); + ret.setMeshDimension(3); + ret.allocateCells(18); + # + ret.insertNextCell(NORM_HEXA8,8,conn[0:8]) + ret.insertNextCell(NORM_HEXA8,8,conn[51:59]) + ret.insertNextCell(NORM_HEXA8,8,conn[59:67]) + ret.insertNextCell(NORM_HEXA8,8,conn[110:118]) + # + ret.insertNextCell(NORM_HEXA8,8,conn[118:126]) + ret.insertNextCell(NORM_HEXA8,8,conn[169:177]) + ret.insertNextCell(NORM_HEXA8,8,conn[177:185]) + ret.insertNextCell(NORM_HEXA8,8,conn[228:236]) + # + ret.insertNextCell(NORM_HEXA8,8,conn[236:244]) + ret.insertNextCell(NORM_HEXA8,8,conn[287:295]) + ret.insertNextCell(NORM_HEXA8,8,conn[295:303]) + ret.insertNextCell(NORM_HEXA8,8,conn[346:354]) + # + ret.insertNextCell(NORM_POLYHED,43,conn[8:51]) + ret.insertNextCell(NORM_POLYHED,43,conn[67:110]) + ret.insertNextCell(NORM_POLYHED,43,conn[126:169]) + ret.insertNextCell(NORM_POLYHED,43,conn[185:228]) + ret.insertNextCell(NORM_POLYHED,43,conn[244:287]) + ret.insertNextCell(NORM_POLYHED,43,conn[303:346]) + # + ret.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,60,3); + myCoords.setInfoOnComponent(0,"titi (m)"); + myCoords.setInfoOnComponent(1,"density power (MW/m^3)"); + myCoords.setInfoOnComponent(2,"t (kW)"); + ret.setCoords(myCoords); + return ret; + + def build3DSurfMesh_1(cls): + targetCoords=[-0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 + ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(6); + targetMesh.setName("3DSurfMesh_1"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,3); + myCoords.setInfoOnComponent(0,"toto (m)"); + myCoords.setInfoOnComponent(2,"ff (km)");#component 1 is not set for test + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DMesh_2(cls): + m3dsurfBase=MEDLoaderDataForTest.build3DSurfMesh_1(); + numbers=[0,1,3,4,5] + m3dsurf=m3dsurfBase.buildPartOfMySelf(numbers,False); + m1dBase=MEDLoaderDataForTest.build1DMesh_1(); + numbers2=[0,1,2,3] + m1d=m1dBase.buildPartOfMySelf(numbers2,False); + m1d.changeSpaceDimension(3); + vec=[0.,1.,0.] + pt=[0.,0.,0.] + m1d.rotate(pt,vec,-pi/2.); + ret=m3dsurf.buildExtrudedMeshFromThis(m1d,0); + return ret; + + def buildVecFieldOnCells_1(cls): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + nbOfCells=mesh.getNumberOfCells(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("VectorFieldOnCells"); + f1.setMesh(mesh); + array=DataArrayDouble.New(); + arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] + array.setValues(arr1,nbOfCells,3); + array.setInfoOnComponent(0,"power (MW/m^3)"); + array.setInfoOnComponent(1,"density (g/cm^3)"); + array.setInfoOnComponent(2,"temperature (K)"); + f1.setArray(array); + tmp=array.getPointer(); + f1.setTime(2.,0,1); + f1.checkCoherency(); + return f1; + + def buildVecFieldOnNodes_1(cls): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + nbOfNodes=mesh.getNumberOfNodes(); + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setName("VectorFieldOnNodes"); + f1.setMesh(mesh); + array=DataArrayDouble.New(); + f1.setArray(array); + arr1=[70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., + 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.] + array.setValues(arr1,nbOfNodes,3); + array.setInfoOnComponent(0,"power (MW/m^3)"); + array.setInfoOnComponent(1,"density (g/cm^3)"); + array.setInfoOnComponent(2,"temperature (K)"); + f1.setTime(2.12,2,3); + f1.checkCoherency(); + return f1; + + def buildVecFieldOnGauss_1(cls): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1; + _gsCoo1=gsCoo1; + _wg1=wg1; + m=MEDLoaderDataForTest.build2DMesh_2(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] + _refCoo2=refCoo2; + _gsCoo1=_gsCoo1[0:6]; + _wg1=_wg1[0:3]; + f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo1,_wg1); + refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo3=refCoo3; + _gsCoo1=_gsCoo1[0:4]; + _wg1=_wg1[0:2]; + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); + array=DataArrayDouble.New(); + array.alloc(19,2); + ptr=array.getPointer(); + for i in xrange(19*2): + array.setIJ(0,i,float(i+7)); + pass + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + array.setInfoOnComponent(0,"power (MW/m^3)"); + array.setInfoOnComponent(1,"density"); + f.checkCoherency(); + return f; + + def buildVecFieldOnGaussNE_1(cls): + m=MEDLoaderDataForTest.build2DMesh_2(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + array=DataArrayDouble.New(); + array.alloc(20,2); + for i in xrange(2*20): + array.setIJ(0,i,float(i+8)); + f.setArray(array); + array.setInfoOnComponent(0,"power (W)"); + array.setInfoOnComponent(1,"temperature"); + f.setName("MyFieldOnGaussNE"); + f.checkCoherency(); + return f; + + build1DMesh_1=classmethod(build1DMesh_1) + build2DCurveMesh_1=classmethod(build2DCurveMesh_1) + build2DMesh_1=classmethod(build2DMesh_1) + build2DMesh_2=classmethod(build2DMesh_2) + build3DMesh_1=classmethod(build3DMesh_1) + build3DSurfMesh_1=classmethod(build3DSurfMesh_1) + build3DMesh_2=classmethod(build3DMesh_2) + buildVecFieldOnCells_1=classmethod(buildVecFieldOnCells_1) + buildVecFieldOnNodes_1=classmethod(buildVecFieldOnNodes_1) + buildVecFieldOnGauss_1=classmethod(buildVecFieldOnGauss_1) + buildVecFieldOnGaussNE_1=classmethod(buildVecFieldOnGaussNE_1) + pass diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py new file mode 100644 index 000000000..e0c9a080a --- /dev/null +++ b/src/MEDLoader/Swig/MEDLoaderTest.py @@ -0,0 +1,542 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D +# +# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from libMEDLoader_Swig import * +import unittest +from math import pi,e,sqrt +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDLoaderTest(unittest.TestCase): + def testMesh1DRW(self): + mesh=MEDLoaderDataForTest.build1DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMesh("Pyfile1.med",mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DCurveRW(self): + mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMesh("Pyfile2.med",mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DRW(self): + mesh=MEDLoaderDataForTest.build2DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMesh("Pyfile3.med",mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DSurfRW(self): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMesh("Pyfile4.med",mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DRW(self): + mesh=MEDLoaderDataForTest.build3DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMesh("Pyfile5.med",mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testFieldRW1(self): + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteField("Pyfile6.med",f1,True); + f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + MEDLoader.WriteField("Pyfile7.med",f1,True); + f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testFieldRW2(self): + fileName="Pyfile8.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteField(fileName,f1,True); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #retrieving time steps... + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); + f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + #test of throw on invalid (dt,it) + self.assertRaises(Exception,MEDLoader.ReadFieldCell,fileName,f1.getMesh().getName(),0,f1.getName(),28,19); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + fileName2="Pyfile9.med"; + MEDLoader.WriteField(fileName2,f1,True); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); + f1.setTime(110.,108,109); + f1.getArray().setIJ(0,3,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); + f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + # + # Multi field in a same file, but this field has several + # + def testFieldRW3(self): + fileName="Pyfile11.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + name1="AField"; + name3="AMesh1"; + name2="AMesh2"; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + f1.getMesh().setName(name3); + f1.setName(name1); + f1.setTime(10.,8,9); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteField(fileName,f1,True); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.getMesh().setName(name2); + f1.setTime(10.55,28,29); + f1.getArray().setIJ(0,0,3*VAL1); + MEDLoader.WriteField(fileName,f1,False); + vec=MEDLoader.GetMeshNamesOnField(fileName,name1); + self.assertEqual(2,len(vec)); + self.assertTrue(vec[0]==name3); + self.assertTrue(vec[1]==name2); + f1.setTime(10.66,38,39); + f1.getArray().setIJ(0,0,3*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.77,48,49); + f1.getArray().setIJ(0,0,4*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + f1.setName(name1); + f1.getMesh().setName(name2); + f1.setTime(110.,8,9); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # + it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); + self.assertEqual(2,len(it1)); + self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); + self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); + it2=MEDLoader.GetCellFieldIterations(fileName,name2,name1); + self.assertEqual(3,len(it2)); + self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]); + self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]); + self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]); + it3=MEDLoader.GetNodeFieldIterations(fileName,name2,name1); + self.assertEqual(3,len(it3)); + self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); + self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); + self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); + it4=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); + self.assertTrue(len(it4)==0); + # + # + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29); + self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39); + self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49); + self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); + # + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9); + self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); + pass + + def testMultiMeshRW1(self): + fileName="Pyfile10.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName("mesh2"); + part2=[3,4,13,14] + mesh3=mesh1.buildPartOfMySelf(part2,True); + mesh3.setName("mesh3"); + mesh4=MEDCouplingUMesh.New(); + mesh4.setName("mesh4"); + mesh4.setMeshDimension(3); + mesh4.allocateCells(1); + conn=[0,11,1,3] + mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4]) + mesh4.finishInsertingCells(); + mesh4.setCoords(mesh1.getCoords()); + meshes=[mesh1,mesh2,mesh3,mesh4] + mnane="3DToto"; + MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True); + # + mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); + mesh1.setName(mnane); + part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] + mesh6=mesh5.buildPartOfMySelf(part3,True); + mesh6.setName(mnane); + self.assertTrue(mesh6.isEqual(mesh1,1e-12)); + grps=MEDLoader.GetMeshGroupsNames(fileName,mnane); + self.assertEqual(4,len(grps)); + grps.index("mesh2"); + grps.index("mesh3"); + grps.index("mesh4"); + grps.index("3DMesh_1"); + # + vec=["mesh2"]; + mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + vec=["mesh3"]; + mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); + vec=["mesh4"]; + mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); + vec=["3DMesh_1"]; + mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1.setName("3DMesh_1"); + self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); + # + vec=["Family_4","Family_2"]; + mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2.setName("mesh2"); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + pass + + def testFieldProfilRW1(self): + fileName="Pyfile12.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + da,b,newNbOfNodes=mesh1.mergeNodes(1e-12); + MEDLoader.WriteUMesh(fileName,mesh1,True); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName(mesh1.getName());#<- important for the test + # + nbOfCells=mesh2.getNumberOfCells(); + self.assertEqual(5,nbOfCells); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("VectorFieldOnCells"); + f1.setMesh(mesh2); + array=DataArrayDouble.New(); + array.alloc(nbOfCells,2); + f1.setArray(array); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,nbOfCells,2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + # + MEDLoader.WriteField(fileName,f1,False);#<- False important for the test + # + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + f2.checkCoherency(); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + pass + + def testFieldGaussRW1(self): + fileName="Pyfile13.med"; + f1=MEDLoaderDataForTest.buildVecFieldOnGauss_1(); + MEDLoader.WriteField(fileName,f1,True); + f2=MEDLoader.ReadField(ON_GAUSS_PT,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testFieldGaussNERW1(self): + fileName="Pyfile14.med"; + f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); + MEDLoader.WriteField(fileName,f1,True); + f2=MEDLoader.ReadField(ON_GAUSS_NE,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testMesh3DSurfShuffleRW(self): + fileName="Pyfile15.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + renumber1=[2,5,1,0,3,4] + mesh.renumberCells(renumber1,False); + mesh.checkCoherency(); + MEDLoader.WriteUMesh(fileName,mesh,True); + mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMultiFieldShuffleRW1(self): + fileName="Pyfile17.med"; + m=MEDLoaderDataForTest.build3DMesh_2(); + self.assertEqual(20,m.getNumberOfCells()); + self.assertEqual(45,m.getNumberOfNodes()); + polys=[1,4,6] + m.convertToPolyTypes(polys); + renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] + m.renumberCells(renum,False); + m.orientCorrectlyPolyhedrons(); + # Writing + MEDLoader.WriteUMesh(fileName,m,True); + f1Tmp=m.getMeasureField(False); + f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False); + f1.setTime(0.,1,2); + f_1=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x"); + f1.setTime(0.01,3,4); + f_2=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x/3"); + f1.setTime(0.02,5,6); + f_3=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # Reading + its=[(1,2),(3,4),(5,6)]; + fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); + self.assertEqual(3,len(fs)); + self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); + self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); + self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); + pass + + def testWriteUMeshesRW1(self): + fileName="Pyfile18.med"; + m3d=MEDLoaderDataForTest.build3DMesh_2(); + pt=[0.,0.,-0.3] + vec=[0.,0.,1.] + nodes=m3d.findNodesOnPlane(pt,vec,1e-12); + m2d=m3d.buildFacePartOfMySelfNode(nodes,True); + renumber=[1,2,0,4,3] + m2d.renumberCells(renumber,False); + m2d.setName("ExampleOfMultiDimW"); + meshes=[m2d,m3d] + MEDLoader.WriteUMeshes(fileName,meshes,True); + m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); + self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); + m3d_bis.setName(m3d.getName()); + self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); + m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces + self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); + # Creation of a field on faces. + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("FieldOnFacesShuffle"); + f1.setMesh(m2d); + array=DataArrayDouble.New(); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,m2d.getNumberOfCells(),2); + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + f1.setArray(array); + tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + pass + + def testFieldNodeProfilRW1(self): + fileName="Pyfile19.med"; + fileName2="Pyfile20.med"; + m=MEDLoaderDataForTest.build2DMesh_1(); + nbOfNodes=m.getNumberOfNodes(); + MEDLoader.WriteUMesh(fileName,m,True); + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setName("VFieldOnNodes"); + f1.setMesh(m); + array=DataArrayDouble.New(); + arr1=[1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.] + array.setValues(arr1,nbOfNodes,2); + f1.setArray(array); + array.setInfoOnComponent(0,"tyty (mm)"); + array.setInfoOnComponent(1,"uiop (MW)"); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + arr2=[2,4,5,3,6,7] + f2=f1.buildSubPart(arr2); + f2.getMesh().setName(f1.getMesh().getName()); + MEDLoader.WriteField(fileName,f2,False);#<- False important for the test + # + f3=MEDLoader.ReadFieldNode(fileName,f2.getMesh().getName(),0,f2.getName(),2,7); + f3.checkCoherency(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + # + arr3=[1,3,0,5,2,4] + f2.renumberNodes(arr3); + MEDLoader.WriteUMesh(fileName2,m,True); + MEDLoader.WriteField(fileName2,f2,False);#<- False important for the test + f3=MEDLoader.ReadFieldNode(fileName2,f2.getMesh().getName(),0,f2.getName(),2,7); + f3.checkCoherency(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + # + pass + + def testFieldNodeProfilRW2(self): + fileName="Pyfile23.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + MEDLoader.WriteUMesh(fileName,mesh,True); + # + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setName("FieldMix"); + f1.setMesh(mesh); + arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.]; + array=DataArrayDouble.New(); + array.setValues(arr2,12,2); + f1.setArray(array); + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + tmp=array.getPointer(); + f1.setTime(3.17,2,7); + # + renumArr=[3,7,2,1,5,11,10,0,9,6,8,4] + f1.renumberNodes(renumArr); + f1.checkCoherency(); + MEDLoader.WriteField(fileName,f1,False);#<- False important for the test + f2=MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + # + pass + + def testMixCellAndNodesFieldRW1(self): + fileName="Pyfile21.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("FieldMix"); + f1.setMesh(mesh); + array=DataArrayDouble.New(); + f1.setArray(array); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] + array.setValues(arr1,6,2); + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + # + f2=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f2.setName("FieldMix"); + f2.setMesh(mesh); + array=DataArrayDouble.New(); + f2.setArray(array); + arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.] + array.setValues(arr2,12,2) + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + f2.setTime(3.17,2,7); + f2.checkCoherency(); + # + MEDLoader.WriteField(fileName,f1,True); + ts=MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName()); + self.assertEqual(1,len(ts)); + self.assertEqual(ON_CELLS,ts[0]); + fs=MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); + self.assertEqual(1,len(fs)); + self.assertTrue(fs[0]=="FieldMix"); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f2); + fs=MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); + self.assertEqual(1,len(fs)); + self.assertTrue(fs[0]=="FieldMix"); + # + ts=MEDLoader.GetTypesOfField(fileName,f1.getName(),f1.getMesh().getName()); + self.assertEqual(2,len(ts)); + self.assertEqual(ON_NODES,ts[0]); + self.assertEqual(ON_CELLS,ts[1]); + # + f3=MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f3=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f3.isEqual(f1,1e-12,1e-12)); + # + pass + + def testGetAllFieldNamesRW1(self): + fileName="Pyfile22.med"; + mesh=MEDLoaderDataForTest.build2DMesh_2(); + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setName("Field1"); + f1.setTime(3.44,5,6); + f1.setMesh(mesh); + f1.fillFromAnalytic(2,"x+y"); + MEDLoader.WriteField(fileName,f1,True); + f1.setTime(1002.3,7,8); + f1.fillFromAnalytic(2,"x+77.*y"); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setName("Field2"); + MEDLoader.WriteField(fileName,f1,False); + f1.setName("Field3"); + mesh.setName("2DMesh_2Bis"); + MEDLoader.WriteField(fileName,f1,False); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("Field8"); + f1.setTime(8.99,7,9); + f1.setMesh(mesh); + f1.fillFromAnalytic(3,"3*x+y"); + MEDLoader.WriteField(fileName,f1,False); + fs=MEDLoader.GetAllFieldNames(fileName); + self.assertEqual(4,len(fs)); + self.assertTrue(fs[0]=="Field1"); + self.assertTrue(fs[1]=="Field2"); + self.assertTrue(fs[2]=="Field3"); + self.assertTrue(fs[3]=="Field8"); + pass + pass + +unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTest2.py b/src/MEDLoader/Swig/MEDLoaderTest2.py new file mode 100644 index 000000000..bc39c1bc0 --- /dev/null +++ b/src/MEDLoader/Swig/MEDLoaderTest2.py @@ -0,0 +1,344 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D +# +# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from libMEDLoader_Swig import * +import unittest +from math import pi,e,sqrt +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDLoaderTest(unittest.TestCase): + def testMesh1DRW(self): + mesh=MEDLoaderDataForTest.build1DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile1.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DCurveRW(self): + mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile2.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DRW(self): + mesh=MEDLoaderDataForTest.build2DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile3.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DSurfRW(self): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile4.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DRW(self): + mesh=MEDLoaderDataForTest.build3DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile5.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testFieldRW1(self): + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteFieldDep("Pyfile6.med",f1,False); + f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + MEDLoader.WriteFieldDep("Pyfile7.med",f1,False); + f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testFieldRW2(self): + fileName="Pyfile8.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteFieldDep(fileName,f1,False); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #retrieving time steps... + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); + f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + fileName2="Pyfile9.med"; + MEDLoader.WriteFieldDep(fileName2,f1,False); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); + f1.setTime(110.,108,109); + f1.getArray().setIJ(0,3,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); + f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + # + # Multi field in a same file, but this field has several + # + def testFieldRW3(self): + fileName="Pyfile11.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + name1="AField"; + name3="AMesh1"; + name2="AMesh2"; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + f1.getMesh().setName(name3); + f1.setName(name1); + f1.setTime(10.,8,9); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteFieldDep(fileName,f1,False); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.getMesh().setName(name2); + f1.setTime(10.55,28,29); + f1.getArray().setIJ(0,0,3*VAL1); + MEDLoader.WriteFieldDep(fileName,f1,False); + f1.setTime(10.66,38,39); + f1.getArray().setIJ(0,0,3*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.77,48,49); + f1.getArray().setIJ(0,0,4*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + f1.setName(name1); + f1.getMesh().setName(name2); + f1.setTime(110.,8,9); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # + it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); + self.assertEqual(2,len(it1)); + self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); + self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); + it2=MEDLoader.GetCellFieldIterations(fileName,name2,name1); + self.assertEqual(3,len(it2)); + self.assertEqual(28,it2[0][0]); self.assertEqual(29,it2[0][1]); + self.assertEqual(38,it2[1][0]); self.assertEqual(39,it2[1][1]); + self.assertEqual(48,it2[2][0]); self.assertEqual(49,it2[2][1]); + it3=MEDLoader.GetNodeFieldIterations(fileName,name2,name1); + self.assertEqual(3,len(it3)); + self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); + self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); + self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); + it4=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); + self.assertTrue(len(it4)==0); + # + # + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,28,29); + self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,38,39); + self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name2,0,name1,48,49); + self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); + # + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,8,9); + self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,108,109); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name2,0,name1,208,209); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); + pass + + def testMultiMeshRW1(self): + fileName="Pyfile10.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName("mesh2"); + part2=[3,4,13,14] + mesh3=mesh1.buildPartOfMySelf(part2,True); + mesh3.setName("mesh3"); + mesh4=MEDCouplingUMesh.New(); + mesh4.setName("mesh4"); + mesh4.setMeshDimension(3); + mesh4.allocateCells(1); + conn=[0,11,1,3] + mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4]) + mesh4.finishInsertingCells(); + mesh4.setCoords(mesh1.getCoords()); + meshes=[mesh1,mesh2,mesh3,mesh4] + mnane="3DToto"; + MEDLoader.WriteUMeshesPartitionDep(fileName,mnane,meshes,False); + # + mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); + mesh1.setName(mnane); + part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] + mesh6=mesh5.buildPartOfMySelf(part3,True); + mesh6.setName(mnane); + self.assertTrue(mesh6.isEqual(mesh1,1e-12)); + grps=MEDLoader.GetMeshGroupsNames(fileName,mnane); + self.assertEqual(4,len(grps)); + grps.index("mesh2"); + grps.index("mesh3"); + grps.index("mesh4"); + grps.index("3DMesh_1"); + # + vec=["mesh2"]; + mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + vec=["mesh3"]; + mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); + vec=["mesh4"]; + mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); + vec=["3DMesh_1"]; + mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1.setName("3DMesh_1"); + self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); + # + vec=["Family_4","Family_2"]; + mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2.setName("mesh2"); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + pass + + def testMesh3DSurfShuffleRW(self): + fileName="Pyfile15.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + renumber1=[2,5,1,0,3,4] + mesh.renumberCells(renumber1,False); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep(fileName,mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMultiFieldShuffleRW1(self): + fileName="Pyfile17.med"; + m=MEDLoaderDataForTest.build3DMesh_2(); + self.assertEqual(20,m.getNumberOfCells()); + self.assertEqual(45,m.getNumberOfNodes()); + polys=[1,4,6] + m.convertToPolyTypes(polys); + renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] + m.renumberCells(renum,False); + m.orientCorrectlyPolyhedrons(); + # Writing + MEDLoader.WriteUMeshDep(fileName,m,False); + f1Tmp=m.getMeasureField(False); + f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False); + f1.setTime(0.,1,2); + f_1=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x"); + f1.setTime(0.01,3,4); + f_2=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x/3"); + f1.setTime(0.02,5,6); + f_3=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # Reading + its=[(1,2),(3,4),(5,6)]; + fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); + self.assertEqual(3,len(fs)); + self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); + self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); + self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); + pass + + def testWriteUMeshesRW1(self): + fileName="Pyfile18.med"; + m3d=MEDLoaderDataForTest.build3DMesh_2(); + pt=[0.,0.,-0.3] + vec=[0.,0.,1.] + nodes=m3d.findNodesOnPlane(pt,vec,1e-12); + m2d=m3d.buildFacePartOfMySelfNode(nodes,True); + renumber=[1,2,0,4,3] + m2d.renumberCells(renumber,False); + m2d.setName("ExampleOfMultiDimW"); + meshes=[m2d,m3d] + MEDLoader.WriteUMeshes(fileName,meshes,False); + m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); + self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); + m3d_bis.setName(m3d.getName()); + self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); + m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces + self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); + # Creation of a field on faces. + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("FieldOnFacesShuffle"); + f1.setMesh(m2d); + array=DataArrayDouble.New(); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,m2d.getNumberOfCells(),2); + array.setInfoOnComponent(0,"plkj (mm)"); + array.setInfoOnComponent(1,"pqqqss (mm)"); + f1.setArray(array); + tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + pass + pass + +unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i new file mode 100644 index 000000000..94811c36d --- /dev/null +++ b/src/MEDLoader/Swig/MEDLoaderTypemaps.i @@ -0,0 +1,134 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include + +static std::vector > convertTimePairIdsFromPy(PyObject *pyLi) +{ + std::vector > ret; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i p; + int size2=PyTuple_Size(o); + if(size2!=2) + { + const char msg[]="tuples in list must be of size 2 (dt,it) !"; + ret.clear(); + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + } + PyObject *o0=PyTuple_GetItem(o,0); + if(PyInt_Check(o0)) + p.first=(int)PyInt_AS_LONG(o0); + else + { + const char msg[]="First elem of tuples in list must be integer : dt !"; + ret.clear(); + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + } + PyObject *o1=PyTuple_GetItem(o,1); + if(PyInt_Check(o1)) + p.second=(int)PyInt_AS_LONG(o1); + else + { + const char msg[]="Second elem of tuples in list must be integer : dt !"; + ret.clear(); + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + } + ret[i]=p; + } + else + { + const char msg[]="list must contain tuples only"; + ret.clear(); + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + return ret; + } + } + } + else + { + ret.clear(); + const char msg[]="convertTimePairIdsFromPy : not a list"; + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + } + return ret; +} + +static PyObject *convertFieldDoubleVecToPy(const std::vector& li) +{ + int sz=li.size(); + PyObject *ret=PyList_New(sz); + for(int i=0;i convertFieldDoubleVecFromPy(PyObject *pyLi) +{ + std::vector ret; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i(argp); + ret[i]=arg; + } + } + else + { + ret.clear(); + const char msg[]="convertFieldDoubleVecFromPy : not a list"; + PyErr_SetString(PyExc_TypeError,msg); + PyErr_Print(); + throw INTERP_KERNEL::Exception(msg); + } + return ret; +} diff --git a/src/MEDLoader/Swig/Makefile.am b/src/MEDLoader/Swig/Makefile.am index eda6669e2..ab110a19d 100644 --- a/src/MEDLoader/Swig/Makefile.am +++ b/src/MEDLoader/Swig/Makefile.am @@ -24,9 +24,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am lib_LTLIBRARIES = _libMEDLoader_Swig.la salomeinclude_HEADERS = \ - libMEDLoader_Swig.i + libMEDLoader_Swig.i MEDLoaderTypemaps.i -SWIG_DEF = libMEDLoader_Swig.i +SWIG_DEF = libMEDLoader_Swig.i MEDLoaderTypemaps.i SWIG_FLAGS = @SWIG_FLAGS@ -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../MEDCoupling -I$(srcdir)/../../MEDCoupling_Swig \ -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Bases @@ -50,5 +50,6 @@ _libMEDLoader_Swig_la_LDFLAGS = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS CLEANFILES = libMEDLoader_Swig_wrap.cxx libMEDLoader_Swig.py -dist_salomescript_DATA= libMEDLoader_Swig.py +dist_salomescript_DATA= libMEDLoader_Swig.py MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py +UNIT_TEST_PROG = MEDLoaderTest.py MEDLoaderTest2.py \ No newline at end of file diff --git a/src/MEDLoader/Swig/libMEDLoader_Swig.i b/src/MEDLoader/Swig/libMEDLoader_Swig.i index 5a5b6087a..5feded4d5 100644 --- a/src/MEDLoader/Swig/libMEDLoader_Swig.i +++ b/src/MEDLoader/Swig/libMEDLoader_Swig.i @@ -19,36 +19,51 @@ %module libMEDLoader_Swig -%include std_vector.i -%include std_string.i +#define MEDCOUPLING_EXPORT +#define MEDLOADER_EXPORT -%include "MEDCouplingTypemaps.i" %include "libMEDCoupling_Swig.i" %{ #include "MEDLoader.hxx" +#include "MEDLoaderTypemaps.i" %} #if SWIG_VERSION >= 0x010329 %template() std::vector; #endif +%newobject MEDLoader::ReadUMeshFromFamilies; +%newobject MEDLoader::ReadUMeshFromGroups; %newobject MEDLoader::ReadUMeshFromFile; -%newobject MEDLoader::ReadFieldDoubleCell; +%newobject MEDLoader::ReadField; +%newobject MEDLoader::ReadFieldCell; +%newobject MEDLoader::ReadFieldNode; +%newobject MEDLoader::ReadFieldGauss; +%newobject MEDLoader::ReadFieldGaussNE; class MEDLoader { public: - static std::vector GetMeshNames(const char *fileName); - static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName); - static std::vector GetMeshFamilyNames(const char *fileName, const char *meshName); - static std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName); - static std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName); + static void setEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); + static void setCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); + static void setTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); + static void CheckFileForRead(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshNames(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshNamesOnField(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshGroupsNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetMeshFamiliesNames(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetAllFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetAllFieldNames(const char *fileName) throw(INTERP_KERNEL::Exception); + static std::vector GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetCellFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static std::vector GetNodeFieldNamesOnMesh(const char *fileName, const char *meshName) throw(INTERP_KERNEL::Exception); + static double GetTimeAttachedOnFieldIteration(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); %extend { - static PyObject *GetCellFieldIterations(const char *fileName, const char *fieldName) + static PyObject *GetFieldIterations(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) { - std::vector< std::pair > res=MEDLoader::GetCellFieldIterations(fileName,fieldName); + std::vector< std::pair > res=MEDLoader::GetFieldIterations(type,fileName,meshName,fieldName); PyObject *ret=PyList_New(res.size()); int rk=0; for(std::vector< std::pair >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) @@ -60,12 +75,96 @@ public: } return ret; } + + static PyObject *GetAllFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair< std::pair, double> > res=MEDLoader::GetAllFieldIterations(fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair< std::pair, double> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(3); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first.first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).first.second)); + PyTuple_SetItem(elt,2,SWIG_From_double((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + + static PyObject *GetCellFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > res=MEDLoader::GetCellFieldIterations(fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + static PyObject *GetNodeFieldIterations(const char *fileName, const char *meshName, const char *fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair > res=MEDLoader::GetNodeFieldIterations(fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + static PyObject *ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, + const char *fieldName, PyObject *liIts) throw(INTERP_KERNEL::Exception) + { + std::vector > its=convertTimePairIdsFromPy(liIts); + std::vector res=MEDLoader::ReadFieldsOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its); + return convertFieldDoubleVecToPy(res); + } + static void WriteUMeshesPartition(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector v=convertFieldDoubleVecFromPy(li); + MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch); + } + static void WriteUMeshesPartitionDep(const char *fileName, const char *meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector v=convertFieldDoubleVecFromPy(li); + MEDLoader::WriteUMeshesPartitionDep(fileName,meshName,v,writeFromScratch); + } + static void WriteUMeshes(const char *fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector v=convertFieldDoubleVecFromPy(li); + std::vector v2(v.begin(),v.end()); + MEDLoader::WriteUMeshes(fileName,v2,writeFromScratch); + } + static PyObject *GetTypesOfField(const char *fileName, const char *fieldName, const char *meshName) throw(INTERP_KERNEL::Exception) + { + std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,fieldName,meshName); + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i > GetNodeFieldIterations(const char *fileName, const char *fieldName); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& fams) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const char *fileName, const char *meshName, int meshDimRelToMax, const std::vector& grps) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, const char *meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const char *fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldDoubleCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order); - static void WriteUMesh(const char *fileName, ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteField(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, ParaMEDMEM::MEDCouplingFieldDouble *f); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const char *fileName, const char *meshName, int meshDimRelToMax, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static void WriteUMesh(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshDep(const char *fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteField(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldDep(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldUsingAlreadyWrittenMesh(const char *fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); }; diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx new file mode 100644 index 000000000..6dadebf48 --- /dev/null +++ b/src/MEDLoader/Test/MEDLoaderTest.cxx @@ -0,0 +1,1053 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDLoaderTest.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" + +#include + +using namespace ParaMEDMEM; + +void MEDLoaderTest::testMesh1DRW() +{ + MEDCouplingUMesh *mesh=build1DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file1.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file1.med",mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh2DCurveRW() +{ + MEDCouplingUMesh *mesh=build2DCurveMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file2.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file2.med",mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh2DRW() +{ + MEDCouplingUMesh *mesh=build2DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file3.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file3.med",mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh3DSurfRW() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file4.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file4.med",mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh3DRW() +{ + MEDCouplingUMesh *mesh=build3DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file5.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file5.med",mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +/*! + * Most basic test : one and only one MEDCoupling field in a new file. + */ +void MEDLoaderTest::testFieldRW1() +{ + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + MEDLoader::WriteField("file6.med",f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell("file6.med",f1->getMesh()->getName(),0,f1->getName(),0,1); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); + // + f1=buildVecFieldOnNodes_1(); + MEDLoader::WriteField("file7.med",f1,true); + f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName(),0,f1->getName(),2,3); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); +} + +/*! + * Multi field writing in a same file. + */ +void MEDLoaderTest::testFieldRW2() +{ + const char fileName[]="file8.med"; + static const double VAL1=12345.67890314; + static const double VAL2=-1111111111111.; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(10.,8,9); + double *tmp=f1->getArray()->getPointer(); + tmp[0]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + //retrieving time steps... + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),8,9); + f1->setTime(10.,8,9); + tmp[0]=VAL1; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),0,1); + MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),18,19); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + //test of throw on invalid (dt,it) + CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),28,19),INTERP_KERNEL::Exception); + f2->decrRef(); + f1->decrRef(); + //ON NODES + f1=buildVecFieldOnNodes_1(); + const char fileName2[]="file9.med"; + MEDLoader::WriteField(fileName2,f1,true); + f1->setTime(110.,108,109); + tmp=f1->getArray()->getPointer(); + tmp[3]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),108,109); + f1->setTime(110.,108,109); + tmp[3]=VAL1; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),2,3); + f3=buildVecFieldOnNodes_1(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName(),0,f1->getName(),208,209); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +/*! + * Multi field in a same file, but this field has several + */ +void MEDLoaderTest::testFieldRW3() +{ + const char fileName[]="file11.med"; + static const double VAL1=12345.67890314; + static const double VAL2=-1111111111111.; + const char name1[]="AField"; + const char name3[]="AMesh1"; + const char name2[]="AMesh2"; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + ((MEDCouplingMesh *)f1->getMesh())->setName(name3); + f1->setName(name1); + f1->setTime(10.,8,9); + double *tmp=f1->getArray()->getPointer(); + tmp[0]=VAL1; + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + ((MEDCouplingMesh *)f1->getMesh())->setName(name2); + f1->setTime(10.55,28,29); + tmp[0]=3*VAL1; + MEDLoader::WriteField(fileName,f1,false); + std::vector vec=MEDLoader::GetMeshNamesOnField(fileName,name1); + CPPUNIT_ASSERT_EQUAL(2,(int)vec.size()); + CPPUNIT_ASSERT(vec[0]==name3); + CPPUNIT_ASSERT(vec[1]==name2); + f1->setTime(10.66,38,39); + tmp[0]=3*VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.77,48,49); + tmp[0]=4*VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + //ON NODES + f1->decrRef(); + f1=buildVecFieldOnNodes_1(); + f1->setName(name1); + ((MEDCouplingMesh *)f1->getMesh())->setName(name2); + f1->setTime(110.,8,9); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(110.,108,109); + tmp=f1->getArray()->getPointer(); + tmp[3]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + // + std::vector< std::pair > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); + CPPUNIT_ASSERT_EQUAL(2,(int)it1.size()); + CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); + CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); + std::vector< std::pair > it2=MEDLoader::GetCellFieldIterations(fileName,name2,name1); + CPPUNIT_ASSERT_EQUAL(3,(int)it2.size()); + CPPUNIT_ASSERT_EQUAL(28,it2[0].first); CPPUNIT_ASSERT_EQUAL(29,it2[0].second); + CPPUNIT_ASSERT_EQUAL(38,it2[1].first); CPPUNIT_ASSERT_EQUAL(39,it2[1].second); + CPPUNIT_ASSERT_EQUAL(48,it2[2].first); CPPUNIT_ASSERT_EQUAL(49,it2[2].second); + std::vector< std::pair > it3=MEDLoader::GetNodeFieldIterations(fileName,name2,name1); + CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); + CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); + CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); + CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); + std::vector< std::pair > it4=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); + CPPUNIT_ASSERT(it4.empty()); + // + f1->decrRef(); + // + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,8,9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,28,29); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,38,39); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name2,0,name1,48,49); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + // + f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,8,9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,108,109); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldNode(fileName,name2,0,name1,208,209); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); +} + +void MEDLoaderTest::testMultiMeshRW1() +{ + const char fileName[]="file10.med"; + MEDCouplingUMesh *mesh1=build3DMesh_1(); + const int part1[5]={1,2,4,13,15}; + MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); + mesh2->setName("mesh2"); + const int part2[4]={3,4,13,14}; + MEDCouplingUMesh *mesh3=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part2,part2+4,true); + mesh3->setName("mesh3"); + MEDCouplingUMesh *mesh4=MEDCouplingUMesh::New(); + mesh4->setName("mesh4"); + mesh4->setMeshDimension(3); + mesh4->allocateCells(1); + int conn[4]={0,11,1,3}; + mesh4->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + mesh4->finishInsertingCells(); + mesh4->setCoords(mesh1->getCoords()); + std::vector meshes; + meshes.push_back(mesh1); + meshes.push_back(mesh2); + meshes.push_back(mesh3); + meshes.push_back(mesh4); + const char mnane[]="3DToto"; + MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true); + // + MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); + mesh1->setName(mnane); + const int part3[18]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; + MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true); + mesh6->setName(mnane); + mesh5->decrRef(); + CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12)); + mesh6->decrRef(); + std::vector grps=MEDLoader::GetMeshGroupsNames(fileName,mnane); + CPPUNIT_ASSERT_EQUAL(4,(int)grps.size()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end()); + // + std::vector vec; + vec.push_back(std::string("mesh2")); + MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh3")); + MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12)); + mesh3_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh4")); + MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12)); + mesh4_2->decrRef(); + vec.clear(); vec.push_back(std::string("3DMesh_1")); + MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1->setName("3DMesh_1"); + CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12)); + mesh1_2->decrRef(); + // + vec.clear(); vec.push_back(std::string("Family_4")); vec.push_back(std::string("Family_2")); + mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2->setName("mesh2"); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + // + mesh4->decrRef(); + mesh3->decrRef(); + mesh2->decrRef(); + mesh1->decrRef(); +} + +void MEDLoaderTest::testFieldProfilRW1() +{ + const char fileName[]="file12.med"; + MEDCouplingUMesh *mesh1=build3DMesh_1(); + bool b; + int newNbOfNodes; + DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes); + da->decrRef(); + MEDLoader::WriteUMesh(fileName,mesh1,true); + const int part1[5]={1,2,4,13,15}; + MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); + mesh2->setName(mesh1->getName());//<- important for the test + // + int nbOfCells=mesh2->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(5,nbOfCells); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setMesh(mesh2); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,2); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; + std::copy(arr1,arr1+10,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + MEDLoader::WriteField(fileName,f1,false);//<- false important for the test + // + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7); + f2->checkCoherency(); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDLoaderTest::testFieldNodeProfilRW1() +{ + const char fileName[]="file19.med"; + const char fileName2[]="file20.med"; + MEDCouplingUMesh *m=build2DMesh_1(); + int nbOfNodes=m->getNumberOfNodes(); + MEDLoader::WriteUMesh(fileName,m,true); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("VFieldOnNodes"); + f1->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + const double arr1[24]={1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.}; + array->alloc(nbOfNodes,2); + std::copy(arr1,arr1+24,array->getPointer()); + f1->setArray(array); + array->setInfoOnComponent(0,"tyty (mm)"); + array->setInfoOnComponent(1,"uiop (MW)"); + array->decrRef(); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + const int arr2[6]={2,4,5,3,6,7}; + MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+6); + ((MEDCouplingMesh *)f2->getMesh())->setName(f1->getMesh()->getName()); + MEDLoader::WriteField(fileName,f2,false);//<- false important for the test + // + MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName(),0,f2->getName(),2,7); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + // + const int arr3[6]={1,3,0,5,2,4}; + f2->renumberNodes(arr3); + MEDLoader::WriteUMesh(fileName2,m,true); + MEDLoader::WriteField(fileName2,f2,false);//<- false important for the test + f3=MEDLoader::ReadFieldNode(fileName2,f2->getMesh()->getName(),0,f2->getName(),2,7); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + // + f1->decrRef(); + m->decrRef(); +} + +void MEDLoaderTest::testFieldNodeProfilRW2() +{ + const char fileName[]="file23.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDLoader::WriteUMesh(fileName,mesh,true); + // + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("FieldMix"); + f1->setMesh(mesh); + const double arr2[24]={ + 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. + }; + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(12,2); + f1->setArray(array); + array->setInfoOnComponent(0,"plkj (mm)"); + array->setInfoOnComponent(1,"pqqqss (mm)"); + array->decrRef(); + double *tmp=array->getPointer(); + std::copy(arr2,arr2+24,tmp); + f1->setTime(3.17,2,7); + // + const int renumArr[12]={3,7,2,1,5,11,10,0,9,6,8,4}; + f1->renumberNodes(renumArr); + f1->checkCoherency(); + MEDLoader::WriteField(fileName,f1,false);//<- false important for the test + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + // + f2->decrRef(); + mesh->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testFieldGaussRW1() +{ + const char fileName[]="file13.med"; + MEDCouplingFieldDouble *f1=buildVecFieldOnGauss_1(); + MEDLoader::WriteField(fileName,f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_PT,fileName,f1->getMesh()->getName(),0,f1->getName(),1,5); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testFieldGaussNERW1() +{ + const char fileName[]="file14.med"; + MEDCouplingFieldDouble *f1=buildVecFieldOnGaussNE_1(); + MEDLoader::WriteField(fileName,f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName(),0,f1->getName(),1,5); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testLittleStrings1() +{ + std::string s("azeeeerrrtty"); + MEDLoaderBase::zipEqualConsChar(s,3); + CPPUNIT_ASSERT(s=="azertty"); +} + +void MEDLoaderTest::testMesh3DSurfShuffleRW() +{ + const char fileName[]="file15.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + const int renumber1[6]={2,5,1,0,3,4}; + mesh->renumberCells(renumber1,false); + mesh->checkCoherency(); + MEDLoader::WriteUMesh(fileName,mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(fileName,mesh->getName(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testFieldShuffleRW1() +{ + const char fileName[]="file16.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldOnCellsShuffle"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(6,2); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; + std::copy(arr1,arr1+12,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + const int renumber1[6]={2,1,5,0,3,4}; + f1->renumberCells(renumber1,false); + MEDLoader::WriteField(fileName,f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,mesh->getName(),0,f1->getName(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + f2->decrRef(); + // + mesh->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testMultiFieldShuffleRW1() +{ + const char fileName[]="file17.med"; + MEDCouplingUMesh *m=build3DMesh_2(); + CPPUNIT_ASSERT_EQUAL(20,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(45,m->getNumberOfNodes()); + const int polys[3]={1,4,6}; + std::vector poly2(polys,polys+3); + m->convertToPolyTypes(poly2); + const int renum[20]={1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11}; + m->renumberCells(renum,false); + m->orientCorrectlyPolyhedrons(); + // Writing + MEDLoader::WriteUMesh(fileName,m,true); + MEDCouplingFieldDouble *f1Tmp=m->getMeasureField(false); + MEDCouplingFieldDouble *f1=f1Tmp->buildNewTimeReprFromThis(ONE_TIME,false); + f1Tmp->decrRef(); + f1->setTime(0.,1,2); + MEDCouplingFieldDouble *f_1=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->applyFunc("2*x"); + f1->setTime(0.01,3,4); + MEDCouplingFieldDouble *f_2=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->applyFunc("2*x/3"); + f1->setTime(0.02,5,6); + MEDCouplingFieldDouble *f_3=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->decrRef(); + // Reading + std::vector > its; + its.push_back(std::pair(1,2)); + its.push_back(std::pair(3,4)); + its.push_back(std::pair(5,6)); + std::vector fs=MEDLoader::ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1->getMesh()->getName(),0,f_1->getName(),its); + CPPUNIT_ASSERT_EQUAL(3,(int)fs.size()); + const MEDCouplingMesh *mm=fs[0]->getMesh(); + CPPUNIT_ASSERT(fs[0]->isEqual(f_1,1e-12,1e-12)); + CPPUNIT_ASSERT(fs[1]->isEqual(f_2,1e-12,1e-12)); + CPPUNIT_ASSERT(fs[2]->isEqual(f_3,1e-12,1e-12)); + CPPUNIT_ASSERT(mm==fs[1]->getMesh());// <- important for the test + CPPUNIT_ASSERT(mm==fs[2]->getMesh());// <- important for the test + for(std::vector::iterator iter=fs.begin();iter!=fs.end();iter++) + (*iter)->decrRef(); + // + f_1->decrRef(); + f_2->decrRef(); + f_3->decrRef(); + // + m->decrRef(); +} + +void MEDLoaderTest::testWriteUMeshesRW1() +{ + const char fileName[]="file18.med"; + MEDCouplingUMesh *m3d=build3DMesh_2(); + const double pt[3]={0.,0.,-0.3}; + const double vec[3]={0.,0.,1.}; + std::vector nodes; + m3d->findNodesOnPlane(pt,vec,1e-12,nodes); + MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true); + const int renumber[5]={1,2,0,4,3}; + m2d->renumberCells(renumber,false); + m2d->setName("ExampleOfMultiDimW"); + std::vector meshes; + meshes.push_back(m2d); + meshes.push_back(m3d); + MEDLoader::WriteUMeshes(fileName,meshes,true); + MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),0); + CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12)); + m3d_bis->setName(m3d->getName()); + CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12)); + MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName(),-1);//-1 for faces + CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12)); + // Creation of a field on faces. + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldOnFacesShuffle"); + f1->setMesh(m2d); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m2d->getNumberOfCells(),2); + array->setInfoOnComponent(0,"plkj (mm)"); + array->setInfoOnComponent(1,"pqqqss (mm)"); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; + std::copy(arr1,arr1+10,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),-1,f1->getName(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); + // + m2d_bis->decrRef(); + m3d_bis->decrRef(); + m2d->decrRef(); + m3d->decrRef(); +} + +void MEDLoaderTest::testMixCellAndNodesFieldRW1() +{ + const char fileName[]="file21.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldMix"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(6,2); + f1->setArray(array); + array->setInfoOnComponent(0,"plkj (mm)"); + array->setInfoOnComponent(1,"pqqqss (mm)"); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; + std::copy(arr1,arr1+12,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f2->setName("FieldMix"); + f2->setMesh(mesh); + array=DataArrayDouble::New(); + array->alloc(12,2); + f2->setArray(array); + array->setInfoOnComponent(0,"plkj (mm)"); + array->setInfoOnComponent(1,"pqqqss (mm)"); + array->decrRef(); + tmp=array->getPointer(); + const double arr2[24]={ + 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. + }; + std::copy(arr2,arr2+24,tmp); + f2->setTime(3.17,2,7); + f2->checkCoherency(); + // + MEDLoader::WriteField(fileName,f1,true); + std::vector ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName()); + CPPUNIT_ASSERT_EQUAL(1,(int)ts.size()); + CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]); + std::vector fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName()); + CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="FieldMix"); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2); + fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName()); + CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="FieldMix"); + // + ts=MEDLoader::GetTypesOfField(fileName,f1->getName(),f1->getMesh()->getName()); + CPPUNIT_ASSERT_EQUAL(2,(int)ts.size()); + CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]); + CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]); + // + MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName(),0,f1->getName(),2,7); + CPPUNIT_ASSERT(f3->isEqual(f1,1e-12,1e-12)); + f3->decrRef(); + // + f1->decrRef(); + f2->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testGetAllFieldNamesRW1() +{ + const char fileName[]="file22.med"; + MEDCouplingUMesh *mesh=build2DMesh_2(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("Field1"); + f1->setTime(3.44,5,6); + f1->setMesh(mesh); + f1->fillFromAnalytic(2,"x+y"); + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(1002.3,7,8); + f1->fillFromAnalytic(2,"x+77.*y"); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setName("Field2"); + MEDLoader::WriteField(fileName,f1,false); + f1->setName("Field3"); + mesh->setName("2DMesh_2Bis"); + MEDLoader::WriteField(fileName,f1,false); + f1->decrRef(); + f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("Field8"); + f1->setTime(8.99,7,9); + f1->setMesh(mesh); + f1->fillFromAnalytic(3,"3*x+y"); + MEDLoader::WriteField(fileName,f1,false); + f1->decrRef(); + std::vector fs=MEDLoader::GetAllFieldNames(fileName); + CPPUNIT_ASSERT_EQUAL(4,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="Field1"); + CPPUNIT_ASSERT(fs[1]=="Field2"); + CPPUNIT_ASSERT(fs[2]=="Field3"); + CPPUNIT_ASSERT(fs[3]=="Field8"); + mesh->decrRef(); +} + +MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1() +{ + double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 }; + int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setName("1DMesh_1"); + mesh->setMeshDimension(1); + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(6,1); + myCoords->setInfoOnComponent(0,"tototototototot (m*m*m*m*m*m*m*m)"); + std::copy(coords,coords+6,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DCurveMesh_1() +{ + double coords[12]={ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 }; + int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setName("2DCurveMesh_1"); + mesh->setMeshDimension(1); + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(6,2); + std::copy(coords,coords+12,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DMesh_1() +{ + double targetCoords[24]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, -0.05,0.95, 0.2,1.2, 0.45,0.95 }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(6); + targetMesh->setName("2DMesh_1"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,2); + myCoords->setInfoOnComponent(0,"tototototototot (m)"); + myCoords->setInfoOnComponent(1,"energie (kW)"); + std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DMesh_2() +{ + double targetCoords[24]={ + -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95 + }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->setName("2DMesh_2"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,2); + myCoords->setInfoOnComponent(0,"toto (m)"); + myCoords->setInfoOnComponent(1,"energie (kW)"); + std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DSurfMesh_1() +{ + double targetCoords[36]={ + -0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 + ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3 + }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(6); + targetMesh->setName("3DSurfMesh_1"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,3); + myCoords->setInfoOnComponent(0,"toto (m)"); + myCoords->setInfoOnComponent(2,"ff (km)");//component 1 is not set for test + std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DMesh_1() +{ + double coords[180]={ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; + + int conn[354]={ + // 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + // 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + // 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58 + }; + // + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName("3DMesh_1"); + ret->setMeshDimension(3); + ret->allocateCells(18); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); + // + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); + // + ret->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(60,3); + myCoords->setInfoOnComponent(0,"titi (m)"); + myCoords->setInfoOnComponent(1,"density power (MW/m^3)"); + myCoords->setInfoOnComponent(2,"t (kW)"); + std::copy(coords,coords+180,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DMesh_2() +{ + MEDCouplingUMesh *m3dsurfBase=build3DSurfMesh_1(); + int numbers[5]={0,1,3,4,5}; + MEDCouplingUMesh *m3dsurf=(MEDCouplingUMesh *)m3dsurfBase->buildPartOfMySelf(numbers,numbers+5,false); + m3dsurfBase->decrRef(); + MEDCouplingUMesh *m1dBase=build1DMesh_1(); + int numbers2[4]={0,1,2,3}; + MEDCouplingUMesh *m1d=(MEDCouplingUMesh *)m1dBase->buildPartOfMySelf(numbers2,numbers2+4,false); + m1dBase->decrRef(); + m1d->changeSpaceDimension(3); + const double vec[3]={0.,1.,0.}; + const double pt[3]={0.,0.,0.}; + m1d->rotate(pt,vec,-M_PI/2.); + MEDCouplingUMesh *ret=m3dsurf->buildExtrudedMeshFromThis(m1d,0); + m1d->decrRef(); + m3dsurf->decrRef(); + return ret; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnCells_1() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + int nbOfCells=mesh->getNumberOfCells(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,3); + array->setInfoOnComponent(0,"power (MW/m^3)"); + array->setInfoOnComponent(1,"density (g/cm^3)"); + array->setInfoOnComponent(2,"temperature (K)"); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[18]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; + std::copy(arr1,arr1+18,tmp); + f1->setTime(2.,0,1); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnNodes_1() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + int nbOfNodes=mesh->getNumberOfNodes(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("VectorFieldOnNodes"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfNodes,3); + f1->setArray(array); + array->setInfoOnComponent(0,"power (MW/m^3)"); + array->setInfoOnComponent(1,"density (g/cm^3)"); + array->setInfoOnComponent(2,"temperature (K)"); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[36]={ + 70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., + 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025., + }; + std::copy(arr1,arr1+36,tmp); + f1->setTime(2.12,2,3); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGauss_1() +{ + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector _refCoo1(refCoo1,refCoo1+6); + std::vector _gsCoo1(gsCoo1,gsCoo1+12); + std::vector _wg1(wg1,wg1+6); + MEDCouplingUMesh *m=build2DMesh_2(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); + f->setTime(3.14,1,5); + f->setMesh(m); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + const double refCoo2[12]={-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; + std::vector _refCoo2(refCoo2,refCoo2+12); + _gsCoo1.resize(6); _wg1.resize(3); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo1,_wg1); + const double refCoo3[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector _refCoo3(refCoo3,refCoo3+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(19,2); + double *ptr=array->getPointer(); + for(int i=0;i<19*2;i++) + ptr[i]=(double)(i+7); + f->setArray(array); + f->setName("MyFirstFieldOnGaussPoint"); + array->setInfoOnComponent(0,"power (MW/m^3)"); + array->setInfoOnComponent(1,"density"); + array->decrRef(); + f->checkCoherency(); + m->decrRef(); + return f; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGaussNE_1() +{ + MEDCouplingUMesh *m=build2DMesh_2(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); + f->setTime(3.14,1,5); + f->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(20,2); + double *ptr=array->getPointer(); + for(int i=0;i<20*2;i++) + ptr[i]=(double)(i+8); + f->setArray(array); + array->setInfoOnComponent(0,"power (W)"); + array->setInfoOnComponent(1,"temperature"); + f->setName("MyFieldOnGaussNE"); + array->decrRef(); + f->checkCoherency(); + m->decrRef(); + return f; +} + diff --git a/src/MEDLoader/Test/MEDLoaderTest.hxx b/src/MEDLoader/Test/MEDLoaderTest.hxx new file mode 100644 index 000000000..aa17ea35f --- /dev/null +++ b/src/MEDLoader/Test/MEDLoaderTest.hxx @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDLOADERTEST_HXX__ +#define __MEDLOADERTEST_HXX__ + +#include + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + + class MEDLoaderTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE(MEDLoaderTest); + CPPUNIT_TEST( testMesh1DRW ); + CPPUNIT_TEST( testMesh2DCurveRW ); + CPPUNIT_TEST( testMesh2DRW ); + CPPUNIT_TEST( testMesh3DSurfRW ); + CPPUNIT_TEST( testMesh3DRW ); + CPPUNIT_TEST( testFieldRW1 ); + CPPUNIT_TEST( testFieldRW2 ); + CPPUNIT_TEST( testFieldRW3 ); + CPPUNIT_TEST( testMultiMeshRW1 ); + CPPUNIT_TEST( testFieldProfilRW1 ); + CPPUNIT_TEST( testFieldNodeProfilRW1 ); + CPPUNIT_TEST( testFieldNodeProfilRW2 ); + CPPUNIT_TEST( testFieldGaussRW1 ); + CPPUNIT_TEST( testFieldGaussNERW1 ); + CPPUNIT_TEST( testLittleStrings1 ); + CPPUNIT_TEST( testMesh3DSurfShuffleRW ); + CPPUNIT_TEST( testFieldShuffleRW1 ); + CPPUNIT_TEST( testMultiFieldShuffleRW1 ); + CPPUNIT_TEST( testWriteUMeshesRW1 ); + CPPUNIT_TEST( testMixCellAndNodesFieldRW1 ); + CPPUNIT_TEST( testGetAllFieldNamesRW1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testMesh1DRW(); + void testMesh2DCurveRW(); + void testMesh2DRW(); + void testMesh3DSurfRW(); + void testMesh3DRW(); + void testFieldRW1(); + void testFieldRW2(); + void testFieldRW3(); + void testMultiMeshRW1(); + void testFieldProfilRW1(); + void testFieldNodeProfilRW1(); + void testFieldNodeProfilRW2(); + void testFieldGaussRW1(); + void testFieldGaussNERW1(); + void testLittleStrings1(); + void testMesh3DSurfShuffleRW(); + void testFieldShuffleRW1(); + void testMultiFieldShuffleRW1(); + void testWriteUMeshesRW1(); + void testMixCellAndNodesFieldRW1(); + void testGetAllFieldNamesRW1(); + private: + MEDCouplingUMesh *build1DMesh_1(); + MEDCouplingUMesh *build2DCurveMesh_1(); + MEDCouplingUMesh *build2DMesh_1(); + MEDCouplingUMesh *build2DMesh_2(); + MEDCouplingUMesh *build3DSurfMesh_1(); + MEDCouplingUMesh *build3DMesh_1(); + MEDCouplingUMesh *build3DMesh_2(); + MEDCouplingFieldDouble *buildVecFieldOnCells_1(); + MEDCouplingFieldDouble *buildVecFieldOnNodes_1(); + MEDCouplingFieldDouble *buildVecFieldOnGauss_1(); + MEDCouplingFieldDouble *buildVecFieldOnGaussNE_1(); + }; +} + +#endif diff --git a/src/MEDLoader/Test/Makefile.am b/src/MEDLoader/Test/Makefile.am new file mode 100755 index 000000000..46e1c4052 --- /dev/null +++ b/src/MEDLoader/Test/Makefile.am @@ -0,0 +1,39 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D +# +# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +bin_PROGRAMS= TestMEDLoader + +TestMEDLoader_CPPFLAGS=@CPPUNIT_INCLUDES@ @PTHREAD_CFLAGS@ -I$(srcdir)/.. -I$(srcdir)/../../INTERP_KERNEL/Bases -I$(srcdir)/../../INTERP_KERNELTest -I$(srcdir)/../../INTERP_KERNEL -I$(srcdir)/../../INTERP_KERNEL/Geometric2D -I$(srcdir)/../../MEDCoupling + +TestMEDLoader_LDFLAGS = @CPPUNIT_LIBS@ ../libmedloader.la ../../MEDCoupling/libmedcoupling.la ../../INTERP_KERNEL/libinterpkernel.la + +dist_TestMEDLoader_SOURCES = TestMEDLoader.cxx MEDLoaderTest.cxx MEDLoaderTest.hxx + +UNIT_TEST_PROG = TestMEDLoader + +check : tests + +CLEANFILES = \ + UnitTestsResult + +clean-local: + rm -rf *.med + \ No newline at end of file diff --git a/src/MEDLoader/Test/TestMEDLoader.cxx b/src/MEDLoader/Test/TestMEDLoader.cxx new file mode 100644 index 000000000..a48da92f5 --- /dev/null +++ b/src/MEDLoader/Test/TestMEDLoader.cxx @@ -0,0 +1,25 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "CppUnitTest.hxx" +#include "MEDLoaderTest.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDLoaderTest ); + +#include "BasicMainTest.hxx" diff --git a/src/ParaMEDMEM/DEC.cxx b/src/ParaMEDMEM/DEC.cxx index 32bcc69ea..4003b65fc 100644 --- a/src/ParaMEDMEM/DEC.cxx +++ b/src/ParaMEDMEM/DEC.cxx @@ -84,42 +84,60 @@ namespace ParaMEDMEM { _union_group = source_group.fuse(target_group); } - - DEC::DEC(const int *src_ids_bg, const int *src_ids_end, - const int *trg_ids_bg, const int *trg_ids_end, - const MPI_Comm& world_comm):_local_field(0), - _owns_field(false), - _owns_groups(true), - _icoco_field(0) + DEC::DEC(const std::set& source_ids, const std::set& target_ids, const MPI_Comm& world_comm):_local_field(0), + _owns_field(false), + _owns_groups(true), + _icoco_field(0) { ParaMEDMEM::CommInterface comm; // Create the list of procs including source and target - int nbOfProcsInComm=std::distance(src_ids_bg,src_ids_end)+std::distance(trg_ids_bg,trg_ids_end); - int *allRanks=new int[nbOfProcsInComm]; - std::copy(src_ids_bg,src_ids_end,allRanks); - std::copy(trg_ids_bg,trg_ids_end,allRanks+std::distance(src_ids_bg,src_ids_end)); + std::set union_ids; // source and target ids in world_comm + union_ids.insert(source_ids.begin(),source_ids.end()); + union_ids.insert(target_ids.begin(),target_ids.end()); + int* union_ranks_world=new int[union_ids.size()]; // ranks of sources and targets in world_comm + std::copy::const_iterator,int*> (union_ids.begin(), union_ids.end(), union_ranks_world); + // Create a communicator on these procs - MPI_Group src_trg_group, world_group; + MPI_Group union_group,world_group; comm.commGroup(world_comm,&world_group); - comm.groupIncl(world_group,nbOfProcsInComm,allRanks,&src_trg_group); - MPI_Comm src_trg_comm; - comm.commCreate(world_comm,src_trg_group,&src_trg_comm); - delete [] allRanks; - // - if(src_trg_comm==MPI_COMM_NULL) - {//Current procid is not part of src_trg_comm + comm.groupIncl(world_group,union_ids.size(),union_ranks_world,&union_group); + MPI_Comm union_comm; + comm.commCreate(world_comm,union_group,&union_comm); + delete[] union_ranks_world; + + if (union_comm==MPI_COMM_NULL) + { // This process is not in union _source_group=0; _target_group=0; _union_group=0; return; } - std::set source_ids(src_ids_bg,src_ids_end); - _source_group=new MPIProcessorGroup(comm,source_ids,src_trg_comm); - std::set target_ids(trg_ids_bg,trg_ids_end); - _target_group=new MPIProcessorGroup(comm,target_ids,src_trg_comm); - std::set src_trg_ids(src_ids_bg,src_ids_end); - src_trg_ids.insert(trg_ids_bg,trg_ids_end); - _union_group=new MPIProcessorGroup(comm,src_trg_ids,src_trg_comm); + + // Translate source_ids and target_ids from world_comm to union_comm + int* source_ranks_world=new int[source_ids.size()]; // ranks of sources in world_comm + std::copy::const_iterator,int*> (source_ids.begin(), source_ids.end(),source_ranks_world); + int* source_ranks_union=new int[source_ids.size()]; // ranks of sources in union_comm + int* target_ranks_world=new int[target_ids.size()]; // ranks of targets in world_comm + std::copy::const_iterator,int*> (target_ids.begin(), target_ids.end(),target_ranks_world); + int* target_ranks_union=new int[target_ids.size()]; // ranks of targets in union_comm + MPI_Group_translate_ranks(world_group,source_ids.size(),source_ranks_world,union_group,source_ranks_union); + MPI_Group_translate_ranks(world_group,target_ids.size(),target_ranks_world,union_group,target_ranks_union); + std::set source_ids_union; + for (int i=0;i<(int)source_ids.size();i++) + source_ids_union.insert(source_ranks_union[i]); + std::set target_ids_union; + for (int i=0;i<(int)target_ids.size();i++) + target_ids_union.insert(target_ranks_union[i]); + delete [] source_ranks_world; + delete [] source_ranks_union; + delete [] target_ranks_world; + delete [] target_ranks_union; + + // Create the MPIProcessorGroups + _source_group= new MPIProcessorGroup(comm,source_ids_union,union_comm); + _target_group = new MPIProcessorGroup(comm,target_ids_union,union_comm); + _union_group = _source_group->fuse(*_target_group); + } DEC::~DEC() diff --git a/src/ParaMEDMEM/DEC.hxx b/src/ParaMEDMEM/DEC.hxx index e60825168..3c5ddf8fb 100644 --- a/src/ParaMEDMEM/DEC.hxx +++ b/src/ParaMEDMEM/DEC.hxx @@ -24,6 +24,8 @@ #include "NormalizedUnstructuredMesh.hxx" #include "DECOptions.hxx" +#include + namespace ICoCo { class Field; @@ -39,8 +41,7 @@ namespace ParaMEDMEM public: DEC():_local_field(0) { } DEC(ProcessorGroup& source_group, ProcessorGroup& target_group); - DEC(const int *src_ids_bg, const int *src_ids_end, - const int *trg_ids_bg, const int *trg_ids_end, + DEC(const std::set& src_ids, const std::set& trg_ids, const MPI_Comm& world_comm=MPI_COMM_WORLD); void setNature(NatureOfField nature); void attachLocalField( MEDCouplingFieldDouble* field); diff --git a/src/ParaMEDMEM/ElementLocator.cxx b/src/ParaMEDMEM/ElementLocator.cxx index e694c4e1d..3252279cd 100644 --- a/src/ParaMEDMEM/ElementLocator.cxx +++ b/src/ParaMEDMEM/ElementLocator.cxx @@ -35,7 +35,7 @@ using namespace std; -#define USE_DIRECTED_BB +//#define USE_DIRECTED_BB namespace ParaMEDMEM { @@ -299,14 +299,11 @@ namespace ParaMEDMEM ptDist2, nbDistElem, MPI_DOUBLE, iprocdistant_in_union, 1112, *comm, &status); - if(!distant_mesh_tmp->isEmptyMesh(tinyInfoDistant)) - { - distant_mesh=distant_mesh_tmp; - //finish unserialization - distant_mesh->unserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - } - else - distant_mesh_tmp->decrRef(); + // + distant_mesh=distant_mesh_tmp; + //finish unserialization + distant_mesh->unserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); + // distant_ids_recv=new int[tinyInfoDistant.back()]; comm_interface.sendRecv((void *)distant_ids_send->getConstPointer(),tinyInfoLocal.back(), MPI_INT, iprocdistant_in_union, 1113, diff --git a/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx b/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx index 7794ef150..0d805af4f 100644 --- a/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx +++ b/src/ParaMEDMEM/ExplicitCoincidentDEC.cxx @@ -288,7 +288,7 @@ namespace ParaMEDMEM } int* recvcounts=new int[world_size]; int* recvdispls=new int[world_size]; - int *dummyrecv; + int *dummyrecv=0; for (int i=0; i #include -#include using namespace ICoCo; using std::string; diff --git a/src/ParaMEDMEM/ICoCoField.hxx b/src/ParaMEDMEM/ICoCoField.hxx index c9d2813f6..b38eb0034 100644 --- a/src/ParaMEDMEM/ICoCoField.hxx +++ b/src/ParaMEDMEM/ICoCoField.hxx @@ -1,31 +1,15 @@ -// Copyright (C) 2007-2010 CEA/DEN, EDF R&D -// -// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __ICOCOFIELD_HXX__ -#define __ICOCOFIELD_HXX__ +// ICoCo file common to several codes +// ICoCoField.h +// version 1.2 10/05/2010 +#ifndef _ICoCoField_included_ +#define _ICoCoField_included_ #include -namespace ICoCo -{ - class Field - { + +namespace ICoCo { + + class Field { public: Field(); virtual ~Field(); @@ -37,5 +21,4 @@ namespace ICoCo std::string* _name; }; } - #endif diff --git a/src/ParaMEDMEM/ICoCoTrioField.cxx b/src/ParaMEDMEM/ICoCoTrioField.cxx index 1e5a14d22..0b18196c2 100644 --- a/src/ParaMEDMEM/ICoCoTrioField.cxx +++ b/src/ParaMEDMEM/ICoCoTrioField.cxx @@ -16,28 +16,41 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -////////////////////////////////////////////////////////////////////////////// -// File: ICoCoTrioField.cpp -// Directory: $TRIO_U_ROOT/Kernel/Framework -// Version: -////////////////////////////////////////////////////////////////////////////// +// ICoCo file common to several codes +// ICoCoTrioField.cpp +// version 1.2 10/05/2010 #include #include #include -#include +#include using namespace ICoCo; using namespace std; +// Default constructor TrioField::TrioField() : _type(0), + _mesh_dim(0), + _space_dim(0), + _nbnodes(0), + _nodes_per_elem(0), + _nb_elems(0), + _itnumber(0), _connectivity(0), _coords(0), + _time1(0.), + _time2(0.), + _nb_field_components(0), _field(0), _has_field_ownership(false) { } +// Copy constructor +TrioField::TrioField(const TrioField& OtherField) { + (*this)=OtherField; +} + +// Destructor TrioField::~TrioField() { clear(); } @@ -57,134 +70,124 @@ void TrioField::clear() { _has_field_ownership=false; } -int TrioField::nb_values() const -{ +// Returns the number of value locations +// The size of field is nb_values()*_nb_field_components +int TrioField::nb_values() const { if (_type==0) return _nb_elems; - else - if (_type==1) - return _nbnodes; - exit(-1); + else if (_type==1) + return _nbnodes; + throw 0; + //exit(-1); return -1; - } + +// Save field to a .field file (loadable by visit!) void TrioField::save(ostream& os) const{ - os <> name; setName(name); - in>>_type; - in>>_mesh_dim; - in>> _space_dim; - in>> _nbnodes; - in>> _nodes_per_elem; - in>> _nb_elems; + in >> _type; + in >> _mesh_dim; + in >> _space_dim; + in >> _nbnodes; + in >> _nodes_per_elem; + in >> _nb_elems; - in>> _itnumber; + in >> _itnumber; if (_connectivity) delete [] _connectivity; _connectivity=new int[_nodes_per_elem*_nb_elems]; - for (int i=0;i<_nb_elems;i++) - { - for (int j=0;j<_nodes_per_elem;j++) - in>>_connectivity[i*_nodes_per_elem+j]; - - } + for (int i=0;i<_nb_elems;i++) { + for (int j=0;j<_nodes_per_elem;j++) + in >> _connectivity[i*_nodes_per_elem+j]; + } if (_coords) delete [] _coords; _coords=new double[_nbnodes*_space_dim]; - for (int i=0;i<_nbnodes;i++) - { - for (int j=0;j<_space_dim;j++) - in>> _coords[i*_space_dim+j] ; - - } + for (int i=0;i<_nbnodes;i++) { + for (int j=0;j<_space_dim;j++) + in >> _coords[i*_space_dim+j]; + } - in>> _time1; - in>>_time2; - in>> _nb_field_components; + in >> _time1; + in >> _time2; + in >> _nb_field_components; int test; - in>> test; - if (test) - { - if (_field) - delete [] _field; - _field=new double[_nb_field_components*nb_values()]; - for (int i=0;i> _field[i*_nb_field_components+j]; - - } + in >> test; + if (test) { + if (_field) + delete [] _field; + _field=new double[_nb_field_components*nb_values()]; + for (int i=0;i> _field[i*_nb_field_components+j]; } + } else - { - _field=0; - } - in>> _has_field_ownership; + _field=0; + + in >> _has_field_ownership; } - void TrioField::print() { - } // After the call to set_standalone(), field ownership is true and field is allocated -// to the size _nb_field_components*_nb_elems. +// to the size _nb_field_components*nb_values(). // The values of the field have been copied if necessary. void TrioField::set_standalone() { if (!_field) { - _field=new double[_nb_field_components*_nb_elems]; + _field=new double[_nb_field_components*nb_values()]; _has_field_ownership=true; } else if (!_has_field_ownership) { - double *tmp_field=new double[_nb_field_components*_nb_elems]; - memcpy(tmp_field,_field,_nb_field_components*_nb_elems*sizeof(double)); + double *tmp_field=new double[_nb_field_components*nb_values()]; + memcpy(tmp_field,_field,_nb_field_components*nb_values()*sizeof(double)); _field=tmp_field; _has_field_ownership=true; } @@ -192,6 +195,7 @@ void TrioField::set_standalone() { // Used to simulate a 0D geometry (Cathare/Trio for example). void TrioField::dummy_geom() { + _type=0; _mesh_dim=2; _space_dim=2; _nbnodes=3; @@ -201,9 +205,9 @@ void TrioField::dummy_geom() { if (_connectivity) delete[] _connectivity; _connectivity=new int[3]; - _connectivity[0]=1; - _connectivity[1]=2; - _connectivity[2]=3; + _connectivity[0]=0; + _connectivity[1]=1; + _connectivity[2]=2; if (_coords) delete[] _coords; _coords=new double[6]; @@ -213,53 +217,60 @@ void TrioField::dummy_geom() { _coords[3]=0; _coords[4]=0; _coords[5]=1; + _time1=0; + _time2=1; + _nb_field_components=1; if (_field && _has_field_ownership) delete[] _field; _has_field_ownership=false; _field=0; } -// Surcharge de l'operateur = pour la classe TrioField -// remplace les valeurs trouvee dans le TrioField donnee en parametre +// Overloading operator = for TrioField +// This becomes an exact copy of NewField. +// If NewField._has_field_ownership is false, they point to the same values. +// Otherwise the values are copied. TrioField& TrioField::operator=(const TrioField& NewField){ - clear(); - _type=NewField._type; - _mesh_dim=NewField._mesh_dim; - _space_dim=NewField._space_dim; - _nbnodes=NewField._nbnodes; - _nodes_per_elem=NewField._nodes_per_elem; - _nb_elems=NewField._nb_elems; - _itnumber=NewField._itnumber; - // std::string _name; // ?? Hérité de la classe mère - _time1=NewField._time1; - _time2=NewField._time2; - _nb_field_components=NewField._nb_field_components; + clear(); - if (!NewField._connectivity) - _connectivity=0; - else { - _connectivity=new int[_nodes_per_elem*_nb_elems]; - memcpy( _connectivity,NewField._connectivity,_nodes_per_elem*_nb_elems*sizeof(int)); - } + _type=NewField._type; + _mesh_dim=NewField._mesh_dim; + _space_dim=NewField._space_dim; + _nbnodes=NewField._nbnodes; + _nodes_per_elem=NewField._nodes_per_elem; + _nb_elems=NewField._nb_elems; + _itnumber=NewField._itnumber; + _time1=NewField._time1; + _time2=NewField._time2; + _nb_field_components=NewField._nb_field_components; - if (!NewField._coords) - _coords=0; - else { - _coords=new double[_nbnodes*_space_dim]; - memcpy( _coords,NewField._coords,_nbnodes*_space_dim*sizeof(double)); - } + if (!NewField._connectivity) + _connectivity=0; + else { + _connectivity=new int[_nodes_per_elem*_nb_elems]; + memcpy( _connectivity,NewField._connectivity,_nodes_per_elem*_nb_elems*sizeof(int)); + } - //Copie des valeurs du champ - _has_field_ownership=NewField._has_field_ownership; - if (_has_field_ownership) { - _field=new double[_nb_elems*_nb_field_components]; - memcpy(_field,NewField._field,_nb_elems*_nb_field_components*sizeof(double)); - } - else - _field=NewField._field; + if (!NewField._coords) + _coords=0; + else { + _coords=new double[_nbnodes*_space_dim]; + memcpy( _coords,NewField._coords,_nbnodes*_space_dim*sizeof(double)); + } - return(*this); + //Copie des valeurs du champ + _has_field_ownership=NewField._has_field_ownership; + if (_has_field_ownership) { + _field=new double[nb_values()*_nb_field_components]; + memcpy(_field,NewField._field,nb_values()*_nb_field_components*sizeof(double)); + } + else + _field=NewField._field; + + return(*this); } + + diff --git a/src/ParaMEDMEM/ICoCoTrioField.hxx b/src/ParaMEDMEM/ICoCoTrioField.hxx index cb238ff5c..738e312ea 100644 --- a/src/ParaMEDMEM/ICoCoTrioField.hxx +++ b/src/ParaMEDMEM/ICoCoTrioField.hxx @@ -16,46 +16,42 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// ICoCo file common to several codes +// ICoCoTrioField.h +// version 1.2 10/05/2010 -////////////////////////////////////////////////////////////////////////////// -// File: ICoCoTrioField.h -// Directory: $TRIO_U_ROOT/Kernel/Framework -// Version: -////////////////////////////////////////////////////////////////////////////// - -#ifndef _ICOCOTRIOFIELD_HXX_ -#define _ICOCOTRIOFIELD_HXX_ +#ifndef _ICoCoTrioField_included_ +#define _ICoCoTrioField_included_ #include -namespace ICoCo -{ - /*! - \brief structure for coupling Trio codes via the ICoCo interface - - This structure contains all the necessary information - for constructing a ParaMEDMEM::ParaFIELD (with the addition of the MPI - communicator). The ICoCo API specifies two kinds of calls for - the ICoCo::Field : either with the mesh only or with the entire information (mesh and field). - This structure can therefore be left without _time, _nb_field_components, _field - information, which are related to the field values. +namespace ICoCo { - _coords and _connectivity tables are always owned by the TrioField. - - */ - class TrioField:public Field - { + ////////////////////////////////////////////////////////////////////////////// + // + // .DESCRIPTION + // class TrioField, used for coupling Trio codes via the ICoCo interface + // This structure contains all the necessary information + // for constructing a ParaMEDMEM::ParaFIELD (with the addition of the MPI + // communicator). + // This structure can either own or not _field values (_has_field_ownership) + // For _coords, _connectivity and _field, a null pointer means no data allocated. + // _coords and _connectivity tables, when allocated, are always owned by the TrioField. + // + ////////////////////////////////////////////////////////////////////////////// + class TrioField:public Field { public: TrioField(); + TrioField(const TrioField& OtherField); ~TrioField(); void clear(); - void print(); void set_standalone(); void dummy_geom(); TrioField& operator=(const TrioField& NewField); void save(std::ostream& os) const; void restore(std::istream& in); int nb_values() const ; + public: int _type ; // 0 elem 1 nodes int _mesh_dim; diff --git a/src/ParaMEDMEM/InterpKernelDEC.cxx b/src/ParaMEDMEM/InterpKernelDEC.cxx index 1eb5a243e..6c4674f84 100644 --- a/src/ParaMEDMEM/InterpKernelDEC.cxx +++ b/src/ParaMEDMEM/InterpKernelDEC.cxx @@ -123,9 +123,8 @@ namespace ParaMEDMEM } - InterpKernelDEC::InterpKernelDEC(const int *src_ids_bg, const int *src_ids_end, - const int *trg_ids_bg, const int *trg_ids_end, - const MPI_Comm& world_comm):DEC(src_ids_bg,src_ids_end,trg_ids_bg,trg_ids_end,world_comm), + InterpKernelDEC::InterpKernelDEC(const std::set& src_ids, const std::set& trg_ids, + const MPI_Comm& world_comm):DEC(src_ids,trg_ids,world_comm), _interpolation_matrix(0) { } @@ -160,10 +159,8 @@ namespace ParaMEDMEM { //locate the distant meshes ElementLocator locator(*_local_field, *_target_group, *_source_group); - - //transfering option from InterpKernelDEC to ElementLocator - locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); - + //transfering option from InterpKernelDEC to ElementLocator + locator.copyOptions(*this); MEDCouplingPointSet* distant_mesh=0; int* distant_ids=0; std::string distantMeth; @@ -194,8 +191,7 @@ namespace ParaMEDMEM { ElementLocator locator(*_local_field, *_source_group, *_target_group); //transfering option from InterpKernelDEC to ElementLocator - locator.setBoundingBoxAdjustment(getBoundingBoxAdjustment()); - + locator.copyOptions(*this); MEDCouplingPointSet* distant_mesh=0; int* distant_ids=0; for (int i=0; i<_source_group->size(); i++) diff --git a/src/ParaMEDMEM/InterpKernelDEC.hxx b/src/ParaMEDMEM/InterpKernelDEC.hxx index 908f21700..7930a044d 100644 --- a/src/ParaMEDMEM/InterpKernelDEC.hxx +++ b/src/ParaMEDMEM/InterpKernelDEC.hxx @@ -33,8 +33,7 @@ namespace ParaMEDMEM public: InterpKernelDEC(); InterpKernelDEC(ProcessorGroup& source_group, ProcessorGroup& target_group); - InterpKernelDEC(const int *src_ids_bg, const int *src_ids_end, - const int *trg_ids_bg, const int *trg_ids_end, + InterpKernelDEC(const std::set& src_ids, const std::set& trg_ids, const MPI_Comm& world_comm=MPI_COMM_WORLD); virtual ~InterpKernelDEC(); void synchronize(); diff --git a/src/ParaMEDMEM/InterpolationMatrix.cxx b/src/ParaMEDMEM/InterpolationMatrix.cxx index 5f3a424ea..c7db0371c 100644 --- a/src/ParaMEDMEM/InterpolationMatrix.cxx +++ b/src/ParaMEDMEM/InterpolationMatrix.cxx @@ -24,6 +24,8 @@ #include "InterpolationMatrix.hxx" #include "TranslationRotationMatrix.hxx" #include "Interpolation.hxx" +#include "Interpolation1D.txx" +#include "Interpolation2DCurve.txx" #include "Interpolation2D.txx" #include "Interpolation3DSurf.txx" #include "Interpolation3D.txx" @@ -160,6 +162,28 @@ namespace ParaMEDMEM { throw INTERP_KERNEL::Exception("local and distant meshes do not have the same space and mesh dimensions"); } + else if( distant_support.getMeshDimension() == 1 + && distant_support.getSpaceDimension() == 1 ) + { + MEDCouplingNormalizedUnstructuredMesh<1,1> target_wrapper(distant_supportC); + MEDCouplingNormalizedUnstructuredMesh<1,1> source_wrapper(source_supportC); + + INTERP_KERNEL::Interpolation1D interpolation(*this); + colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + target_wrapper.releaseTempArrays(); + source_wrapper.releaseTempArrays(); + } + else if( distant_support.getMeshDimension() == 1 + && distant_support.getSpaceDimension() == 2 ) + { + MEDCouplingNormalizedUnstructuredMesh<2,1> target_wrapper(distant_supportC); + MEDCouplingNormalizedUnstructuredMesh<2,1> source_wrapper(source_supportC); + + INTERP_KERNEL::Interpolation2DCurve interpolation(*this); + colSize=interpolation.interpolateMeshes(target_wrapper,source_wrapper,surfaces,interpMethod.c_str()); + target_wrapper.releaseTempArrays(); + source_wrapper.releaseTempArrays(); + } else if ( distant_support.getMeshDimension() == 2 && distant_support.getSpaceDimension() == 3 ) { diff --git a/src/ParaMEDMEM/ParaFIELD.cxx b/src/ParaMEDMEM/ParaFIELD.cxx index 6822a19fb..e0f0ba085 100644 --- a/src/ParaMEDMEM/ParaFIELD.cxx +++ b/src/ParaMEDMEM/ParaFIELD.cxx @@ -213,7 +213,7 @@ namespace ParaMEDMEM double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const { CommInterface comm_interface = _topology->getProcGroup()->getCommInterface(); - double integral=_field->measureAccumulate(icomp,isWAbs); + double integral=_field->integral(icomp,isWAbs); double total=0.; const MPI_Comm* comm = (dynamic_cast(_topology->getProcGroup()))->getComm(); comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm); diff --git a/src/ParaMEDMEMTest/MPI2Connector.cxx b/src/ParaMEDMEMTest/MPI2Connector.cxx new file mode 100644 index 000000000..8daa23516 --- /dev/null +++ b/src/ParaMEDMEMTest/MPI2Connector.cxx @@ -0,0 +1,143 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MPI2Connector.hxx" + +#include + +MPI2Connector::MPI2Connector() +{ + MPI_Comm_size( MPI_COMM_WORLD, &_nb_proc ); + MPI_Comm_rank( MPI_COMM_WORLD, &_num_proc ); +} + +MPI2Connector::~MPI2Connector() +{ +} + +MPI_Comm MPI2Connector::remoteMPI2Connect(const std::string& service) +{ + int i; + char port_name[MPI_MAX_PORT_NAME]; + char port_name_clt[MPI_MAX_PORT_NAME]; + std::ostringstream msg; + MPI_Comm icom; + + if( service.size() == 0 ) + { + msg << "[" << _num_proc << "] You have to give a service name !"; + std::cerr << msg.str().c_str() << std::endl; + throw std::exception(); + } + + _srv = false; + + MPI_Barrier(MPI_COMM_WORLD); + + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN); + if( _num_proc == 0 ) + { + /* rank 0 try to be a server. If service is already published, try to be a cient */ + MPI_Open_port(MPI_INFO_NULL, port_name); + if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS ) + { + _srv = true; + _port_name = port_name; + std::cerr << "[" << _num_proc << "] service " << service << " available at " << port_name << std::endl; + } + else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ) + { + std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl; + MPI_Close_port( port_name ); + } + else + { + msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt; + std::cerr << msg.str().c_str() << std::endl; + throw std::exception(); + } + } + else + { + i=0; + /* Waiting rank 0 publish name and try to be a client */ + while ( i != TIMEOUT ) + { + sleep(1); + if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ) + { + std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl; + break; + } + i++; + } + if(i==TIMEOUT) + { + msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt; + std::cerr << msg.str().c_str() << std::endl; + throw std::exception(); + } + } + MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL); + + /* If rank 0 is server, all processes call MPI_Comm_accept */ + /* If rank 0 is not server, all processes call MPI_Comm_connect */ + int srv = (int)_srv; + MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD); + _srv = (bool)srv; + if ( _srv ) + MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom ); + else + MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom ); + + /* create global communicator: servers have low index in global communicator*/ + MPI_Intercomm_merge(icom,!_srv,&_gcom); + + /* only rank 0 can be server for unpublish name */ + if(_num_proc != 0) _srv = false; + + return _gcom; + +} + +void MPI2Connector::remoteMPI2Disconnect(const std::string& service) +{ + std::ostringstream msg; + + if( service.size() == 0 ) + { + msg << "[" << _num_proc << "] You have to give a service name !"; + std::cerr << msg.str().c_str() << std::endl; + throw std::exception(); + } + + MPI_Comm_disconnect( &_gcom ); + if ( _srv ) + { + + char port_name[MPI_MAX_PORT_NAME]; + strcpy(port_name,_port_name.c_str()); + + MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name); + std::cerr << "[" << _num_proc << "] " << service << ": close port " << _port_name << std::endl; + MPI_Close_port( port_name ); + } + +} + diff --git a/src/ParaMEDMEMTest/MPI2Connector.hxx b/src/ParaMEDMEMTest/MPI2Connector.hxx new file mode 100644 index 000000000..905de10fb --- /dev/null +++ b/src/ParaMEDMEMTest/MPI2Connector.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MPI2CONNECTOR_HXX__ +#define __MPI2CONNECTOR_HXX__ + +#include +#include +#include + +class MPI2Connector +{ +public: + MPI2Connector(); + ~MPI2Connector(); + // MPI2 connection + MPI_Comm remoteMPI2Connect(const std::string& service); + // MPI2 disconnection + void remoteMPI2Disconnect(const std::string& service); +private: + // Processus id + int _num_proc; + // Processus size + int _nb_proc; + MPI_Comm _gcom; + bool _srv; + std::string _port_name; +private: + static const int TIMEOUT=5; +}; + +#endif diff --git a/src/ParaMEDMEMTest/Makefile.am b/src/ParaMEDMEMTest/Makefile.am index 200a4bf44..f172ee9fc 100644 --- a/src/ParaMEDMEMTest/Makefile.am +++ b/src/ParaMEDMEMTest/Makefile.am @@ -25,9 +25,8 @@ salomeinclude_HEADERS = \ MPIMainTest.hxx \ MPIAccessDECTest.hxx \ MPIAccessTest.hxx \ - ParaMEDMEMTest.hxx - -EXTRA_DIST += MPIMainTest.hxx ParaMEDMEMTest_NonCoincidentDEC.cxx + ParaMEDMEMTest.hxx \ + MPI2Connector.hxx dist_libParaMEDMEMTest_la_SOURCES = \ ParaMEDMEMTest.cxx \ @@ -39,6 +38,7 @@ dist_libParaMEDMEMTest_la_SOURCES = \ ParaMEDMEMTest_ICocoTrio.cxx \ ParaMEDMEMTest_Gauthier1.cxx \ ParaMEDMEMTest_FabienAPI.cxx \ + ParaMEDMEMTest_NonCoincidentDEC.cxx \ MPIAccessDECTest.cxx \ test_AllToAllDEC.cxx \ test_AllToAllvDEC.cxx \ @@ -62,7 +62,6 @@ dist_libParaMEDMEMTest_la_SOURCES = \ test_MPI_Access_Time_0.cxx \ test_MPI_Access_ISend_IRecv_BottleNeck.cxx - libParaMEDMEMTest_la_CPPFLAGS = \ @CPPUNIT_INCLUDES@ \ $(MPI_INCLUDES) \ @@ -91,6 +90,21 @@ dist_TestMPIAccessDEC_SOURCES = TestMPIAccessDEC.cxx dist_TestMPIAccess_SOURCES = TestMPIAccess.cxx dist_test_perf_SOURCES = test_perf.cxx +if MPI2_IS_OK +bin_PROGRAMS += \ + ParaMEDMEMTestMPI2_1 \ + ParaMEDMEMTestMPI2_2 + +dist_ParaMEDMEMTestMPI2_1_SOURCES = \ + MPI2Connector.cxx \ + ParaMEDMEMTestMPI2_1.cxx + +dist_ParaMEDMEMTestMPI2_2_SOURCES = \ + MPI2Connector.cxx \ + ParaMEDMEMTestMPI2_2.cxx + +endif + LDADD = $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm $(MPI_LIBS) \ libParaMEDMEMTest.la \ ../INTERP_KERNEL/libinterpkernel.la $(CPPUNIT_LIBS) \ @@ -101,7 +115,6 @@ LDADD = $(MED2_LIBS) $(libMEDMEMTest_la_LDFLAGS) -lm $(MPI_LIBS) \ if MED_ENABLE_FVM LDADD += $(FVM_LIBS) - dist_libParaMEDMEMTest_la_SOURCES += ParaMEDMEMTest_NonCoincidentDEC.cxx libParaMEDMEMTest_la_CPPFLAGS += -DMED_ENABLE_FVM $(FVM_INCLUDES) libParaMEDMEMTest_la_LDFLAGS += $(FVM_LIBS) endif diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx index da4e4873c..be30599ae 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest.hxx @@ -36,6 +36,8 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testMPIProcessorGroup_rank); CPPUNIT_TEST(testBlockTopology_constructor); CPPUNIT_TEST(testBlockTopology_serialize); + CPPUNIT_TEST(testInterpKernelDEC_1D); + CPPUNIT_TEST(testInterpKernelDEC_2DCurve); CPPUNIT_TEST(testInterpKernelDEC_2D); CPPUNIT_TEST(testInterpKernelDEC2_2D); CPPUNIT_TEST(testInterpKernelDEC_2DP0P1); @@ -44,6 +46,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testInterpKernelDECNonOverlapp_2D_P0P1P1P0); CPPUNIT_TEST(testInterpKernelDEC2DM1D_P0P0); CPPUNIT_TEST(testInterpKernelDECPartialProcs); + CPPUNIT_TEST(testInterpKernelDEC3DSurfEmptyBBox); CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpNativeDEC_2D); CPPUNIT_TEST(testSynchronousEqualInterpKernelWithoutInterpDEC_2D); @@ -68,6 +71,7 @@ class ParaMEDMEMTest : public CppUnit::TestFixture CPPUNIT_TEST(testGauthier1); CPPUNIT_TEST(testGauthier2); CPPUNIT_TEST(testFabienAPI1); + CPPUNIT_TEST(testFabienAPI2); CPPUNIT_TEST(testMEDLoaderRead1); CPPUNIT_TEST(testMEDLoaderPolygonRead); CPPUNIT_TEST(testMEDLoaderPolyhedronRead); @@ -87,6 +91,8 @@ public: void testMPIProcessorGroup_rank(); void testBlockTopology_constructor(); void testBlockTopology_serialize(); + void testInterpKernelDEC_1D(); + void testInterpKernelDEC_2DCurve(); void testInterpKernelDEC_2D(); void testInterpKernelDEC2_2D(); void testInterpKernelDEC_2DP0P1(); @@ -95,6 +101,7 @@ public: void testInterpKernelDECNonOverlapp_2D_P0P1P1P0(); void testInterpKernelDEC2DM1D_P0P0(); void testInterpKernelDECPartialProcs(); + void testInterpKernelDEC3DSurfEmptyBBox(); #ifdef MED_ENABLE_FVM void testNonCoincidentDEC_2D(); void testNonCoincidentDEC_3D(); @@ -118,6 +125,7 @@ public: void testGauthier1(); void testGauthier2(); void testFabienAPI1(); + void testFabienAPI2(); // void testMEDLoaderRead1(); void testMEDLoaderPolygonRead(); @@ -130,11 +138,13 @@ public: std::string makeTmpFile( const std::string&, const std::string& = "" ); private: +#ifdef MED_ENABLE_FVM void testNonCoincidentDEC(const std::string& filename1, const std::string& meshname1, const std::string& filename2, const std::string& meshname2, int nbprocsource, double epsilon); +#endif void testAsynchronousInterpKernelDEC_2D(double dtA, double tmaxA, double dtB, double tmaxB, bool WithPointToPoint, bool Asynchronous, bool WithInterp, const char *srcMeth, const char *targetMeth); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx new file mode 100644 index 000000000..599d3fb57 --- /dev/null +++ b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_1.cxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include + +#include "MPI2Connector.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "InterpKernelDEC.hxx" +#include "MPIProcessorGroup.hxx" +#include "CommInterface.hxx" + +#include +#include +#include + +class MPI2ParaMEDMEMTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest ); + CPPUNIT_TEST( testBasicMPI2_1 ); + CPPUNIT_TEST_SUITE_END(); +public: + void testBasicMPI2_1(); +}; + +using namespace ParaMEDMEM; + +void MPI2ParaMEDMEMTest::testBasicMPI2_1() +{ + int lsize, lrank, gsize, grank; + MPI_Comm gcom; + std::string service = "SERVICE"; + std::ostringstream meshfilename, meshname; + ParaMEDMEM::ParaMESH *paramesh=0; + ParaMEDMEM::MEDCouplingUMesh *mesh; + ParaMEDMEM::ParaFIELD *parafield=0; + ParaMEDMEM::CommInterface *interface; + ParaMEDMEM::MPIProcessorGroup *source, *target; + + MPI_Comm_size( MPI_COMM_WORLD, &lsize ); + MPI_Comm_rank( MPI_COMM_WORLD, &lrank ); + if(lsize!=2) + { + CPPUNIT_ASSERT(false); + return; + } + + /* Connection to remote programm */ + MPI2Connector *mpio = new MPI2Connector; + gcom = mpio->remoteMPI2Connect(service); + MPI_Comm_size( gcom, &gsize ); + MPI_Comm_rank( gcom, &grank ); + if(gsize!=5) + { + CPPUNIT_ASSERT(false); + return; + } + interface = new ParaMEDMEM::CommInterface; + source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,lsize-1,gcom); + target = new ParaMEDMEM::MPIProcessorGroup(*interface,lsize,gsize-1,gcom); + + const double sourceCoordsAll[2][8]={{0.4,0.5,0.4,1.5,1.6,1.5,1.6,0.5}, + {0.3,-0.5,1.6,-0.5,1.6,-1.5,0.3,-1.5}}; + + int conn4All[8]={0,1,2,3,4,5,6,7}; + + std::ostringstream stream; stream << "sourcemesh2D proc " << grank; + mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + const double *sourceCoords=sourceCoordsAll[grank]; + std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*source,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + double *value=parafield->getField()->getArray()->getPointer(); + value[0]=34+13*((double)grank); + + ParaMEDMEM::InterpKernelDEC dec(*source,*target); + parafield->getField()->setNature(ConservativeVolumic); + + + dec.setMethod("P0"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + /* Deconnection of remote programm */ + mpio->remoteMPI2Disconnect(service); + /* clean-up */ + delete mpio; + delete parafield; + mesh->decrRef(); + delete paramesh; + delete source; + delete target; + delete interface; +} + +CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest ); + +#include "MPIMainTest.hxx" diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx new file mode 100644 index 000000000..9ed8819b0 --- /dev/null +++ b/src/ParaMEDMEMTest/ParaMEDMEMTestMPI2_2.cxx @@ -0,0 +1,130 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D +// +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include + +#include "MPI2Connector.hxx" +#include "ParaMESH.hxx" +#include "ParaFIELD.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "InterpKernelDEC.hxx" +#include "MPIProcessorGroup.hxx" +#include "CommInterface.hxx" + +#include +#include +#include + +class MPI2ParaMEDMEMTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MPI2ParaMEDMEMTest ); + CPPUNIT_TEST( testBasicMPI2_1 ); + CPPUNIT_TEST_SUITE_END(); +public: + void testBasicMPI2_1(); +}; + +using namespace ParaMEDMEM; + +void MPI2ParaMEDMEMTest::testBasicMPI2_1() +{ + int lsize, lrank, gsize, grank; + MPI_Comm gcom; + std::string service = "SERVICE"; + std::ostringstream meshfilename, meshname; + ParaMEDMEM::ParaMESH *paramesh=0; + ParaMEDMEM::MEDCouplingUMesh* mesh; + ParaMEDMEM::ParaFIELD *parafield=0; + ParaMEDMEM::CommInterface* interface; + ParaMEDMEM::MPIProcessorGroup* source, *target; + + MPI_Comm_size( MPI_COMM_WORLD, &lsize ); + MPI_Comm_rank( MPI_COMM_WORLD, &lrank ); + if(lsize!=3) + { + CPPUNIT_ASSERT(false); + return; + } + + /* Connection to remote programm */ + MPI2Connector *mpio = new MPI2Connector; + gcom = mpio->remoteMPI2Connect(service); + + MPI_Comm_size( gcom, &gsize ); + MPI_Comm_rank( gcom, &grank ); + if(gsize!=5) + { + CPPUNIT_ASSERT(false); + return; + } + + interface = new ParaMEDMEM::CommInterface; + source = new ParaMEDMEM::MPIProcessorGroup(*interface,0,gsize-lsize-1,gcom); + target = new ParaMEDMEM::MPIProcessorGroup(*interface,gsize-lsize,gsize-1,gcom); + + const double targetCoordsAll[3][16]={{0.7,1.45,0.7,1.65,0.9,1.65,0.9,1.45, 1.1,1.4,1.1,1.6,1.3,1.6,1.3,1.4}, + {0.7,-0.6,0.7,0.7,0.9,0.7,0.9,-0.6, 1.1,-0.7,1.1,0.6,1.3,0.6,1.3,-0.7}, + {0.7,-1.55,0.7,-1.35,0.9,-1.35,0.9,-1.55, 1.1,-1.65,1.1,-1.45,1.3,-1.45,1.3,-1.65}}; + int conn4All[8]={0,1,2,3,4,5,6,7}; + double targetResults[3][2]={{34.,34.},{38.333333333333336,42.666666666666664},{47.,47.}}; + + std::ostringstream stream; stream << "targetmesh2D proc " << grank-(gsize-lsize); + mesh=MEDCouplingUMesh::New(stream.str().c_str(),2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn4All+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(8,2); + const double *targetCoords=targetCoordsAll[grank-(gsize-lsize)]; + std::copy(targetCoords,targetCoords+16,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH (mesh,*target,"target mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafield = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + + ParaMEDMEM::InterpKernelDEC dec(*source,*target); + parafield->getField()->setNature(ConservativeVolumic); + + dec.setMethod("P0"); + dec.attachLocalField(parafield); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res=parafield->getField()->getArray()->getConstPointer(); + const double *expected=targetResults[grank-(gsize-lsize)]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[0],res[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[1],res[1],1e-13); + /* Deconnection of remote programm */ + mpio->remoteMPI2Disconnect(service); + /* clean-up */ + delete mpio; + delete parafield; + mesh->decrRef(); + delete paramesh; + delete source; + delete target; + delete interface; +} + +CPPUNIT_TEST_SUITE_REGISTRATION( MPI2ParaMEDMEMTest ); + +#include "MPIMainTest.hxx" diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx index 92c33f5b3..a08eb9995 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_FabienAPI.cxx @@ -40,8 +40,10 @@ void ParaMEDMEMTest::testFabienAPI1() // if(size!=3) return ; - int procs_source[1]={0}; - int procs_target[1]={1}; + int procs_source_c[1]={0}; + std::set procs_source(procs_source_c,procs_source_c+1); + int procs_target_c[1]={1}; + std::set procs_target(procs_target_c,procs_target_c+1); // ParaMEDMEM::MEDCouplingUMesh *mesh=0; ParaMEDMEM::ParaMESH *paramesh=0; @@ -53,7 +55,92 @@ void ParaMEDMEMTest::testFabienAPI1() double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. }; CommInterface comm; // - ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_source+1,procs_target,procs_target+1); + ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target); + if(dec->isInSourceSide()) + { + mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + int targetConn[4]={0,2,3,1}; + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + mesh->finishInsertingCells(); + ParaMEDMEM::ComponentTopology comptopo; + paramesh=new ParaMESH(mesh,*dec->getSourceGrp(),"source mesh"); + parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafield->getField()->setNature(ConservativeVolumic); + double *vals=parafield->getField()->getArray()->getPointer(); + vals[0]=7.; + } + if(dec->isInTargetSide()) + { + mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + int targetConn[6]={0,2,1,2,3,1}; + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + mesh->finishInsertingCells(); + ParaMEDMEM::ComponentTopology comptopo; + paramesh=new ParaMESH(mesh,*dec->getTargetGrp(),"target mesh"); + parafield=new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafield->getField()->setNature(ConservativeVolumic); + } + dec->attachLocalField(parafield); + dec->synchronize(); + dec->sendRecvData(); + if(dec->isInTargetSide()) + { + const double *valsToTest=parafield->getField()->getArray()->getConstPointer(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[0],7.,1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(valsToTest[1],7.,1e-14); + } + // + delete parafield; + delete paramesh; + if(mesh) + mesh->decrRef(); + delete dec; + MPI_Barrier(MPI_COMM_WORLD); +} + +/*! + * Idem testFabienAPI1 except that procs are shuffled. Test of the good management of group translation in newly created communicator. + */ +void ParaMEDMEMTest::testFabienAPI2() +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=3) + return ; + int procs_source_c[1]={2};//difference with testFabienAPI1 + std::set procs_source(procs_source_c,procs_source_c+1); + int procs_target_c[1]={1}; + std::set procs_target(procs_target_c,procs_target_c+1); + // + ParaMEDMEM::MEDCouplingUMesh *mesh=0; + ParaMEDMEM::ParaMESH *paramesh=0; + ParaMEDMEM::ParaFIELD *parafield=0; + // + ParaMEDMEM::CommInterface interface; + // + MPI_Barrier(MPI_COMM_WORLD); + double targetCoords[8]={ 0.,0., 1., 0., 0., 1., 1., 1. }; + CommInterface comm; + // + ParaMEDMEM::InterpKernelDEC *dec=new ParaMEDMEM::InterpKernelDEC(procs_source,procs_target); if(dec->isInSourceSide()) { mesh=MEDCouplingUMesh::New(); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx index 11c582843..17cadfe05 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_Gauthier1.cxx @@ -252,7 +252,7 @@ void ParaMEDMEMTest::testGauthier1() MPI_Barrier(MPI_COMM_WORLD); - clock_t clock0= clock (); + //clock_t clock0= clock (); int compti=0; bool init=true; // first time step ?? @@ -261,7 +261,7 @@ void ParaMEDMEMTest::testGauthier1() while (!stop) { compti++; - clock_t clocki= clock (); + //clock_t clocki= clock (); //cout << compti << " CLOCK " << (clocki-clock0)*1.e-6 << endl; for (int non_unif=0;non_unif<2;non_unif++) { @@ -278,7 +278,7 @@ void ParaMEDMEMTest::testGauthier1() if(rank!=3) champ_emetteur._field[0]=40; } - bool ok=false; // Is the time interval successfully solved ? + //bool ok=false; // Is the time interval successfully solved ? // Loop on the time interval tries if(1) { diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_ICocoTrio.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_ICocoTrio.cxx index 386491362..b3a573c3e 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_ICocoTrio.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_ICocoTrio.cxx @@ -236,7 +236,7 @@ void ParaMEDMEMTest::testICocoTrio1() if (cas=="emetteur") if (non_unif) champ_emetteur._field[0]=40; - bool ok=false; // Is the time interval successfully solved ? + //bool ok=false; // Is the time interval successfully solved ? // Loop on the time interval tries if(1) diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx index c41981608..f4e941ee0 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_InterpKernelDEC.cxx @@ -47,7 +47,7 @@ using namespace std; using namespace ParaMEDMEM; - + void ParaMEDMEMTest::testInterpKernelDEC_2D() { testInterpKernelDEC_2D_("P0","P0"); @@ -68,6 +68,385 @@ void ParaMEDMEMTest::testInterpKernelDEC_2DP0P1() //testInterpKernelDEC_2D_("P0","P1"); } +void ParaMEDMEMTest::testInterpKernelDEC_1D() +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=5) + return ; + int nproc_source = 3; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + if(rank==0) + { + double coords[4]={0.3,0.7, 0.9,1.0}; + int conn[4]={0,1,2,3}; + mesh=MEDCouplingUMesh::New("Source mesh Proc0",1); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,1); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + if(rank==1) + { + double coords[2]={0.7,0.9}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Source mesh Proc1",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,1); + std::copy(coords,coords+2,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + if(rank==2) + { + double coords[2]={1.,1.12}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Source mesh Proc2",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,1); + std::copy(coords,coords+2,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + parafieldP0->getField()->setNature(ConservativeVolumic); + if(rank==0) + { + valueP0[0]=7.; valueP0[1]=8.; + } + if(rank==1) + { + valueP0[0]=9.; + } + if(rank==2) + { + valueP0[0]=10.; + } + } + else + { + const char targetMeshName[]="target mesh"; + if(rank==3) + { + double coords[2]={0.5,0.75}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Target mesh Proc3",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,1); + std::copy(coords,coords+2,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + if(rank==4) + { + double coords[2]={0.75,1.2}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Target mesh Proc4",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,1); + std::copy(coords,coords+2,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafieldP0->getField()->setNature(ConservativeVolumic); + } + // test 1 + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + if (source_group->containsMyRank()) + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + dec.recvData(); + const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + if(rank==0) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); + } + if(rank==1) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); + } + if(rank==2) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); + } + } + else + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res=parafieldP0->getField()->getArray()->getConstPointer(); + if(rank==3) + { + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); + } + if(rank==4) + { + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); + } + dec.sendData(); + } + // + delete parafieldP0; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +} + +void ParaMEDMEMTest::testInterpKernelDEC_2DCurve() +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=5) + return ; + int nproc_source = 3; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + if(rank==0) + { + double coords[8]={0.3,0.3,0.7,0.7, 0.9,0.9,1.0,1.0}; + int conn[4]={0,1,2,3}; + mesh=MEDCouplingUMesh::New("Source mesh Proc0",1); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(coords,coords+8,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + if(rank==1) + { + double coords[4]={0.7,0.7,0.9,0.9}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Source mesh Proc1",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,2); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + if(rank==2) + { + double coords[4]={1.,1.,1.12,1.12}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Source mesh Proc2",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,2); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + } + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + parafieldP0->getField()->setNature(ConservativeVolumic); + if(rank==0) + { + valueP0[0]=7.; valueP0[1]=8.; + } + if(rank==1) + { + valueP0[0]=9.; + } + if(rank==2) + { + valueP0[0]=10.; + } + } + else + { + const char targetMeshName[]="target mesh"; + if(rank==3) + { + double coords[4]={0.5,0.5,0.75,0.75}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Target mesh Proc3",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,2); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + if(rank==4) + { + double coords[4]={0.75,0.75,1.2,1.2}; + int conn[2]={0,1}; + mesh=MEDCouplingUMesh::New("Target mesh Proc4",1); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(2,2); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafieldP0->getField()->setNature(ConservativeVolumic); + } + // test 1 + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + if (source_group->containsMyRank()) + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.sendData(); + dec.recvData(); + const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + if(rank==0) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); + } + if(rank==1) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); + } + if(rank==2) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); + } + } + else + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + dec.setForcedRenormalization(false); + dec.recvData(); + const double *res=parafieldP0->getField()->getArray()->getConstPointer(); + if(rank==3) + { + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); + } + if(rank==4) + { + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); + } + dec.sendData(); + } + // + delete parafieldP0; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +} + + /* * Check methods defined in InterpKernelDEC.hxx * @@ -1531,6 +1910,158 @@ void ParaMEDMEMTest::testInterpKernelDECPartialProcs() MPI_Barrier(MPI_COMM_WORLD); } +/*! + * This test reproduces bug of Gauthier on 13/9/2010 concerning 3DSurf meshes. + * It is possible to lead to dead lock in InterpKernelDEC when 3DSurfMeshes global bounding boxes intersects whereas cell bounding box intersecting only on one side. + */ +void ParaMEDMEMTest::testInterpKernelDEC3DSurfEmptyBBox() +{ + int size; + int rank; + MPI_Comm_size(MPI_COMM_WORLD,&size); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + // + if(size!=3) + return ; + int nproc_source = 1; + set self_procs; + set procs_source; + set procs_target; + + for (int i=0; icontainsMyRank()) + { + double coords[15]={1.,0.,0., 2.,0.,0., 2.,2.,0., 0.,2.,0., 0.5,0.5,1.}; + int conn[7]={0,1,2,3,0,3,4}; + mesh=MEDCouplingUMesh::New("Source mesh Proc0",2); + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,3); + std::copy(coords,coords+15,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + // + paramesh=new ParaMESH(mesh,*source_group,"source mesh"); + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + parafieldP0->getField()->setNature(ConservativeVolumic); + valueP0[0]=7.; valueP0[1]=8.; + } + else + { + const char targetMeshName[]="target mesh"; + if(rank==1) + { + double coords[12]={0.25,0.25,0.5, 0.,0.25,0.5, 0.,0.,0.5, 0.25,0.,0.5}; + int conn[4]={0,1,2,3}; + mesh=MEDCouplingUMesh::New("Target mesh Proc1",2); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(coords,coords+12,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + if(rank==2) + { + double coords[12]={0.,0.25,0.5, 0.,0.,0.5, -1.,0.,0.5, -1.,0.25,0.5}; + int conn[4]={0,1,2,3}; + mesh=MEDCouplingUMesh::New("Target mesh Proc2",2); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(coords,coords+12,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + paramesh=new ParaMESH(mesh,*target_group,targetMeshName); + } + ParaMEDMEM::ComponentTopology comptopo; + parafieldP0 = new ParaFIELD(ON_CELLS,NO_TIME,paramesh, comptopo); + parafieldP0->getField()->setNature(ConservativeVolumic); + } + // test 1 + ParaMEDMEM::InterpKernelDEC dec(*source_group,*target_group); + if (source_group->containsMyRank()) + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + // dec.setForcedRenormalization(false); + // dec.sendData(); + // dec.recvData(); + // const double *valueP0=parafieldP0->getField()->getArray()->getPointer(); + // if(rank==0) + // { + // CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,valueP0[0],1e-7); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[1],1e-7); + // } + // if(rank==1) + // { + // CPPUNIT_ASSERT_DOUBLES_EQUAL(8.64054054054054,valueP0[0],1e-7); + // } + // if(rank==2) + // { + // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540544,valueP0[0],1e-7); + // } + } + else + { + dec.setMethod("P0"); + dec.attachLocalField(parafieldP0); + dec.synchronize(); + // dec.setForcedRenormalization(false); + // dec.recvData(); + // const double *res=parafieldP0->getField()->getArray()->getConstPointer(); + // if(rank==3) + // { + // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(7.4,res[0],1e-12); + // } + // if(rank==4) + // { + // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfTuples()); + // CPPUNIT_ASSERT_EQUAL(1,parafieldP0->getField()->getNumberOfComponents()); + // CPPUNIT_ASSERT_DOUBLES_EQUAL(9.0540540540540526,res[0],1e-12); + // } + // dec.sendData(); + } + // + delete parafieldP0; + mesh->decrRef(); + delete paramesh; + delete self_group; + delete target_group; + delete source_group; + // + MPI_Barrier(MPI_COMM_WORLD); +} + /*! * Tests an asynchronous exchange between two codes * one sends data with dtA as an interval, the max time being tmaxA diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx index 325b46f03..b0b216137 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_MEDLoader.cxx @@ -45,17 +45,17 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllTypes().size()); for(int i=0;i<12;i++) CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,mesh->getTypeOfCell(i)); - for(int i=12;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(i)); - for(int i=14;i<16;i++) - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,mesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,mesh->getTypeOfCell(15)); CPPUNIT_ASSERT_EQUAL(90,mesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(701,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(711,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+17,0)); + CPPUNIT_ASSERT_EQUAL(705,std::accumulate(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+17,0)); CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); mesh->decrRef(); // - vector families=MEDLoader::GetMeshFamilyNames(fileName.c_str(),meshNames[0].c_str()); + vector families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str()); CPPUNIT_ASSERT_EQUAL(8,(int)families.size()); CPPUNIT_ASSERT(families[2]=="FAMILLE_ELEMENT_3"); // @@ -103,21 +103,21 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(2,(int)fieldsName.size()); CPPUNIT_ASSERT(fieldsName[0]=="fieldcelldoublescalar"); CPPUNIT_ASSERT(fieldsName[1]=="fieldcelldoublevector"); - std::vector > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[0].c_str()); + std::vector > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str()); CPPUNIT_ASSERT_EQUAL(1,(int)its0.size()); CPPUNIT_ASSERT_EQUAL(-1,its0[0].first); CPPUNIT_ASSERT_EQUAL(-1,its0[0].second); - std::vector > its1=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[1].c_str()); + std::vector > its1=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[1].c_str()); CPPUNIT_ASSERT_EQUAL(1,(int)its1.size()); CPPUNIT_ASSERT_EQUAL(-1,its1[0].first); CPPUNIT_ASSERT_EQUAL(-1,its1[0].second); // - MEDCouplingFieldDouble *field0=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); + MEDCouplingFieldDouble *field0=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); field0->checkCoherency(); CPPUNIT_ASSERT(field0->getName()==fieldsName[0]); CPPUNIT_ASSERT_EQUAL(1,field0->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(16,field0->getNumberOfTuples()); - const double expectedValues[16]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,3.,3.,2.,2.}; + const double expectedValues[16]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,2.,3.,3.,2.}; double diffValue[16]; std::transform(field0->getArray()->getPointer(),field0->getArray()->getPointer()+16,expectedValues,diffValue,std::minus()); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue,diffValue+16),1e-12); @@ -131,22 +131,22 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size()); for(int i=0;i<12;i++) CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - for(int i=12;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i)); - for(int i=14;i<16;i++) - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); + CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12); field0->decrRef(); // - MEDCouplingFieldDouble *field1=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[1].c_str(),its1[0].first,its1[0].second); + MEDCouplingFieldDouble *field1=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[1].c_str(),its1[0].first,its1[0].second); field1->checkCoherency(); CPPUNIT_ASSERT(field1->getName()==fieldsName[1]); CPPUNIT_ASSERT_EQUAL(3,field1->getNumberOfComponents()); CPPUNIT_ASSERT_EQUAL(16,field1->getNumberOfTuples()); - const double expectedValues2[48]={1.,0.,1.,1.,0.,1.,1.,0.,1.,2.,1.,0.,2.,1.,0.,2.,1.,0.,3.,0.,1.,3.,0.,1.,3.,0.,1.,4.,1.,0.,4.,1.,0.,4.,1.,0.,6.,1.,1.,6.,0.,0.,5.,0.,0.,5.,1.,1.}; + const double expectedValues2[48]={1.,0.,1.,1.,0.,1.,1.,0.,1.,2.,1.,0.,2.,1.,0.,2.,1.,0.,3.,0.,1.,3.,0.,1.,3.,0.,1.,4.,1.,0.,4.,1.,0.,4.,1.,0.,5.,0.,0.,6.,1.,1.,6.,0.,0.,5.,1.,1.}; double diffValue2[48]; std::transform(field1->getArray()->getPointer(),field1->getArray()->getPointer()+48,expectedValues2,diffValue2,std::minus()); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,*std::max_element(diffValue2,diffValue2+48),1e-12); @@ -160,13 +160,13 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size()); for(int i=0;i<12;i++) CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - for(int i=12;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i)); - for(int i=14;i<16;i++) - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); + CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12); field1->decrRef(); //fields on nodes @@ -174,7 +174,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(2,(int)fieldsNameNode.size()); CPPUNIT_ASSERT(fieldsNameNode[0]=="fieldnodedouble"); CPPUNIT_ASSERT(fieldsNameNode[1]=="fieldnodeint"); - std::vector > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),fieldsNameNode[0].c_str()); + std::vector > its0Node=MEDLoader::GetNodeFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsNameNode[0].c_str()); CPPUNIT_ASSERT_EQUAL(3,(int)its0Node.size()); CPPUNIT_ASSERT_EQUAL(1,its0Node[0].first); CPPUNIT_ASSERT_EQUAL(-1,its0Node[0].second); @@ -182,7 +182,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(-1,its0Node[1].second); CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].first);//strange but like that CPPUNIT_ASSERT_EQUAL(-1,its0Node[2].second); - MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); + MEDCouplingFieldDouble *field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[0].first,its0Node[0].second); field0Nodes->checkCoherency(); CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); @@ -196,7 +196,7 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT(constMesh); field0Nodes->decrRef(); // - field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[1].first,its0Node[1].second); + field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[1].first,its0Node[1].second); field0Nodes->checkCoherency(); CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); @@ -214,17 +214,17 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size()); for(int i=0;i<12;i++) CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - for(int i=12;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i)); - for(int i=14;i<16;i++) - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); + CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12); field0Nodes->decrRef(); // - field0Nodes=MEDLoader::ReadFieldDoubleNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second); + field0Nodes=MEDLoader::ReadFieldNode(fileName.c_str(),meshNames[0].c_str(),0,fieldsNameNode[0].c_str(),its0Node[2].first,its0Node[2].second); field0Nodes->checkCoherency(); CPPUNIT_ASSERT(field0Nodes->getName()==fieldsNameNode[0]); CPPUNIT_ASSERT_EQUAL(1,field0Nodes->getNumberOfComponents()); @@ -242,13 +242,13 @@ void ParaMEDMEMTest::testMEDLoaderRead1() CPPUNIT_ASSERT_EQUAL(3,(int)constMesh->getAllTypes().size()); for(int i=0;i<12;i++) CPPUNIT_ASSERT_EQUAL(NORM_TETRA4,constMesh->getTypeOfCell(i)); - for(int i=12;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(i)); - for(int i=14;i<16;i++) - CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_HEXA8,constMesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_PYRA5,constMesh->getTypeOfCell(15)); CPPUNIT_ASSERT_EQUAL(90,constMesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(701,std::accumulate(constMesh->getNodalConnectivity()->getPointer(),constMesh->getNodalConnectivity()->getPointer()+90,0)); - CPPUNIT_ASSERT_EQUAL(711,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); + CPPUNIT_ASSERT_EQUAL(705,std::accumulate(constMesh->getNodalConnectivityIndex()->getPointer(),constMesh->getNodalConnectivityIndex()->getPointer()+17,0)); CPPUNIT_ASSERT_DOUBLES_EQUAL(46.,std::accumulate(constMesh->getCoords()->getPointer(),constMesh->getCoords()->getPointer()+57,0),1e-12); field0Nodes->decrRef(); } @@ -286,9 +286,9 @@ void ParaMEDMEMTest::testMEDLoaderPolygonRead() CPPUNIT_ASSERT(fieldsName[0]=="bord_:_distorsion"); CPPUNIT_ASSERT(fieldsName[1]=="bord_:_familles"); CPPUNIT_ASSERT(fieldsName[2]=="bord_:_non-ortho"); - std::vector > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),fieldsName[0].c_str()); + std::vector > its0=MEDLoader::GetCellFieldIterations(fileName.c_str(),meshNames[0].c_str(),fieldsName[0].c_str()); CPPUNIT_ASSERT_EQUAL(1,(int)its0.size()); - MEDCouplingFieldDouble *field=MEDLoader::ReadFieldDoubleCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); + MEDCouplingFieldDouble *field=MEDLoader::ReadFieldCell(fileName.c_str(),meshNames[0].c_str(),0,fieldsName[0].c_str(),its0[0].first,its0[0].second); field->checkCoherency(); CPPUNIT_ASSERT(field->getName()==fieldsName[0]); CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfComponents()); @@ -345,18 +345,29 @@ void ParaMEDMEMTest::testMEDLoaderPolyhedronRead() CPPUNIT_ASSERT_EQUAL(17,mesh->getNumberOfCells()); CPPUNIT_ASSERT_EQUAL(19,mesh->getNumberOfNodes()); CPPUNIT_ASSERT_EQUAL(3,(int)mesh->getAllTypes().size()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(i)); - for(int i=6;i<14;i++) - CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(i)); - for(int i=14;i<17;i++) - CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(i)); + CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(4)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(5)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(6)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(7)); + CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(8)); + CPPUNIT_ASSERT_EQUAL(NORM_POLYGON,mesh->getTypeOfCell(9)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(10)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(11)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(12)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(13)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(14)); + CPPUNIT_ASSERT_EQUAL(NORM_QUAD4,mesh->getTypeOfCell(15)); + CPPUNIT_ASSERT_EQUAL(NORM_TRI3,mesh->getTypeOfCell(16)); CPPUNIT_ASSERT_DOUBLES_EQUAL(110.,std::accumulate(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+57,0),1e-12); CPPUNIT_ASSERT_EQUAL(83,mesh->getNodalConnectivity()->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(619,std::accumulate(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+83,0)); mesh->decrRef(); // - vector families=MEDLoader::GetMeshFamilyNames(fileName.c_str(),meshNames[0].c_str()); + vector families=MEDLoader::GetMeshFamiliesNames(fileName.c_str(),meshNames[0].c_str()); CPPUNIT_ASSERT_EQUAL(4,(int)families.size()); CPPUNIT_ASSERT(families[0]=="FAMILLE_FACE_POLYGONS3"); CPPUNIT_ASSERT(families[1]=="FAMILLE_FACE_QUAD41"); diff --git a/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx b/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx index ee55782a8..8911fba39 100644 --- a/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx +++ b/src/ParaMEDMEMTest/ParaMEDMEMTest_NonCoincidentDEC.cxx @@ -17,6 +17,8 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +#ifdef MED_ENABLE_FVM + #include "ParaMEDMEMTest.hxx" #include @@ -251,3 +253,4 @@ void ParaMEDMEMTest::testNonCoincidentDEC(const string& filename1, MPI_Barrier(MPI_COMM_WORLD); } +#endif diff --git a/src/ParaMEDMEM_Swig/Makefile.am b/src/ParaMEDMEM_Swig/Makefile.am index 8df876e60..c65f7eace 100644 --- a/src/ParaMEDMEM_Swig/Makefile.am +++ b/src/ParaMEDMEM_Swig/Makefile.am @@ -43,7 +43,7 @@ _libParaMEDMEM_Swig_la_CPPFLAGS = $(PYTHON_INCLUDES) \ $(MED2_INCLUDES) $(HDF5_INCLUDES) @CXXTMPDPTHFLAGS@ \ -I$(srcdir)/../INTERP_KERNEL \ $(MPI_INCLUDES) -I$(srcdir)/../ParaMEDMEM -I$(srcdir)/../MEDCoupling_Swig -I$(srcdir)/../INTERP_KERNEL/Bases \ - -I$(srcdir)/../MEDCoupling -I$(srcdir)/../ParaMEDLoader -I$(srcdir)/../MEDLoader + -I$(srcdir)/../MEDCoupling -I$(srcdir)/../ParaMEDLoader -I$(srcdir)/../MEDLoader -I$(srcdir)/../MEDLoader/Swig _libParaMEDMEM_Swig_la_LDFLAGS = -module $(MED2_LIBS) $(HDF5_LIBS) $(PYTHON_LIBS) $(MPI_LIBS) \ ../MEDCoupling/libmedcoupling.la ../INTERP_KERNEL/libinterpkernel.la \