Allink  v0.1
VarDataBackFold.cpp
00001 /***********************************************************************
00002 VarData: This  Program reads and writes a specific file format 
00003 storing all the information relative to a set of equal structure
00004 polymers to the CHAIN, PART and GENERAL structures. It provides 
00005 two different ways to backfold the coordinates, a fanction that 
00006 creates an initial system with different option and some function
00007 for the data analisys. The first calculate the distribution of the
00008 monomer in the box, the second the distribution of the bonds.
00009 Copyright (C) 2008 by Giovanni Marelli <sabeiro@virgilio.it>
00010 
00011 
00012 This program is free software; you can redistribute it and/or modify
00013 it under the terms of the GNU General Public License as published by
00014 the Free Software Foundation; either version 2 of the License, or
00015 (at your option) any later version.
00016 
00017 This program is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 GNU General Public License for more details.
00021 
00022 You should have received a copy of the GNU General Public License
00023 along with this program; if not, write to the Free Software
00024 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 ***********************************************************************/
00026 #include "../include/VarData.h"
00027 ;
00028 int VarData::BfDefChain(){
00029   if(VAR_IF_TYPE(SysType,VAR_CHAIN_DEF)){
00030     for(int c=0,b=0;c<Gen->NChain;c++){
00031       for(int d=0;d<3;d++){
00032    Ch[c].Pos[d] -= floor(Ch[c].Pos[d]*pInvEdge(d))*Gen->Edge[d];
00033       }
00034     }
00035     return 0;
00036   }
00037   VarMessage("BackFold.DefChains");
00038   Vettore Ax0(1.,0.,0.);
00039   Vettore Ax2(0.,0.,1.);
00040   for(int b=0,NCh=0;b<pNBlock();NCh+=Block[b++].NChain){
00041     double *xc = (double *)calloc(pNPCh(b),sizeof(double));
00042     double *yc = (double *)calloc(pNPCh(b),sizeof(double));
00043     double *zc = (double *)calloc(pNPCh(b),sizeof(double));
00044     //if(strcasestr(Block[b].Name, "PEP") == Block[b].Name) continue;
00045     int ChType = CHAIN_POLY;
00046     if(Block[b].Asym == 0) ChType = CHAIN_ADDED;
00047     //printf("\n%s type %d asym %d ppc %d #chain %d offset %d %d\n",Block[b].Name,ChType,Block[b].Asym,pNPCh(b),Block[b].NChain,NCh,Block[b].NChain+NCh);
00048     for(int c=NCh;c<NCh+Block[b].NChain;c++){
00049       Ch[c].Type = 0;
00050       if(Block[b].Asym == 0){
00051    VAR_ADD_TYPE(Ch[c].Type,CHAIN_ADDED);
00052       }
00053       for(int d=0;d<3;d++){
00054    Ch[c].Pos[d] = 0.;
00055    Ch[c].Vel[d] = 0.;
00056       }
00057       int p1 = Block[b].InitIdx + (c-NCh)*pNPCh(b);
00058       for(int p=p1;p<p1+pNPCh(b);p++){
00059    for(int d=0;d<3;d++){
00060      Ch[c].Pos[d] += Pm[p].Pos[d];
00061      Ch[c].Vel[d] += Pm[p].Vel[d];
00062    }
00063    }
00064       for(int d=0;d<3;d++){
00065    Ch[c].Pos[d] /= (double)pNPCh(b);
00066    Ch[c].Vel[d] /= (double)pNPCh(b);
00067       }
00068       for(int ppc=0;ppc<pNPCh(b);ppc++){
00069    xc[ppc] = Pm[p1+ppc].Pos[0];
00070    yc[ppc] = Pm[p1+ppc].Pos[1];
00071    zc[ppc] = Pm[p1+ppc].Pos[2];
00072       }
00073       RETTA rzx = Mat->InterRett(zc,xc,pNPCh(b));
00074       RETTA rzy = Mat->InterRett(zc,yc,pNPCh(b));
00075       double x1 = Pm[p1].Pos[2]*rzx.m + rzx.q;
00076       double x2 = Pm[p1+pNPCh(b)-1].Pos[2]*rzx.m + rzx.q;
00077       double y1 = Pm[p1].Pos[2]*rzy.m + rzy.q;
00078       double y2 = Pm[p1+pNPCh(b)-1].Pos[2]*rzy.m + rzy.q;
00079       Ch[c].Dir[2] = Pm[p1].Pos[2] - Pm[p1+pNPCh(b)-1].Pos[2];
00080       Ch[c].Dir[1] = y1 - y2;
00081       Ch[c].Dir[0] = x1 - x2;
00082       Vettore ChDir(Ch[c].Dir[0],Ch[c].Dir[1],Ch[c].Dir[2]);
00083       Ch[c].Angle = Ax0.Angle(&Ax2,&ChDir);
00084       if(Ch[c].Angle > .5*M_PI)
00085    VAR_ADD_TYPE(Ch[c].Type,CHAIN_UP);
00086       else
00087    VAR_ADD_TYPE(Ch[c].Type,CHAIN_DOWN);
00088       Vettore Origin(pCm(0)-Ch[c].Pos[0],pCm(1)-Ch[c].Pos[1],pCm(2)-Ch[c].Pos[2]);
00089       double Angle = Origin.Angle(&ChDir);
00090       if(Angle < .5*M_PI)
00091    VAR_ADD_TYPE(Ch[c].Type,CHAIN_OUTER);
00092       else 
00093    VAR_ADD_TYPE(Ch[c].Type,CHAIN_INNER);
00094     }
00095     free(xc);
00096     free(yc);
00097     free(zc);
00098   }
00099   VAR_ADD_TYPE(SysType,VAR_CHAIN_DEF);
00100   return 0;
00101 }
00102 void VarData::BfPep(){
00103   int nBlock = 0;
00104   for(int n=0;n<pNNano();n++){
00105     if(Nano[n].Shape != SHAPE_CLUSTER) continue;
00106     int nChain = 0;
00107     for(int b=0;b<Gen->NBlock;b++){
00108       if(!strncmp(Block[b].Name,"PEP",3)){
00109    if(b > nBlock){
00110      nBlock = b;
00111      break;
00112    }
00113       }
00114       nChain += Block[b].NChain;
00115     }
00116     int p1 = Block[nBlock].InitIdx;
00117     double Cm[3] = {0.,0.,0.};
00118     double NCm = 0.;
00119     double *xc = (double *)calloc(pNPCh(nBlock),sizeof(double));
00120     double *yc = (double *)calloc(pNPCh(nBlock),sizeof(double));
00121     double *zc = (double *)calloc(pNPCh(nBlock),sizeof(double));
00122     for(int ppc=0;ppc<pNPCh(nBlock);ppc++){
00123       xc[ppc] = Pm[p1+ppc].Pos[0];
00124       yc[ppc] = Pm[p1+ppc].Pos[1];
00125       zc[ppc] = Pm[p1+ppc].Pos[2];
00126     }
00127     RETTA rzx = Mat->InterRett(zc,xc,pNPCh(nBlock));
00128     RETTA rzy = Mat->InterRett(zc,yc,pNPCh(nBlock));
00129     double x1 = Pm[p1].Pos[2]*rzx.m + rzx.q;
00130     double x2 = Pm[p1+pNPCh(nBlock)-1].Pos[2]*rzx.m + rzx.q;
00131     double y1 = Pm[p1].Pos[2]*rzy.m + rzy.q;
00132     double y2 = Pm[p1+pNPCh(nBlock)-1].Pos[2]*rzy.m + rzy.q;
00133     Nano[n].Axis[2] = Pm[p1].Pos[2] - Pm[p1+pNPCh(nBlock)-1].Pos[2];
00134     Nano[n].Axis[1] = y1 - y2;
00135     Nano[n].Axis[0] = x1 - x2;      
00136     for(int p=Block[nBlock].InitIdx;p<Block[nBlock].EndIdx;p++){
00137       for(int d=0;d<3;d++) Cm[d] += Pm[p].Pos[d];
00138       NCm += 1.;
00139     }
00140     for(int d=0;d<3;d++) Nano[n].Pos[d] = Cm[d]/NCm;
00141     SetNanoBkf(n);
00142     double Norm = 0.;
00143     for(int d=0;d<3;d++){
00144       //SigErr(isnan(Nano[n].Axis[d]),"Wrong nano axis %d %lf ",d,Nano[n].Axis[d]);
00145       Norm += SQR(Nano[n].Axis[d]);
00146     }
00147     Norm = sqrt(Norm);
00148     for(int d=0;d<3;d++){
00149       Nano[n].Axis[d] /= -Norm;
00150     }
00151     free(xc);
00152     free(yc);
00153     free(zc);
00154   }
00155 }
00156 int VarData::BfEdge(){
00157   double Edge[3][2];
00158   if( VAR_IF_TYPE(SysType,VAR_EDGE) ) return 0;
00159   Edge[0][0] = Pm[0].Pos[0];Edge[0][1] = Pm[0].Pos[0];
00160   Edge[1][0] = Pm[0].Pos[1];Edge[1][1] = Pm[0].Pos[1];
00161   Edge[2][0] = Pm[0].Pos[2];Edge[2][1] = Pm[0].Pos[2];
00162   for(int p=0;p<Gen->NPart;p++){
00163     for(int d=0;d<3;d++){
00164       if(Edge[d][1] < Pm[p].Pos[d] )
00165    Edge[d][1] = Pm[p].Pos[d];
00166       if(Edge[d][0] >  Pm[p].Pos[d])
00167    Edge[d][0] = Pm[p].Pos[d];
00168     }
00169   }
00170   for(int d=0;d<3;d++)
00171     SetEdge(Edge[d][1] - Edge[d][0],d);
00172     // SetEdge(Edge[d][1],d);
00173   VAR_ADD_TYPE(SysType,VAR_EDGE);
00174   return 0;
00175 }
00176 void VarData::ShiftRef(int BackFold){
00177   VarMessage("BackFold");
00178   if(BackFold == BF_SKIP) return ;
00179   BfEdge();
00180   BfPep();
00181   double Shift[3];
00182   for(int d=0;d<3;d++){
00183     Shift[d] = -ShiftPos[d]*Gen->Edge[d];
00184   }
00185   for(int c=0;c<Gen->NChain;c++){
00186     for(int d=0;d<3;d++){
00187       Ch[c].Pos[d] -= Shift[d];
00188       //Ch[c].Pos[d] -= floor(Ch[c].Pos[d]/Gen->Edge[d])*Gen->Edge[d];
00189     }
00190   }
00191   if(BackFold == BF_CHAIN){
00192     BfDefChain();
00193     for(int p=0;p<Gen->NPart;p++){
00194       for(int d=0;d<3;d++){
00195    Pm[p].Pos[d] -= Shift[d];
00196    Pm[p].Bkf[d] = -floor((Ch[Pm[p].CId].Pos[d]-Shift[d])*pInvEdge(d))*Gen->Edge[d];
00197       }
00198     }
00199     for(int c=0;c<Gen->NChain;c++){
00200       for(int d=0;d<3;d++){
00201    Ch[c].Pos[d] -= floor(Ch[c].Pos[d]*pInvEdge(d))*pEdge(d);
00202       }
00203     }
00204   }
00205   else if(BackFold == BF_PART){
00206     for(int p=0;p<Gen->NPart;p++){
00207       for(int d=0;d<3;d++){
00208    Pm[p].Pos[d] -= Shift[d];
00209    Pm[p].Bkf[d] = -floor(Pm[p].Pos[d]*pInvEdge(d))*Gen->Edge[d];
00210       }
00211     }
00212   }
00213   else if(BackFold == BF_NANO){
00214     for(int d=0;d<3;d++){
00215       ShiftPos[d] = pNanoPos(0,d)*pInvEdge(d);
00216       Shift[d] = (ShiftPos[d]-.5)*Gen->Edge[d];
00217     }
00218     for(int p=0;p<Gen->NPart;p++){
00219       for(int d=0;d<3;d++){
00220    Pm[p].Pos[d] -= Shift[d];
00221    Pm[p].Bkf[d] = -floor(Pm[p].Pos[d]*pInvEdge(d))*Gen->Edge[d];
00222       }
00223     }
00224   }
00225   else if(BackFold == BF_TILT){
00226     int n=0;
00227     for(int d=0;d<3;d++){
00228       ShiftPos[d] = pNanoPos(n,d);
00229       Shift[d] = ShiftPos[d]-.5*Gen->Edge[d];
00230     }
00231     Vettore NanoAx(Nano[n].Axis[0],Nano[n].Axis[1],Nano[n].Axis[2]);
00232     NanoAx.Set(0.,CNorm);
00233     NanoAx.Normalize();
00234     Vettore Ex(0.,0.,0.);
00235     Vettore Zed(0.,0.,0.);
00236     Zed.Set(1.,CNorm);
00237     Ex.Set(1.,CLat1);
00238     //double Angle = atan(Nano[0].Axis[CLat2]/Nano[0].Axis[CLat1]);//Zed.Angle(&NanoAx,&Ex);
00239     double Angle = Ex.Angle(&NanoAx);
00240     if(isnan(Angle)) Angle = 0.;
00241     int NRow = 4;
00242     Matrice M(Zed.x,.5*Angle,NRow);
00243     // printf("angle %lf\n",Angle*360./DUE_PI);
00244     // M.Print();
00245     Vettore PosOld(NRow);
00246     Vettore PosNew(NRow);
00247     for(int p=0;p<pNPart();p++){
00248       for(int d=0;d<3;d++){
00249    PosOld.Set(Pm[p].Pos[d]-pNanoPos(0,d),d);
00250       }
00251       for(int r=0;r<NRow;r++){
00252    double Temp=0.;
00253    for(int c=0;c<NRow;c++)
00254      Temp += M.Val(r,c)*PosOld.Val(c);
00255    PosNew.Set(Temp,r);
00256       }
00257       //PosNew = M.Mult(PosOld);
00258       for(int d=0;d<3;d++){
00259    Pm[p].Pos[d] = PosNew.Val(d) +.5*pEdge(d);
00260    Pm[p].Bkf[d] = -floor(Pm[p].Pos[d]*pInvEdge(d))*Gen->Edge[d];
00261       }
00262     }
00263     Nano[0].Axis[CLat2] = -sqrt(1.-SQR(Nano[0].Axis[CNorm]));
00264     Nano[0].Axis[CLat1] = 0.;
00265   }
00266   for(int n=0;n<MAX(1,Gen->NNano);n++){
00267     for(int d=0;d<3;d++){
00268       Nano[n].Pos[d] -= Shift[d];
00269     }
00270     SetNanoBkf(n);
00271   }
00272 }
00273 //obsolete?
00274 void VarData::DefBlock(int *NChStep,int How){
00275   if(How == VAR_OPPOSED){
00276     Gen->NBlock = 4;
00277     Block = (BLOCK *)realloc(Block,Gen->NBlock*sizeof(*Block));
00278     sprintf(Block[0].Name,"Lower1");
00279     sprintf(Block[1].Name,"Upper1");
00280     sprintf(Block[2].Name,"Lower2");
00281     sprintf(Block[3].Name,"Upper2");
00282   }
00283   else if(How == VAR_VESICLE || How == VAR_TUBE){
00284     Gen->NBlock = 2;
00285     Block = (BLOCK *)realloc(Block,Gen->NBlock*sizeof(*Block));
00286     sprintf(Block[0].Name,"Inner");
00287     sprintf(Block[1].Name,"Outer");
00288   }
00289   Block[0].InitIdx= 0;
00290   Block[0].EndIdx = NChStep[0]*Gen->NPCh;
00291   Block[0].NChain = NChStep[0];
00292   Block[0].NPCh = Gen->NPCh;
00293   for(int b=1;b<Gen->NBlock;b++){
00294     Block[b].InitIdx= Block[b-1].EndIdx;
00295     Block[b].EndIdx = NChStep[b]*Gen->NPCh+Block[b-1].EndIdx;
00296     Block[b].NChain = NChStep[b];
00297     Block[b].NPCh = Gen->NPCh;
00298   }
00299   for(int b=0;b<Gen->NBlock;b++)
00300     printf("%d %d %d %d\n",Block[b].NChain,Block[b].InitIdx,Block[b].EndIdx,Block[b].NChain);
00301 }
00302 //obsolete?
00303 bool VarData::BackFold(int How){
00304   VarMessage("BackFold");
00305   if(How == BF_SKIP) return 0;
00306   BfEdge();
00307   double ShiftNano[3];
00308   SetNanoBkf(0);  
00309   if(How == BF_PART)
00310     for(int p=0;p<Gen->NPart;p++)
00311       for(int d=0;d<3;d++)
00312    Pm[p].Bkf[d] = -floor(Pm[p].Pos[d]/Gen->Edge[d])*Gen->Edge[d];
00313   else if(How == BF_CHAIN)
00314     for(int p=0;p<Gen->NPart;p++){
00315       int c = Pm[p].CId;
00316       if(c < 0 || c >= Gen->NChain) continue;
00317       for(int d=0;d<3;d++)
00318    Pm[p].Bkf[d] = -floor(Ch[c].Pos[d]/Gen->Edge[d])*Gen->Edge[d];
00319     }
00320   else if(How == BF_NANO)
00321     for(int p=0;p<Gen->NPart;p++)
00322       for(int d=0;d<3;d++)
00323    Pm[p].Pos[d] += ShiftNano[d];
00324   BfDefChain();
00325   return 0;
00326 }
00327 //Obsolete
00328 bool VarData::ShiftSys(int How){
00329   if(How == SHIFT_NO) return 0;
00330   double Shift[3] = {0.,0.,0.};
00331   SetNanoBkf(0);
00332   if(How == SHIFT_CM){//Cm
00333     for(int d=0;d<3;d++)
00334       Gen->Cm[d] = 0.;
00335     for(int p=0;p<Gen->NPart;p++){
00336       Gen->Cm[0] += Pm[p].Pos[0];
00337       Gen->Cm[1] += Pm[p].Pos[1];
00338       Gen->Cm[2] += Pm[p].Pos[2];
00339     }
00340     for(int d=0;d<3;d++){
00341       Gen->Cm[d] /= (double)Gen->NPart;
00342       Shift[d] = (Gen->Edge[d]*.5-Gen->Cm[d]);
00343       Nano->Pos[d] += Shift[d]; 
00344     }
00345     SetNanoBkf(0);
00346   }
00347   else if(How == SHIFT_NANO){//Nano Particle
00348     for(int d=0;d<3;d++){
00349       Shift[d] = (Gen->Edge[d]*.5 - pNanoPos(0,d));
00350       Nano->Pos[d] += Shift[d]; 
00351     }
00352     SetNanoBkf(0);
00353   }
00354   else if(How == SHIFT_CM_NANO){//x,y Nano; z Cm
00355     for(int d=0;d<3;d++)
00356       Gen->Cm[d] = 0.;
00357     for(int p=0;p<Gen->NPart;p++){
00358       Gen->Cm[2] += Pm[p].Pos[2];
00359     }
00360     Gen->Cm[0] = pNanoPos(0,0);
00361     Gen->Cm[1] = pNanoPos(0,1);
00362     Gen->Cm[2] /= (double)Gen->NPart;
00363     for(int d=0;d<3;d++){
00364       Shift[d] = (Gen->Edge[d]*.5 - Gen->Cm[d]);
00365       if(d < 2) Nano->Pos[d] += Shift[d];
00366     }
00367     SetNanoBkf(0);
00368   }
00369   else return 1;
00370   for(int p=0;p<Gen->NPart;p++){
00371     // if(Pm[p].Typ == 2){
00372     //   Pm[p].Pos[0] = Nano->PosBf[0];
00373     //   Pm[p].Pos[1] = Nano->PosBf[1];
00374     //   Pm[p].Pos[2] = Nano->PosBf[2];
00375     //   continue;
00376     // }
00377     Pm[p].Pos[0] += Shift[0];
00378     Pm[p].Pos[1] += Shift[1];
00379     Pm[p].Pos[2] += Shift[2];
00380   }
00381   //printf("NanoPos %lf %lf %lf %lf %lf %lf\n",Nano->Pos[0],Nano->Pos[1],Nano->Pos[2],Nano->PosBf[0],Nano->PosBf[1],Nano->PosBf[2]);
00382   return 0;
00383 }
00384 void VarData::BackBone(double *Line,int NBin){
00385   double *Count = new double[NBin];
00386   double *LineS = new double[NBin];
00387   for(int b=0;b<NBin;b++){
00388     Line[b] = 0.;
00389     Count[b] = 0.;
00390   }
00391   CLat1 = 1;
00392   CLat2 = 0;
00393   //average
00394   for(int p=0;p<pNPart();p++){
00395     if(Pm[p].Pos[2] < .02*pEdge(2))continue;
00396     int b = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NBin);
00397     if(b<0 || b >= NBin)continue;
00398     double Weight = Pm[p].Pos[2];
00399     Line[b] += Pm[p].Pos[CLat2]*Weight;
00400     Count[b] += Weight;
00401   }
00402   for(int b=0;b<NBin;b++){
00403     Line[b] /= Count[b] > 0. ? Count[b] : 1.;
00404   }
00405   //smooth
00406   for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00407   InterBSpline1D(LineS,Line,NBin,NBin);
00408   for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00409   InterBSpline1D(LineS,Line,NBin,NBin);
00410   // //reweighting
00411   // for(int b=0;b<NBin;b++){
00412   //   Line[b] = 0.;
00413   //   Count[b] = 0.;
00414   // }
00415   // double NormDist = 1./(.5*pEdge(CLat2));
00416   // for(int p=0;p<pNPart();p++){
00417   //   if(Pm[p].Pos[2] < .02*pEdge(2))continue;
00418   //   int b = (Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NBin);
00419   //   if(b < 0 || b >= NBin)continue;
00420   //   double Dist = SQR(Pm[p].Pos[CLat2] - LineS[b]);
00421   //   if(Dist > SQR(.1)) continue;
00422   //   int bm1 = b-3;
00423   //   if(bm1 < 0) bm1 = b;
00424   //   double Distm1 = SQR(Pm[p].Pos[CLat2] - LineS[bm1]);
00425   //   if(Distm1 > SQR(.3)) continue;
00426   //   int bp1 = b+3;
00427   //   if(bp1 > NBin-1) bp1 = b;
00428   //   double Distp1 = SQR(Pm[p].Pos[CLat2] - LineS[bp1]);
00429   //   if(Distp1 > SQR(.3)) continue;
00430   //   double Weight = 100.*(1. - Dist*Distm1*Distp1*CUBE(NormDist));
00431   //   Line[b] += Pm[p].Pos[CLat2]*Weight;
00432   //   Count[b] += Weight;
00433   // }
00434   // for(int b=0;b<NBin;b++){
00435   //   Line[b] /= Count[b] > 0. ? Count[b] : 1.;
00436   // }
00437   // //smooth
00438   // for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00439   // InterBSpline1D(LineS,Line,NBin,NBin);
00440   // for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00441   // InterBSpline1D(LineS,Line,NBin,NBin);
00442   //fourier
00443 #ifdef USE_FFTW
00444   fftw_complex *FouOut = (fftw_complex *)fftw_malloc(NBin*sizeof(fftw_complex));
00445   fftw_complex *FouIn  = (fftw_complex *)fftw_malloc(NBin*sizeof(fftw_complex));
00446   fftw_plan direct = fftw_plan_dft_1d(NBin,
00447                  FouIn,FouOut,FFTW_FORWARD,FFTW_PATIENT);
00448   fftw_plan reverse = fftw_plan_dft_1d(NBin,
00449                  FouOut,FouIn,FFTW_BACKWARD,FFTW_PATIENT);
00450   for(int b=0;b<NBin;b++) FouIn[b][0] = Line[b];
00451   fftw_execute(direct);
00452   int NComp = NBin;// - 2;//NBin/2;
00453   for(int b=NBin-1;b>=NComp;b--){
00454     FouOut[b][0] = 0.;
00455     FouOut[b][1] = 0.;
00456   }
00457   fftw_execute(reverse);
00458   for(int b=0;b<NBin;b++) Line[b] = FouIn[b][0]/(double)NBin;  
00459 #endif
00460   //write
00461   if(1==0){
00462     FILE *FOut = fopen("BackBone.dat","w");
00463     fprintf(FOut,"#l(%lf %lf %lf) v[%d] d[part]\n",pEdge(CLat1),pEdge(CLat2),pEdge(CNorm),NBin);
00464     int NPart = 0;
00465     for(int p=0;p<pNPart();p++){
00466       if(Pm[p].Pos[2] < .02*pEdge(2)) continue;
00467       fprintf(FOut,"{t[0 0 0] x(%lf %lf %lf)}\n",Pm[p].Pos[CLat1],Pm[p].Pos[CLat2],Pm[p].Pos[CNorm]);
00468       NPart++;
00469     }
00470     for(int b=0;b<NBin;b++){
00471       double x = (b+.5) * pEdge(CLat1)/(double)NBin;
00472       double y = b * pEdge(CLat2)/(double)NBin;
00473       fprintf(FOut,"{t[0 0 1] x(%lf %lf 0.) l[%d]} \n",x,Line[b],NPart+1);
00474       NPart++;
00475     }
00476     fclose(FOut);
00477   }
00478   FILE *FOut1 = fopen("LineProf.dat","w");
00479   for(int b=0;b<NBin;b++){
00480     double x = (b+.5) * pEdge(CLat1)/(double)NBin;
00481     double y = b * pEdge(CLat2)/(double)NBin;
00482     fprintf(FOut1,"%lf %lf\n",x,Line[b]);
00483   }
00484   fclose(FOut1);  
00485 }
00486 void VarData::StalkLineProf(double *Line,int NBin){
00487   //-------------------alloc
00488   Vettore Ax0(1.,0.,0.);
00489   Vettore Ax2(0.,0.,1.);
00490   double Dist[4];
00491   BfDefChain();
00492   //double CmStalk[3] = {0.,0.,0.};
00493   double *CountStalk =  (double *)calloc(NBin,sizeof(double));
00494   int NSample = 8;
00495   int NIter = 6;
00496   Matrice Mask(5);
00497   Mask.FillGaussian(.5,3.);
00498   int NDim = 1;
00499   int IfMinImConv = 1;
00500   int IfSpline = 1;
00501   int IfGaussian = 1;
00502   double InvNSample = 1./(double)NSample;
00503   double **PlotUp    = (double **)calloc(NSample,sizeof(double));
00504   double **PlotUpS   = (double **)calloc(NSample,sizeof(double));
00505   double **CountUp   = (double **)calloc(NSample,sizeof(double));
00506   double **PlotDown  = (double **)calloc(NSample,sizeof(double));
00507   double **PlotDownS = (double **)calloc(NSample,sizeof(double));
00508   double **CountDown = (double **)calloc(NSample,sizeof(double));
00509   double *LineS = (double *)calloc(NBin,sizeof(double));
00510   for(int s=0;s<NSample;s++){
00511     PlotUp[s]    = (double *)calloc(NSample,sizeof(double));
00512     PlotUpS[s]   = (double *)calloc(NSample,sizeof(double));
00513     CountUp[s]   = (double *)calloc(NSample,sizeof(double));
00514     PlotDown[s]  = (double *)calloc(NSample,sizeof(double));
00515     PlotDownS[s] = (double *)calloc(NSample,sizeof(double));
00516     CountDown[s] = (double *)calloc(NSample,sizeof(double));
00517   }
00518   for(int vx=0;vx<NBin;vx++){
00519     Line[vx] = 0.;
00520   }
00521   //---------------defines the two midplanes
00522   //center of mass of the upper layer of the lower membrane
00523   for(int b=0,cOff=0;b<pNBlock();b++,cOff+=Block[b].NChain){
00524     if(strcasestr(Block[b].Name, "TT0") != Block[b].Name) continue;
00525     for(int p=Block[b].InitIdx;p<Block[b].EndIdx;p++){
00526       if(!VAR_IF_TYPE(Ch[Pm[p].CId].Type,CHAIN_UP))continue;
00527       if(Pm[p].Typ == 0) continue;
00528       double Posx = Pm[p].Pos[CLat1] - floor(Pm[p].Pos[CLat1]*pInvEdge(CLat1))*pEdge(CLat1);
00529       double Posy = Pm[p].Pos[CLat2] - floor(Pm[p].Pos[CLat2]*pInvEdge(CLat2))*pEdge(CLat2);
00530       int sx = (int)(Posx*pInvEdge(CLat1)*NSample);
00531       int sy = (int)(Posy*pInvEdge(CLat2)*NSample);
00532       PlotDown[sx][sy] += Pm[p].Pos[CNorm];
00533       CountDown[sx][sy] += 1.;
00534     }
00535   }
00536   //center of mass of the lower layer of the upper membrane
00537   for(int b=0,cOff=0;b<pNBlock();b++,cOff+=Block[b].NChain){
00538     if(strcasestr(Block[b].Name, "TT1") != Block[b].Name) continue;
00539     for(int p=Block[b].InitIdx;p<Block[b].EndIdx;p++){
00540       if(!VAR_IF_TYPE(Ch[Pm[p].CId].Type,CHAIN_DOWN))continue;
00541       if(Pm[p].Typ == 0) continue;
00542       //if(Pm[p].Pos[2] < .5*pEdge(2))continue;
00543       double Posx = Pm[p].Pos[CLat1] - floor(Pm[p].Pos[CLat1]*pInvEdge(CLat1))*pEdge(CLat1);
00544       double Posy = Pm[p].Pos[CLat2] - floor(Pm[p].Pos[CLat2]*pInvEdge(CLat2))*pEdge(CLat2);
00545       int sx = (int)(Posx*pInvEdge(CLat1)*NSample);
00546       int sy = (int)(Posy*pInvEdge(CLat2)*NSample);
00547       PlotUp[sx][sy] += Pm[p].Pos[CNorm];
00548       CountUp[sx][sy] += 1.;
00549     }
00550   }
00551   for(int sx=0;sx<NSample;sx++){
00552     for(int sy=0;sy<NSample;sy++){
00553       PlotUp[sx][sy] /= CountUp[sx][sy] > 0. ? CountUp[sx][sy] : 1.;
00554       PlotDown[sx][sy] /= CountDown[sx][sy] > 0. ? CountDown[sx][sy] : 1.;
00555     }
00556   }
00557   //InterBSpline2D(PlotUp,PlotUpS,NSample,NSample);
00558   //InterBSpline2D(PlotDown,PlotDownS,NSample,NSample);
00559   for(int sx=0;sx<NSample;sx++){
00560     for(int sy=0;sy<NSample;sy++){
00561       PlotUpS[sx][sy] = PlotUp[sx][sy];
00562       PlotDownS[sx][sy] = PlotDown[sx][sy];
00563     }
00564   }
00565   //----------------count the chains between the two midplanes
00566   double AngleMax = 1./(.5*M_PI);
00567   for(int p=0;p<pNPart();p++){
00568     if(Pm[p].Typ == 1) continue;
00569     int sx = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00570     if(sx < 0 || sx >= NSample) continue;
00571     int sy = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00572     if(sy < 0 || sy >= NSample) continue;
00573     if(Pm[p].Pos[CNorm] > PlotUpS[sx][sy] || Pm[p].Pos[CNorm] < PlotDownS[sx][sy]) continue;
00574     int vx = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NBin);
00575     if(vx < 0 || vx >= NBin) continue;
00576     int c = Pm[p].CId;
00577     Vettore ChDir(Ch[c].Dir[0],Ch[c].Dir[1],Ch[c].Dir[2]);
00578     double Angle = Ax0.Angle(&Ax2,&ChDir);
00579     if(Angle < .7 || Angle > 2.3) continue;
00580     double Weight = 1.;//1. - SQR((Angle-.5*M_PI)*AngleMax);
00581     Line[vx] += Pm[p].Pos[CLat1]*Weight;
00582     CountStalk[vx] += Weight;
00583   }
00584   for(int vx=0;vx<NBin;vx++){
00585     Line[vx] /= CountStalk[vx] > 0. ? CountStalk[vx] : 1.;
00586   }
00587   //-------------------------smoothing
00588   if(IfSpline){
00589     for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00590     InterBSpline1D(LineS,Line,NBin,NBin);
00591     for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00592     InterBSpline1D(LineS,Line,NBin,NBin);
00593   }
00594   if(IfGaussian){
00595     Mask.ConvoluteMatrix(Line,NBin,NDim,IfMinImConv);
00596     Mask.ConvoluteMatrix(Line,NBin,NDim,IfMinImConv);
00597   }
00598   // // //------------------------Squared-average------------
00599   for(int i=0;i<NIter;i++){
00600     for(int v=0;v<NBin;v++){
00601       LineS[v] = Line[v];
00602       Line[v] = 0.;
00603       CountStalk[v] = 0.;
00604     }
00605     double NormDist = 1./(.5*pEdge(CLat2));
00606     for(int p=0;p<pNPart();p++){
00607       if(Pm[p].Typ == 1) continue;
00608       int sx = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00609       if(sx < 0 || sx >= NSample) continue;
00610       int sy = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00611       if(sy < 0 || sy >= NSample) continue;
00612       if(Pm[p].Pos[CNorm] > PlotUpS[sx][sy] || Pm[p].Pos[CNorm] < PlotDownS[sx][sy]) continue;
00613       int vx = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NBin);
00614       if(vx < 0 || vx >= NBin) continue;
00615       double Dist = SQR(Pm[p].Pos[CLat1] - LineS[vx]);
00616       if(Dist > SQR(3.)) continue;
00617       double Weight = 100.*(1. - SQR((Pm[p].Pos[CLat1]-LineS[vx])*NormDist));
00618       Line[vx] += Pm[p].Pos[CLat1]*Weight;
00619       CountStalk[vx] += Weight;
00620     }
00621     double Average = 0.;
00622     for(int vx=0;vx<NBin;vx++){
00623       Line[vx] /= CountStalk[vx] > 0. ? CountStalk[vx] : 1.;
00624       Average += Line[vx];
00625     }
00626     // //-------------------------smoothing
00627     if(IfSpline){
00628       for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00629       InterBSpline1D(LineS,Line,NBin,NBin);
00630       for(int v=0;v<NBin;v++) LineS[v] = Line[v];
00631       InterBSpline1D(LineS,Line,NBin,NBin);
00632     }
00633     if(IfGaussian){
00634       Mask.ConvoluteMatrix(Line,NBin,NDim,IfMinImConv);
00635       Mask.ConvoluteMatrix(Line,NBin,NDim,IfMinImConv);
00636     }
00637   }
00638   //-------------------------print-temp-files
00639   if(1==0){
00640     FILE *F2Write = fopen("TwoMid.dat","w");
00641     FILE *FWrite = fopen("StalkLine.dat","w");
00642     FILE *FWrite1 = fopen("StalkLine1.dat","w");
00643     fprintf(F2Write,"#l(%lf %lf %lf) v[%d] d[part]\n",pEdge(0),pEdge(1),pEdge(2),NSample);
00644     WriteSurf(F2Write,PlotUpS,NSample,0);
00645     WriteSurf(F2Write,PlotDownS,NSample,SQR(NSample));
00646     for(int p=0;p<pNPart();p++){
00647       if(Pm[p].Typ == 1) continue;
00648       int sx = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NSample);
00649       if(sx < 0 || sx >= NSample) continue;
00650       int sy = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NSample);
00651       if(sy < 0 || sy >= NSample) continue;
00652       if(Pm[p].Pos[CNorm] > PlotUpS[sx][sy] || Pm[p].Pos[CNorm] < PlotDownS[sx][sy]) continue;
00653       int c = Pm[p].CId;
00654       Vettore ChDir(Ch[c].Dir[0],Ch[c].Dir[1],Ch[c].Dir[2]);
00655       double Angle = Ax0.Angle(&Ax2,&ChDir);
00656       if(Angle < .7 || Angle > 2.3) continue;
00657       fprintf(F2Write,"{t[0 0 1] x(%lf %lf %lf)}\n",Pm[p].Pos[0],Pm[p].Pos[1],Pm[p].Pos[2]);
00658       fprintf(FWrite,"%lf %lf \n",Pm[p].Pos[1],Pm[p].Pos[0]);
00659     }
00660     for(int vx=0;vx<NBin;vx++){
00661       fprintf(FWrite1,"%lf %lf \n",vx*pEdge(CLat2)/(double)NBin,Line[vx]);
00662     }
00663     fclose(FWrite);
00664     fclose(F2Write);
00665     //exit(0);
00666   }
00667   for(int s=0;s<NSample;s++){
00668     free(PlotUp[s]);
00669     free(PlotUpS[s]);
00670     free(CountUp[s]);
00671     free(PlotDown[s]);
00672     free(PlotDownS[s]);
00673     free(CountDown[s]);
00674   }
00675   free(PlotUp);
00676   free(PlotUpS);
00677   free(CountUp);
00678   free(CountDown);
00679   free(PlotDown);
00680   free(PlotDownS);
00681   free(CountStalk);
00682 }
00683 void VarData::StalkPos2(double *OldPos,double *CmStalk){
00684   Vettore Ax0(1.,0.,0.);
00685   Vettore Ax2(0.,0.,1.);
00686   double Dist[4];
00687   BfDefChain();
00688   double CountStalk = 1.;
00689   for(int b=0,cOff=0;b<pNBlock();b++,cOff+=Block[b].NChain){
00690     if(strncmp(Block[b].Name,"TT",2)) continue;
00691     for(int c=cOff;c<cOff+Block[b].NChain;c++){
00692       Vettore ChDir(Ch[c].Dir[0],Ch[c].Dir[1],Ch[c].Dir[2]);
00693       double Angle = Ax0.Angle(&Ax2,&ChDir);
00694       if(Ch[c].Pos[2] < OldPos[2] - 1.5 || Ch[c].Pos[2] > OldPos[2] + 1.5) continue;
00695       if(Angle < 1. || Angle > 2.) continue;
00696       for(int p=0;p<Block[b].NPCh;p++){
00697          int pCurr = Block[b].InitIdx + (c-cOff)*Block[b].NPCh + p;
00698          if(Pm[p].Typ == 1) continue;
00699    for(int d=0;d<3;d++){
00700      Dist[d] = Pm[p].Pos[d] - OldPos[d];
00701      Dist[d] -= floor(Dist[d]*pInvEdge(d))*pEdge(d);
00702    }
00703    Dist[3] = (SQR(Dist[0])+SQR(Dist[1])+SQR(Dist[2]));
00704    double Weight = .00001/(Dist[3]*SQR(Angle-.5*M_PI));
00705    //double Weight = .1/(Dist[3]);
00706    if(Weight > 1.) continue;
00707    //printf("%lf %lf %lf\n",Angle,Dist[3],Weight);
00708    for(int d=0;d<3;d++){
00709      CmStalk[d] += Pm[p].Pos[d]*Weight;//(Pm[p].Pos[d]-OldPos[d])*Weight;
00710    }
00711    CountStalk += Weight;
00712       }
00713     }
00714   }
00715   if(CountStalk <= 0.) CountStalk = 1.;
00716   for(int d=0;d<3;d++){
00717     CmStalk[d] /= CountStalk;
00718   }
00719 }
00720 void VarData::StalkPos3(double *OldPos,double *CmStalk){
00721   int NSample = 32;
00722   int NGrid = NSample-1;
00723   double VolEl = pVol()/(double)CUB(NSample);
00724   double *Plot3d = (double *)calloc(CUBE(NSample),sizeof(double));
00725   double *Plot2d = (double *)calloc(SQR(NGrid),sizeof(double));
00726   double Min = 0.;
00727   double Max = 0.;
00728   double CountStalk = 0.;
00729   VAR_TRIANGLE *Triang = NULL;
00730   double Dist[4];
00731   for(int d=0;d<3;d++) CmStalk[d] = 0.;
00732   for(int p=0;p<pNPart();p++){
00733     //if(Pm[p].Typ != 0) continue;
00734     double Posx = Pm[p].Pos[0] - floor(Pm[p].Pos[0]*pInvEdge(0))*pEdge(0);
00735     double Posy = Pm[p].Pos[1] - floor(Pm[p].Pos[1]*pInvEdge(1))*pEdge(1);
00736     double Posz = Pm[p].Pos[2] - floor(Pm[p].Pos[2]*pInvEdge(2))*pEdge(2);
00737     int sx = (int)(Posx*pInvEdge(0)*NSample);
00738     int sy = (int)(Posy*pInvEdge(1)*NSample);
00739     int sz = (int)(Posz*pInvEdge(2)*NSample);
00740     int sTot = (sx*NSample+sy)*NSample+sz;
00741     Plot3d[sTot] += VolEl;
00742     CmStalk[CNorm] += Pm[p].Pos[CNorm];
00743     if(Max < Plot3d[sTot]) Max = Plot3d[sTot];
00744     if(Min > Plot3d[sTot]) Min = Plot3d[sTot];
00745   }
00746   double IsoLevel = .1*Max;
00747   int NTri = 0;
00748   Triang = MarchingCubes(Plot3d,NSample,IsoLevel,&NTri);  
00749   free(Plot3d);
00750   for(int gx=0;gx<NGrid;gx++){
00751     for(int gy=0;gy<NGrid;gy++){
00752       Plot2d[gx*NGrid+gy] = 1.;
00753     }
00754   }
00755   for(int t=0;t<NTri;t++){
00756     for(int v=0;v<3;v++){
00757       for(int d=0;d<3;d++){
00758    Dist[d] = OldPos[d] - Triang[t].p[v].x[d];
00759       }
00760       Dist[3] = SQR(Dist[0])+SQR(Dist[1])+SQR(Dist[2]);
00761       int gx = (int)(Triang[t].p[v].x[CLat1]*pInvEdge(CLat1)*NGrid);
00762       int gy = (int)(Triang[t].p[v].x[CLat2]*pInvEdge(CLat2)*NGrid);
00763       if(gx < 0 || gx >= NGrid) continue;
00764       if(gy < 0 || gy >= NGrid) continue;
00765       Plot2d[gx*NGrid+gy] += sqrt(Dist[3]);
00766     }
00767   }
00768   double Dx = .5*pEdge(CLat1)/(double)NGrid;
00769   double Dy = .5*pEdge(CLat2)/(double)NGrid;
00770   double Count = 0.;
00771   if(1==0){
00772     FILE *Ciccia = fopen("Ciccia.dat","w");
00773     for(int gx=0;gx<NGrid;gx++){
00774       double x = gx/(double)NGrid*pEdge(CLat1) + Dx;
00775       for(int gy=0;gy<NGrid;gy++){
00776    double y = gy/(double)NGrid*pEdge(CLat1) + Dy;
00777    double Weight = 1./(Plot2d[gx*NGrid+gy]);
00778    fprintf(Ciccia,"%lf %lf %lf\n",x,y,Weight*10000.);
00779       }
00780     }
00781     fclose(Ciccia);
00782     exit(0);
00783   }
00784   for(int gx=0;gx<NGrid;gx++){
00785     double x = gx/(double)NGrid*pEdge(CLat1) + Dx;
00786     for(int gy=0;gy<NGrid;gy++){
00787       double y = gy/(double)NGrid*pEdge(CLat1) + Dy;
00788       double Weight = 1./(Plot2d[gx*NGrid+gy]*SQR(x-OldPos[0])*SQR(y-OldPos[1]));
00789       CmStalk[CLat1] += x*Weight;
00790       CmStalk[CLat2] += y*Weight;
00791       CountStalk     +=   Weight;
00792       //printf("  %lf %lf %lf\n",CmStalk[CLat1],CmStalk[CLat2],Weight);
00793     }
00794   }
00795   CmStalk[0] /= CountStalk;
00796   CmStalk[1] /= CountStalk;
00797   CmStalk[2] /= pNPart();
00798   free(Plot2d);
00799 }
00800 int VarData::StalkPos4(double *OldPos,double *CmStalk){
00801   Nano->Shape = SHAPE_TORUS;
00802   Point2Shape(Nano->Shape);
00803   int NInt = 30;
00804   int NBin = 12;
00805   double kElPhob = 40000.;
00806   double kElPhil = -1.;//-2.;
00807   double MinRad = .2;//.4;
00808   double MinHei = .1;//2.;
00809   double RadMax = .3;
00810   double RadMin = .3;//.4;
00811   double HeiMax = 6.;
00812   double HeiMin = 1.0;
00813   double GainRad = 100.;
00814   double GainHei = 2000.;
00815   double MoveStep = .05;
00816   double RadStep = .01;
00817   double HeiStep = .1;
00818   //Yuliya
00819   double *Count = (double *)calloc(NBin*NBin,sizeof(double));
00820   // first configuration
00821   for(int d=0;d<3;d++) Nano->Pos[d] = OldPos[d];
00822   Nano->Rad = MAX(MIN(RadMax,OldPos[3] + 1.0 ),RadMin);
00823   Nano->Height = MAX(MIN(HeiMax,OldPos[4] + 0.),HeiMin);
00824   double OldNrg = 0.;
00825   for(int p=0;p<pNPart();p++){
00826     double Dist2 = NanoDist2(Pm[p].Pos,0);
00827     if(Dist2 > SQR(2.*Nano->Rad)) continue;
00828     if(Pm[p].Typ == 0) OldNrg += kElPhob*Dist2;
00829     if(Pm[p].Typ == 1) OldNrg += kElPhil*Dist2;
00830   }
00831   OldNrg += (GainRad*SQR(Nano->Rad-MinRad) + GainHei*SQR(Nano->Height-MinHei));
00832   // fake Monte Carlo
00833   for(int i=0;i<NInt;i++){
00834     //change position
00835     double OldNPos[5] = {Nano->Pos[0],Nano->Pos[1],Nano->Pos[2],Nano->Rad,Nano->Height};
00836     for(int m=0;m<3;m++){
00837       //change the torus
00838       if(m==0){
00839          for(int d=0;d<3;d++){
00840            Nano->Pos[d] += MoveStep*(2.*Mat->Casuale()-1.);
00841          }
00842    SetNanoBkf(0);
00843       }
00844       if(m==1){
00845          Nano->Rad += RadStep*(2.*Mat->Casuale()-1.);
00846          if(Nano->Rad < RadMin || Nano->Rad > RadMax){
00847            Nano->Rad = OldNPos[3];
00848            continue;
00849          }
00850       }
00851       if(m==2){
00852          Nano->Height += HeiStep*(2.*Mat->Casuale()-1.);
00853          if(Nano->Height < HeiMin || Nano->Height > HeiMax){
00854            Nano->Height = OldNPos[4];
00855            continue;
00856          }
00857       }
00858       // recalc the energy
00859       double Nrg = 0.;
00860       for(int p=0;p<pNPart();p++){
00861    double Dist2 = NanoDist2(Pm[p].Pos,0);
00862    if(Dist2 > SQR(2.*Nano->Rad)) continue;
00863    if(Pm[p].Typ == 0) Nrg += kElPhob*Dist2;
00864    if(Pm[p].Typ == 1) Nrg += kElPhil*Dist2;
00865       }
00866       Nrg += (GainRad*SQR(Nano->Rad-MinRad) + GainHei*SQR(Nano->Height-MinHei));
00867       // accept/remove
00868       if(exp(OldNrg-Nrg) > Mat->Casuale()){
00869    if(m==0){
00870      printf("NewNrg \t%lf Rad ___ Hei ___ Pos %.2f %.2f %.2f\n",Nrg-OldNrg,Nano->Pos[0]-OldNPos[0],Nano->Pos[1]-OldNPos[1],Nano->Pos[2]-OldNPos[2]);
00871    }
00872    if(m==1){
00873      printf("NewNrg \t%lf Rad %.3f Hei ___ Pos ___ ___ ___\n",Nrg-OldNrg,Nano->Rad);
00874    }
00875    if(m==2){
00876      printf("NewNrg \t%lf Rad ___ Hei %.3f Pos ___ ___ ___\n",Nrg-OldNrg,Nano->Height);
00877    }
00878    OldNrg = Nrg;
00879       }
00880       else{
00881    if(m==0){
00882      for(int d=0;d<3;d++){
00883        Nano->Pos[d] = OldNPos[d];
00884      }
00885      SetNanoBkf(0);
00886    }
00887    if(m==1){
00888      Nano->Rad = OldNPos[3];
00889    }
00890    if(m==2){
00891      Nano->Height = OldNPos[4];
00892    }
00893       }
00894       //printf("%lf %lf %lf -> %lf %lf %lf\n",Nano->Pos[0],Nano->Pos[1],Nano->Pos[2],OldNPos[0],OldNPos[1],OldNPos[2]);
00895       //printf("%lf-> %lf %lf-> %lf\n",SRad,Nano->Rad,LRad,Nano->Height);  
00896     }
00897   }
00898   double Cm[3];
00899   double CountCm = 0;
00900   for(int p=0;p<pNPart();p++){
00901     if(Pm[p].Typ == 1) continue;
00902     double Pos[3];
00903     for(int d=0;d<3;d++){
00904       Pos[d] = Pm[p].Pos[d] - Nano->Pos[d];
00905       Pos[d] -= floor(Pos[d]*pInvEdge(d))*pEdge(d);
00906     }
00907     double Rad = sqrt( SQR(Pos[CLat1]) + SQR(Pos[CLat2]) );
00908     if(Rad > Nano->Height) continue;
00909     for(int d=0;d<3;d++){
00910       Cm[d] += Pm[p].Pos[d];
00911     }
00912     CountCm += 1.;
00913     if(Pm[p].Pos[CNorm] < Nano->Pos[CNorm] - Nano->Rad || Pm[p].Pos[CNorm] > Nano->Pos[CNorm] + Nano->Rad) continue;
00914     int vx = (int)(Pos[CLat1]/Nano->Height*NBin);
00915     vx += NBin/2;
00916     if(vx < 0 || vx >= NBin) continue;
00917     int vy = (int)(Pos[CLat2]/Nano->Height*NBin);
00918     vy += NBin/2;
00919     if(vy < 0 || vy >= NBin) continue;
00920     Count[vx*NBin+vy] += 1.;
00921   }
00922   double Area = 0.;
00923   for(int vx=0;vx<NBin;vx++){
00924     for(int vy=0;vy<NBin;vy++){
00925       if(Count[vx*NBin+vy] < 1.) continue;
00926       Area += 1.;
00927     }
00928   }
00929   if(CountCm <= 0.){
00930     printf("No particles in the torus\n");
00931     return 1;
00932   }
00933   Nano->Area = SQR(Nano->Height)*Area/(double)(SQR(NBin));
00934   for(int d=0;d<3;d++){
00935     Cm[d] /= CountCm;
00936     //Nano->Pos[d] = Cm[d];
00937     CmStalk[d] = Nano->Pos[d];
00938   }
00939   SetNanoBkf(0);
00940   printf("Pos %lf %lf %lf Area %lf Count %lf\n",Nano->Pos[0],Nano->Pos[1],Nano->Pos[2],Nano->Area,CountCm);
00941   free(Count);
00942   return 0;
00943 }
00944 #include <Cubo.h>
00945 double VarData::NormalWeight(VAR_TRIANGLE *Triang,double *WeightL,int NGrid,int NTri){
00946   double Edge[3] = {pEdge(0),pEdge(1),pEdge(2)};
00947   NeiVertex VList(NTri,3,NGrid,Edge);
00948   double CountStalk = 0.;
00949   Vettore Ax(1.,0.,0.);
00950   Vettore n1(3);
00951   Vettore n2(3);
00952   double Max = 0.;
00953   for(int t=0;t<NTri;t++){
00954     for(int v=0;v<3;v++){
00955       int vCurr = Triang[t].v[v];
00956       VList.Add(vCurr,t,Triang[t].p[v].x);
00957     }
00958   }
00959   VList.Reorder();
00960   VList.SetCounters();
00961   for(int t=0;t<NTri;t++){
00962     for(int v=0;v<3;v++){
00963       int vCurr = Triang[t].v[v];
00964       double Weight = 0.;
00965       for(VList.SetCounters(vCurr);VList.IfItCell(vCurr);VList.IncrCurr(vCurr)){
00966    int tt = VList.VertCurr(vCurr);
00967    int p = tt*pNPCh();
00968    for(int d=0;d<3;d++){
00969      n1.Set(Pm[p].Vel[d],d);
00970    }
00971    if(n1.Norm() <= 0.) continue;
00972    Weight += n2.Angle(&Ax,&n1);
00973       }
00974       WeightL[vCurr] = Weight;
00975       if(Max < Weight) Max = Weight;
00976     }
00977   }
00978   return Max;
00979 }
00981 void VarData::ConnectLineChain(VAR_LINE *Triang,int NGrid,int NTri){
00982   SetNPart(2*NTri);
00983   int *Exist = (int *)calloc(NGrid*NGrid,sizeof(int));
00984   int NPart = 0;
00985   DdLinkedList *Pc = new DdLinkedList(Gen->Edge,pNPart(),1.5);
00986   double InvNGrid = 1./(double)NGrid;
00987   for(int t=0;t<NTri;t++){
00988     for(int v=0;v<2;v++){
00989       int vx = (int)(Triang[t].p[v].x[0]*pEdge(0)*InvNGrid);
00990       int vy = (int)(Triang[t].p[v].x[1]*pEdge(1)*InvNGrid);
00991       int vv = vx*NGrid+vy;
00992       Exist[vv] += 1;
00993       if(Exist[vv] > 1) continue;
00994       Pc->AddPart(NPart,Triang[t].p[v].x);
00995       for(int d=0;d<3;d++) Pm[NPart].Pos[d] = Triang[t].p[v].x[d];
00996       NPart++;
00997     }
00998   }
00999   SetNPart(NPart);
01000   for(int p=0;p<pNPart();p++){
01001     Ln[p].Link[0] = 0;
01002   }
01003   double DistRel[4];
01004   char FName[60];
01005   int link = 0;
01006   double Pos[5] = {0.,.5*pCm(CLat2),pCm(CLat2),1.5*pCm(CLat2),pEdge(CLat2)};
01007   double pList[4];
01008   for(int p=0,c=0;p<pNPart();p++){
01009     if(Pm[p].Pos[CLat1] <= 0.9 && Pm[p].Pos[CLat2] > Pos[c] + 3.){
01010       Pos[c+1] = Pm[p].Pos[CLat2] + .1;
01011       pList[c] = p;
01012       c++;
01013       if(c==4) break;
01014     }
01015   }
01016   for(int p=pList[0],c=0;c<4;c++,p=pList[c]){
01017     sprintf(FName,"Chain%d.dat",c);
01018     FILE *FChain = fopen(FName,"w");
01019     fprintf(FChain,"%lf %lf\n",Pm[p].Pos[0],Pm[p].Pos[1]);
01020     link = p;
01021     for(int p1=0;p1<pNPart();p1++){
01022       for(Pc->SetCurr(p1);Pc->IfCurr();Pc->NextCurr()){
01023    if(p1 == Pc->p2Curr) continue;
01024    //printf("%d %d %d %d\n",p,p1,Pc->p2Curr,link);
01025    if(link == Pc->p2Curr){
01026      fprintf(FChain,"%lf %lf\n",Pm[p1].Pos[0],Pm[p1].Pos[1]);
01027      Ln[p1].Link[0] = link;
01028      link = p1;
01029      break;
01030    }
01031       }
01032     }
01033   }
01034 }
01036 void VarData::ConnectLineChain3(VAR_LINE *Triang,int NGrid,int NTri){
01037   SetNPart(2*NTri);
01038   int *Called = (int *)calloc(pNPart(),sizeof(int));
01039   int *Exist = (int *)calloc(NGrid*NGrid,sizeof(int));
01040   double *DirPrev = (double *)calloc(3*pNPart(),sizeof(int));
01041   int NChain = 0;
01042   int NPart = 0;
01043   double InvNGrid = 1./(double)NGrid;
01044   DdLinkedList *Pc = new DdLinkedList(Gen->Edge,pNPart(),2.5);
01045   for(int t=0;t<NTri;t++){
01046     for(int v=0;v<2;v++){
01047       int vx = (int)(Triang[t].p[v].x[0]*pEdge(0)*InvNGrid);
01048       int vy = (int)(Triang[t].p[v].x[1]*pEdge(1)*InvNGrid);
01049       int vv = vx*NGrid+vy;
01050       Exist[vv] += 1;
01051       if(Exist[vv] > 1) continue;
01052       Pc->AddPart(NPart,Triang[t].p[v].x);
01053       for(int d=0;d<3;d++) Pm[NPart].Pos[d] = Triang[t].p[v].x[d];
01054       NPart++;
01055     }
01056   }
01057   SetNPart(NPart);
01058   for(int p=0;p<pNPart();p++){
01059     Ln[p].NLink = 0;
01060     Ln[p].Link[0] = -1;
01061     Exist[p] = 0;
01062     Pm[p].CId = p;
01063   }
01064   // for(int p=0;p<pNPart();p++){
01065   //   Ln[p].NLink = 1;
01066   //   int link = Pc->FindClosest(p);
01067   //   if(link == -1) Ln[p].NLink = 0;
01068   //   Ln[p].Link[0] = link;
01069   // }
01070   double DistRel[4];
01071   for(int p=0;p<pNPart();p++){
01072     Ln[p].NLink = 1;
01073     double Closest = 1000000.;
01074     int pClosest = -1;
01075     for(Pc->SetCurr(p);Pc->IfCurr();Pc->NextCurr()){
01076       int link = Pc->p2Curr;
01077       if(link == p) continue;
01078       if(Ln[link].Link[0] == p) continue;
01079       Pc->Dist2Curr(DistRel);
01080       double Weight = DirPrev[link*3+0]*DistRel[0] + DirPrev[link*3+1]*DistRel[1];
01081       if(Weight >= 0.) Weight = 0.9;
01082       else if(Weight < 0.) Weight = 1.1;
01083       if(DistRel[3]*Weight < Closest){
01084    Closest = DistRel[3];
01085    pClosest = link;
01086    for(int d=0;d<3;d++){
01087      DirPrev[3*p+d] = DistRel[d];
01088    }
01089       }
01090     }
01091     if(pClosest == -1){
01092       Ln[p].NLink = 0;
01093       continue;
01094     }
01095     Ln[p].Link[0] = pClosest;
01096     Exist[pClosest] += 1;
01097     if(Exist[pClosest] > 1 && Ln[pClosest].NLink == 1) Ln[p].NLink = 0;
01098   }
01099   NChain = 0;
01100   for(int p=0;p<pNPart();p++){
01101     int link = Ln[p].Link[0];
01102     if(Pm[p].CId > NChain){
01103       NChain++;
01104       Pm[p].CId = NChain;
01105     }
01106     Pm[link].CId = Pm[p].CId;
01107   }
01108   NChain = 0;
01109   for(int p=pNPart();p>=0;p--){
01110     int link = Ln[p].Link[0];
01111     if(Pm[p].CId > NChain){
01112       NChain++;
01113       Pm[p].CId = NChain;
01114     }
01115     Pm[link].CId = Pm[p].CId;
01116   }
01117   NChain = 0;
01118   for(int p=0;p<pNPart();p++){
01119     int link = Ln[p].Link[0];
01120     if(Pm[p].CId > NChain){
01121       NChain++;
01122       Pm[p].CId = NChain;
01123     }
01124     Pm[link].CId = Pm[p].CId;
01125   }
01126   SetNChain(NChain);
01127   return;
01128   //isolate multiple connected points
01129   // for(int p=0;p<pNPart();p++){
01130   //   int link = Ln[p].Link[0];
01131   //   Called[link]++;
01132   //   if(Called[link] > 1){
01133   //     Ln[p].NLink = 0;
01134   //     NPart--;
01135   //   }
01136   // }
01137   for(int p=0;p<pNPart()-1;p++){
01138     if(Ln[p].NLink == 0) continue;
01139     int link = Ln[p].Link[0];
01140     int MemPos = -1;
01141     for(int pp=p+1;pp<pNPart();pp++){
01142       if(Pm[pp].Idx == link){
01143    MemPos = pp;
01144    break;
01145       }
01146     }
01147     if(MemPos == -1){
01148       Ln[p].NLink = 0;
01149       continue;
01150     }
01151     printf("%d %d %d %d\n",p,link,MemPos,Pm[p+1].Idx);
01152     //if(p < pNPart() - 2) SwapPart(p+1,p+2);
01153     SwapPart(p+1,MemPos);
01154     printf("%d %d\n",Pm[p+1].Idx,Pm[MemPos].Idx);
01155   }
01156   for(int p=0;p<pNPart()-1;p++){
01157     Ln[p].Link[0] = p+1;
01158   }
01159   // for(int p=0;p<pNPart();p++){
01160   //   int link = Ln[p].Link[0];
01161   //   for(int pp=0;pp<pNPart();pp++){
01162   //     if(Pm[pp].Idx == link){
01163   //  Ln[p].Link[0] = pp;
01164   //  break;
01165   //     }
01166   //   }
01167   // }
01168   SetNPart(NPart);
01169   NChain = 0;
01170   for(int p=0;p<pNPart();p++){
01171     Pm[p].CId = NChain;
01172     if(Ln[p].NLink == 0) NChain++;
01173   }
01174   SetNChain(NChain);
01175   free(Exist);
01176   free(Called);
01177   free(DirPrev);
01178 }
01180 void VarData::ConnectLineChain2(VAR_LINE *Triang,int NGrid,int NTri){
01181   //can't follow degenerate triangles..
01182   double Edge[3] = {pEdge(0),pEdge(1),pEdge(2)};
01183   NeiVertex VList(NTri,2,NGrid,Edge);
01184   double CountStalk = 0.;
01185   Vettore Ax(1.,0.,0.);
01186   Vettore n1(3);
01187   Vettore n2(3);
01188   double Max = 0.;
01189   int NTria = 0;
01190   for(int t=0;t<NTri;t++){
01191     if(Triang[t].p[0].x[0] == Triang[t].p[1].x[0] && Triang[t].p[0].x[1] == Triang[t].p[1].x[1]) continue;
01192     for(int v=0;v<2;v++){
01193       int vCurr = Triang[t].v[v];
01194       VList.Add(vCurr,NTria,Triang[t].p[v].x);
01195       for(int d=0;d<3;d++) Pm[NTria*2+v].Pos[d] = Triang[t].p[v].x[d];
01196       NTria++;
01197     }
01198   }
01199   VList.Reorder();
01200   SetNPart(2*NTri);
01201   //VList.Print();
01202   VList.SetCounters();
01203   for(int p=0;p<pNPart();p++){
01204     Ln[p].NLink = 0;
01205   }
01206   for(int t=0;t<NTri;t++){
01207     for(int v=0;v<2;v++){
01208       int vCurr = Triang[t].v[v];
01209       for(VList.SetCounters(vCurr);VList.IfItCell(vCurr);VList.IncrCurr(vCurr)){
01210    int tt = VList.TriaCurr(vCurr);
01211    int p = tt*2+v;
01212    if(vCurr > tt){
01213      Ln[p].NLink = 1;
01214      Ln[p].Link[0] = vCurr;
01215    }
01216       }
01217     }
01218   }
01219   int nChain=0;
01220   for(int c=0;c<pNChain();c++){
01221     Ch[c].NPCh = 0;
01222   }
01223   for(int p=0;p<pNPart();p++){
01224     if(Pm[p].CId <= nChain) continue;
01225     Ch[nChain].InitBead = p;
01226     int pp1 = Ln[p].Link[0];
01227     int pp = 0;
01228     printf("------ %d %d\n",p,pp1);
01229     for(pp=pp1;Ln[pp].NLink > 0;pp=Ln[pp].Link[0]){
01230       printf(" %d %d\n",pp,Ch[nChain].NPCh);
01231       Pm[pp1].CId = nChain;
01232       Ch[nChain].NPCh++;
01233       pp = Ln[pp].Link[0];
01234       if(pp == pp1) break;
01235     }
01236     Ch[nChain].EndBead = pp;
01237     nChain++;
01238   }
01239   SetNChain(nChain);
01240   for(int c=0;c<pNChain();c++){
01241     printf("%d %d %d %d\n",c,Ch[c].InitBead,Ch[c].EndBead,Ch[c].NPCh);
01242     for(int p=Ch[c].InitBead,ppc=0;ppc<Ch[c].NPCh;p=Ln[p].Link[0]){
01243       printf("%d %d \n",c,p);
01244     }
01245   }
01246 }
01247 int VarData::StalkPos(double *OldPos){
01248   double CmStalk[3] = {OldPos[0],OldPos[1],OldPos[2]};
01249   //pPos(OldPos);
01250   //if(StalkPos4(OldPos,CmStalk)) return 1;
01251   int NTrials = 10;
01252   int n=0;
01253   while(StalkPos4(OldPos,CmStalk)){
01254     n++;
01255     if(n > NTrials) continue;
01256   }
01257   //pPos(CmStalk);
01258   for(int d=0;d<3;d++){
01259     //Nano->Pos[d]   = CmStalk[d];// + OldPos[d];
01260     //Nano->PosBf[d] = Nano->Pos[d];// - floor(Nano->Pos[d]*pInvEdge(d))*pEdge(d);
01261     OldPos[d] = pNanoPos(0,d);;
01262   }
01263   OldPos[3] = Nano->Rad;
01264   OldPos[4] = Nano->Height;
01265   Nano->Axis[CLat1] = 0.;
01266   Nano->Axis[CLat2] = 0.;
01267   Nano->Axis[CNorm] = 1.;
01268   // Nano->Rad     = .5;
01269   // Nano->Height  = 4.;
01270   // Nano->Hamaker = 1.;
01271   // Nano->OffSet  = 1.;
01272   // Nano->Shape = SHAPE_STALK;
01273   return 0;
01274 }
01275 double VarData::PorePos(){
01276   const int NGrid = 26;
01277   double *Plot = (double *)calloc(NGrid*NGrid,sizeof(double));
01278   double *Plot2 = (double *)calloc(NGrid*NGrid,sizeof(double));
01279   double Cm[3]  = {0.,0.,0.};
01280   double Cm1[3] = {0.,0.,0.};
01281   double Incr = 500.;
01282   double Threshold = SQR(SQR(1./Incr));
01283   int NReweight = 2;
01284   for(int gx=0;gx<NGrid;gx++){
01285     for(int gy=0;gy<NGrid;gy++){
01286       Plot[gx*NGrid+gy] = 1.;
01287     }
01288   }
01289   for(int p=0;p<pNPart();p++){
01290     if(Pm[p].Typ != 0 ) continue;
01291     int gx = (int)(Pm[p].Pos[CLat1]*pInvEdge(CLat1)*NGrid);
01292     int gy = (int)(Pm[p].Pos[CLat2]*pInvEdge(CLat2)*NGrid);
01293     if(gx < 0 || gx >= NGrid) continue;
01294     if(gy < 0 || gy >= NGrid) continue;
01295     Plot[gx*NGrid+gy] += Incr;
01296   }
01297   double Dx = .5*pEdge(CLat1)/(double)NGrid;
01298   double Dy = .5*pEdge(CLat2)/(double)NGrid;
01299   double Count = 0.;
01300   //FILE *Ciccia = fopen("PoreGrid.dat","w");
01301   double Area = 0.;
01302   //weigthing by neighbours
01303   for(int gx=0;gx<NGrid;gx++){
01304     for(int gy=0;gy<NGrid;gy++){
01305       Plot2[gx*NGrid+gy] = Plot[gx*NGrid+gy];
01306     }
01307   }
01308   for(int gx=0;gx<NGrid;gx++){
01309     for(int gy=0;gy<NGrid;gy++){
01310       if(gx == 0){ Plot[gx*NGrid+gy] = 1./SQR(SQR(Plot2[gx*NGrid+gy]));continue;}
01311       if(gy == 0){ Plot[gx*NGrid+gy] = 1./SQR(SQR(Plot2[gx*NGrid+gy]));continue;}
01312       if(gx == NGrid-1){ Plot[gx*NGrid+gy] = 1./SQR(SQR(Plot2[gx*NGrid+gy]));continue;}
01313       if(gy == NGrid-1){ Plot[gx*NGrid+gy] = 1./SQR(SQR(Plot2[gx*NGrid+gy]));continue;}
01314       Plot[gx*NGrid+gy] = 1./(Plot2[(gx-1)*NGrid+gy]*Plot2[(gx+1)*NGrid+gy]*Plot2[gx*NGrid+(gy-1)]*Plot2[gx*NGrid+(gy+1)]);
01315     }
01316   }
01317   //above the threshold
01318   for(int gx=0;gx<NGrid;gx++){
01319     double x = gx/(double)NGrid*pEdge(CLat1) + Dx;
01320     for(int gy=0;gy<NGrid;gy++){
01321       double y = gy/(double)NGrid*pEdge(CLat2) + Dy;
01322       //Plot[gx*NGrid+gy] /= 100.;
01323       //fprintf(Ciccia,"%lf %lf %lf 0\n",x,y,10.*Plot[gx*NGrid+gy]);
01324       Cm[CLat1] +=  x*Plot[gx*NGrid+gy];
01325       Cm[CLat2] +=  y*Plot[gx*NGrid+gy];
01326       Count     += Plot[gx*NGrid+gy];
01327       if(Plot[gx*NGrid+gy] > Threshold ){
01328    Area += 1.;//Plot[gx*NGrid+gy];
01329    //fprintf(Ciccia,"%lf %lf %lf %d\n",x,y,1.,2);
01330       }
01331       //else fprintf(Ciccia,"%lf %lf %lf %d\n",x,y,.5,0);
01332     }
01333   }
01334   Area = Area/(double)SQR(NGrid)*pEdge(CLat1)*pEdge(CLat2);
01335   Area /= 1.;//Count;
01336   Nano->Rad = sqrt(Area/M_PI);
01337   Cm[0] /= Count;
01338   Cm[1] /= Count;
01339   //reweighting wrt to the former position
01340   for(int r=0;r<NReweight;r++){
01341     Count = 0.;
01342     Cm1[0] = Cm[0];Cm1[1] = Cm[1];
01343     Cm[0] = 0.;Cm[1] = 0.;
01344     Area = 0.;
01345     //printf("%lf %lf\n",Cm1[0],Cm1[1]);
01346     for(int gx=0;gx<NGrid;gx++){
01347       double x = gx/(double)NGrid*pEdge(CLat1) + Dx;
01348       for(int gy=0;gy<NGrid;gy++){
01349    double y = gy/(double)NGrid*pEdge(CLat2) + Dy;
01350    double Dist = (SQR(x-Cm1[CLat1]) + SQR(y-Cm1[CLat2]));
01351    if(Dist > SQR(1.1*Nano->Rad)) continue;
01352    double Weight = 1./pow(Dist,.2);
01353    //fprintf(Ciccia,"%lf %lf %lf 1\n",x,y,10.*Plot[gx*NGrid+gy]*Weight);
01354    Cm[CLat1] +=  x*Plot[gx*NGrid+gy]*Weight;
01355    Cm[CLat2] +=  y*Plot[gx*NGrid+gy]*Weight;
01356    Count     +=  Plot[gx*NGrid+gy]*Weight;
01357    if(Plot[gx*NGrid+gy] > Threshold ) Area += 1.;
01358      }
01359     }
01360     Cm[0] /= Count;
01361     Cm[1] /= Count;
01362     Area = Area/(double)SQR(NGrid)*pEdge(CLat1)*pEdge(CLat2);
01363     //Nano->Rad = sqrt(Area/M_PI);
01364   }
01365   //assigning
01366   Cm[2] = pCm(2);
01367   for(int d=0;d<3;d++){
01368     Nano->Pos[d] = Cm[d];
01369   }
01370   SetNanoBkf(0);
01371   //asymmetry
01372   double AreaOut = 0.;
01373   double AreaIn = 0.;
01374   for(int gx=0;gx<NGrid;gx++){
01375     double x = gx/(double)NGrid*pEdge(CLat1) + Dx;
01376     for(int gy=0;gy<NGrid;gy++){
01377       double y = gy/(double)NGrid*pEdge(CLat2) + Dy;
01378       double Dist = SQR(x-Cm[0]) + SQR(y-Cm[1]);
01379       if(Dist <= SQR(Nano->Rad)){
01380    AreaIn += 1.;
01381    if(Plot[gx*NGrid+gy] < Threshold ) AreaOut += 1.;
01382    //fprintf(Ciccia,"%lf %lf %lf %d\n",x,y,0.,1);
01383       }
01384       else{
01385    if(Plot[gx*NGrid+gy] > Threshold ) AreaOut += 1.;
01386       }
01387     }
01388   }
01389   //fclose(Ciccia);
01390   free(Plot);
01391   return AreaOut/AreaIn;
01392 }