Back to index

salome-med  6.5.0
ParaFIELD.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "Topology.hxx"
00021 #include "BlockTopology.hxx"
00022 #include "ComponentTopology.hxx"
00023 #include "ExplicitCoincidentDEC.hxx"
00024 #include "StructuredCoincidentDEC.hxx"
00025 #include "CommInterface.hxx"
00026 #include "ProcessorGroup.hxx"
00027 #include "MPIProcessorGroup.hxx"
00028 #include "ParaFIELD.hxx"
00029 #include "ParaMESH.hxx"
00030 #include "InterpKernelUtilities.hxx"
00031 #include "InterpolationMatrix.hxx"
00032 
00033 #include <numeric>
00034 
00035 namespace ParaMEDMEM
00036 {
00066   ParaFIELD::ParaFIELD(TypeOfField type, TypeOfTimeDiscretization td, ParaMESH* para_support, const ComponentTopology& component_topology)
00067     :_field(0),
00068      _component_topology(component_topology),_topology(0),_own_support(false),
00069      _support(para_support)
00070   {
00071     if (para_support->isStructured() || (para_support->getTopology()->getProcGroup()->size()==1 && component_topology.nbBlocks()!=1))
00072       {
00073         const BlockTopology* source_topo = dynamic_cast<const BlockTopology*>(para_support->getTopology());
00074         _topology=new BlockTopology(*source_topo,component_topology);
00075       }
00076     else
00077       {
00078         if (component_topology.nbBlocks()!=1 &&  para_support->getTopology()->getProcGroup()->size()!=1)
00079           throw INTERP_KERNEL::Exception(LOCALIZED("ParaFIELD constructor : Unstructured Support not taken into account with component topology yet"));
00080         else 
00081           {
00082             const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (para_support->getTopology());
00083             int nb_local_comp=component_topology.nbLocalComponents();
00084             _topology=new BlockTopology(*source_topo,nb_local_comp);
00085           }
00086       }
00087     int nb_components = component_topology.nbLocalComponents();
00088     if (nb_components!=0)
00089       {
00090         _field=MEDCouplingFieldDouble::New(type,td);
00091         _field->setMesh(_support->getCellMesh());
00092         DataArrayDouble *array=DataArrayDouble::New();
00093         array->alloc(_field->getNumberOfTuples(),nb_components);
00094         _field->setArray(array);
00095         array->decrRef();
00096       }
00097     else return;
00098   
00099     _field->setName("Default ParaFIELD name");
00100     _field->setDescription("Default ParaFIELD description");
00101   } 
00102 
00109   ParaFIELD::ParaFIELD(MEDCouplingFieldDouble* subdomain_field, ParaMESH *sup, const ProcessorGroup& proc_group):
00110     _field(subdomain_field),
00111     _component_topology(ComponentTopology(_field->getNumberOfComponents())),_topology(0),_own_support(false),
00112     _support(sup)
00113   {
00114     if(_field)
00115       _field->incrRef();
00116     const BlockTopology* source_topo=dynamic_cast<const BlockTopology*> (_support->getTopology());
00117     _topology=new BlockTopology(*source_topo,_component_topology.nbLocalComponents());
00118   }
00119 
00120   ParaFIELD::~ParaFIELD()
00121   {
00122     if(_field)
00123       _field->decrRef();
00124     if(_own_support)
00125       delete _support;
00126     delete _topology;
00127   }
00128 
00129   void ParaFIELD::synchronizeTarget(ParaFIELD* source_field)
00130   {
00131     DisjointDEC* data_channel;
00132     if (dynamic_cast<BlockTopology*>(_topology)!=0)
00133       {
00134         data_channel=new StructuredCoincidentDEC;
00135       }
00136     else
00137       {
00138         data_channel=new ExplicitCoincidentDEC;
00139       }
00140     data_channel->attachLocalField(this);
00141     data_channel->synchronize();
00142     data_channel->prepareTargetDE();
00143     data_channel->recvData();
00144   
00145     delete data_channel;
00146   }
00147 
00148   void ParaFIELD::synchronizeSource(ParaFIELD* target_field)
00149   {
00150     DisjointDEC* data_channel;
00151     if (dynamic_cast<BlockTopology*>(_topology)!=0)
00152       {
00153         data_channel=new StructuredCoincidentDEC;
00154       }
00155     else
00156       {
00157         data_channel=new ExplicitCoincidentDEC;
00158       }
00159     data_channel->attachLocalField(this);
00160     data_channel->synchronize();
00161     data_channel->prepareSourceDE();
00162     data_channel->sendData();
00163   
00164     delete data_channel;
00165   }
00166 
00173   DataArrayInt* ParaFIELD::returnCumulativeGlobalNumbering() const
00174   {
00175     if(!_field)
00176       return 0;
00177     TypeOfField type=_field->getTypeOfField();
00178     switch(type)
00179       {
00180       case ON_CELLS:
00181         return 0;
00182       case ON_NODES:
00183         return _support->getGlobalNumberingNodeDA();
00184       default:
00185         return 0;
00186       }
00187   }
00188 
00189   DataArrayInt* ParaFIELD::returnGlobalNumbering() const
00190   {
00191     if(!_field)
00192       return 0;
00193     TypeOfField type=_field->getTypeOfField();
00194     switch(type)
00195       {
00196       case ON_CELLS:
00197         return _support->getGlobalNumberingCellDA();
00198       case ON_NODES:
00199         return _support->getGlobalNumberingNodeDA();
00200       default:
00201         return 0;
00202       }
00203   }
00204   
00205   int ParaFIELD::nbComponents() const
00206   {
00207     return _component_topology.nbComponents();
00208   }
00209 
00210 
00213   double ParaFIELD::getVolumeIntegral(int icomp, bool isWAbs) const
00214   {
00215     CommInterface comm_interface = _topology->getProcGroup()->getCommInterface();
00216     double integral=_field->integral(icomp,isWAbs);
00217     double total=0.;
00218     const MPI_Comm* comm = (dynamic_cast<const MPIProcessorGroup*>(_topology->getProcGroup()))->getComm();
00219     comm_interface.allReduce(&integral, &total, 1, MPI_DOUBLE, MPI_SUM, *comm);
00220   
00221     return total;
00222   }
00223 }