]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Addition of some usefull methods.
authorageay <ageay>
Fri, 19 Feb 2010 17:27:27 +0000 (17:27 +0000)
committerageay <ageay>
Fri, 19 Feb 2010 17:27:27 +0000 (17:27 +0000)
14 files changed:
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingCMesh.hxx
src/MEDCoupling/MEDCouplingExtrudedMesh.cxx
src/MEDCoupling/MEDCouplingExtrudedMesh.hxx
src/MEDCoupling/MEDCouplingFieldDiscretization.cxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/MEDCouplingUMeshDesc.cxx
src/MEDCoupling/MEDCouplingUMeshDesc.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx

index 34c3f3c8ee46b633f732a1996962af08666a5ab6..523fb31c856cb6b54a7fc1dcd0bbdcd702553c40 100644 (file)
@@ -18,6 +18,7 @@
 //
 #include "MEDCouplingCMesh.hxx"
 #include "MEDCouplingMemArray.hxx"
+#include "MEDCouplingFieldDouble.hxx"
 
 using namespace ParaMEDMEM;
 
@@ -174,6 +175,29 @@ MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureField(bool isAbs) const
   return 0;
 }
 
+MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const
+{
+  //not implemented yet !
+  return 0;
+}
+
+MEDCouplingFieldDouble *MEDCouplingCMesh::buildOrthogonalField() const
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  int nbOfCells=getNumberOfCells();
+  array->alloc(nbOfCells,3);
+  double *vals=array->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    { vals[3*i]=1.; vals[3*i+1]=1.; vals[3*i+2]=1.; }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
 void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle)
 {
   throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to StructuredMesh to apply it !");
index 7d4f7e03ed22d51b2af1d448a47b2387d1cf520f..4f4096a448a6f947beb6639707704fc02f941fca 100644 (file)
@@ -46,6 +46,8 @@ namespace ParaMEDMEM
     // tools
     void getBoundingBox(double *bbox) const;
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
     void rotate(const double *center, const double *vector, double angle);
     void translate(const double *vector);
     MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
index 87a61f7c3b243f7999904349b0f70665df75b274..f89a0e5d9080a3a65b6cbf300450f5190c8e4465 100644 (file)
@@ -120,6 +120,18 @@ MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const
   return 0;
 }
 
+MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool) const
+{
+  //not implemented yet
+  return 0;
+}
+
+MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const
+{
+  //not implemented yet
+  throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField not implemented yet !");
+}
+
 MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh()
 {
   if(_mesh2D)
index 5b6f0ede5c3b28029d565f1822c79de0b6057c49..8480bcf2dfd1d10777320acc6848d14b6a5757bc 100644 (file)
@@ -47,6 +47,8 @@ namespace ParaMEDMEM
     MEDCouplingUMesh *getMesh1D() const { return _mesh1D; }
     DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; }
     MEDCouplingFieldDouble *getMeasureField(bool) const;
+    MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const;
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
     static int findCorrespCellByNodalConn(const std::vector<int>& nodalConnec,
                                           const int *revNodalPtr, const int *revNodalIndxPtr) throw(INTERP_KERNEL::Exception);
     void rotate(const double *center, const double *vector, double angle);
index a2e0493a2b667ddac980be6da965387ec7524b7f..a9f648117fc834d0745d80a836ebdc108ef3ff06 100644 (file)
@@ -179,9 +179,7 @@ void MEDCouplingFieldDiscretizationP1::checkCoherencyBetween(const MEDCouplingMe
 
 MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationP1::getWeightingField(const MEDCouplingMesh *mesh, bool isAbs) const
 {
-  //not implemented yet.
-  //Dual mesh to build
-  return 0;
+  return mesh->getMeasureFieldOnNode(isAbs);
 }
 
 void MEDCouplingFieldDiscretizationP1::renumberValuesOnNodes(const DataArrayInt *old2New, DataArrayDouble *arr) const
index 5ab8f7998810f29a0aece98e3727318302c73999..93beaa32853d8463c839289262f24c0abde7417a 100644 (file)
@@ -118,6 +118,16 @@ double MEDCouplingFieldDouble::accumulate(int compId) const
   return ret;
 }
 
+void MEDCouplingFieldDouble::accumulate(double *res) const
+{
+  const double *ptr=getArray()->getConstPointer();
+  int nbTuple=getArray()->getNumberOfTuples();
+  int nbComps=getArray()->getNumberOfComponents();
+  std::fill(res,res+nbComps,0.);
+  for(int i=0;i<nbTuple;i++)
+    std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
+}
+
 double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const
 {
   if(!_mesh)
@@ -132,6 +142,26 @@ double MEDCouplingFieldDouble::measureAccumulate(int compId, bool isWAbs) const
   return ret;
 }
 
+void MEDCouplingFieldDouble::measureAccumulate(bool isWAbs, double *res) const
+{
+  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<nbOfValues; i++)
+    {
+      std::transform(vals+i*nbComps,vals+(i+1)*nbComps,tmp,std::bind2nd(std::multiplies<double>(),ptr[i]));
+      std::transform(tmp,tmp+nbComps,res,res,std::plus<double>());
+    }
+  weight->decrRef();
+  delete [] tmp;
+}
+
 void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const throw(INTERP_KERNEL::Exception)
 {
   _time_discr->checkNoTimePresence();
index 16496f0ec0a304a0dad6d7a390c0f7b8c0202aa9..bcece9122ecb3585a19337aaa6714de6d6d3b56a 100644 (file)
@@ -49,7 +49,9 @@ namespace ParaMEDMEM
     void setArray(DataArrayDouble *array);
     DataArrayDouble *getArray() const { return _time_discr->getArray(); }
     double accumulate(int compId) const;
+    void accumulate(double *res) const;
     double measureAccumulate(int compId, bool isWAbs) const;
+    void measureAccumulate(bool isWAbs, double *res) const;
     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
index f49496d6d9435232363aa2c8b21357bc55f39194..e2878182777da60d20744afffa815ee56c9a7a11 100644 (file)
@@ -55,7 +55,9 @@ namespace ParaMEDMEM
     // 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, FunctionToEvaluate func) const;
+    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 *mergeMyselfWith(const MEDCouplingMesh *other) const = 0;
index 984704e1ab1f9acd48cf078c21b605308d98aaa8..5bb6c99e26c6b73d3d5cb43d5c7a9e88c5f1997e 100644 (file)
@@ -20,6 +20,7 @@
 #include "MEDCouplingFieldDouble.hxx"
 #include "CellModel.hxx"
 #include "VolSurfUser.txx"
+#include "InterpolationUtils.hxx"
 
 #include <sstream>
 #include <limits>
@@ -840,6 +841,69 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
   return field;
 }
 
+MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const
+{
+  MEDCouplingFieldDouble *tmp=getMeasureField(abs);
+  std::string name="MeasureOnNodeOfMesh_";
+  name+=getName();
+  int nbNodes=getNumberOfNodes();
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_NODES);
+  double cst=1./((double)getMeshDimension()+1.);
+  DataArrayDouble* array=DataArrayDouble::New();
+  array->alloc(nbNodes,1);
+  double *valsToFill=array->getPointer();
+  std::fill(valsToFill,valsToFill+nbNodes,0.);
+  const double *values=tmp->getArray()->getConstPointer();
+  DataArrayInt *da=DataArrayInt::New();
+  DataArrayInt *daInd=DataArrayInt::New();
+  getReverseNodalConnectivity(da,daInd);
+  const int *daPtr=da->getConstPointer();
+  const int *daIPtr=daInd->getConstPointer();
+  for(int i=0;i<nbNodes;i++)
+    for(const int *cell=daPtr+daIPtr[i];cell!=daPtr+daIPtr[i+1];cell++)
+      valsToFill[i]+=cst*values[*cell];
+  ret->setMesh(this);
+  da->decrRef();
+  daInd->decrRef();
+  ret->setArray(array);
+  array->decrRef();
+  tmp->decrRef();
+  return ret;
+}
+
+MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 2 !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  int nbOfCells=getNumberOfCells();
+  array->alloc(nbOfCells,3);
+  double *vals=array->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  const double *coords=_coords->getConstPointer();
+  if(getSpaceDimension()==3)
+    {
+      for(int i=0;i<nbOfCells;i++,vals+=3)
+        {
+          int offset=connI[i];
+          INTERP_KERNEL::crossprod<3>(coords+3*conn[offset+1],coords+3*conn[offset+2],coords+3*conn[offset+3],vals);
+          double n=INTERP_KERNEL::norm<3>(vals);
+          std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
+        }
+    }
+  else
+    {
+      for(int i=0;i<nbOfCells;i++)
+        { vals[3*i]=1.; vals[3*i+1]=1.; vals[3*i+2]=1.; }
+    }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
 /*!
  * This method is only available for a mesh with meshDim==2 and spaceDim==2||spaceDim==3.
  * This method returns a vector 'cells' where all detected butterfly cells have been added to cells.
index e793c931c8b2d35c1fad1fbddf745e3003234c4e..9c036342ffa384d4197374223f5890bc2b043207 100644 (file)
@@ -70,6 +70,8 @@ namespace ParaMEDMEM
     void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     void giveElemsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems);
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
     void checkButterflyCells(std::vector<int>& cells) const;
     bool checkConsecutiveCellTypes() const;
     MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
index 1dba15e9a1e05dc03ff1bf8c9267a60d98c83c41..3a34d1f847552635bbf3fa9b4c1c8e631487a7f0 100644 (file)
@@ -262,6 +262,20 @@ MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureField(bool isAbs) const
   return 0;
 }
 
+MEDCouplingFieldDouble *MEDCouplingUMeshDesc::getMeasureFieldOnNode(bool isAbs) const
+{
+  //not implemented yet.
+  return 0;
+}
+
+MEDCouplingFieldDouble *MEDCouplingUMeshDesc::buildOrthogonalField() const
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("Expected a cmesh with meshDim == 2 !");
+  //not implemented yet !
+  return 0;
+}
+
 DataArrayInt *MEDCouplingUMeshDesc::zipCoordsTraducer()
 {
   //not implemented yet.
index b6ef8aa0c1d5afec32bec6c7b0ef5a3f6a3dba82..ebd34115ae3555edb386d63845a388a0631505a3 100644 (file)
@@ -56,6 +56,8 @@ namespace ParaMEDMEM
     MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const;
     void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     MEDCouplingFieldDouble *getMeasureField(bool isAbs) const;
+    MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const;
+    MEDCouplingFieldDouble *buildOrthogonalField() const;
     DataArrayInt *zipCoordsTraducer();
     MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const;
     DataArrayDouble *getBarycenterAndOwner() const;
index 5b5263c12f07f759da7f27d26f0ad02d4631d7d1..bfa87a1a3a7ac4f8d6e5e8f435765b3a2b3c8d0c 100644 (file)
@@ -1140,6 +1140,13 @@ void MEDCouplingBasicsTest::testFillFromAnalytic()
   std::transform(values3,values3+18,values3,std::ptr_fun<double,double>(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->measureAccumulate(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();
   //
   CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,func3),INTERP_KERNEL::Exception);
@@ -1317,6 +1324,20 @@ void MEDCouplingBasicsTest::testCheckConsecutiveCellTypes()
   sourceMesh->decrRef();
 }
 
+void MEDCouplingBasicsTest::testBuildOrthogonalField()
+{
+  MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1();
+  MEDCouplingFieldDouble *field=targetMesh->buildOrthogonalField();
+  double expected[3]={0.70710678118654746,0.,-0.70710678118654746};
+  CPPUNIT_ASSERT_EQUAL(5,field->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents());
+  const double *vals=field->getArray()->getConstPointer();
+  for(int i=0;i<15;i++)
+    CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i%3],vals[i],1e-12);
+  field->decrRef();
+  targetMesh->decrRef();
+}
+
 void MEDCouplingBasicsTest::test2DInterpP0P0_1()
 {
   MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1();
index ef9558d4bc55af3ff4bd18f0adf94bce704b36a9..9d362831341c3b79a43637b3ce602189e94ed963 100644 (file)
@@ -59,6 +59,7 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testOperationsOnFields );
     CPPUNIT_TEST( testMergeNodesOnField );
     CPPUNIT_TEST( testCheckConsecutiveCellTypes );
+    CPPUNIT_TEST( testBuildOrthogonalField );
     CPPUNIT_TEST( test2DInterpP0P0_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_1 );
     CPPUNIT_TEST( test2DInterpP0P0PL_2 );
@@ -137,6 +138,7 @@ namespace ParaMEDMEM
     void testOperationsOnFields();
     void testMergeNodesOnField();
     void testCheckConsecutiveCellTypes();
+    void testBuildOrthogonalField();
     void test2DInterpP0P0_1();
     void test2DInterpP0P0PL_1();
     void test2DInterpP0P0PL_2();