Salome HOME
Merge from BR_V5_DEV 16Feb09
[tools/medcoupling.git] / src / ParaMEDMEM / ICoCoMEDField.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "ICoCoMEDField.hxx"
20 #include "ICoCoTrioField.hxx"
21 #include "ProcessorGroup.hxx"
22 #include "ParaMESH.hxx"
23 #include "ParaFIELD.hxx"
24 #include "NormalizedUnstructuredMesh.hxx"
25
26 namespace ICoCo
27 {
28
29   /*! Constructor directly attaching a ParaMESH and a ParaFIELD
30     the object does not take the control the objects pointed by 
31     \a mesh and \a field.
32   */
33     
34   MEDField::MEDField(ParaMEDMEM::ParaMESH* mesh, ParaMEDMEM::ParaFIELD* field): 
35     _mesh(mesh),
36     _field(field),
37     _has_field_ownership(false),
38     _local_mesh(0),
39     _support(0),
40     _comp_topology(0)
41   {
42   }
43   
44   MEDField::MEDField(TrioField& triofield, const ParaMEDMEM::ProcessorGroup& group):
45   _has_field_ownership(true)
46   {
47     _local_mesh = ParaMEDMEM::MEDCouplingUMesh::New();
48     _local_mesh->setMeshDimension(triofield._space_dim);
49     ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New();
50     myCoords->alloc(triofield._nbnodes,triofield._space_dim);
51     _local_mesh->setCoords(myCoords);
52     double *ptr=myCoords->getPointer();
53     std::copy(triofield._coords,triofield._coords+triofield._space_dim*triofield._nbnodes,ptr);
54     _local_mesh->allocateCells(triofield._nb_elems);
55     INTERP_KERNEL::NormalizedCellType elemtype;
56     switch (triofield._mesh_dim)
57       {
58       case 2:
59         switch (triofield._nodes_per_elem)
60           {
61           case 3:
62             elemtype=INTERP_KERNEL::NORM_TRI3;
63             break;
64           case 4 : 
65             elemtype=INTERP_KERNEL::NORM_QUAD4;
66             break;
67           default:
68             throw INTERP_KERNEL::Exception("incompatible Trio field - wrong nb of nodes per elem");
69           }
70         break;
71       case 3:
72         switch (triofield._nodes_per_elem)
73           {
74           case 4:
75             elemtype=INTERP_KERNEL::NORM_TETRA4;
76             break;
77           case 8 : 
78             elemtype=INTERP_KERNEL::NORM_HEXA8;
79             break;
80           default:
81             throw INTERP_KERNEL::Exception("incompatible Trio field - wrong nb of nodes per elem");
82           }
83         break;
84       default:
85         throw INTERP_KERNEL::Exception("incompatible Trio field - wrong mesh dimension");
86       }
87     //creating a connectivity table that complies to MED (1 indexing)
88     //and passing it to _local_mesh
89     int* conn=new int[triofield._nb_elems*triofield._nodes_per_elem];
90     for (int i=0; i<triofield._nb_elems;i++)
91       for(int j=0;j<triofield._nodes_per_elem;j++)
92         {
93           conn[j]=(triofield._connectivity)[i*triofield._nb_elems+j];
94           _local_mesh->insertNextCell(elemtype,triofield._nodes_per_elem,conn);
95         }
96     delete[] conn;
97
98     _local_mesh->setMeshDimension(triofield._mesh_dim);
99     
100     _mesh=new ParaMEDMEM::ParaMESH(_local_mesh, group, "support for trio field");
101     _comp_topology=new ParaMEDMEM::ComponentTopology(triofield._nb_field_components);
102     
103     //field on the sending end
104     if (triofield._field!=0)
105       {
106         _field =  new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,_mesh, *_comp_topology );
107         ParaMEDMEM::DataArrayDouble *fieldArr=_field->getField()->getArray();
108         _field->getField()->setName(triofield.getName().c_str());
109         _field->getField()->setTime(triofield._time1);
110         _field->getField()->setDtIt(0,triofield._itnumber);
111         for (int i =0; i<triofield._nb_elems; i++)
112           for (int j=0; j<triofield._nb_field_components; j++)
113             {
114               fieldArr->setIJ(i,j,triofield._field[i*triofield._nb_field_components+j]);
115             }
116       }
117     //field on the receiving end
118     else
119       {
120         _field =  new ParaMEDMEM::ParaFIELD(ParaMEDMEM::ON_CELLS,_support, *_comp_topology );
121         _field->getField()->setName(triofield.getName().c_str());
122         _field->getField()->setTime(triofield._time1);
123         _field->getField()->setDtIt(0,triofield._itnumber);
124         // the trio field points to the pointer inside the MED field
125         triofield._field=const_cast<double*> (_field->getField()->getArray()->getPointer());
126         for (int i=0; i<triofield._nb_field_components*triofield._nb_elems;i++)
127           triofield._field[i]=0.0;
128       }
129   }
130
131   MEDField::~MEDField()
132   {
133     delete _comp_topology;
134     delete _support;
135     _support=0;
136     if (_has_field_ownership)
137       {
138         delete _field;
139         delete _mesh;
140       }
141   }
142
143 };