libs/ck-libs/datatransfer/transfer.C

Go to the documentation of this file.
00001 
00005 #include <stdio.h>
00006 #include <string.h> // For memmove
00007 #include <stdlib.h> // for abort
00008 #include <vector> //for std::vector 
00009 #include "transfer.h" 
00010 //#include "geom_util.h" 
00011 #include "charm++.h" 
00012 #include "MgcIntr3DTetrTetr.h"
00013 using namespace Mgc;
00014 
00016 double getSharedVolumeTets(const ConcreteElement &A,const ConcreteElement &B)
00017 {
00018         Mgc::Tetrahedron kT0,kT1;
00019         for(int i=0;i<4;i++){
00020                 CkVector3d pts0 = A.getNodeLocation(i);
00021                 kT0[i] = Mgc::Vector3((double)pts0.x,(double)pts0.y,(double)pts0.z);
00022                 CkVector3d pts1 = B.getNodeLocation(i);
00023                 kT1[i] = Mgc::Vector3((double)pts1.x,(double)pts1.y,(double)pts1.z);
00024         }
00025         Mgc::TetrahedronVolumeConsumer vol;
00026         Mgc::FindIntersection(kT0,kT1,vol);
00027         double sumVol = vol;
00028         if(sumVol < 0){
00029                 printf("volume less than zero!\n");
00030                 abort();
00031         }
00032         return sumVol;
00033 }
00034 
00035 
00036 double getSharedArea(const ConcreteElement &A,const ConcreteElement &B) {
00037   double area=0.0;
00038   /*  vector<Vec3D> xpoly2;
00039   double tri[3][3];
00040   double pri[6][3];
00041 
00042   for (int i=0; i<6; i++) {
00043     CkVector3d pt = A.getNodeLocation(i);
00044     pri[i][0] = pt[0];
00045     pri[i][1] = pt[1];
00046     pri[i][2] = pt[2];
00047   }
00048 
00049   for (int i=0; i<3; i++) {
00050     CkVector3d pt = B.getNodeLocation(i);
00051     tri[i][0] = pt[0];
00052     tri[i][1] = pt[1];
00053     tri[i][2] = pt[2];
00054   }
00055   */
00056   // need to uncomment the line below when geom_util is functional
00057   //area = tri_prism_X(tri,pri,xpoly2);
00058   CkPrintf("datatransfer> transfer.C:getSharedArea: not yet functional\n");
00059   return area;
00060 }
00061 
00062 // Compute the volume shared by cell s of srcMesh
00063 //   and cell d of destMesh.
00064 double getSharedVolume(int s,const TetMesh &srcMesh,
00065         int d,const TetMesh &destMesh) 
00066 {
00067         TetMeshElement se(s,srcMesh);
00068         TetMeshElement de(d,destMesh);
00069         return getSharedVolumeTets(se,de);
00070 }
00071 
00072 
00079 void transferCells(int valsPerTet,
00080         double *srcVals,const TetMesh &srcMesh,
00081         double *destVals,const TetMesh &destMesh)
00082 {
00083         int d,nd=destMesh.getTets(); //Destination cells
00084         int s,ns=srcMesh.getTets(); //Source cells
00085         int v,nv=valsPerTet; //Values (for one cell)
00086         const int maxV=30;
00087         
00088         /* For each dest cell: */
00089         for (d=0;d<nd;d++) {
00090                 
00091                 //Accumulate volume-weighted-average destination values
00092                 double destAccum[maxV]; 
00093                 for (v=0;v<nv;v++) destAccum[v]=0.0;
00094                 double destVolume=0; // Volume accumulator
00095                 
00096                 /* For each source cell: */
00097                 for (s=0;s<ns;s++) {
00098                         // Compute the volume shared by s and d:
00099                         double shared=getSharedVolume(s,srcMesh,d,destMesh);
00100                         if (shared<-1.0e-10) CkAbort("Negative volume shared region!");
00101                         if (shared>0) {
00102                                 for (int v=0;v<nv;v++) 
00103                                         destAccum[v]+=shared*srcVals[s*nv+v];
00104                                 destVolume+=shared;
00105                                 
00106                         }
00107                 }
00108                 
00109                 /* Check the relative volume error, to make sure we've 
00110                    totally covered each destination cell. Checking precision
00111                    is low, since meshing tools often use single precision. */
00112                 double trueVolume=destMesh.getTetVolume(d);
00113                 double volErr=destVolume-trueVolume;
00114                 double accumScale=1.0/destVolume; //Reverse volume weighting
00115                 if (fabs(volErr*accumScale)>1.0e-10) {
00116                         printf("WARNING: ------------- volume mismatch: dest tet %d -------------\n"
00117                                 " True volume %g, but total is only %g (err %g)\n",
00118                                 d,trueVolume,destVolume,volErr);
00119                 }
00120                 
00121                 /* Copy the accumulated values into dest */
00122                 for (v=0;v<nv;v++) 
00123                         destVals[d*nv+v]=destAccum[v]*accumScale;
00124         }
00125 }
00126 

Generated on Sun Jun 29 13:29:19 2008 for Charm++ by  doxygen 1.5.1