Salome HOME
MERGE stage 1: keep doc/dev and src/MEDCalc/doc
[tools/medcoupling.git] / src / ParaMEDMEM / ParaFIELD.cxx
index a59eb912575b6a58e31aa786c689401b05b01161..9995ccae18aac924f6455eb6ac4bc972adf03974 100644 (file)
@@ -1,21 +1,22 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2015  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 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, or (at your option) any later version.
 //
-//  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.
+// 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
+// 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
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "Topology.hxx"
 #include "BlockTopology.hxx"
 #include "ComponentTopology.hxx"
 namespace ParaMEDMEM
 {
   /*!
-    \defgroup parafield ParaFIELD
-    This class encapsulates parallel fields. It basically encapsulates
+    \anchor ParaFIELD-det
+    \class ParaFIELD
+
+    This class encapsulates parallel fields.
+
+    It basically encapsulates
     a MEDCouplingField with extra information related to parallel 
     topology.
+
     It is most conveniently created by giving a pointer to a MEDCouplingField
     object and a \c ProcessorGroup.
     By default, a ParaFIELD object will be constructed with all field components
     located on the same processors. In some specific cases, it might be necessary to scatter components over several processors. In this case, the constructor
     using a ComponentTopology is required.
 
-    @{ */
+    */
 
   /*!
 
@@ -62,12 +68,10 @@ namespace ParaMEDMEM
     \endverbatim
 
   */
-  ParaFIELD::ParaFIELD(TypeOfField type, ParaMESH* para_support, const ComponentTopology& component_topology)
-    :_support(para_support),
-     _component_topology(component_topology),_topology(0),
-     _field(0),
-     _has_field_ownership(true),
-     _has_support_ownership(false)
+  ParaFIELD::ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* para_support, const ComponentTopology& component_topology)
+    :_field(0),
+     _component_topology(component_topology),_topology(0),_own_support(false),
+     _support(para_support)
   {
     if (para_support->isStructured() || (para_support->getTopology()->getProcGroup()->size()==1 && component_topology.nbBlocks()!=1))
       {
@@ -88,7 +92,7 @@ namespace ParaMEDMEM
     int nb_components = component_topology.nbLocalComponents();
     if (nb_components!=0)
       {
-        _field=MEDCouplingFieldDouble::New(type);
+        _field=MEDCouplingFieldDouble::New(type,td);
         _field->setMesh(_support->getCellMesh());
         DataArrayDouble *array=DataArrayDouble::New();
         array->alloc(_field->getNumberOfTuples(),nb_components);
@@ -99,8 +103,6 @@ namespace ParaMEDMEM
   
     _field->setName("Default ParaFIELD name");
     _field->setDescription("Default ParaFIELD description");
-    _field->setDtIt(0,0);
-    _field->setTime(0.0);
   } 
 
   /*! \brief Constructor creating the ParaFIELD
@@ -109,29 +111,29 @@ namespace ParaMEDMEM
     This constructor supposes that support underlying \a subdomain_field has no ParaSUPPORT 
     attached and it therefore recreates one. It therefore takes ownership over _support. The component topology associated with the field is a basic one (all components on the same processor). 
   */
-  ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, const ProcessorGroup& proc_group):
+  ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, ParaMESH *sup, const ProcessorGroup& proc_group):
     _field(subdomain_field),
-    _support(),
-    _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0),
-    _has_field_ownership(false),
-    _has_support_ownership(true)
+    _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0),_own_support(false),
+    _support(sup)
   {
     if(_field)
       _field->incrRef();
-    const ExplicitTopology* source_topo=dynamic_cast<const ExplicitTopology*> (_support->getTopology());
-    _topology=new ExplicitTopology(*source_topo,_component_topology.nbLocalComponents());
+    const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (_support->getTopology());
+    _topology=new BlockTopology(*source_topo,_component_topology.nbLocalComponents());
   }
 
   ParaFIELD::~ParaFIELD()
   {
     if(_field)
       _field->decrRef();
+    if(_own_support)
+      delete _support;
     delete _topology;
   }
 
   void ParaFIELD::synchronizeTarget(ParaFIELD* source_field)
   {
-    DEC* data_channel;
+    DisjointDEC* data_channel;
     if (dynamic_cast<BlockTopology*>(_topology)!=0)
       {
         data_channel=new StructuredCoincidentDEC;
@@ -150,7 +152,7 @@ namespace ParaMEDMEM
 
   void ParaFIELD::synchronizeSource(ParaFIELD* target_field)
   {
-    DEC* data_channel;
+    DisjointDEC* data_channel;
     if (dynamic_cast<BlockTopology*>(_topology)!=0)
       {
         data_channel=new StructuredCoincidentDEC;
@@ -167,20 +169,56 @@ namespace ParaMEDMEM
     delete data_channel;
   }
 
+  /*!
+   * This method returns, if it exists, an array with only one component and as many as tuples as _field has.
+   * This array gives for every element on which this->_field lies, its global number, if this->_field is nodal.
+   * For example if _field is a nodal field : returned array will be the nodal global numbers.
+   * The content of this method is used to inform Working side to accumulate data recieved by lazy side.
+   */
+  DataArrayInt* ParaFIELD::returnCumulativeGlobalNumbering() const
+  {
+    if(!_field)
+      return 0;
+    TypeOfField type=_field->getTypeOfField();
+    switch(type)
+      {
+      case ON_CELLS:
+        return 0;
+      case ON_NODES:
+        return _support->getGlobalNumberingNodeDA();
+      default:
+        return 0;
+      }
+  }
+
+  DataArrayInt* ParaFIELD::returnGlobalNumbering() const
+  {
+    if(!_field)
+      return 0;
+    TypeOfField type=_field->getTypeOfField();
+    switch(type)
+      {
+      case ON_CELLS:
+        return _support->getGlobalNumberingCellDA();
+      case ON_NODES:
+        return _support->getGlobalNumberingNodeDA();
+      default:
+        return 0;
+      }
+  }
+  
+  int ParaFIELD::nbComponents() const
+  {
+    return _component_topology.nbComponents();
+  }
+
+
   /*! This method retrieves the integral of component \a icomp
     over the all domain. */
-  double ParaFIELD::getVolumeIntegral(int icomp) const
+  double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const
   {
     CommInterface comm_interface = _topology->getProcGroup()->getCommInterface();
-    MEDCouplingFieldDouble *volume=InterpolationMatrix::getSupportVolumes(_field->getMesh());
-    double *ptr=volume->getArray()->getPointer();
-    int nbOfValues=volume->getArray()->getNbOfElems();
-    double integral=0.;
-    for (int i=0; i<nbOfValues; i++)
-      integral+=_field->getIJ(i,icomp)*ptr[i];
-
-    volume->decrRef();
-
+    double integral=_field->integral(icomp,isWAbs);
     double total=0.;
     const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*>(_topology->getProcGroup()))->getComm();
     comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm);
@@ -188,4 +226,3 @@ namespace ParaMEDMEM
     return total;
   }
 }
-