Allink  v0.1
VarDataCreate.cpp
00001 /***********************************************************************
00002 VarDataCreate: Functions that create an initial configuration system as read from Polymer.conf. 
00003 Copyright (C) 2008-2010 by Giovanni Marelli <sabeiro@virgilio.it>
00004 
00005 
00006 This program is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 You should have received a copy of the GNU General Public License
00016 along with this program; If not, see <http://www.gnu.org/licenses/>.
00017 ***********************************************************************/
00018 #include "../include/VarData.h"
00019 
00020 static int Tries = 0;
00021 
00022 int VarData::DefSoft(char *nome2,char *ConfF){
00023   /*---------Variables--------------------*/
00024   char cSystem[512];
00025   double ReOSigma = 5.;
00026   int NChain = 1250;
00027   //  Dens = 5.;
00028   double ChainPArea = 1./(0.01974*QUAD(ReOSigma));
00029   double Thickness = 0.849*ReOSigma;
00030   double Volume = 1.;
00031   double Area =0.;
00032   int *arch;
00033   if(ReadConf(ConfF)) return 1;
00034   /*----------Setting----------*/
00035   Gen->NChain = 0;
00036   Gen->NPart  = 0;
00037   Gen->Step   = 0;
00038   Gen->NBlock = 0;
00039   //if(Gen->kappaBend  <= 0.) Gen->kappaSpring = 3.*(Gen->NPCh-1)/(2.*QUAD(Gen->ReOverCutOff));
00040   VAR_ADD_TYPE(SysType,VAR_EDGE);
00041   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00042   sigma = 1./sqrt(pkSpr());
00043   Mat->InizializzaGaussiano(sigma,100);
00044   int AddNSoft = 0;
00045   for(int s=0;s<NSoft;s++){
00046     //------------------------16---------------------------
00047     if (Gen->NPCh == 16){
00048       ChainPArea = 2.6*Soft[s].Size[2];
00049       Thickness = 0.93*ReOSigma;
00050     }
00051     //------------------------11------------------------
00052     else if (Gen->NPCh == 11){
00053       ChainPArea = 3.19*Soft[s].Size[2];
00054       Thickness = 2.55;
00055     }
00056     //------------------------12------------------------
00057     else if (Gen->NPCh == 12){
00058       ChainPArea = 3.19*Soft[s].Size[2];
00059       Thickness = 2.55;
00060     }
00061     //------------------------13------------------------
00062     else if (Gen->NPCh == 13){
00063       ChainPArea = 3.19*Soft[s].Size[2];
00064       Thickness = 2.55;
00065     }
00066     //------------------------10------------------------
00067     else if (Gen->NPCh == 10){
00068       ChainPArea = 3.98*Soft[s].Size[2];
00069       Thickness = 0.8*ReOSigma;
00070     }
00071     //------------------------14------------------------
00072     else if (Gen->NPCh == 14){
00073       ChainPArea = 3.65*Soft[s].Size[2];
00074       Thickness = 0.5*ReOSigma;
00075     }
00076     //------------------------20------------------------
00077     else if (Gen->NPCh==21||Gen->NPCh==20){
00078       ChainPArea = 3.65*Soft[s].Size[2];
00079       Thickness = 0.6*ReOSigma;
00080     }
00081     //------------------------32---------------------
00082     else if (Gen->NPCh == 32){
00083       ChainPArea = 2.6*Soft[s].Size[2];
00084       Thickness = 3.5;//1.14*ReOSigma;
00085     }
00086     if(VAR_IF_TYPE(SysType,VAR_TWOTAILS)){
00087       if (Gen->NPCh == 21 ||Gen->NPCh == 20 ){
00088    ChainPArea = 3.65*Soft[s].Size[2];
00089    Thickness = 0.6*ReOSigma;
00090       }
00091       if (Gen->NPCh == 11||Gen->NPCh == 12||Gen->NPCh == 13){
00092    ChainPArea = 3.19*Soft[s].Size[2];
00093    Thickness = 2.55;
00094       }
00095     }
00096     //-------------------arch--------------------
00097     arch = (int *)calloc(Gen->NPCh,sizeof(int));
00098     for(int b=0;b<Block[0].Asym;b++){
00099       arch[b] = 0;
00100     }
00101     for(int b=Block[0].Asym;b<Gen->NPCh;b++){
00102       arch[b] = 1;
00103     }
00104     //--------------------Area---------------------
00105     Volume = Gen->Edge[CLat1]*Gen->Edge[CLat2]*Thickness;
00106     if(VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR)){
00107       Area = Gen->Edge[CLat1]*Gen->Edge[CLat2];
00108     }
00109     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_COATING)){
00110       Thickness = 4.0;//1.15;
00111       Area = .7*DUE_PI*(Nano->Rad+Thickness)*Nano->Height;
00112       if(VAR_IF_TYPE(Nano->Shape,SHAPE_SPH)){
00113    Area = .3*2.*DUE_PI*SQR(Nano->Rad+Thickness);
00114    if (Gen->NPCh == 32){
00115      Thickness = 6.0;//1.15;
00116      Area = .1*2.*DUE_PI*SQR(Nano->Rad+Thickness);
00117    }
00118       }
00119     }
00120     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_TUBE)){
00121       Area = DUE_PI*(Soft[s].Size[0]+Thickness)*Soft[s].Size[1];
00122     }
00123     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_VESICLE)){
00124       ChainPArea = 3.6/Soft[s].Size[2];
00125       //Thickness = 3.5;
00126       Area  = DUE_PI*SQR(Soft[s].Size[0]+.5*Thickness);
00127       Area += DUE_PI*SQR(Soft[s].Size[0]-.5*Thickness);
00128       AddNSoft += 1;
00129     }
00130     for(int n=0;n<Gen->NNano;n++){
00131       if(Nano[n].Shape == SHAPE_NONE) continue;
00132       if(Nano[n].Shape == SHAPE_WALL) continue;
00133       Area -= PI*SQR(Nano[n].Rad);
00134     }
00135      //------------------NChain-------------------
00136     if(Nano->Shape == SHAPE_SPH){
00137       Volume -= 4.*PI*CUB((Nano->Rad))/3.;
00138       Nano->Height = 0.;
00139     }
00140     if(Nano->Shape == SHAPE_CYL || Nano->Shape == SHAPE_TILT)
00141       Volume -= PI*QUAD(Nano->Rad)*Nano->Height;
00142     if(Nano->Shape == SHAPE_CLUSTER){
00143       Volume -= PI*QUAD(Nano->Rad)*Nano->Height;
00144     }
00145     if(VAR_IF_TYPE(Soft[s].Topology,VAR_DISTRIBUTED)){
00146       Volume = Gen->Edge[CLat1]*Gen->Edge[CLat2]*Gen->Edge[CNorm];
00147       NChain = (int)( Volume*Soft[s].Size[2]/Gen->NPCh);
00148     }
00149     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR)){
00150       NChain = (int)(Area*ChainPArea);
00151     }
00152     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_OBSTACLE)){
00153       Soft[s].NPCh = 2*Gen->NPCh;
00154       NChain = (int)(Area*ChainPArea*Soft[s].Size[2]);
00155       NChain = 200;
00156     }
00157     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_COATING)){
00158       NChain = (int)( .53*Area*ChainPArea);    
00159     }
00160     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_TUBE)){
00161       NChain = (int)( .69*Area*ChainPArea);    
00162     }
00163     else if(VAR_IF_TYPE(Soft[s].Topology,VAR_VESICLE)){
00164       ChainPArea = 3.0/Soft[s].Size[2];
00165       //Thickness = 3.5;
00166       NChain = (int)(Area*ChainPArea);
00167     }
00168     //------------DefBlock---------------
00169     Soft[s].NChain = NChain;
00170     Soft[s].NPCh = Gen->NPCh;
00171     if(VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR_PE)){
00172       Soft[s].NPCh = Gen->NPCh-1;
00173     }
00174     if(VAR_IF_TYPE(Soft[s].Topology,VAR_OBSTACLE))
00175       Soft[s].NPCh = 2*Gen->NPCh;
00176     Soft[s].NPart = Soft[s].NPCh*NChain;
00177     //Soft[s].NPart = NChain*Gen->NPCh;
00178     Gen->NChain += Soft[s].NChain;
00179     Gen->NPart += Soft[s].NPart;
00180   }
00181   Gen->NBlock = NSoft+AddNSoft;
00182   //----------Nano---------------
00183   for(int n=0;n<Gen->NNano;n++){
00184     if(Nano[n].Shape == SHAPE_CLUSTER){
00185       Gen->NBlock++;
00186       Gen->NChain += 1;
00187       Gen->NPart += Nano[n].NCircle*Nano[n].NHeight;
00188       if(Gen->NLink < 6) Gen->NLink = 6;
00189     }
00190   }
00191   if(NAddChain > 0) Gen->NBlock++;
00192   for(int s=0;s<NSoft;s++)
00193     if( VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR) )
00194       if(NAddChol  > 0) Gen->NBlock++;
00195   if(NStuffing > 0) Gen->NBlock++;
00196   if(NSolvent  > 0) Gen->NBlock++;
00197   //--------------Block---------------
00198   int DiblockLim = Block[0].Asym;
00199   Block = (BLOCK *)calloc(Gen->NBlock,sizeof(BLOCK));
00200   Soft[0].InitIdx = 0;
00201   for(int s=1;s<NSoft;s++){
00202     Soft[s].InitIdx += Soft[s-1].NPart + Soft[s-1].InitIdx;
00203   }
00204   for(int s=0,s1=0;s<NSoft;s++,s1++){
00205     Soft[s].EndIdx   = Soft[s].InitIdx + Soft[s].NPart;
00206     Block[s1].Asym = DiblockLim;
00207     Block[s1].InitIdx = Soft[s].InitIdx;
00208     Block[s1].NChain  = Soft[s].NChain;
00209     Block[s1].EndIdx  = Soft[s].EndIdx;
00210     Block[s1].NPCh = Soft[s].NPCh;
00211     sprintf(Block[s1].Name,"LIPID%d",s);
00212     if(VAR_IF_TYPE(SysType,VAR_TWOTAILS))
00213       sprintf(Block[s1].Name,"TT%d",s);
00214     if(VAR_IF_TYPE(Soft[s].Topology,VAR_VESICLE)){
00215       int NLayerIn = (int)(Soft[s].NChain*SQR(Soft[s].Size[0])/(SQR(Soft[s].Size[0])+SQR(Soft[s].Size[0]+Thickness)));
00216       int NLayerOut = Soft[s].NChain - NLayerIn;
00217       Block[s1].NChain = NLayerIn;
00218       Block[s1].EndIdx = Block[s1].InitIdx+Soft[s].NPCh*NLayerIn;
00219       Block[s1+1].InitIdx = Block[s1].EndIdx;
00220       Block[s1+1].EndIdx  = Soft[s].EndIdx;
00221       Block[s1+1].NChain = NLayerOut;
00222       Block[s1+1].NPCh = Soft[s].NPCh;
00223       sprintf(Block[s1].Name,"INNER%d",s);
00224       sprintf(Block[s1+1].Name,"OUTER%d",s);
00225       s1++;
00226     }
00227   }
00228   for(int n=0,b=NSoft+AddNSoft;n<Gen->NNano;n++){
00229     if(Nano[n].Shape == SHAPE_CLUSTER){
00230       Block[b].InitIdx = b != 0 ? Block[b-1].EndIdx : 0 ;
00231       Block[b].NChain  = 1;
00232       Block[b].EndIdx  = Block[b].InitIdx + Nano[n].NCircle*Nano[n].NHeight;
00233       Block[b].NPCh = Nano[n].NCircle*Nano[n].NHeight;
00234       Block[b].NPart = Block[b].NPCh;
00235       sprintf(Block[b].Name,"PEP%d",n);
00236       Nano[n].nBlock = b;
00237       b++;
00238     }
00239   }
00240   //-------------Alloc---------------
00241   Pm = (PART *)calloc(Gen->NPart,sizeof(PART));
00242   Ln = (LINKS *)calloc(Gen->NPart,sizeof(LINKS));
00243   if(Pm == NULL){printf("Non s'alloca\n"); return 1;}
00244   for(int p=0;p<Gen->NPart;p++){
00245     Ln[p].Link = (int *)calloc(Gen->NLink,sizeof(int));
00246     if(Ln[p].Link == NULL){printf("Non s'alloca\n"); return 1;}
00247   }
00248   SysInfo(cSystem);
00249   printf("%s\n",cSystem);
00250   SysDef(cSystem);
00251   printf("%s",cSystem);
00252   if(!HeaderSoft(cSystem))
00253     printf("%s",cSystem);
00254   /*---------Creating--------*/
00255   char ArchFile[60];
00256   int NMonCluster = 0;
00257   for(int s=0,b=0;s<NSoft;s++,b++){
00258     CreateSoft(arch,Thickness,s);
00259     if(VAR_IF_TYPE(Soft[s].Topology,VAR_VESICLE))
00260       b++;
00261     NMonCluster = Block[b].EndIdx;
00262   }
00263   for(int n=0;n<Gen->NNano;n++){
00264     if(Nano[n].Shape == SHAPE_CLINKS){
00265       FindNeighbours("CrossLinks.dat");
00266     }
00267     if(Nano[n].Shape != SHAPE_CLUSTER) continue;
00268     sprintf(ArchFile,"Architecture%d.dat",n);
00269     CreateProtein(n,NMonCluster);
00270     NMonCluster += Nano[n].NCircle*Nano[n].NHeight;
00271   }
00272   SetCoeff();
00273   double Norm2 = CUBE(pReOverCutOff()) / SQR(pNPCh());
00274   double Norm3 = CUBE(SQR(pReOverCutOff()) / pNPCh());
00275   MInt->Rescale(Norm2,2);
00276   MInt->Rescale(Norm3,3);
00277   Write(nome2);
00278   AddStuffing(nome2,NStuffing,0);
00279   AddChains(nome2,Thickness);
00280   AddSolvent(nome2,NSolvent);
00281   for(int s=0;s<NSoft;s++){
00282     if( VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR) ){
00283       AddCholesterol(nome2,Thickness,s);
00284     }
00285   }
00286   return 0;
00287 }
00288 bool VarData::CreateSoft(int *arch,double Thickness,int s){
00289   if( VAR_IF_TYPE(Soft[s].Topology,VAR_COATING) )
00290     CreateCoating(arch,Thickness,s);
00291   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_VESICLE) )
00292     CreateVesicle(arch,Thickness,s);
00293   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_TUBE) )
00294     CreateTube(arch,Thickness,s);
00295   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR) )
00296     CreatePlanar(arch,Thickness,s);
00297   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_PLANAR_PE) )
00298     CreatePlanar(arch,Thickness,s);
00299   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_OBSTACLE) )
00300     CreateObstacle(arch,Thickness,s);
00301   else if( VAR_IF_TYPE(Soft[s].Topology,VAR_DISTRIBUTED) ){
00302     double sigma = 1./sqrt(pkSpr());
00303     //sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00304     for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;){
00305       for(int d=0;d<3;d++)
00306    Pm[p].Pos[d] = Mat->Casuale()*Gen->Edge[d];
00307       int IfContinue = 1;
00308       for(int i=1;i<Gen->NPCh;i++){
00309    for(int d=0;d<3;d++)
00310      Pm[p+i].Pos[d] = Pm[p+i-1].Pos[d]+Mat->Gaussiano(0.,sigma);
00311    if(CheckNano(Pm[p+i].Pos,s)){IfContinue=0;break;}
00312       }
00313       if(IfContinue){
00314    c++;
00315    p += Gen->NPCh;
00316       }
00317     }
00318   }
00319   else {
00320     printf("System topology not recognized\n");
00321     return 1;
00322   }
00323   DefRest(arch,s);
00324   printf("Efficency: %d Tries for %d Particle\n",Tries,Soft[s].NPart);
00325   return 0;
00326 }
00327 int VarData::TrialSys(){
00328   int Values=32;
00329   double dValues = 1./(double)(Values);
00330   double **Plot = (double **)calloc(Values,sizeof(double));
00331   Gen->NPart = Values*Values;
00332   Gen->NChain = Gen->NPart;
00333   Gen->NPCh = 1;
00334   for(int d=0;d<3;d++){
00335     Gen->Edge[d] = (double)Values;
00336   }
00337   Pm = (PART *)calloc(Gen->NPart,sizeof(PART));
00338   Ch = (CHAIN *)calloc(Gen->NChain,sizeof(CHAIN));
00339   for(int i=0;i<Values;i++){
00340     Plot[i] = (double *)malloc(Values*sizeof(double));
00341     for(int j=0;j<Values;j++){
00342       Pm[i*Values+j].Pos[CLat1] = Ch[i*Values+j].Pos[CLat1] = (double) j;
00343       Pm[i*Values+j].Pos[CLat2] = Ch[i*Values+j].Pos[CLat2] = (double) i;
00344       Pm[i*Values+j].Pos[CNorm] = Ch[i*Values+j].Pos[CNorm] =
00345    Gen->Edge[CNorm]*.5 + cos(DUE_PI*(i)*dValues) + cos(DUE_PI*(i)*dValues*2.) + cos(DUE_PI*(i)*dValues*4.) +
00346    cos(DUE_PI*(j)*dValues) + cos(DUE_PI*(j)*dValues*2.) + cos(DUE_PI*(j)*dValues*4.);
00347     }
00348   }
00349   return 0;
00350 }
00351 void VarData::DefRest(int *arch,int s){
00352   double sigma = 1./sqrt(pkSpr());
00353   for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;c++){
00354     for(int i=0;i<Soft[s].NPCh;i++){
00355       for(int d=0;d <3;d++){
00356    Pm[p].Vel[d] = Mat->Gaussiano(0.,sigma) + Soft[s].Vel[d];
00357       }
00358       if(i == Soft[s].NPCh-1){
00359    Ln[p].Link[0] = p-1;
00360    Ln[p].NLink = 1;
00361       }
00362       else if(i == 0){
00363    Ln[p].Link[0] = p+1;
00364    Ln[p].NLink = 1;
00365       }
00366       else{
00367    Ln[p].NLink = 2;
00368    Ln[p].Link[0] = p-1;
00369    Ln[p].Link[1] = p+1;
00370       }
00371       if( VAR_IF_TYPE(Soft[s].Topology,VAR_ADDED) )
00372    Pm[p].Typ = 0;
00373       else 
00374    Pm[p].Typ = arch[i];
00375       Pm[p].CId = c;
00376       Pm[p].Idx = p;
00377       p++;
00378     }
00379   }
00380 }
00381 int VarData::PutPart(int j,int p,int HalfLim,double sigma){
00382   int i=0;
00383   if( j <= Block[0].Asym){
00384     i = Block[0].Asym - j;
00385     for(int d=0;d <3;d++){
00386       Pm[p+i].Pos[d] = Pm[p+1+i].Pos[d]+Mat->Gaussiano(0.,sigma);
00387     }
00388     if( VAR_IF_TYPE(SysType,VAR_TWOTAILS) ){
00389       if(i==HalfLim-1){
00390    for(int d=0;d <3;d++)
00391      Pm[p+i].Pos[d] = Pm[p+Block[0].Asym].Pos[d]+Mat->Gaussiano(0.,sigma);
00392       }
00393     }
00394   }
00395   else if(j>Block[0].Asym){
00396     i = j;
00397     for(int d=0;d <3;d++){
00398       Pm[p+i].Pos[d] = Pm[p-1+i].Pos[d]+Mat->Gaussiano(0.,sigma);
00399     }
00400   }
00401   return i;
00402 }
00403 void VarData::CreateObstacle(int *arch,double Thickness,int s){
00404   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00405   int HalfLim = (int)(Block[0].Asym*.5);
00406   double Dz = Thickness/16.;
00407   double Leaflet = -.5*Thickness - 2.*Dz;
00408   for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;c++,p+=Soft[s].NPCh){
00409     double Cas1 = Mat->Casuale(),Cas2 = Mat->Casuale();
00410     Pm[p].Pos[CLat1] = Cas1*Gen->Edge[CLat1]*.5;
00411     Pm[p].Pos[CLat2] = Cas2*Gen->Edge[CLat2]*.5;
00412     Pm[p].Pos[CNorm] = Soft[s].Pos[CNorm]+Leaflet;
00413     Pm[p].Typ = 1;
00414     for(int pn=1;pn<Soft[s].NPCh;pn++){
00415       Pm[p+pn].Pos[CLat1] = Pm[p].Pos[CLat1];
00416       Pm[p+pn].Pos[CLat2] = Pm[p].Pos[CLat2];
00417       Pm[p+pn].Pos[CNorm] = Pm[p+pn-1].Pos[CNorm] + Dz;
00418       Pm[p+pn].Typ = 0;
00419       if( (pn < 2) || (pn >= Soft[s].NPCh - 2)){
00420    Pm[p+pn].Typ = 1;
00421       }
00422     }
00423   }
00424 }
00425 void VarData::CreatePlanar(int *arch,double Thickness,int s){
00426   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00427   int HalfLim = (int)(Block[0].Asym*.5);
00428   for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;){
00429     printf("%d %d %d %lf \r",p,c,Tries,p/(double)Soft[s].NPart);
00430     double Leaflet = -.5*Thickness;
00431     if(c >= Soft[s].NChain/2) Leaflet = .5*Thickness;
00432     //first part
00433     double Cas1 = Mat->Casuale(),Cas2 = Mat->Casuale();
00434     Pm[p+Block[0].Asym].Pos[CLat1] = Cas1*Gen->Edge[CLat1];
00435     Pm[p+Block[0].Asym].Pos[CLat2] = Cas2*Gen->Edge[CLat2];
00436     Pm[p+Block[0].Asym].Pos[CNorm] = Soft[s].Pos[CNorm]+Leaflet;
00437     int IfContinue = 1;
00438     //others
00439     for(int j=1;j<Soft[s].NPCh;j++){
00440       int i = PutPart(j,p,HalfLim,sigma);
00441       //absorbing boundary condition
00442       if(arch[i] == 0 ){
00443    if(Pm[p+i].Pos[CNorm] > Soft[s].Pos[CNorm]+.5*Thickness ||
00444       Pm[p+i].Pos[CNorm] < Soft[s].Pos[CNorm]-.5*Thickness ){
00445      Tries++;
00446      IfContinue = 0;
00447      break;
00448    }
00449       }
00450       else if (arch[i] == 1 ){
00451    if(Pm[p+i].Pos[CNorm] < Soft[s].Pos[CNorm]+.5*Thickness &&
00452       Pm[p+i].Pos[CNorm] > Soft[s].Pos[CNorm]-.5*Thickness ){
00453      Tries++;
00454      IfContinue = 0;
00455      break;
00456    }
00457       }
00458       if(CheckNano(Pm[p+i].Pos,s)){IfContinue=0;break;}
00459     }
00460     if(IfContinue){
00461       c++;
00462       p += Soft[s].NPCh;
00463     }
00464   }
00465 }
00466 void VarData::CreateVesicle(int *arch,double Thickness,int s){
00467   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00468   int NLayerIn = (int)(Soft[s].NChain*SQR(Soft[s].Size[0])/(SQR(Soft[s].Size[0])+SQR(Soft[s].Size[0]+Thickness)) );
00469   int NLayerOut = Soft[s].NChain - NLayerIn;
00470   int HalfLim = (int)(Block[0].Asym*.5);
00471   double inc = M_PI * (3. - sqrt(5.));
00472   double NInv = 1. / (double)NLayerIn;
00473   double Leaflet = -.5*Thickness;
00474   for(int c=0,cc=0,p=Soft[s].InitIdx;c<Soft[s].NChain;){
00475     printf("%d %d %d %lf \r",p,c,Tries,p/(double)Soft[s].NPart);
00476     if(c == NLayerIn){
00477       cc=0;
00478       NInv = 1./(double)NLayerOut;
00479       Leaflet = .5*Thickness;
00480     }
00481     double x = cc*2.*NInv - 1. + (NInv);
00482     double r = sqrt(1.-x*x);
00483     double phi = cc*inc;
00484     double y = cos(phi)*r;
00485     double z = sin(phi)*r;
00486     //first part
00487     Pm[p+Block[0].Asym].Pos[CLat1] =
00488       (Soft[s].Size[0]+Leaflet)*x + Soft[s].Pos[CLat1];
00489     Pm[p+Block[0].Asym].Pos[CLat2] = 
00490       (Soft[s].Size[0]+Leaflet)*y + Soft[s].Pos[CLat2];
00491     Pm[p+Block[0].Asym].Pos[CNorm] = 
00492       (Soft[s].Size[0]+Leaflet)*z + Soft[s].Pos[CNorm];
00493     //others
00494     int IfContinue = 1;
00495     for(int j=1;j<Gen->NPCh;j++){
00496       int i = PutPart(j,p,HalfLim,sigma);
00497       // absorbing boundary condition
00498       double Dist = SQR(Pm[p+i].Pos[CLat1]-Soft[s].Pos[CLat1]) + SQR(Pm[p+i].Pos[CLat2]-Soft[s].Pos[CLat2]) + SQR(Pm[p+i].Pos[CNorm]-Soft[s].Pos[CNorm]);
00499       if(arch[i] == 0){
00500    if( Dist < SQR(Soft[s].Size[0]-.5*Thickness) || Dist > SQR(Soft[s].Size[0]+.5*Thickness) ) {
00501      Tries++;
00502      IfContinue = 0;
00503      break;
00504    }
00505       }
00506       else if(arch[i] == 1){
00507    if(Dist < SQR(Soft[s].Size[0]+.5*Thickness) && Dist > SQR(Soft[s].Size[0] - .5*Thickness) ){
00508      Tries++;
00509      IfContinue = 0;
00510      break;
00511    }
00512       }
00513       if(CheckNano(Pm[p+i].Pos,s)){IfContinue=0;break;}
00514     }
00515     if(IfContinue){
00516       c++;
00517       cc++;
00518       p += Gen->NPCh;
00519     }
00520   }
00521   // for(int p=0;p<pNPart();p++){
00522   //   pPos(p);
00523   // }
00524 }
00525 void VarData::CreateCoating(int *arch,double Thickness,int s){
00526   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00527   int HalfLim = (int)(Block[0].Asym*.5);
00528   double NInv = 1./(double)Soft[s].NChain;
00529   double inc = 3.141592654 * (3. - sqrt(5.));
00530   double Dist = 0.;
00531   for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;){
00532     printf("%d %d %d %lf \r",p,c,Tries,p/(double)Soft[s].NPart);
00533     //first part
00534     double Cas1 = Mat->Casuale()*DUE_PI;
00535     if(VAR_IF_TYPE(Nano->Shape,SHAPE_HEI)){
00536       Pm[p+Block[0].Asym].Pos[CLat1] = 
00537    (Nano->Rad+.5*Thickness)*cos(Cas1) + Nano->Pos[CLat1];
00538       Pm[p+Block[0].Asym].Pos[CLat2] = 
00539    (Nano->Rad+.5*Thickness)*sin(Cas1) + Nano->Pos[CLat2];
00540       Pm[p+Block[0].Asym].Pos[CNorm] = 
00541    (.5 - Mat->Casuale())*Nano->Height + Nano->Pos[CNorm];
00542     }
00543     else if(VAR_IF_TYPE(Nano->Shape,SHAPE_SPH)){
00544       double x = c*2.*NInv - 1. + (NInv);
00545       double r = sqrt(1.-x*x);
00546       double y = cos(c*inc)*r;
00547       double z = sin(c*inc)*r;
00548       Pm[p+Block[0].Asym].Pos[CLat1] =
00549    (Nano->Rad+.5*Thickness)*x + Nano->Pos[CLat1];
00550       Pm[p+Block[0].Asym].Pos[CLat2] = 
00551    (Nano->Rad+.5*Thickness)*y + Nano->Pos[CLat2];
00552       Pm[p+Block[0].Asym].Pos[CNorm] = 
00553    (Nano->Rad+.5*Thickness)*z + Nano->Pos[CNorm];
00554     }
00555     int IfContinue = 1;
00556     //others
00557     for(int j=1;j<Gen->NPCh;j++){
00558       int i = PutPart(j,p,HalfLim,sigma);
00559       // absorbing boundary condition
00560       if(VAR_IF_TYPE(Nano->Shape,SHAPE_HEI))
00561    Dist = SQR(Pm[p+i].Pos[CLat1]-Nano->Pos[CLat1]) + SQR(Pm[p+i].Pos[CLat2]-Nano->Pos[CLat2]);
00562       else if(VAR_IF_TYPE(Nano->Shape,SHAPE_SPH))
00563    Dist = SQR(Pm[p+i].Pos[CLat1]-Nano->Pos[CLat1]) + SQR(Pm[p+i].Pos[CLat2]-Nano->Pos[CLat2]) + SQR(Pm[p+i].Pos[CNorm]-Nano->Pos[CNorm]);
00564       if(arch[i] == 0 && Dist > SQR(Nano->Rad+.5*Thickness) ){
00565    Tries++;
00566    IfContinue = 0;
00567    break;
00568       }
00569       else if(arch[i] == 1 && Dist < SQR(Nano->Rad+.5*Thickness) ){
00570    Tries++;
00571    IfContinue = 0;
00572    break;
00573       }
00574       if(CheckNano(Pm[p+i].Pos,s)){IfContinue=0;break;}
00575     }
00576     if(IfContinue){
00577       c++;
00578       p += Gen->NPCh;
00579     }
00580   }
00581 }
00582 void VarData::CreateTube(int *arch,double Thickness,int s){
00583   double sigma = sqrt(QUAD(Gen->ReOverCutOff)/(Gen->NPCh-1)/3.);
00584   int HalfLim = (int)(Block[0].Asym*.5);
00585   int NLayerIn = (int)(Soft[s].NChain/2.*SQR(Soft[s].Size[0])/(SQR(Soft[s].Size[0])+SQR(Soft[s].Size[0]+Thickness)) );
00586   for(int c=0,p=Soft[s].InitIdx;c<Soft[s].NChain;){
00587     printf("%d %d %d %lf \r",p,c,Tries,p/(double)Soft[s].NPart);
00588     double Leaflet = -.5*Thickness;
00589     if(c >= NLayerIn) Leaflet = .5*Thickness;
00590     //first part
00591     double Cas1 = DUE_PI*Mat->Casuale();
00592     //FIXME: this distribution is somehow not uniform
00593     Pm[p+Block[0].Asym].Pos[CLat1] = 
00594       (Soft[s].Size[0]+Leaflet)*cos(Cas1) + Soft[s].Pos[CLat1];
00595     Pm[p+Block[0].Asym].Pos[CLat2] = 
00596       (Soft[s].Size[0]+Leaflet)*sin(Cas1) + Soft[s].Pos[CLat2];
00597     Pm[p+Block[0].Asym].Pos[CNorm] = (Mat->Casuale() - .5)*Soft[s].Size[1] + Soft[s].Pos[CNorm];
00598 
00599     //others
00600     int IfContinue = 1;
00601     for(int j=1;j<Gen->NPCh;j++){
00602       int i = PutPart(j,p,HalfLim,sigma);
00603       // absorbing boundary condition
00604       double Dist = SQR(Pm[p+i].Pos[CLat1]-Soft[s].Pos[CLat1]) + SQR(Pm[p+i].Pos[CLat2]-Soft[s].Pos[CLat2]);
00605       if(arch[i] == 0)
00606    if( Dist < SQR(Soft[s].Size[0]-.5*Thickness) || Dist > SQR(Soft[s].Size[0]+.5*Thickness) ) {
00607      Tries++;
00608      IfContinue = 0;
00609      break;
00610    }
00611    else if(arch[i] == 1)
00612      if(Dist > SQR(Soft[s].Size[0]-.5*Thickness) || Dist < SQR(Soft[s].Size[0] + .5*Thickness) ){
00613        Tries++;
00614        IfContinue = 0;
00615        break;
00616      }
00617       if(CheckNano(Pm[p+i].Pos,s)){IfContinue=0;break;}
00618     }
00619     if(IfContinue){
00620       c++;
00621       p += Gen->NPCh;
00622     }
00623   }
00624 }
00625 int VarData::CheckNano(double *Pos,int s){
00626   for(int n=0;n<pNNano();n++){
00627     Point2Shape(Nano[n].Shape);
00628     double Add = .0;
00629     double Radius2 = 0.;
00630     if(VAR_IF_TYPE(Nano[n].Shape,SHAPE_BOUND)) Add = .3;
00631     if(VAR_IF_TYPE(Nano[n].Shape,SHAPE_NONE)) continue;
00632     else{
00633       Radius2 = NanoDist2(Pos,n);
00634     }
00635     // else{
00636     //   Vettore PosRel(3);
00637     //   Vettore NanoAxis(3);
00638     //   Vettore Distance(3);
00639     //   for(int d=0;d<3;d++){
00640     //   PosRel.Set(Nano[n].Pos[d] - Pos[d],d);
00641     //   NanoAxis.Set(Nano[n].Axis[d],d);
00642     //   }
00643     //   Distance.VetV(&NanoAxis,&PosRel);
00644     //   Radius2 = SQR(Distance.Norm());
00645     //   double HeiOnAxis = PosRel.ProjOnAxis(&NanoAxis);
00646     //   if( fabs(HeiOnAxis) > Nano[n].Height*.5)
00647     //   Radius2 = QUAD(Nano[n].Rad+Add);
00648     // }
00649     if(Radius2 < QUAD(Nano[n].Rad+Add)){
00650       Tries++;
00651       return 1;
00652     }
00653   }
00654   return 0;
00655 }
00656 //Obsolete
00657 void VarData::AddProtein(int NCircle,int NHeight,int nNano,char *filename){
00658   int NPart = NCircle*NHeight;
00659   PART *Pn = (PART *)calloc(NPart,sizeof(PART));
00660   double CirInv = 1./(double)NCircle;
00661   double HeiInv = Nano[nNano].Height/(double)NHeight;
00662   for(int c=0;c<NCircle;c++){
00663     double Sin = sin(c*CirInv*DUE_PI);
00664     double Cos = cos(c*CirInv*DUE_PI);
00665     double x = Nano[nNano].Rad * Cos + Nano[nNano].Pos[0];
00666     double y = Nano[nNano].Rad * Sin + Nano[nNano].Pos[1];
00667     for(int h=0;h<NHeight;h++){
00668       int p = c*NHeight + h;
00669       double z = h*HeiInv + Nano[nNano].Pos[2] - .5*Nano[nNano].Height;
00670       Pn[p].Pos[CLat1] = x;
00671       Pn[p].Pos[CLat2] = y;
00672       Pn[p].Pos[CNorm] = z;
00673     }
00674   }
00675   FILE *ReSave = fopen(filename,"a");
00676   fprintf(ReSave,"# n=1 N=%d name=PEP1\n",NPart);
00677   for(int p=0;p<NPart;p++)
00678     fprintf(ReSave,"%lf %lf %lf %lf %lf %lf %d\n",
00679        Pn[p].Pos[0],Pn[p].Pos[1],Pn[p].Pos[2],
00680        0.0,0.0,0.0,0);
00681   Nano[nNano].OffSet = (double)NCircle;
00682 }
00683 void VarData::CreateProtein(int nNano,int np){
00684   int NCircle = Nano[nNano].NCircle;
00685   int NHeight = Nano[nNano].NHeight;
00686   int NCyl = NCircle*NHeight;
00687   int NSph = (NCircle)*(NCircle/2-1) + 2;
00688   int NTot = NCyl;// + NSph;
00689   int IfDoubleSided = 0;
00690   int IfKink = 0;
00691   double AsymPhil = -.1*Nano[nNano].Rad;
00692   double CirInv = 1./(double)NCircle;
00693   double HeiInv = Nano[nNano].Height/(double)(NHeight-1);
00694   double HeiSph = Nano[nNano].Height;
00695   if(Nano[nNano].NHeight == 0 ) HeiSph + HeiInv;
00696   int pWrote = 0;
00697   double Shift = .5*sin(1*CirInv*DUE_PI);
00698   double SegSide = Nano[nNano].Height/(double)Nano[nNano].NHeight;
00699   double SegCirc = DUE_PI*Nano[nNano].Rad/(double)Nano[nNano].NCircle;
00700   // Part positions
00701   // Cylinder
00702   for(int c=0;c<NCircle;c++){
00703     for(int h=0;h<NHeight;h++){
00704       int NLink = 0;
00705       int p = c*NHeight + h;
00706       //pos current particle
00707       double Sin = sin(c*CirInv*DUE_PI);
00708       double Cos = cos(c*CirInv*DUE_PI);
00709       double Rad = Nano[nNano].Rad;
00710       double Weight = 1.;
00711       double Axes[3] = {pNanoPos(nNano,0),pNanoPos(nNano,1),pNanoPos(nNano,2)};
00712       if(IfKink){
00713    Axes[0] += .25*Nano->Height*(fabs((double)(h-NHeight/2))/(double)(NHeight));
00714    // Weight -= .1*Cos;
00715    // Weight -= .8*(1.-fabs((double)(h-NHeight/2))/(double)(NHeight));
00716       }
00717       if( ((h)%2)==0 ){
00718    Sin = sin((c+.5)*CirInv*DUE_PI);
00719    Cos = cos((c+.5)*CirInv*DUE_PI);
00720    Rad = Nano[nNano].Rad - .1;
00721       }
00722       Ln[p+np].NLink = 0;
00723       Pm[p+np].Pos[0] = Rad * Cos + Axes[0];
00724       Pm[p+np].Pos[1] = Rad * Sin + Axes[1];
00725       Pm[p+np].Pos[2] = h*HeiInv*Weight - .5*Nano[nNano].Height*Weight + Axes[2];
00726       Pm[p+np].Typ = 0;
00727       if(IfDoubleSided){
00728    if(Pm[p+np].Pos[0] < (Nano[nNano].Pos[0] + AsymPhil))
00729      Pm[p+np].Typ = 1;
00730       }
00731       if(h < 2 || h > NHeight - 3) Pm[p+np].Typ = 1;
00732       pWrote++;
00733       //-------------Connections------------------
00734       // Right
00735       int pp = (c+1)*NHeight + h;
00736       if( pp >= NCyl ) pp -= NCyl;
00737       Ln[p+np].Link[NLink++] = pp + np;
00738       pp = p + 1;
00739       if( (pp%NHeight)!=0 ) Ln[p+np].Link[NLink++] = pp + np;
00740       //Left up
00741       pp = (c-1)*NHeight + h + 1;
00742       if(c==0) pp = (NCircle-1)*NHeight + h + 1;
00743       if( ((h)%2)==0 ){
00744    pp = (c+1)*NHeight + h + 1;
00745    if(c==NCircle-1) pp = 0 + h + 1;
00746       }
00747       if( (pp%Nano[nNano].NHeight) ) Ln[p+np].Link[NLink++] = pp + np;    
00748       // Side
00749       if( h == 0 ) {
00750    pp = (c)*NHeight + NHeight - 2;
00751    //if(pp < NCyl) Ln[p+np].Link[NLink++] = pp + np;
00752    // Diagonal
00753    pp = (c+NCircle/2)*NHeight + NHeight-2;//p + NCyl/2 + NCircle - 1;
00754    if(pp > NCyl) pp = (c-NCircle/2)*NHeight + NHeight-2;
00755    //if(pp < NCyl) Ln[p+np].Link[NLink++] = pp + np;
00756       }
00757       // Disks
00758       pp = p + NCircle/2*NHeight;
00759       //if(pp < NCyl-1) Ln[p+np].Link[NLink++] = pp + np;
00760       Ln[p+np].NLink = NLink;
00761     }
00762   }
00763   Vettore Axis(0.,0.,1.);
00764   Vettore Axis1(Nano[nNano].Axis[0],Nano[nNano].Axis[1],Nano[nNano].Axis[2]);
00765   Vettore Axis2(3);
00766   Axis2 = Axis1 + Axis;
00767   for(int d=0;d<3;d++){
00768     Axis2.Set(Axis1.Val(d)+Axis.Val(d),d);
00769   }
00770   Vettore Origin(Nano[nNano].Pos[0],Nano[nNano].Pos[1],Nano[nNano].Pos[2]);
00771   int b = nNano + NSoft;
00772   RotateBlock(&Axis2,&Origin,b);
00773   char Filename[60];
00774   sprintf(Filename,"Architecture%d.dat",nNano);
00775   FILE *CSave = fopen(Filename,"w");
00776   fprintf(CSave,"# Cylinder\n");
00777   //write the initial mutual distances
00778   for(int p=np;p<NTot+np;p++){
00779     for(int l=0;l<Ln[p].NLink;l++){
00780       int l2 = Ln[p].Link[l];
00781       double Dist = sqrt( SQR(Pm[p].Pos[0]-Pm[l2].Pos[0]) + SQR(Pm[p].Pos[1]-Pm[l2].Pos[1]) + SQR(Pm[p].Pos[2]-Pm[l2].Pos[2]) );
00782       double kSpr = 10000.;
00783       if(Dist > 2.) kSpr = 10000.;
00784       if(Dist > 4.) kSpr = 10000.;
00785       fprintf(CSave,"%d %d %lf %.0f\n",p-np,l2-np,Dist,kSpr);
00786     }
00787   }
00788   fclose(CSave);return;
00789   // FIXME: the links are not closing at the boundaries
00790   // Cupola
00791   fprintf(CSave,"# Cupola\n");
00792   int PType = 2;
00793   int NCircHalf = NCircle/2;
00794   // Vertical
00795   for(int cc=1;cc<NCircHalf-1;cc++){
00796     double Sin2 = sin(cc*CirInv*DUE_PI);
00797     double Cos2 = cos(cc*CirInv*DUE_PI);
00798     // Horizontal
00799     for(int c=0;c<NCircle;c++){
00800       double Sin = sin(c*CirInv*DUE_PI);
00801       double Cos = cos(c*CirInv*DUE_PI);
00802       if( (cc%2)==0 ){
00803    Sin = sin((c+.5)*CirInv*DUE_PI);
00804    Cos = cos((c+.5)*CirInv*DUE_PI);
00805       }
00806       double x = Nano[nNano].Rad * Cos * Sin2 + Nano[nNano].Pos[0];
00807       double y = Nano[nNano].Rad * Sin * Sin2 + Nano[nNano].Pos[1];
00808       double Quota = Nano[nNano].Height*.5;
00809       if(cc > NCircle/4) Quota = - Nano[nNano].Height*.5;
00810       double z = Nano[nNano].Rad * Cos2 + Nano[nNano].Pos[2] + Quota;
00811       pWrote++;
00812       //fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",x,y,z,0.,0.,0.,PType);
00813       // Connections
00814       double Dx = x - Nano[nNano].Rad*cos((c+1)*CirInv*DUE_PI)*Sin2 - Nano[nNano].Pos[0];
00815       double Dy = y - Nano[nNano].Rad*sin((c+1)*CirInv*DUE_PI)*Sin2 - Nano[nNano].Pos[1];
00816       double Elong = sqrt(SQR(Dx)+SQR(Dy));
00817       int p = NCyl + c + cc*NCircle;
00818       int pp = NCyl + (c+1) + cc*NCircle;
00819       if( c+1==NCircle ) pp = NCyl + (0) + cc*NCircle;
00820       if(c != 0 && c != NCircle-1) fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00821       if( cc != NCircle/2-1 && cc != NCircle/4){
00822    pp = NCyl + (c+1) + (cc+1)*NCircle;
00823    Elong = sqrt( SQR(Nano[nNano].Rad*1.*CirInv*DUE_PI) + SQR(.5*Elong));
00824    fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00825    pp = NCyl + (c) + (cc-1)*NCircle;
00826    if( (cc%2)==0 )
00827      pp = NCyl + (c+1) + (cc)*NCircle;
00828    fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00829       }
00830     }
00831   }
00832   // Closing the extrema
00833   fprintf(CSave,"# Extrema\n");
00834   {
00835     double x = Nano[nNano].Pos[0];
00836     double y = Nano[nNano].Pos[1];
00837     double z = Nano[nNano].Pos[2] - HeiSph*.5 - Nano[nNano].Rad;
00838     pWrote++;
00839     //fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",x,y,z,0.,0.,0.,PType);
00840     z = Nano[nNano].Pos[2] + HeiSph*.5 + Nano[nNano].Rad;
00841     pWrote++;
00842     //fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",x,y,z,0.,0.,0.,PType);
00843     {
00844       int p = pWrote - 1;
00845       int pp = pWrote - 2;
00846       double Elong = Nano[nNano].Height + 2.*Nano[nNano].Rad;
00847       fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00848     }
00849     for(int c=0;c<NCircle;c++){
00850       int p = pWrote-2;
00851       int pp = c + NCyl + NCircle*(NCircle/2-2);
00852       double Elong = Nano[nNano].Rad * 1.*CirInv*DUE_PI;
00853       fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00854       p = pWrote-1;
00855       pp = c + NCyl;
00856       fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00857       // Conntecting to the cylinder
00858       p = c*NHeight;
00859       pp = c + NCyl + NCircle*(NCircle/4);
00860       Elong = HeiInv;//Actually it is a bit more
00861       fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00862       p = c*(NHeight) + NHeight - 1;
00863       pp = c + NCyl + NCircle*(NCircle/4-1);
00864       fprintf(CSave,"%d %d %lf\n",p,pp,Elong);
00865     }
00866   }
00867   fclose(CSave);
00868   //fclose(PSave);
00869 }
00870 void VarData::AddStuffing(char *filename,int NWater,int nNano){
00871   if(NWater == 0) return;
00872   FILE *PSave = fopen(filename,"a");
00873   fprintf(PSave,"# n=%d N=10 name=STUFFING\n",NWater/10);
00874   for(int p=0;p<NWater;p++){
00875     double Angle = Mat->Casuale()*DUE_PI;
00876     double Rad = 2.*(Mat->Casuale()-.5)*Nano[nNano].Rad;
00877     double x = cos(Angle)*Rad + Nano[nNano].Pos[0];
00878     double y = sin(Angle)*Rad + Nano[nNano].Pos[1];
00879     double z = (Mat->Casuale()-.5)*Nano[nNano].Height + Nano[nNano].Pos[2];
00880     fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",x,y,z,0.,0.,0.,1);
00881   }
00882   fclose(PSave);
00883 }
00884 void VarData::AddSolvent(char *filename,int NWater){
00885   if(NSolvent <= 0) return;
00886   FILE *PSave = fopen(filename,"a");
00887   double sigma = 1./sqrt(pkSpr());
00888   fprintf(PSave,"# n=%d N=1 name=SOLVENT\n",NWater);
00889   for(int p=0;p<NWater;p++){
00890     double x = Mat->Casuale()*Gen->Edge[CLat1];
00891     double y = Mat->Casuale()*Gen->Edge[CLat2];
00892     double z = Mat->Casuale()*Gen->Edge[CNorm]*.3;
00893     fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",x,y,z,Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),2);
00894   }
00895   fclose(PSave);
00896 }
00897 void VarData::AddChains(char *filename,double Thickness){
00898   if(NAddChain <= 0) return;
00899   double sigma = 1./sqrt(pkSpr());
00900   PART *Pn = (PART *)calloc(Gen->NPCh,sizeof(PART));
00901   FILE *PSave = fopen(filename,"a");
00902   int NPCh = (int)(.5*pNPCh());
00903   fprintf(PSave,"# n=%d N=%d name=ADDED\n",NAddChain,NPCh);
00904   int s = 0;
00905   for(int c=0;c<NAddChain;){
00906     Pn[0].Pos[CLat1] = Mat->Casuale()*Gen->Edge[CLat1];
00907     Pn[0].Pos[CLat2] = Mat->Casuale()*Gen->Edge[CLat2];
00908     Pn[0].Pos[CNorm] = .2*(Mat->Casuale()-.5)*Thickness + Soft[s].Pos[CNorm];
00909     int IfContinue = !CheckNano(Pn[0].Pos,s);
00910     for(int i=1;i<NPCh;i++){
00911       for(int d=0;d<3;d++)
00912    Pn[i].Pos[d] = Pn[i-1].Pos[d]+Mat->Gaussiano(0.,sigma);
00913       if(Pn[i].Pos[CNorm] > Soft[s].Pos[CNorm]+.5*Thickness ||
00914     Pn[i].Pos[CNorm] < Soft[s].Pos[CNorm]-.5*Thickness ){
00915    Tries++;
00916    IfContinue = 0;
00917    break;
00918       }
00919       //if(CheckNano(Pn[i].Pos,0)){IfContinue=0;break;}
00920     }
00921     if(IfContinue){
00922       for(int i=0;i<NPCh;i++){
00923    fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",Pn[i].Pos[0],Pn[i].Pos[1],Pn[i].Pos[2],Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),0);
00924       }
00925       c++;
00926       s++;if(s==NSoft)s=0;
00927     }
00928   }
00929   fclose(PSave);
00930   free(Pn);
00931 }
00932 void VarData::AddCholesterol(char *filename,double Thickness,int s){
00933   if(NAddChol <= 0) return;
00934   double sigma = 1./sqrt(pkSpr());
00935   int HalfLim = (int)(Block[0].Asym*.5);
00936   int NPCh = 5;
00937   int DLim = NPCh-1;
00938   PART *Pn = (PART *)calloc(Gen->NPCh,sizeof(PART));
00939   FILE *PSave = fopen(filename,"a");
00940   fprintf(PSave,"# n=%d N=%d name=CHOL%d\n",NAddChol,NPCh,s);
00941   for(int c=0;c<NAddChol;){
00942     printf("%d %d %lf \r",c,Tries,c/(double)(NAddChol));
00943     double Leaflet = -.5*Thickness;
00944     if(c >= NAddChol/2) Leaflet = +.5*Thickness;
00945     //first part
00946     double Cas1 = Mat->Casuale(),Cas2 = Mat->Casuale();
00947     Pn[DLim].Pos[CLat1] = Cas1*Gen->Edge[CLat1];
00948     Pn[DLim].Pos[CLat2] = Cas2*Gen->Edge[CLat2];
00949     Pn[DLim].Pos[CNorm] = Soft[s].Pos[CNorm]+Leaflet;
00950     Pn[DLim].Typ = 1;
00951     int IfContinue = !CheckNano(Pn[DLim].Pos,s);
00952     //others
00953     for(int j=DLim-1;j>=0;j--){
00954       Pn[j].Typ = 0;
00955       for(int d=0;d<3;d++)
00956    Pn[j].Pos[d] = Pn[j+1].Pos[d]+Mat->Gaussiano(0.,sigma);
00957       if(Pn[j].Pos[CNorm] > Soft[s].Pos[CNorm]+.5*Thickness ||
00958     Pn[j].Pos[CNorm] < Soft[s].Pos[CNorm]-.5*Thickness ){
00959    Tries++;
00960    IfContinue = 0;
00961    break;
00962       }
00963       if(CheckNano(Pn[j].Pos,s)){IfContinue=0;break;}
00964     }
00965     if(IfContinue){
00966       for(int i=0;i<NPCh;i++){
00967    fprintf(PSave,"%lf %lf %lf %lf %lf %lf %d\n",Pn[i].Pos[0],Pn[i].Pos[1],Pn[i].Pos[2],Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),Mat->Gaussiano(0.,sigma),Pn[i].Typ);
00968       }
00969       c++;
00970     }
00971   }
00972   fclose(PSave);
00973 }
00974 #include <Cubo.h>
00975 typedef DdLinkedList Cubo;
00976 void VarData::FindNeighbours(char *FileName){
00977   double CutOff = 1.0;
00978   double Edge[3] = {pEdge(0),pEdge(1),pEdge(2)};
00979   int NeiList[27];
00980   int NPair = (int)(pNChain()/10.);
00981   int NChOffSet = 0;
00982   int bInner = 0;
00983   for(int b=0,NCh=0;b<pNBlock();NCh+=Block[b++].NChain){
00984     if(strcmp(Block[b].Name,"INNER0")) continue;
00985     NChOffSet = NCh;
00986     bInner = b;
00987   }
00988   int NChain = 0;
00989   for(int b=0;b<pNBlock();b++){
00990     NChain += Block[b].NChain;
00991   }
00992   SetNChain(NChain);
00993   for(int c=0;c<pNChain();c++){
00994     for(int d=0;d<3;d++){
00995       Ch[c].Pos[d] = Pm[c*pNPCh()+pNPCh()-1].Pos[d];
00996     }
00997     // for(int p=c*pNPCh();p<(c+1)*pNPCh();p++){
00998     //   for(int d=0;d<3;d++){
00999     //   Ch[c].Pos[d] += Pm[p].Pos[d];
01000     //   }
01001     // }
01002     // for(int d=0;d<3;d++){
01003     //   Ch[c].Pos[d] /= (double)pNPCh();
01004     // }
01005   }
01006   double *cPair = (double *)calloc(3*pNChain(),sizeof(double));
01007   for(int c=0;c<pNChain();c++){
01008     cPair[c*3+0] = c;
01009     cPair[c*3+1] = c;
01010     cPair[c*3+2] = 1000.;
01011   }
01012   Cubo *Pc = new Cubo(Edge,pNChain(),CutOff);
01013   for(int c=0;c<pNChain();c++){
01014     int p = c*pNPCh()+pNPCh()-1;
01015     //Pc->AddPart(c,Pm[p].Pos);
01016     Pc->AddPart(c,Ch[c].Pos);
01017   }
01018   FILE *FWrite = fopen(FileName,"w");
01019   for(int c=NChOffSet;c<NChOffSet+Block[bInner].NChain-1;c++){
01020     cPair[c*3+0] = (double)c;
01021     int p1 = c*pNPCh(bInner)+pNPCh(bInner)-1;
01022     double MinDist = 1000.;
01023     int NNei = Pc->GetNei(Pm[p1].Pos,NeiList);
01024     for(int i=0;i<NNei;i++){
01025       int c1 = NeiList[i];
01026       for(Pc->SetCounters(c1);Pc->IfItCell(c1);Pc->IncrCurr(c1)){
01027    int c2 = Pc->ItCell(c1);
01028    if(c2 <= c) continue;
01029    int p2 = c2*pNPCh(bInner)+pNPCh(bInner)-1;
01030    double Dist2 = 0.;
01031    for(int d=0;d<3;d++){
01032      Dist2 += SQR(Ch[c].Pos[d] - Ch[c2].Pos[d]);
01033      //Dist2 += SQR(Pm[p1].Pos[d] - Pm[p2].Pos[2]);
01034    }
01035    if(MinDist > Dist2){
01036      MinDist = Dist2;
01037      cPair[c*3+1] = (double)c2;
01038      cPair[c*3+2] = MinDist;
01039    }
01040       }
01041     }
01042   }
01043   double Temp[3];
01044   for(int c=1;c<pNChain();c++){
01045     for(int c1=c;c1>=0;c1--){
01046       if(cPair[c1*3+2] >= cPair[(c1-1)*3+2]) break;
01047       for(int d=0;d<3;d++){
01048          Temp[d] = cPair[c1*3+d];
01049          cPair[c1*3+d] = cPair[(c1-1)*3+d];
01050          cPair[(c1-1)*3+d] = Temp[d];
01051       }
01052       // Mat->Swap(cPair,c1*3+2,cPair,(c1-1)*3+2,3);
01053       //printf("%d) %d %lf %lf\n",c,c1,cPair[(c1)*3+2],cPair[(c1-1)*3+2]);
01054     }
01055   }
01056   int pRef = 0;//NChOffSet*pNPCh(bInner);
01057   double KEl = 1.;
01058   for(int c=0;c<NPair;c++){
01059     int p1 = (int)cPair[c*3+0]*pNPCh(bInner)+pNPCh(bInner)-1;
01060     int p2 = (int)cPair[c*3+1]*pNPCh(bInner)+pNPCh(bInner)-1;
01061     double Dist = 0.;
01062     for(int d=0;d<3;d++){
01063       Dist += SQR(Ch[(int)cPair[c*3+0]].Pos[d] - Ch[(int)cPair[c*3+1]].Pos[d]);
01064       //Dist += SQR(Pm[p1].Pos[d] - Pm[p2].Pos[d]);
01065     }
01066     Dist = sqrt(Dist);
01067     //Dist = 0.;
01068     fprintf(FWrite,"%d %d %lf %lf\n",p1-pRef,p2-pRef,Dist,KEl);
01069   }
01070   fclose(FWrite);
01071 }