00001
00005 #include <stdio.h>
00006 #include <string.h>
00007 #include <stdlib.h>
00008 #include <vector>
00009 #include "transfer.h"
00010
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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 CkPrintf("datatransfer> transfer.C:getSharedArea: not yet functional\n");
00059 return area;
00060 }
00061
00062
00063
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();
00084 int s,ns=srcMesh.getTets();
00085 int v,nv=valsPerTet;
00086 const int maxV=30;
00087
00088
00089 for (d=0;d<nd;d++) {
00090
00091
00092 double destAccum[maxV];
00093 for (v=0;v<nv;v++) destAccum[v]=0.0;
00094 double destVolume=0;
00095
00096
00097 for (s=0;s<ns;s++) {
00098
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
00110
00111
00112 double trueVolume=destMesh.getTetVolume(d);
00113 double volErr=destVolume-trueVolume;
00114 double accumScale=1.0/destVolume;
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
00122 for (v=0;v<nv;v++)
00123 destVals[d*nv+v]=destAccum[v]*accumScale;
00124 }
00125 }
00126