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