00001 
00002 
00003 
00004 
00005 #ifndef AMROC_BREP_OUTPUT_H
00006 #define AMROC_BREP_OUTPUT_H
00007 
00015 #include "AMRInterpolation.h"
00016 #include "geom/kernel.h"
00017 
00024 template <class VectorType, int dim> class BrepOutOps;
00025 
00026 template <class VectorType>
00027 class BrepOutOps<VectorType,2> {
00028 public:
00029   BrepOutOps() {}
00030 
00031   void ElementNormals(const int num_pos, const ads::FixedArray<2,DataType>* pos,
00032                       const int num_elem, const ads::FixedArray<2,int>* conn,
00033                       ads::FixedArray<2,DataType>* normals) {
00034     for (register int i=0; i<num_elem; i++) {
00035       ads::FixedArray<2,DataType> tangent(pos[conn[i][1]]);
00036       tangent -= pos[conn[i][0]];
00037       geom::normalize(&tangent);
00038       normals[i][0] = -tangent[1];
00039       normals[i][1] =  tangent[0];
00040     }
00041   }
00042 
00043   void ElementAreas(const int num_pos, const ads::FixedArray<2,DataType>* pos,
00044                     const int num_elem, const ads::FixedArray<2,int>* conn,
00045                     DataType* areas) {
00046     for (register int i=0; i<num_elem; i++)
00047       areas[i] = geom::computeDistance(pos[conn[i][0]],pos[conn[i][1]]); 
00048   }
00049 
00050   void CrossProducts(const int num_vec, const ads::FixedArray<2,DataType>* v1, 
00051                      const ads::FixedArray<2,DataType>* v2, 
00052                      ads::FixedArray<2,DataType>* r) {
00053     for (register int i=0; i<num_vec; i++) {
00054       r[i][0] = v1[i][0]*v2[i][1]-v1[i][1]*v2[i][0]; r[i][1] = 0.;
00055     }
00056   }
00057 
00058   void DotProducts(const int num_vec, const ads::FixedArray<2,DataType>* v1, 
00059                    const ads::FixedArray<2,DataType>* v2, 
00060                    DataType* r) {
00061     for (register int i=0; i<num_vec; i++) 
00062       r[i] = geom::computeDotProduct(v1[i],v2[i]);
00063   }
00064 };
00065 
00066 
00067 template <class VectorType>
00068 class BrepOutOps<VectorType,3> {
00069 public:
00070   BrepOutOps() {}
00071 
00072   void ElementNormals(const int num_pos, const ads::FixedArray<3,DataType>* pos,
00073                       const int num_elem, const ads::FixedArray<3,int>* conn,
00074                       ads::FixedArray<3,DataType>* normals) {
00075     for (register int i=0; i<num_elem; i++) {
00076       const ads::FixedArray<3,int>& face = conn[i];
00077       geom::computeCrossProduct(pos[face[2]] - pos[face[1]],
00078                                 pos[face[1]] - pos[face[0]], &(normals[i]));
00079       geom::normalize(&(normals[i]));
00080     }
00081   }
00082 
00083   void ElementAreas(const int num_pos, const ads::FixedArray<3,DataType>* pos,
00084                     const int num_elem, const ads::FixedArray<3,int>* conn,
00085                     DataType* areas) {
00086     for (register int i=0; i<num_elem; i++)
00087       areas[i] = geom::computeArea(pos[conn[i][0]],pos[conn[i][1]],pos[conn[i][2]]); 
00088   }
00089 
00090   void CrossProducts(const int num_vec, const ads::FixedArray<3,DataType>* v1, 
00091                      const ads::FixedArray<3,DataType>* v2, 
00092                      ads::FixedArray<3,DataType>* r) {
00093     for (register int i=0; i<num_vec; i++) 
00094       r[i] = geom::computeCrossProduct(v1[i],v2[i]);
00095   }
00096 
00097   void DotProducts(const int num_vec, const ads::FixedArray<3,DataType>* v1, 
00098                    const ads::FixedArray<3,DataType>* v2, 
00099                    DataType* r) {
00100     for (register int i=0; i<num_vec; i++) 
00101       r[i] = geom::computeDotProduct(v1[i],v2[i]);
00102   }
00103 };
00104 
00105 
00106 template <class VectorType, int dim>
00107 class BrepOutput : public AMRBase<VectorType,dim>, public BrepOutOps<VectorType,dim> {
00108   typedef AMRBase<VectorType,dim> base;
00109   typedef typename VectorType::InternalDataType DataType;
00110 
00111 public:
00112   typedef typename base::vec_grid_fct_type vec_grid_fct_type;  
00113   typedef GridFunction<DataType,dim> grid_fct_type;
00114   typedef AMRInterpolation<VectorType,dim> interpolation_type;
00115   typedef typename interpolation_type::point_type point_type;
00116   typedef ads::FixedArray<dim,DataType> geom_point_type;
00117   typedef ads::FixedArray<dim,int> multi_index_type;
00118   typedef BrepOutOps<VectorType,dim> ops;
00119 
00120   BrepOutput(interpolation_type* interpol) : base(), _Interpolation(interpol), 
00121                                              _Ncnt(0), _OutputType(0), StepFormat(0), 
00122                                              StepDirectories(0) {
00123     BaseFileName = "-";
00124     CompName = (std::string*) 0;
00125     CompDir = "-";
00126   } 
00127 
00128   virtual ~BrepOutput() {
00129     if (CompName) delete [] CompName;
00130     if (_Interpolation) delete _Interpolation;
00131   }
00132 
00133   virtual void register_at(ControlDevice& Ctrl) { register_at(Ctrl, ""); }
00134   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00135     LocCtrl = Ctrl.getSubDevice(prefix+"BrepFile");    
00136     RegisterAt(LocCtrl,"OutputName",BaseFileName);
00137     RegisterAt(LocCtrl,"Type",_OutputType);
00138     if (CompName) delete [] CompName;
00139     CompName = new std::string[MAXCOMPONENTS];
00140     for (int d=0; d<MAXCOMPONENTS; d++) {
00141       char Name[16];
00142       std::sprintf(Name,"-");
00143       CompName[d] = Name;
00144       std::sprintf(Name,"CompName(%d)",d+1);
00145       RegisterAt(LocCtrl,Name,CompName[d]);
00146     }    
00147     RegisterAt(LocCtrl,"OutputDirectory",CompDir);
00148     RegisterAt(LocCtrl,"StepFormat",StepFormat);
00149     RegisterAt(LocCtrl,"StepDirectories",StepDirectories);    
00150   }
00151   virtual void update() {
00152     int d=MAXCOMPONENTS;
00153     for (; d>0; d--) 
00154       if (CompName[d-1].c_str()[0] != '-') 
00155         break;
00156     if (d>0) SetNcnt(d);
00157   }
00158 
00159   virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00160     base::SetupData(gh, ghosts);
00161     Interpolation().SetupData(gh, ghosts);
00162   }
00163 
00164   virtual void WriteOut(vec_grid_fct_type& u, 
00165                         const int num_vertices, const DataType* vertices,
00166                         const int num_connections, const int* connections) {
00167 
00168     VectorType* data = new VectorType[num_vertices];
00169     int Time = CurrentTime(base::GH(),0);
00170     double t = GetPhysicalTime(u,Time,0);
00171     Interpolation().PointsValues(u,t,num_vertices,(const point_type*)vertices,data);
00172     int NValues = num_vertices*base::NEquations();
00173     Interpolation().ArrayCombine(VizServer,NValues,(DataType *)data);
00174     if (MY_PROC==VizServer) 
00175       WriteMesh(num_vertices,vertices,num_connections,connections,Time,t,(DataType *)data);
00176     delete [] data;
00177   } 
00178 
00179   virtual void WriteOut(grid_fct_type& IOfunc, 
00180                         const int num_vertices, const DataType* vertices,
00181                         const int num_connections, const int* connections) {
00182 
00183     DataType* data = new DataType[num_vertices];
00184     int Time = CurrentTime(base::GH(),0);
00185     double t = GetPhysicalTime(IOfunc,Time,0);
00186     Interpolation().PointsValues(IOfunc,t,num_vertices,(const point_type*)vertices,data);
00187     Interpolation().ArrayCombine(VizServer,num_vertices,data);
00188     if (MY_PROC==VizServer) 
00189       WriteMesh(num_vertices,vertices,num_connections,connections,Time,t,data);
00190     delete [] data;
00191   } 
00192 
00193   void WriteMesh(const int num_vertices, const DataType* vertices,
00194                  const int num_connections, const int* connections, 
00195                  const int Time, const double t, const DataType* data) {
00196 
00197     char ioname[DAGHBktGFNameWidth+256];
00198     OutputFileName(ioname,BaseFileName.c_str(),Time);
00199     std::cout << " *** Writing " << ioname << " at t = " << t << std::endl;
00200 
00201     std::ofstream outfile;
00202     std::ostream* out;
00203     outfile.open(ioname, std::ios::out);
00204     out = new std::ostream(outfile.rdbuf());
00205 
00206     if (OutputType()==0) {
00207       *out << "title = \"mesh t=" << t << "\"" << std::endl;
00208       *out << "variables = x y z";
00209       for (int cnt=0;cnt<Ncnt(); cnt++) 
00210         if (OutputName(cnt).c_str()[0] != '-') 
00211           *out << " " << OutputName(cnt);
00212       *out << std::endl;
00213       *out << "zone t=\"zone 1\", I=" << num_vertices << ", J="
00214            << num_connections << ", solutiontime=" << t << ", F=FEPOINT, ET=TRIANGLE" << std::endl;
00215       for (register int j=0;j<num_vertices; j++) {
00216         if (dim==3) 
00217           *out << vertices[3*j] << " " << vertices[3*j+1] << " " << vertices[3*j+2]; 
00218         else if (dim==2)
00219           *out << vertices[2*j] << " " << vertices[2*j+1] << " 0.";     
00220         for (int cnt=0;cnt<Ncnt(); cnt++) 
00221           if (OutputName(cnt).c_str()[0] != '-') 
00222             *out << " " << data[cnt*num_vertices+j];
00223         *out << std::endl;
00224       }
00225       for (register int j=0;j<num_connections; j++)
00226         if (dim==3) 
00227           *out << connections[3*j]+1 << " " << connections[3*j+1]+1 << " " << connections[3*j+2]+1 << std::endl; 
00228         else if (dim==2)
00229           *out << connections[2*j]+1 << " " << connections[2*j+1]+1 << " " << connections[2*j+1]+1 << std::endl; 
00230     }
00231 
00232     outfile.close();
00233     delete out; 
00234   }   
00235 
00236   void OutputFileName(char *ioname, const char* name, const int& Time) {
00237     char time[20], help[DAGHBktGFNameWidth+256];
00238     if (StepFormat<=0)
00239       std::sprintf(time,"%d",Time); 
00240     else if (StepFormat==1) {
00241       if (Time<=999999) 
00242         std::sprintf(time,"%6.6d",Time);
00243       else if (Time<=99999999) 
00244         std::sprintf(time,"%8.8d",Time);
00245       else
00246         std::sprintf(time,"%d",Time);
00247     }
00248     if (CompDir.c_str()[0] != '-' && CompDir.length()>0) 
00249       std::sprintf(ioname,"%s/",CompDir.c_str());
00250     else
00251       ioname[0]='\0';
00252     if (StepDirectories>0) {
00253       std::sprintf(help,"%s/",time); 
00254       std::strcat(ioname,help);
00255     }
00256     if (OutputType()==0) 
00257       std::sprintf(help,"%s_%s.tec",name,time); 
00258     std::strcat(ioname,help);
00259   }
00260 
00261   DataType Integrate(const DataType* data,
00262                      const int num_pos, const DataType* vertices,
00263                      const int num_elem, const int* connections) {
00264     DataType sum = 0.;
00265     geom_point_type* area = new DataType[num_elem];
00266       
00267     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00268     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00269     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00270     
00271     for (register int i=0; i<num_elem; i++)
00272       if (data[i] != Interpolation().ErrorValue())
00273         sum += data[i]*area[i];
00274     
00275     delete [] area;
00276 
00277     return sum;
00278   } 
00279 
00280   DataType Integrate(grid_fct_type& IOfunc, 
00281                      const int num_pos, const DataType* vertices,
00282                      const int num_elem, const int* connections) {
00283     geom_point_type* centroids = new geom_point_type[num_elem];
00284     DataType* data = new DataType[num_elem];
00285 
00286     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00287     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00288     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00289 
00290     int Time = CurrentTime(base::GH(),0);
00291     double t = GetPhysicalTime(IOfunc,Time,0);
00292     Interpolation().PointsValues(IOfunc,t,num_elem,reinterpret_cast<const point_type*>(centroids),data);
00293     Interpolation().ArrayCombine(VizServer,num_elem,data);
00294 
00295     DataType sum = 0.;
00296     if (MY_PROC==VizServer) {
00297       geom_point_type* area = new DataType[num_elem];
00298       
00299       ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00300       for (register int i=0; i<num_elem; i++)
00301         if (data[i] != Interpolation().ErrorValue())
00302           sum += data[i]*area[i];
00303 
00304      delete [] area;
00305     }
00306 
00307     delete [] centroids;
00308     delete [] data;
00309 
00310     return sum;
00311   } 
00312 
00313   geom_point_type IntegrateNormal(const DataType* data, 
00314                                   const int num_pos, const DataType* vertices,
00315                                   const int num_elem, const int* connections) {
00316     geom_point_type sum(0.);
00317     DataType* area = new DataType[num_elem];
00318     geom_point_type* normal = new geom_point_type[num_elem];
00319     
00320     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00321     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00322     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00323     ops::ElementNormals(num_pos,pos,num_elem,conn,normal);
00324     
00325     for (register int i=0; i<num_elem; i++) 
00326       if (data[i] != Interpolation().ErrorValue())
00327         sum += data[i]*area[i]*normal[i];
00328     
00329     delete [] area;
00330     delete [] normal;
00331 
00332     return sum;
00333   } 
00334 
00335   geom_point_type IntegrateNormal(grid_fct_type& IOfunc, 
00336                                   const int num_pos, const DataType* vertices,
00337                                   const int num_elem, const int* connections) {
00338     geom_point_type* centroids = new geom_point_type[num_elem];
00339     DataType* data = new DataType[num_elem];
00340 
00341     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00342     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00343     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00344 
00345     int Time = CurrentTime(base::GH(),0);
00346     double t = GetPhysicalTime(IOfunc,Time,0);
00347     Interpolation().PointsValues(IOfunc,t,num_elem,reinterpret_cast<const point_type*>(centroids),data);
00348     Interpolation().ArrayCombine(VizServer,num_elem,data);
00349 
00350     geom_point_type sum(0.);
00351     if (MY_PROC==VizServer) {
00352       DataType* area = new DataType[num_elem];
00353       geom_point_type* normal = new geom_point_type[num_elem];
00354 
00355       ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00356       ops::ElementNormals(num_pos,pos,num_elem,conn,normal);     
00357       for (register int i=0; i<num_elem; i++) 
00358         if (data[i] != Interpolation().ErrorValue())
00359           sum += data[i]*area[i]*normal[i];
00360 
00361       delete [] area;
00362       delete [] normal;
00363     }
00364 
00365     delete [] centroids;
00366     delete [] data;
00367 
00368     return sum;
00369   } 
00370 
00371   geom_point_type IntegrateVector(const geom_point_type* data, 
00372                                   const int num_pos, const DataType* vertices,
00373                                   const int num_elem, const int* connections) {
00374     geom_point_type sum(0.);
00375     DataType* area = new DataType[num_elem];
00376     geom_point_type* normal = new geom_point_type[num_elem];
00377     
00378     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00379     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00380     ops::ElementAreas(num_pos,pos,num_elem,conn,area);   
00381     for (register int i=0; i<num_elem; i++) 
00382       if (data[i][0] != Interpolation().ErrorValue())
00383         sum += area[i]*data[i];
00384     
00385     delete [] area;
00386 
00387     return sum;
00388   } 
00389 
00390   DataType IntegrateVectorNormal(const geom_point_type* data, 
00391                                  const int num_pos, const DataType* vertices,
00392                                  const int num_elem, const int* connections) {
00393     DataType sum(0.);
00394     DataType* area = new DataType[num_elem];
00395     geom_point_type* normal = new geom_point_type[num_elem];
00396     
00397     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00398     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00399     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00400     ops::ElementNormals(num_pos,pos,num_elem,conn,normal);  
00401     for (register int i=0; i<num_elem; i++) 
00402       if (data[i][0] != Interpolation().ErrorValue())
00403         sum += area[i]*geom::computeDotProduct(data[i],normal[i]);
00404     
00405     delete [] area;
00406     delete [] normal;
00407     
00408     return sum;
00409   } 
00410 
00411   geom_point_type IntegrateTensorNormal(const geom_point_type* data, 
00412                                         const int num_pos, const DataType* vertices,
00413                                         const int num_elem, const int* connections) {
00414     geom_point_type sum(0.);
00415     DataType* area = new DataType[num_elem];
00416     geom_point_type* normal = new geom_point_type[num_elem];
00417     
00418     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00419     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00420     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00421     ops::ElementNormals(num_pos,pos,num_elem,conn,normal);
00422     
00423     for (register int i=0; i<num_elem; i++) 
00424       for (register int d=0; d<dim; d++) 
00425       if (data[dim*i+d][0] != Interpolation().ErrorValue())
00426         sum[d] += area[i]*geom::computeDotProduct(data[dim*i+d],normal[i]);
00427     
00428     delete [] area;
00429     delete [] normal;
00430     
00431     return sum;
00432   } 
00433 
00434   geom_point_type IntegrateMoment(const DataType* data, 
00435                                   const int num_pos, const DataType* vertices,
00436                                   const int num_elem, const int* connections,
00437                                   const geom_point_type& point) {
00438     geom_point_type sum(0.);
00439     DataType* area = new DataType[num_elem];
00440     geom_point_type* normal = new geom_point_type[num_elem];
00441     geom_point_type* cross = new geom_point_type[num_elem];
00442     geom_point_type* centroids = new geom_point_type[num_elem];
00443     
00444     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00445     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00446     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00447     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00448     ops::ElementNormals(num_pos,pos,num_elem,conn,normal);
00449     
00450     for (register int i=0; i<num_elem; i++)
00451       if (data[i] != Interpolation().ErrorValue()) {
00452         centroids[i] -= point;
00453         normal[i] *= data[i];
00454       }
00455     ops::CrossProducts(num_elem,centroids,normal,cross);
00456     for (register int i=0; i<num_elem; i++) 
00457       if (data[i] != Interpolation().ErrorValue()) 
00458         sum += area[i]*cross[i];
00459     
00460     delete [] area;
00461     delete [] normal;
00462     delete [] cross;
00463     delete [] centroids;
00464 
00465     return sum;
00466   }
00467 
00468   geom_point_type IntegrateMoment(grid_fct_type& IOfunc, 
00469                                   const int num_pos, const DataType* vertices,
00470                                   const int num_elem, const int* connections,
00471                                   const geom_point_type& point) {
00472     geom_point_type* centroids = new geom_point_type[num_elem];
00473     DataType* data = new DataType[num_elem];
00474 
00475     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00476     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00477     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00478 
00479     int Time = CurrentTime(base::GH(),0);
00480     double t = GetPhysicalTime(IOfunc,Time,0);
00481     Interpolation().PointsValues(IOfunc,t,num_elem,reinterpret_cast<const point_type*>(centroids),data);
00482     Interpolation().ArrayCombine(VizServer,num_elem,data);
00483  
00484     geom_point_type sum(0.);
00485     if (MY_PROC==VizServer) {
00486       DataType* area = new DataType[num_elem];
00487       geom_point_type* normal = new geom_point_type[num_elem];
00488       geom_point_type* cross = new geom_point_type[num_elem];
00489 
00490       ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00491       ops::ElementNormals(num_pos,pos,num_elem,conn,normal);
00492       for (register int i=0; i<num_elem; i++)
00493         if (data[i] != Interpolation().ErrorValue()) {
00494           centroids[i] -= point;
00495           normal[i] *= data[i];
00496         }
00497       ops::CrossProducts(num_elem,centroids,normal,cross);
00498       for (register int i=0; i<num_elem; i++) 
00499         if (data[i] != Interpolation().ErrorValue()) 
00500           sum += area[i]*cross[i];
00501 
00502       delete [] area;
00503       delete [] normal;
00504       delete [] cross;
00505     }
00506 
00507     delete [] centroids;
00508     delete [] data;
00509 
00510     return sum;
00511   }
00512 
00513   geom_point_type IntegrateVectorMoment(const geom_point_type* data, 
00514                                         const int num_pos, const DataType* vertices,
00515                                         const int num_elem, const int* connections,
00516                                         const geom_point_type& point) {
00517     geom_point_type sum(0.);
00518     DataType* area = new DataType[num_elem];
00519     geom_point_type* cross = new geom_point_type[num_elem];
00520     geom_point_type* centroids = new geom_point_type[num_elem];
00521     
00522     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00523     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00524     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00525     ops::ElementAreas(num_pos,pos,num_elem,conn,area);    
00526     for (register int i=0; i<num_elem; i++)
00527       if (data[i][0] != Interpolation().ErrorValue()) 
00528         centroids[i] -= point;
00529     ops::CrossProducts(num_elem,centroids,data,cross);
00530     for (register int i=0; i<num_elem; i++) 
00531       if (data[i][0] != Interpolation().ErrorValue()) 
00532         sum += area[i]*cross[i];
00533     
00534     delete [] area;
00535     delete [] cross;
00536     delete [] centroids;
00537 
00538     return sum;
00539   }
00540 
00541   geom_point_type IntegrateTensorMoment(const geom_point_type* data, 
00542                                         const int num_pos, const DataType* vertices,
00543                                         const int num_elem, const int* connections,
00544                                         const geom_point_type& point) {
00545     geom_point_type sum(0.);
00546     DataType* area = new DataType[num_elem];
00547     geom_point_type* normal = new geom_point_type[num_elem];
00548     geom_point_type* cross = new geom_point_type[num_elem];
00549     geom_point_type* datavec = new geom_point_type[num_elem];
00550     geom_point_type* centroids = new geom_point_type[num_elem];
00551     
00552     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00553     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00554     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00555     ops::ElementAreas(num_pos,pos,num_elem,conn,area);
00556     ops::ElementNormals(num_pos,pos,num_elem,conn,normal);
00557     for (register int i=0; i<num_elem; i++) {
00558       centroids[i] -= point;
00559       for (register int d=0; d<dim; d++) 
00560         if (data[dim*i+d][0] != Interpolation().ErrorValue())
00561           datavec[i][d] = geom::computeDotProduct(data[dim*i+d],normal[i]);
00562         else
00563           datavec[i][d] = Interpolation().ErrorValue();
00564     }
00565     ops::CrossProducts(num_elem,centroids,datavec,cross);
00566     for (register int i=0; i<num_elem; i++) 
00567       if (datavec[i][0] != Interpolation().ErrorValue()) 
00568         sum += area[i]*cross[i];
00569     
00570     delete [] area;
00571     delete [] normal;
00572     delete [] cross;
00573     delete [] datavec;
00574     delete [] centroids;
00575 
00576     return sum;
00577   }
00578 
00579   void ElementCentroids(const int num_pos, const geom_point_type* pos,
00580                         const int num_elem, const multi_index_type* conn,
00581                         geom_point_type* centroids) {
00582     for (register int i=0; i<num_elem; i++) {
00583       const multi_index_type& face = conn[i];
00584       centroids[i] = pos[face[0]];
00585       for (register int d=1; d<dim; d++)
00586         centroids[i] += pos[face[d]];
00587       centroids[i] /= dim;
00588     }
00589   }
00590 
00591   void ElementCentroids(const int num_pos, const DataType* vertices,
00592                         const int num_elem, const int* connections,
00593                         geom_point_type* centroids) {
00594     const geom_point_type* pos = reinterpret_cast<const geom_point_type*>(vertices);
00595     const multi_index_type* conn = reinterpret_cast<const multi_index_type*>(connections);
00596     ElementCentroids(num_pos,pos,num_elem,conn,centroids);
00597   }
00598   
00599   inline void SetNcnt(const int& cnt) { _Ncnt = cnt; }
00600   inline const int& Ncnt() const { return _Ncnt; }
00601   inline const int& OutputType() const { return _OutputType; }
00602   inline const std::string& OutputName(const int cnt) const 
00603   { assert (cnt>=0 && cnt<MAXCOMPONENTS); return CompName[cnt]; }
00604 
00605   inline void SetInterpolation(interpolation_type* interpol) { _Interpolation = interpol; }
00606   inline interpolation_type& Interpolation() { return *_Interpolation; }
00607   inline const interpolation_type& Interpolation() const { return *_Interpolation; }
00608 
00609 protected:
00610   interpolation_type* _Interpolation;
00611   int _Ncnt, _OutputType;
00612   int StepFormat, StepDirectories;
00613   std::string BaseFileName;
00614   std::string* CompName;
00615   std::string CompDir;
00616   ControlDevice LocCtrl;
00617 };
00618 
00619 
00620 #endif