From 2f9f9d034449b83f4b850727ea3c6b46684cc187 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 8 Apr 2013 15:16:45 +0000 Subject: [PATCH] 0021856: [CEA 663] Documenting API of MEDCoupling and MEDLoader MEDCouplingMesh documented --- doc/doxygen/medcouplingexamples.doxy | 86 +++++- src/MEDCoupling/MEDCouplingMesh.cxx | 264 ++++++++++++++---- .../Test/MEDCouplingExamplesTest.cxx | 107 +++++++ .../MEDCouplingExamplesTest.py | 83 +++++- 4 files changed, 485 insertions(+), 55 deletions(-) diff --git a/doc/doxygen/medcouplingexamples.doxy b/doc/doxygen/medcouplingexamples.doxy index ef07978cf..dfaba4afb 100644 --- a/doc/doxygen/medcouplingexamples.doxy +++ b/doc/doxygen/medcouplingexamples.doxy @@ -3,7 +3,7 @@ -\anchor cpp_mcumesh_ +\anchor cpp_mcmesh_

First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. @@ -12,6 +12,90 @@ First, we create a 2D mesh with 3 QUAD4 and 2 TRI3 cells. \snippet MEDCouplingExamplesTest.py Snippet_MEDCouplingUMesh_ +\anchor cpp_mcmesh_fillFromAnalytic3 +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3 "fillFromAnalytic3()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3 + + + +\anchor cpp_mcmesh_fillFromAnalytic2 +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +Note that we set names to coordinates arrays ("a" and "b" ) which will be used to refer to +corresponding coordinates within a function. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2 "fillFromAnalytic2()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3 + + +\anchor cpp_mcmesh_fillFromAnalytic +

Creating a field using a formular

+ +First, we create a 2D Cartesian mesh constituted by 2 cells. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_1 +Now we use +\ref ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic "fillFromAnalytic()" +to get a \ref ParaMEDMEM::MEDCouplingFieldDouble "MEDCouplingFieldDouble" on cells filled +with values computed using a formular \b func. This formular is applied to coordinates of +each point (barycenter) for which the field value is computed. We want to get the +field on cells, with 3 components computed as follows. (In \b func, we refer to the +first component of a point using the variable "a", and to the second component, using +the variable "b"). +- Component #0 = the second coordinate of the point; hence "IVec * b" in \b func. +- Component #1 = the first coordinate of the point; hence "JVec * a". +- Component #2 = distance between the point and SC origin (0.,0.); hence +"KVec * sqrt( a*a + b*b )". + +In addition we want to add 10.0 to each component computed as described above, hence +"10" in \b func. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_2 +Now we ascertain that the result field is as we expect. We check the second tuple of +the \b field. We get barycenter of the cell #1 and checks that values of the second +tuple are computed as we want. +\snippet MEDCouplingExamplesTest.cxx CppSnippet_MEDCouplingMesh_fillFromAnalytic_3 + + \anchor cpp_mccmesh_getCoordsAt

Getting node coordinates

diff --git a/src/MEDCoupling/MEDCouplingMesh.cxx b/src/MEDCoupling/MEDCouplingMesh.cxx index d48d0a73e..4aef8bfa1 100644 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ b/src/MEDCoupling/MEDCouplingMesh.cxx @@ -100,6 +100,15 @@ bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, return true; } +//================================================================================ +/*! + * Checks if \a this and another MEDCouplingMesh are fully equal. + * \param [in] other - an instance of MEDCouplingMesh to compare with \a this one. + * \param [in] prec - precision value used to compare node coordinates. + * \return bool - \c true if the two meshes are equal, \c false else. + */ +//================================================================================ + bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) { std::string tmp; @@ -170,9 +179,13 @@ void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levO } /*! - * 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. + * Finds cells whose all nodes are in a given array of node ids. + * \param [in] partBg - the array of node ids. + * \param [in] partEnd - end of \a partBg, i.e. a pointer to a (last+1)-th element + * of \a partBg. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found + * cells. The caller is to delete this array using decrRef() as it is no + * more needed. */ DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const { @@ -268,34 +281,48 @@ void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTER _order=other->_order; } +//================================================================================ /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. - * This method is equivalent to those taking a C++ function pointer except that here the 'func' is informed by - * an interpretable input string. + * \anchor mcmesh_fillFromAnalytic + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. The function can include arbitrary named variables + * (e.g. "x","y" or "va44") to refer to components of point coordinates. Names of + * variables are sorted in \b alphabetical \b order to associate a variable name with a + * component. For example, in the expression "2*x+z", "x" stands for the component #0 + * and "z" stands for the component #1 (\b not #2)!
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of the field. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (5.,5.,5.,5.) + * - "2*x + 0*y + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,4.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,4.) * - * The dynamic interpretor uses \b alphabetical \b order to assign the component id to the var name. - * For example : - * - "2*x+z" func : x stands for component #0 and z stands for component #1 \b NOT #2 ! - * - * Some var names are reserved and have special meaning. IVec stands for (1,0,0,...). JVec stands for (0,1,0...). - * KVec stands for (0,0,1,...)... These keywords allows too differentate the evaluation of output components each other. - * - * If 'nbOfComp' equals to 4 for example and that 'this->getSpaceDimension()' equals to 3. - * - * For the input tuple T = (1.,3.,7.) : - * - '2*x+z' will return (5.,5.,5.,5.) - * - '2*x+0*y+z' will return (9.,9.,9.,9.) - * - '2*x*IVec+(x+z)*LVec' will return (2.,0.,0.,4.) - * - '2*x*IVec+(y+z)*KVec' will return (2.,0.,10.,0.) + * \param [in] t - the field type. It defines, apart from other things, points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic "Here is a Python example". */ +//================================================================================ + MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const { MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); @@ -305,17 +332,49 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbO return ret.retn(); } +//================================================================================ /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. This method is different than MEDCouplingMesh::fillFromAnalytic, because the info on components are used here to determine vars pos in 'func'. + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters. This method differs from \ref mcmesh_fillFromAnalytic "fillFromAnalytic() + * by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a variable name corresponding to a component is retrieved from + * a corresponding node coordinates array (where it is set via + * DataArrayDouble::setInfoOnComponent()).
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr.
+ * In a general case, a value resulting from the function evaluation is assigned to all + * components of a field value. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of + * spatial components are "x", "y" and "z", coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \param [in] t - the field type. It defines, apart from other things, the points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the node coordinates are not defined. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. + * + * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". */ +//================================================================================ + MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const { MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); @@ -325,17 +384,51 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nb return ret.retn(); } +//================================================================================ /*! - * This method builds a field lying on 'this' with 'nbOfComp' components. - * 'func' is a string that is the expression to evaluate. - * The return field will have type specified by 't'. 't' is also used to determine where values of field will be - * evaluate. This method is different than MEDCouplingMesh::fillFromAnalytic, because 'varsOrder' specifies the pos to assign of vars in 'func'. + * Creates a new MEDCouplingFieldDouble of a given type, one time, with given number of + * components, lying on \a this mesh, with contents got by applying a specified + * function to coordinates of field location points (defined by the given field type). + * For example, if \a t == ParaMEDMEM::ON_CELLS, the function is applied to cell + * barycenters. This method differs from \ref \ref mcmesh_fillFromAnalytic + * "fillFromAnalytic()" by the way how variable + * names, used in the function, are associated with components of coordinates of field + * location points; here, a component index of a variable is defined by a + * rank of the variable within the input array \a varsOrder.
+ * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. + * In a general case, a value resulting from the function evaluation is assigned to all + * components of the field. But there is a possibility to have its own expression for + * each component within one function. For this purpose, there are predefined variable + * names (IVec, JVec, KVec, LVec etc) each dedicated to a certain component (IVec, to + * the component #0 etc). A factor of such a variable is added to the + * corresponding component only.
+ * For example, \a nbOfComp == 4, \a this->getSpaceDimension() == 3, names of + * spatial components are given in \a varsOrder: ["x", "y","z"], coordinates of a + * point are (1.,3.,7.), then + * - "2*x + z" produces (9.,9.,9.,9.) + * - "2*x*IVec + (x+z)*LVec" produces (2.,0.,0.,8.) + * - "2*y*IVec + z*KVec + x" produces (7.,1.,1.,8.) * - * @param t type of field returned and specifies where the evaluation of func will be done. - * @param nbOfComp number of components of returned field. - * @param func expression. - * @return field with counter = 1. + * \param [in] t - the field type. It defines, apart from other things, the points to + * coordinates of which the function is applied to get field values. + * \param [in] nbOfComp - the number of components in the result field. + * \param [in] varsOrder - the vector defining names of variables used to refer to + * components of coordinates of field location points. A variable named + * varsOrder[0] refers to the component #0 etc. + * \param [in] func - a string defining the expression which is evaluated to get + * field values. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If the node coordinates are not defined. + * \throw If the nodal connectivity of cells is not defined. + * \throw If computing \a func fails. + * + * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".
+ * \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". */ +//================================================================================ + MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const char *func) const { MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); @@ -345,12 +438,22 @@ MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nb return ret.retn(); } +//================================================================================ /*! - * retruns a newly created mesh with counter=1 - * that is the union of \b mesh1 and \b mesh2 if possible. The cells of \b mesh2 will appear after cells of \b mesh1. Idem for nodes. - * The only contraint is that \b mesh1 an \b mesh2 have the same mesh types. If it is not the case please use the other API of MEDCouplingMesh::MergeMeshes, - * with input vector of meshes. + * Creates a new MEDCouplingMesh by concatenating two given meshes, if possible. + * Cells and nodes of + * the first mesh precede cells and nodes of the second mesh within the result mesh. + * The meshes must be of the same mesh type, else, an exception is thrown. The method + * MergeMeshes(), accepting a vector of input meshes, has no such a limitation. + * \param [in] mesh1 - the first mesh. + * \param [in] mesh2 - the second mesh. + * \return MEDCouplingMesh * - the result mesh. It is a new instance of + * MEDCouplingMesh. The caller is to delete this mesh using decrRef() as it + * is no more needed. + * \throw If the meshes are of different mesh type. */ +//================================================================================ + MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception) { if(!mesh1) @@ -360,12 +463,27 @@ MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, cons return mesh1->mergeMyselfWith(mesh2); } +//================================================================================ /*! - * retruns a newly created mesh with counter=1 - * that is the union of meshes if possible. The cells of \b meshes[1] will appear after cells of \b meshes[0]. Idem for nodes. - * This method performs a systematic conversion to unstructured meshes before performing aggregation contrary to the other ParaMEDMEM::MEDCouplingMesh::MergeMeshes with - * two parameters that work only on the same type of meshes. So here it is possible to mix different type of meshes. + * Creates a new MEDCouplingMesh by concatenating all given meshes, if possible. + * Cells and nodes of + * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. + * This method performs a systematic conversion to unstructured meshes before + * performing aggregation contrary to the other MergeMeshes() + * with two parameters that works only on the same type of meshes. So here it is possible + * to mix different type of meshes. + * \param [in] meshes - a vector of meshes to concatenate. + * \return MEDCouplingMesh * - the result mesh. It is a new instance of + * MEDCouplingUMesh. The caller is to delete this mesh using decrRef() as it + * is no more needed. + * \throw If \a meshes.size() == 0. + * \throw If \a size[ *i* ] == NULL. + * \throw If the coordinates is not set in none of the meshes. + * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. + * \throw If the \a meshes are of different dimension (getMeshDimension()). */ +//================================================================================ + MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector& meshes) throw(INTERP_KERNEL::Exception) { std::vector< MEDCouplingAutoRefCountObjectPtr > ms1(meshes.size()); @@ -410,12 +528,48 @@ const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCel return cm.getRepr(); } +/*! + * Finds cells in contact with a ball (i.e. a point with precision). + * \warning This method is suitable if the caller intends to evaluate only one + * point, for more points getCellsContainingPoints() is recommended as it is + * faster. + * \param [in] pos - array of coordinates of the ball central point. + * \param [in] eps - ball radius. + * \param [in,out] elts - vector returning ids of the found cells. It is cleared + * before inserting ids. + * + * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
+ * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + */ void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const { int ret=getCellContainingPoint(pos,eps); elts.push_back(ret); } +/*! + * Finds cells in contact with several balls (i.e. points with precision). + * This method is an extension of getCellContainingPoint() and + * getCellsContainingPoint() for the case of multiple points. + * \param [in] pos - an array of coordinates of points in full interlace mode : + * X0,Y0,Z0,X1,Y1,Z1,... Size of the array must be \a + * this->getSpaceDimension() * \a nbOfPoints + * \param [in] nbOfPoints - number of points to locate within \a this mesh. + * \param [in] eps - radius of balls (i.e. the precision). + * \param [in,out] elts - vector returning ids of found cells. + * \param [in,out] eltsIndex - an array, of length \a nbOfPoints + 1, + * dividing cell ids in \a elts into groups each referring to one + * point. Its every element (except the last one) is an index pointing to the + * first id of a group of cells. For example cells in contact with the *i*-th + * point are described by following range of indices: + * [ \a eltsIndex[ *i* ], \a eltsIndex[ *i*+1 ] ) and the cell ids are + * \a elts[ \a eltsIndex[ *i* ]], \a elts[ \a eltsIndex[ *i* ] + 1 ], ... + * Number of cells in contact with the *i*-th point is + * \a eltsIndex[ *i*+1 ] - \a eltsIndex[ *i* ]. + * + * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
+ * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + */ void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector& elts, std::vector& eltsIndex) const { eltsIndex.resize(nbOfPoints+1); @@ -436,10 +590,14 @@ void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints } } +//================================================================================ /*! - * This method writes a file in VTK format into file 'fileName'. - * An exception is thrown if the file is not writable. + * Writes \a this mesh into a VTK format file named as specified. + * \param [in] fileName - the name of the file to write in. + * \throw If \a fileName is not a writable file. */ +//================================================================================ + void MEDCouplingMesh::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception) { std::string cda,pda; diff --git a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx b/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx index fbf0a9c3d..943dc5b2a 100644 --- a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx +++ b/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx @@ -26,6 +26,113 @@ #include "MEDCouplingMemArray.hxx" #include "MEDCouplingMultiFields.hxx" + +void CppExample_MEDCouplingPointSet_fillFromAnalytic3() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components + std::vector varNamesVec( varNames, varNames+2 ); + MEDCouplingAutoRefCountObjectPtr field = + mesh->fillFromAnalytic3( ParaMEDMEM::ON_CELLS, 3, varNamesVec, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] + double vals1[3]; // values of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, vals1 ); + // + MEDCouplingAutoRefCountObjectPtr bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] +} + +void CppExample_MEDCouplingPointSet_fillFromAnalytic2() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function + y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function + MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + MEDCouplingAutoRefCountObjectPtr field = + mesh->fillFromAnalytic2( ParaMEDMEM::ON_CELLS, 3, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] + double vals1[3]; // values of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, vals1 ); + // + MEDCouplingAutoRefCountObjectPtr bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] +} + +void CppExample_MEDCouplingPointSet_fillFromAnalytic() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + MEDCouplingAutoRefCountObjectPtr field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS, 3, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] + double vals1[3]; // values of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, vals1 ); + // + MEDCouplingAutoRefCountObjectPtr bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vals1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] +} + void CppExample_MEDCouplingPointSet_getCoordsAt() { using namespace ParaMEDMEM; diff --git a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py b/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py index 4e5be8492..37c6f3776 100644 --- a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py +++ b/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py @@ -20,13 +20,94 @@ from MEDCoupling import * import unittest -from math import pi +from math import pi, sqrt class MEDCouplingBasicsTest(unittest.TestCase): def testExample_MEDCouplingUMesh_(self): #! [PySnippet_MEDCouplingUMesh__1] return + def testExample_MEDCouplingMesh_fillFromAnalytic3(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble.New(coords[:3],3,1) + y=DataArrayDouble.New(coords[:2],2,1) + mesh=MEDCouplingCMesh.New() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + varNames=["a","b"] # names used to refer to X and Y coord components + field=mesh.fillFromAnalytic3(ON_CELLS,3,varNames,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] + return + + def testExample_MEDCouplingMesh_fillFromAnalytic2(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble.New(coords[:3],3,1) + y=DataArrayDouble.New(coords[:2],2,1) + x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function + y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function + mesh=MEDCouplingCMesh.New() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field=mesh.fillFromAnalytic2(ON_CELLS,3,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] + return + + def testExample_MEDCouplingMesh_fillFromAnalytic(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble.New(coords[:3],3,1) + y=DataArrayDouble.New(coords[:2],2,1) + mesh=MEDCouplingCMesh.New() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field=mesh.fillFromAnalytic(ON_CELLS,3,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] + return + def testExample_MEDCouplingCMesh_getCoordsAt(self): #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] coords = [1.,2.,4.] -- 2.39.2