Allink  v0.1
VarDataEl.cpp
00001 /***********************************************************************
00002 VarDataEl: Elaboration functions for the VarData class. This functions
00003 provides a simple manipulation of the data read by [Open]. The
00004 options are provided to elaborate different system's shapes.
00005 Copyright (C) 2008 by Giovanni Marelli <sabeiro@virgilio.it>
00006 
00007 
00008 This program is free software; you can redistribute it and/or modify
00009 it under the terms of the GNU General Public License as published by
00010 the Free Software Foundation; either version 2 of the License, or
00011 (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 ***********************************************************************/
00022 #include "../include/VarData.h"
00023 
00024 int VarData::RadDistr(int Values,double *Plot,double Border[2],int How){
00025   return 1;
00026 }
00027 char *VarData::SysState(){
00028   char *Info;
00029   Info = (char *)malloc(256*sizeof(char));
00030   Gen->Temp = 0.;
00031   double VelSquare[3];
00032   for(int d=0;d<3;d++){
00033     Gen->Pre[d] = 0.;
00034     VelSquare[d] = 0.;
00035   }
00036   for(int p=0;p<Gen->NPart;p++){
00037     for(int d=0;d<3;d++){
00038       Gen->Pre[d] += SQUARE(Pm[p].Vel[d]);
00039     }
00040   }
00041   Gen->Temp = (Gen->Pre[0] + Gen->Pre[1] + Gen->Pre[2])/(3.*Gen->NPart);
00042   for(int d=0;d<3;d++){
00043     Gen->Pre[d] /= (Gen->Edge[0]*Gen->Edge[1]*Gen->Edge[2]);
00044   }
00045   Gen->SurfTens = Gen->Edge[2]*(Gen->Pre[2] - .5*(Gen->Pre[0] + Gen->Pre[1]) );
00046   sprintf(Info,"Pre0\tPre1\tPre2\tSurfTens\tTemp\n%.4g\t%.4g\t%.4g\t%.4g\t%.4g\n",Gen->Pre[0],Gen->Pre[1],Gen->Pre[2],Gen->SurfTens,Gen->Temp);
00047   return Info;
00048 }
00049 MOMENTI VarData::SampleSurfaceMem(int NSample){
00050   if(IfPlotMem){
00051     MOMENTI m1;
00052     m1.Num = 0;
00053   }
00054   PlotMem = (double *) calloc(SQR(NSample),sizeof(double));
00055   double *PlotR = (double *) calloc(SQR(NEdge),sizeof(double));
00056   //LoadDensFile(PlotR,NEdge);
00057   MOMENTI m1 = SampleSurfacePart(PlotR,NEdge,0);
00058   InterBSpline2D(PlotR,PlotMem,NEdge,NSample);
00059   if(IfPlotMem){
00060     free(PlotR);
00061   }
00062   IfPlotMem = 1;
00063   return m1;
00064 }
00065 void VarData::SampleSurface(double *Plot,int NSample,int Type){
00066   double Average=0.;
00067   double NAverage=0;
00068   double **Norma = (double **)calloc(NSample,sizeof(double));
00069   for(int v=0;v<NSample;v++){
00070     Norma[v] = (double *)calloc(NSample,sizeof(double));
00071     for(int vv=0;vv<NSample;vv++){
00072       Plot[v*NSample+vv] = 0.;
00073     }
00074   }
00075   if(Type == 0){
00076     for(int c=0;c<Gen->NChain;c++){
00077       //if(!CHAIN_IF_TYPE(Ch[c].Type,NChType))continue;
00078       Average += Ch[c].Pos[CNorm];NAverage += 1.;
00079    int v = (int)(Ch[c].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00080    if( v < 0 || v >= NSample) continue;
00081    int vv = (int)(Ch[c].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00082    if( vv < 0 || vv >= NSample) continue;
00083    Plot[v*NSample+vv] += Ch[c].Pos[CNorm];
00084    Norma[v][vv] += 1.;
00085    //printf("%d %d %lf %lf\n",v,vv,Plot[v][vv],Norma[v][vv]);
00086     }
00087   }
00088   else {
00089     for(int p=0;p<Gen->NPart;p++){
00090       Average += Pm[p].Pos[CNorm];NAverage += 1.;
00091    int v = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00092    if( v < 0 || v >= NSample) continue;
00093    int vv = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00094    if( vv < 0 || vv >= NSample) continue;
00095    Plot[v*NSample+vv] += Pm[p].Pos[CNorm];
00096    Norma[v][vv] += 1.;
00097    //printf("%d %d %lf %lf\n",v,vv,Plot[v][vv],Norma[v][vv]);
00098     }
00099   }
00100   Average /= (double)NAverage;
00101   for(int v=0;v<NSample;v++){
00102     for(int vv=0;vv<NSample;vv++){
00103       if(Norma[v][vv] > 0.){
00104    Plot[v*NSample+vv] /= Norma[v][vv];
00105       }
00106       else Plot[v*NSample+vv] = Average;
00107     }
00108   }
00109   for(int v=0;v<NSample;v++)
00110     free(Norma[v]);
00111   free(Norma);
00112 }
00113 MOMENTI VarData::SampleSurface(Matrice *Plot,int NSample,int Type){
00114   MOMENTI m1;
00115   double Average=0.;
00116   double NAverage=0;
00117   double **Norma = (double **)calloc(NSample,sizeof(double));
00118   for(int v=0;v<NSample;v++){
00119     Norma[v] = (double *)calloc(NSample,sizeof(double));
00120     for(int vv=0;vv<NSample;vv++){
00121       Plot->Set(v,vv,0);
00122     }
00123   }
00124   for(int c=0;c<Gen->NChain;c++){
00125     if(!CHAIN_IF_TYPE(Ch[c].Type,NChType))continue;
00126     Average += Ch[c].Pos[CNorm];NAverage += 1.;
00127       int v = (int)(Ch[c].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00128       if( v < 0 || v >= NSample) continue;
00129       int vv = (int)(Ch[c].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00130       if( vv < 0 || vv >= NSample) continue;
00131       Plot->Add(v,vv,Ch[c].Pos[CNorm]);
00132       Norma[v][vv] += 1.;
00133       //printf("%d %d %'lf\n",v,vv,Plot[v][vv]);
00134   }
00135   Average /= (double)NAverage;
00136   for(int v=0;v<NSample;v++){
00137     for(int vv=0;vv<NSample;vv++){
00138       if(Norma[v][vv] > 0.)
00139    Plot->Set(v,vv,Plot->Val(v,vv)/Norma[v][vv]);
00140       //pasticcio
00141       else Plot->Set(v,vv,Average);
00142       //printf("%d %d %'lf\n",v,vv,Plot[v][vv]);
00143     }
00144   }
00145   free(Norma);
00146   m1.Uno = Average;
00147   m1.Num = SQR(NSample);
00148   return m1;
00149 }
00150 void VarData::LoadDensFile(double **Plot,int NSample){
00151   double Round = 0.001;
00152   double *Count = (double *)calloc(3*NSample*NSample,sizeof(double));
00153   for(int p=0;p<pNPart();p++){
00154     int sr = (int)((pPos(p,0)+Round)*pInvEdge(0)*NSample);
00155     if(sr < 0 || sr >= NSample) continue;
00156     int sz = (int)((pPos(p,1)+Round)*pInvEdge(1)*NSample);
00157     if(sz < 0 || sz >= NSample) continue;
00158     int t = pType(p);
00159     Plot[t][sr*NSample+sz] += pPos(p,2);
00160     Count[(sr*NSample+sz)*3+t] += 1.;
00161   }  
00162   Matrice Mask(5,5);
00163   Mask.FillGaussian(.5,3.);
00164   for(int t=0;t<3;t++){
00165     for(int s=0;s<NSample*NSample;s++){
00166       if(Count[s*3+t] > 0.)
00167    Plot[t][s] /= Count[s*3+t];
00168     }
00169   }
00170   int NDim = 2;
00171   int IfMinImConv = 1;
00172   for(int t=0;t<3;t++){
00173     Mask.ConvoluteMatrix(Plot[t],NSample,NDim,IfMinImConv);
00174     Mask.ConvoluteMatrix(Plot[t],NSample,NDim,IfMinImConv);
00175   }
00176   free(Count);
00177 }
00178 MOMENTI VarData::SampleSurfacePart(double *Plot,int NSample,int Type){
00179   double Round = 0.001;
00180   double Average=0.;
00181   double NAverage=0;
00182   double Min = 10000000.;
00183   double Max =-10000000.;
00184   double **Norma = (double **)calloc(NSample,sizeof(double));
00185   MOMENTI m1;
00186   for(int v=0;v<NSample;v++){
00187     Norma[v] = (double *)calloc(NSample,sizeof(double));
00188     for(int vv=0;vv<NSample;vv++){
00189       Plot[v*NSample+vv] = 0;
00190     }
00191   }
00192   for(int p=0;p<Gen->NPart;p++){
00193     if(Pm[p].Typ != Type) continue;
00194     int v = (int)((Pm[p].Pos[CLat1]+Round)*pInvEdge(CLat1)*NSample);
00195     if( v < 0 || v >= NSample) continue;
00196     int vv = (int)((Pm[p].Pos[CLat2]+Round)*pInvEdge(CLat2)*NSample);
00197     if( vv < 0 || vv >= NSample) continue;
00198     Plot[v*NSample+vv] += Pm[p].Pos[CNorm];
00199     Norma[v][vv] += 1.;
00200     Average += Pm[p].Pos[CNorm];NAverage += 1.;
00201   }
00202   Average /= (double)NAverage;
00203   for(int v=0;v<NSample;v++){
00204     for(int vv=0;vv<NSample;vv++){
00205       if(Norma[v][vv] > 0.){
00206    Plot[v*NSample+vv] /= Norma[v][vv];
00207       }
00208       else Plot[v*NSample+vv] = Average;
00209       if(Plot[v*NSample+vv] < Min) Min = Plot[v*NSample+vv];
00210       if(Plot[v*NSample+vv] > Max) Max = Plot[v*NSample+vv];
00211     }
00212   }
00213   for(int v=0;v<NSample;v++)
00214     free(Norma[v]);
00215   free(Norma);
00216   m1.Min = Min;
00217   m1.Max = Max;
00218   m1.Uno = Average;
00219   m1.Num = SQR(NSample);
00220   return m1;
00221 }
00222 int VarData::SpatialDerivative(Matrice *Surface,Matrice *Resp,SPLINE Weight,int NSample){
00223   SampleSurface(Surface,NSample,NChType);
00224   Matrice *Mask = new Matrice(Weight);
00225   for(int h=0;h<Resp->Size();h++)
00226     for(int w=0;w<Resp->Size();w++)
00227       Resp->Set(h,w,0.);
00228   Mat->ApplyFilter(Surface,Resp,Mask);
00229   Mask->Transpose();
00230   Mat->ApplyFilter(Surface,Resp,Mask);
00231   delete Mask;
00232   return 0;
00233 }
00234 Properties VarData::SysProperties(){
00235   Properties *Pr = new Properties();
00236   double StructPhil = 0.;
00237   double StructPhob = 0.;
00238   for(int c=0;c<Gen->NChain;c++){
00239     for(int cc=0;cc<Gen->NChain;cc++){
00240       Pr->ChDiff += QUAD((Ch[c].Pos[CLat1]-Ch[cc].Pos[CLat1]));
00241       Pr->ChDiff += QUAD((Ch[c].Pos[CLat2]-Ch[cc].Pos[CLat2]));
00242     }
00243     double CmPhil[3] = {0.,0.,0.};
00244     double CmPhob[3] = {0.,0.,0.};
00245     double RadPhil=0.;
00246     double RadPhob=0.;
00247     double NPhil=0.;
00248     double NPhob=0.;
00249     double q=1./Gen->Edge[3];
00250     double Dist[3] = {0.,0.,0.}; 
00251     for(int p=c*pNPCh();p<pNPCh()*c+Block[0].Asym;p++){//Phob
00252       for(int d=0;d<3;d++){
00253    CmPhob[d] += Pm[p].Pos[d];
00254    for(int pp=c*Gen->NPCh;pp<Gen->NPCh*c+Block[0].Asym-1;pp++){//Phob
00255      Dist[d] = Pm[p].Pos[d] - Pm[pp].Pos[d];
00256      if(p == pp) StructPhob += 1.;
00257      else 
00258        //StructPhob += Dist[d]*sin(q*Dist[d])/(q);
00259        StructPhob += exp(-QUAD(( q*Dist[d] ))/6. );
00260    }
00261    if(p == Gen->NPCh*c+Block[0].Asym-1) continue;
00262    Pr->RePhob += QUAD(( Pm[p].Pos[d] - Pm[p+1].Pos[d]));
00263       }
00264     }
00265     for(int p=c*Gen->NPCh+Block[0].Asym;p<Gen->NPCh*(c+1)-1;p++){//Phil
00266       for(int d=0;d<3;d++){
00267    CmPhil[d] += Pm[p].Pos[d];
00268    for(int pp=c*Gen->NPCh+Block[0].Asym;pp<Gen->NPCh*(c+1)-1;pp++){//Phil
00269      Dist[d] = Pm[p].Pos[d] - Pm[pp].Pos[d];
00270      if(p == pp) StructPhil += 1.;
00271      else 
00272        //       StructPhil += sin(q*Dist[d])/(q*Dist[d]);
00273        StructPhil += exp(-QUAD(( q*Dist[d] ))/6. );
00274    }
00275    if( p == Gen->NPCh*(c+1)-1) continue;
00276    Pr->RePhil += QUAD(( Pm[p].Pos[d] - Pm[p+1].Pos[d]));
00277       }
00278     }
00279     for(int d=0;d<3;d++){
00280       CmPhob[d] /= (double) Block[0].Asym;
00281       CmPhil[d] /= (double) Gen->NPCh-Block[0].Asym;
00282     }
00283     for(int p=c*Gen->NPCh;p<Gen->NPCh*c+Block[0].Asym;p++){//Phob
00284       for(int d=0;d<3;d++)
00285    RadPhob += QUAD(( CmPhob[d] - Pm[p].Pos[d]));
00286     }
00287     for(int p=c*Gen->NPCh+Block[0].Asym;p<Gen->NPCh*(c+1);p++){//Phil
00288       for(int d=0;d<3;d++)
00289    RadPhil += QUAD(( CmPhil[d] - Pm[p].Pos[d]));
00290     }
00291     Pr->GyrPhob += RadPhob / (double)(Block[0].Asym*Gen->NChain);
00292     Pr->GyrPhil += RadPhil / (double)((Gen->NPCh - Block[0].Asym)*Gen->NChain);
00293   }
00294   Pr->RePhob /= Gen->NChain;
00295   Pr->RePhil /= Gen->NChain;
00296   Pr->ChDiff /= (double)QUAD((Gen->NChain));
00297   Pr->FactPhob += StructPhob/(double)(Gen->NChain);//*QUAD((Asym)));
00298   Pr->FactPhil += StructPhil/(double)(Gen->NChain);//*QUAD((Gen->NPCh-Asym)));
00299   Pr->Print();
00300   return *Pr;
00301 }
00302 int VarData::Folding(){
00303   double *Interp1 = (double *)calloc(Gen->NPCh,sizeof(double));
00304   double *Interp2 = (double *)calloc(Gen->NPCh,sizeof(double));
00305   double *InterpN = (double *)calloc(Gen->NPCh,sizeof(double));
00306   RETTA r1;
00307   RETTA r2;
00308   for(int c=0;c<Gen->NChain;c++){
00309     double Comp[3]={0.,0.,0.};
00310     for(int p= c*Gen->NPCh,pp=0;p<(c+1)*Gen->NPCh;p++,pp++){
00311       Interp1[pp] = Pm[p].Pos[CLat1];
00312       Interp2[pp] = Pm[p].Pos[CLat2];
00313       InterpN[pp] = Pm[p].Pos[CNorm];
00314       if(p == (c+1)*Gen->NPCh - 1) break;
00315       double Segm[3]={0.,0.,0.};
00316       double Rad=0.;
00317       for(int d=0;d<3;d++){
00318    Segm[d] = Pm[p].Pos[d] - Pm[p+1].Pos[d];
00319    Rad += QUAD((Segm[d]));
00320       }
00321       Rad = sqrt(Rad);
00322       for(int d=0;d<3;d++){
00323    Comp[d] += Segm[d] / (Rad*Gen->NPCh);
00324       }
00325     }
00326     if( ASS((Comp[CNorm])) < .7)
00327       Ch[c].Type |= CHAIN_FLABBY;
00328     else 
00329       Ch[c].Type |= CHAIN_STRETCH;
00330     r1 = Mat->InterRett(Interp1,InterpN,Gen->NPCh);
00331     r2 = Mat->InterRett(Interp2,InterpN,Gen->NPCh);
00332     if( POS(r1.m) < .5 || POS(r2.m) < .5)
00333       Ch[c].Type |= CHAIN_TILTED;
00334   }
00335   free(Interp1);
00336   free(Interp2);
00337   free(InterpN);
00338   return 0;
00339 }
00340 void VarData::ChangeNChain(int NChain,int nBlock){
00341   int NChainTemp = 0;
00342   Block[nBlock].NChain = NChain;
00343   Block[nBlock].EndIdx = Block[nBlock].InitIdx + Block[nBlock].NChain*Block[nBlock].NPCh;
00344   NChainTemp = Block[0].NChain;
00345   for(int b=1;b<Gen->NBlock;b++){
00346     Block[b].InitIdx = Block[b-1].EndIdx;
00347     Block[b].EndIdx = Block[b].InitIdx + Block[b].NChain*Block[b].NPCh;
00348     NChainTemp += Block[b].NChain;
00349   }
00350   Gen->NChain = NChainTemp;
00351 }
00352 void VarData::SwapChain(int c1,int c2){
00353   SwapChain(c1,c2,0);
00354 }
00355 void VarData::SwapChain(int c1,int c2,int b){
00356   int p1 = Block[b].InitIdx+c1*Block[b].NPCh;
00357   int p2 = Block[b].InitIdx+c2*Block[b].NPCh;
00358   double Temp[3];
00359   for(int p=0;p<Block[b].NPCh;p++){
00360     for(int d=0;d<3;d++){
00361       Temp[d] = Pm[p+p1].Pos[d];
00362       Pm[p+p1].Pos[d] = Pm[p+p2].Pos[d];
00363       Pm[p+p2].Pos[d] = Temp[d];
00364       Temp[d] = Pm[p+p1].Vel[d];
00365       Pm[p+p1].Vel[d] = Pm[p+p2].Vel[d];
00366       Pm[p+p2].Vel[d] = Temp[d];
00367     }
00368   }
00369   for(int d=0;d<3;d++){
00370     Temp[d] = Ch[c1].Pos[d];
00371     Ch[c1].Pos[d] = Ch[c2].Pos[d];
00372     Ch[c2].Pos[d] = Temp[d];
00373     Temp[d] = Ch[c1].Vel[d];
00374     Ch[c1].Vel[d] = Ch[c2].Vel[d];
00375     Ch[c2].Vel[d] = Temp[d];
00376   }
00377 }
00378 void VarData::SwapPart(int p1,int p2){
00379   double Temp[3];
00380   for(int d=0;d<3;d++){
00381     Temp[d] = Pm[p1].Pos[d];
00382     Pm[p1].Pos[d] = Pm[p2].Pos[d];
00383     Pm[p2].Pos[d] = Temp[d];
00384     Temp[d] = Pm[p1].Vel[d];
00385     Pm[p1].Vel[d] = Pm[p2].Vel[d];
00386     Pm[p2].Vel[d] = Temp[d];
00387   }
00388   int tmp = Ln[p1].NLink;
00389   Ln[p1].NLink = Ln[p2].NLink;
00390   Ln[p2].NLink = tmp;
00391   for(int l=0;l<MAX(Ln[p1].NLink,Ln[p2].NLink);l++){
00392     tmp = Ln[p2].Link[l];
00393     Ln[p2].Link[l] = Ln[p1].Link[l];
00394     Ln[p1].Link[l] = tmp;
00395   }
00396   tmp = Pm[p1].CId;
00397   Pm[p1].CId = Pm[p2].CId;
00398   Pm[p2].CId = tmp;
00399   tmp = Pm[p1].Typ;
00400   Pm[p1].Typ = Pm[p2].Typ;
00401   Pm[p2].Typ = tmp;
00402   tmp = Pm[p1].Idx;
00403   Pm[p1].Idx = Pm[p2].Idx;
00404   Pm[p2].Idx = tmp;
00405 }
00406 double VarData::TwoPartDist2(int p1,int p2,double *DistRel){
00407   return TwoPartDist2(Pm[p1].Pos,p2,DistRel);
00408 }
00409 double VarData::TwoPartDist2(double *Pos,int p2,double *DistRel){
00410   for(int d=0;d<3;d++){
00411     DistRel[d] = Pos[d] - Pm[p2].Pos[d];
00412     DistRel[d] -= floor(DistRel[d]*pInvEdge(d) + .5)*pEdge(d);
00413   }
00414   return DistRel[3] = (SQR(DistRel[0])+SQR(DistRel[1])+SQR(DistRel[2]));
00415 }
00416 double VarData::TwoPartDist(double *Pos,int p2,double *DistRel){
00417   return DistRel[3] = sqrt(TwoPartDist2(Pos,p2,DistRel));
00418 }
00419 double VarData::TwoPartDist(int p1,int p2,double *DistRel){
00420   return TwoPartDist(Pm[p1].Pos,p2,DistRel);
00421 }
00422 int VarData::TwoPartDist(int p1,int p2,double *DistRel,double CutOff){
00423   return TwoPartDist(Pm[p1].Pos,p2,DistRel,CutOff);
00424 }
00425 int VarData::TwoPartDist(double *Pos,int p2,double *DistRel,double CutOff){
00426   for(int d=0;d<3;d++){
00427     DistRel[d] = Pos[d] - Pm[p2].Pos[d];
00428     DistRel[d] -= floor(DistRel[d]*pInvEdge(d) + .5)*pEdge(d);
00429   }
00430   DistRel[3] = (SQR(DistRel[0])+SQR(DistRel[1])+SQR(DistRel[2]));
00431   if(DistRel[3] > SQR(CutOff)) return 0;
00432   DistRel[3] = sqrt(DistRel[3]);
00433   return 1;
00434 }
00435 void VarData::ShiftBlock(Vettore *Shift,int b){
00436   for(int p=Block[b].InitIdx;p<Block[b].EndIdx;p++){
00437     if(!(Pm[p].CId%2)) continue;
00438     for(int d=0;d<3;d++){
00439       Pm[p].Pos[d] += Shift->Val(d);
00440       Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00441     }
00442   }
00443 }
00444 void VarData::RotateBlock(Vettore *Axis,Vettore *Origin,int b){
00445   double Norm = Axis->Normalize();
00446   if(Norm <= 0.){printf("Cannot rotate block, the axis is null\n"); return;};
00447   Vettore Proj(3);
00448   Vettore Pos(3);
00449   for(int p=Block[b].InitIdx;p<Block[b].EndIdx;p++){
00450     for(int d=0;d<3;d++){
00451       Pos.Set(Pm[p].Pos[d]-Origin->Val(d),d);
00452     }
00453     Proj.Copy(&Pos);
00454     //Proj.ProjOnAxis(Axis);
00455     Proj.PerpTo(&Pos,Axis);
00456     for(int d=0;d<3;d++){
00457       Pm[p].Pos[d] = Origin->Val(d) + Pos[d] + 2.*Proj[d];
00458       Pm[p].Pos[d] -= floor(Pm[p].Pos[d]*pInvEdge(d))*pEdge(d);
00459     }
00460   }
00461 }
00462 void VarData::MirrorBlock(Vettore *S1,Vettore *S2,Vettore *S3,int b){
00463   Vettore PS(3);
00464   Vettore Pos(3);
00465   for(int p=Block[b].InitIdx;p<Block[b].EndIdx;p++){
00466     for(int d=0;d<3;d++){
00467       Pos.Set(Pm[p].Pos[d],0);
00468     }
00469     PS.ProjOnSurf(S1,S2,S3,&Pos);
00470     for(int d=0;d<3;d++){
00471       Pm[p].Pos[d] = PS.Val(d);
00472     }
00473   }  
00474 }
00475 void VarData::Transform(int b){
00476   if(b>=pNBlock())return;
00477   Vettore Axis(1.,0.,1.);
00478   Axis.Normalize();
00479   Vettore Shift(0.,0.,-.6*pEdge(2));
00480   Vettore Px1(.5*pEdge(0),.5*pEdge(1),.1*pEdge(2));
00481   Vettore Px2(.5*pEdge(0),.5*pEdge(1),.3*pEdge(2));
00482   Vettore Px3(.5*pEdge(0),.5*pEdge(1),.7*pEdge(2));
00483   int nNano = b-1;
00484   Vettore Origin(pNanoPos(nNano,0),pNanoPos(nNano,1),pNanoPos(nNano,2));
00485   Origin.Print();
00486   //ShiftBlock(&Shift,b);
00487   RotateBlock(&Axis,&Origin,b);
00488   //MirrorBlock(&Px1,&Px2,&Px3,b);
00489 }
00490 void VarData::Point2Shape(int iShape){
00491   if(VAR_IF_TYPE(iShape,SHAPE_NONE))
00492     Nano_Dist = &VarData::FieldNo;
00493   else if(VAR_IF_TYPE(iShape,SHAPE_SPH))
00494     Nano_Dist = &VarData::FieldSphere;
00495   else if(VAR_IF_TYPE(iShape,SHAPE_CYL))
00496     //Nano_Dist = &VarData::FieldCyl;
00497     Nano_Dist = &VarData::FieldTransMem;
00498   else if(VAR_IF_TYPE(iShape,SHAPE_CLUSTER))
00499     Nano_Dist = &VarData::FieldCyl;
00500   else if(VAR_IF_TYPE(iShape,SHAPE_PILL))
00501     Nano_Dist = &VarData::FieldCyl;
00502   else if(VAR_IF_TYPE(iShape,SHAPE_TILT))
00503     //Nano_Dist = &VarData::FieldSphere;
00504     Nano_Dist = &VarData::FieldTransMem;
00505   else if(VAR_IF_TYPE(iShape,SHAPE_WALL))
00506     Nano_Dist = &VarData::FieldTiltWall;
00507   else if(VAR_IF_TYPE(iShape,SHAPE_PORE))
00508     Nano_Dist = &VarData::FieldSphere;
00509   else if(VAR_IF_TYPE(iShape,SHAPE_EXT)) 
00510     Nano_Dist = &VarData::FieldSphere;
00511   else if(VAR_IF_TYPE(iShape,SHAPE_JANUS))
00512     Nano_Dist = &VarData::FieldJanus;
00513   else if(VAR_IF_TYPE(iShape,SHAPE_STALK))
00514     Nano_Dist = &VarData::FieldTorus;
00515   else if(VAR_IF_TYPE(iShape,SHAPE_TIP))
00516     //Nano_Dist = &VarData::FieldParab;
00517     Nano_Dist = &VarData::FieldElips;
00518   else if(VAR_IF_TYPE(iShape,SHAPE_TORUS))
00519     Nano_Dist = &VarData::FieldTorus;
00520   else if(VAR_IF_TYPE(iShape,SHAPE_HARM))
00521     Nano_Dist = &VarData::FieldTiltWall;
00522   else if(VAR_IF_TYPE(iShape,SHAPE_UMBR))
00523     Nano_Dist = &VarData::FieldTiltWall;
00524   else if(VAR_IF_TYPE(iShape,SHAPE_BOUND))
00525     Nano_Dist = &VarData::FieldBound;
00526   else{
00527     Nano_Dist = &VarData::FieldNo;
00528     //printf("No distance fuction assigned to the shape of the nano shape %d\n",iShape);
00529   }
00530 }
00531 double VarData::NanoDist2(double x,double y,double z,int n){
00532   double Pos[3] = {x,y,z};
00533   return NanoDist2(Pos,n);
00534 }
00535 double VarData::FieldNo(double *Pos,int n){
00536   return 100000.;
00537 }
00538 double VarData::FieldSphere(double *Pos,int n){
00539   return (SQR(pNanoPos(n,0)-Pos[0])+SQR(pNanoPos(n,1)-Pos[1])+SQR(pNanoPos(n,2)-Pos[2]));
00540 }
00541 double VarData::FieldElips(double *Pos,int n){
00542   double PosRel[3];
00543   for(int d=0;d<3;d++){
00544     PosRel[d] = pNanoPos(n,d) - Pos[d];
00545     PosRel[d] -= floor(PosRel[d]*pInvEdge(d) + .5)*pEdge(d);
00546   }
00547   double Ratio = Nano[n].Height>0.?Nano[n].Rad/Nano[n].Height:.5;
00548   double Lat = SQR(PosRel[0])+SQR(PosRel[1]);
00549   double Norm = SQR(Ratio*(PosRel[2]));
00550   return (Lat+Norm);
00551 }
00552 double VarData::FieldParab(double *Pos,int n){
00553   double PosRel[3];
00554   for(int d=0;d<3;d++){
00555     PosRel[d] = pNanoPos(n,d) - Pos[d];
00556     //PosRel[d] -= floor(PosRel[d]*pInvEdge(d) + .5)*pEdge(d);
00557   }
00558   double r2 = SQR(PosRel[0])+SQR(PosRel[1]);
00559   return SQR(-4.*Nano[n].Height*Pos[CNorm]+r2+3.*Nano[n].Height+4.*Nano[n].Height*Nano[n].Pos[CNorm]);
00560   double r = sqrt(r2);
00561   double z = Pos[CNorm];//Nano[n].Pos[CNorm] - Pos[CNorm];
00562   double a = -4.*Nano[n].Height;
00563   double b = 1.;
00564   double c = -2.*0.;
00565   double d = 3.*Nano[n].Height+4.*Nano[n].Height*Nano[n].Pos[CNorm];
00566   return SQR(a*z + b*r2 + c*r + d);
00567 }
00568 double VarData::FieldCyl(double *Pos,int n){
00569   double Dist2 = SQR(pNanoPos(n,0)-Pos[0])+SQR(pNanoPos(n,1)-Pos[1]);
00570   if(Pos[2] > Nano[n].Height*.5+pNanoPos(n,2))
00571     Dist2 += SQR(Pos[2]-Nano[n].Height*.5-pNanoPos(n,2));
00572   else if(Pos[2] < -Nano[n].Height*.5+Nano[n].Pos[2])
00573     Dist2 += SQR(Pos[2]+Nano[n].Height*.5+pNanoPos(n,2));
00574   return (Dist2);
00575 }
00576 double VarData::FieldTransMem(double *Pos,int n){
00577   double PosRel[3];
00578   for(int d=0;d<3;d++){
00579     PosRel[d] = pNanoPos(n,d) - Pos[d];
00580     PosRel[d] -= floor(PosRel[d]*pInvEdge(d) + .5)*pEdge(d);
00581   }
00582   // double RadLat = SQR(PosRel[CLat1]) + SQR(PosRel[CLat2]);
00583   // if(PosRel[CNorm] > .5*Nano[n].Height + 1.) return 500.;
00584   // if(PosRel[CNorm] < -.5*Nano[n].Height - 1.) return 500.;
00585   // if(PosRel[CNorm] > .5*Nano[n].Height){
00586   //   PosRel[CNorm] -= .5*Nano[n].Height - .5*Nano[n].Rad;
00587   //   if(SQR(PosRel[CNorm]) > RadLat )
00588   //     return - RadLat + SQR(PosRel[CNorm]);
00589   //   else
00590   //     return RadLat - SQR(PosRel[CNorm]);
00591   // }
00592   // if(PosRel[CNorm] < -.5*Nano[n].Height){
00593   //   PosRel[CNorm] += .5*Nano[n].Height - .5*Nano[n].Rad;
00594   //   if(SQR(PosRel[CNorm]) > RadLat )
00595   //     return - RadLat + SQR(PosRel[CNorm]);
00596   //   else
00597   //     return RadLat - SQR(PosRel[CNorm]);
00598   // }
00599   // PosRel[CNorm] = 0.;
00600   // return SQR(PosRel[CLat1]) + SQR(PosRel[CLat2]) + SQR(PosRel[CNorm]);
00601   // if and how much above the cylinder (for the smoothing)
00602   if(PosRel[CNorm] > Nano[n].Height*.5){
00603     PosRel[CNorm] = (PosRel[CNorm] - (Nano[n].Height*.5+Nano[n].Rad));
00604     for(int d=0;d<3;d++)
00605       PosRel[d]  *= .65;//*Nano[n].Rad;
00606     if(PosRel[CNorm] > 0.) PosRel[CNorm] = 100.;
00607   }
00608   else if(PosRel[CNorm] < -Nano[n].Height*.5){
00609     PosRel[CNorm] = (PosRel[CNorm] + (Nano[n].Height*.5+Nano[n].Rad));
00610     for(int d=0;d<3;d++)
00611       PosRel[d]  *= .65;//*Nano[n].Rad;
00612     if(PosRel[CNorm] < 0.) PosRel[CNorm] = 100.;
00613   }
00614   else{
00615     PosRel[CNorm]  = 0.;
00616   }
00617   double Dist2 = SQR(PosRel[0]) + SQR(PosRel[1]) + SQR(PosRel[2]);
00618   return (Dist2);
00619 }
00620 double VarData::FieldTorus(double *Pos,int n){
00621   double PosRel[3];
00622   for(int d=0;d<3;d++){
00623     PosRel[d] = pNanoPos(n,d) - Pos[d];
00624     PosRel[d] -= floor(PosRel[d]*pInvEdge(d) + .5)*pEdge(d);
00625   }
00626   double Radxy = sqrt(SQR(PosRel[CLat1]) + SQR(PosRel[CLat2]));
00627   double Temp = SQR(Nano[n].Height - Radxy) - SQR(Nano[n].Rad) + SQR(PosRel[CNorm]);
00628   return SQR(Temp);
00629 }
00630 double VarData::FieldTilt(double *Pos,int n){
00631   Vettore NanoAxis(Nano[n].Axis[0],Nano[n].Axis[1],Nano[n].Axis[2]);
00632   Vettore PosRel(3);
00633   Vettore Dist(3);
00634   double dr[3];
00635   for(int d=0;d<3;d++){
00636     PosRel.Set(pNanoPos(n,d) - Pos[d],d);
00637   }
00638   double r2 = fabs(Dist.PerpTo3(&PosRel,&NanoAxis));
00639   double HeiOnAxis = PosRel.ProjOnAxis(&NanoAxis);
00640   if(fabs(HeiOnAxis) > .5*Nano[n].Height){
00641     double Sign = HeiOnAxis > 0. ? 1. : -1.;
00642     r2 = 0.;
00643     for(int d=0;d<3;d++){
00644       dr[d] = - (Sign*Nano[n].Height*.5*Nano[n].Axis[d]) + PosRel[d];
00645       r2 += SQR(dr[d]);
00646     }
00647   }
00648   return r2;
00649 }
00650 double VarData::FieldTiltWall(double *Pos,int n){
00651   double a = Nano[n].Axis[0];
00652   double b = Nano[n].Axis[1];
00653   double c = Nano[n].Axis[2];
00654   double d = -Nano[n].Axis[0]*Nano[n].Pos[0] - Nano[n].Axis[1]*Nano[n].Pos[1] - Nano[n].Axis[2]*Nano[n].Pos[2];
00655   double Dist2 = a*Pos[0]+b*Pos[1]+c*Pos[2]+d;
00656   Dist2 = SQR(Dist2)/(SQR(a)+SQR(b)+SQR(c));
00657   return Dist2;
00658 }
00659 double VarData::FieldBound(double *Pos,int n){
00660   double dr[3] = {Pos[0],Pos[1],Pos[2]};
00661   dr[CNorm] = 0.;
00662   if(Pos[CLat1] > .5*pEdge(CLat1)) dr[CLat1] = pEdge(CLat1) - Pos[CLat1];
00663   if(Pos[CLat2] > .5*pEdge(CLat2)) dr[CLat2] = pEdge(CLat2) - Pos[CLat2];
00664   if(dr[CLat1] < dr[CLat2] ) dr[CLat2] = 0.;
00665   else dr[CLat1] = 0.;
00666   return SQR(dr[0]) + SQR(dr[1]) + SQR(dr[2]);
00667   // return MIN(SQR(dr[CLat1]),SQR(dr[CLat2]));
00668 }
00669 double VarData::FieldJanus(double *Pos,int n){
00670   Vettore NanoAxis(Nano[n].Axis[0],Nano[n].Axis[1],Nano[n].Axis[2]);
00671   Vettore PosRel(3);
00672   Vettore Dist(3);
00673   for(int d=0;d<3;d++){
00674     PosRel.Set(pNanoPos(n,d) - Pos[d],d);
00675   }
00676   PosRel.Set(PosRel.Val(2)*2.,2);
00677   double r2 = fabs(Dist.PerpTo3(&PosRel,&NanoAxis));
00678   return SQR(r2);
00679 }
00680 
00681 // # include "../Matematica/cvt.H"
00682 
00683 // int VarData::Voronoi(){
00684 //   int NDim = 2;
00685 //   int NCell = Gen->NChain;
00686 //   int Batch = 1000;
00687 //   int DontCreate = 4;
00688 //   int SampleType = 1;//Halton
00689 //   int NSample = 10000;
00690 //   int NItMax = 40;
00691 //   int NItFix = 1;
00692 //   int Seme = 45322643;
00693 //   int NIt = 0;
00694 //   double ItDiff = 0.;
00695 //   double Energy = 0.;
00696 //   double *Pos = (double *)calloc(NCell*NDim,sizeof(double));
00697 //   for(int c=0;c<NCell;c++){
00698 //     for(int d=0;d<NDim;d++){
00699 //       Pos[c*NDim+d] = Ch[c].Pos[d];
00700 //     }
00701 //   }
00702 //   cvt(NDim,NCell,Batch,DontCreate,SampleType,NSample,NItMax,NItFix,&Seme,Pos,&NIt,&ItDiff,&Energy);
00703 // }
00704 
00705 // #ifndef VOROPP
00706 // #include "../share/voro++/src/voro++.cc"
00707 // #include "../../share/include/container.hh"
00708 
00709 // int VarData::Voronoi(){
00710 //   double xMin = 0.;
00711 //   double xMax = Gen->Edge[CLat1];
00712 //   double yMin = 0.;
00713 //   double yMax = Gen->Edge[CLat2];
00714 //   double zMin = .4*Gen->Edge[CNorm];
00715 //   double zMax = .6*Gen->Edge[CNorm];
00716 //   double LengthScale = 1./(xMax*2.6);
00717 //   int nxf = (int)( (xMax-xMin)*LengthScale ) + 1;
00718 //   int nyf = (int)( (yMax-yMin)*LengthScale ) + 1;
00719 //   int nzf = (int)( (zMax-zMin)*LengthScale ) + 1;
00720 //   bool xperiodic = true;
00721 //   bool yperiodic = true;
00722 //   bool zperiodic = false;
00723 //   const int memory=8;
00724 //   container con(xMin,xMax,yMin,yMax,zMin,zMax,nxf,nyf,nzf,xperiodic,yperiodic,zperiodic,memory);
00725 //   for(int c=0;c<Gen->NChain;c++){
00726 //     if(!CHAIN_IF_TYPE(Ch[c].Type,NChType)) continue;
00727 //     con.put(0,Ch[c].Pos[CLat1],Ch[c].Pos[CLat2],Ch[c].Pos[CNorm]);
00728 //   }
00729 //   //con.draw_cells_gnuplot("random_points_v.gnu");
00730 //   //con.draw_cells_pov("pack_six_cube_v.pov");
00731 //   //con.draw_particles_pov("pack_six_cube_p.pov");
00732 //   return 0;
00733 // }
00734 // #else
00735 // int VarData::Voronoi(){
00736 //   printf("Voronoi library not supplied\n");
00737 //   return 1;
00738 // }
00739 // #endif