00001 #include <iostream.h>
00002 #include "lattice.h"
00003
00011 ClassImp(Atom);
00012
00013 Atom::Atom(Double_t x, Double_t y, Int_t i, Lattice *lat)
00014 : TMarker(x, y, kFullSquare)
00015 {
00016 index = i;
00017 pLattice = lat;
00018 SetMarkerColor(kWhite);
00019 SetMarkerStyle(pLattice->atomShape);
00020 SetMarkerSize(pLattice->atomSize);
00021 bDefect = kFALSE;
00022 bBorderAtom = kFALSE;
00023 bCornerAtom = kFALSE;
00024 bLink = kTRUE;
00025 pos = kAtomCenter;
00026 type = 0;
00027 }
00028
00029 Atom::~Atom()
00030 {
00031 }
00032
00034 void Atom::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00035 {
00036 if (!gPad->IsEditable()) return;
00037
00038 switch (event) {
00039 case kButton1Down:
00040 case kButton1Up:
00041 if (bDefect == kFALSE) return;
00042 case kMouseMotion:
00043 gPad->SetCursor(kPointer);
00044 break;
00045 default:
00046 TMarker::ExecuteEvent(event, px, py);
00047 }
00048 }
00049
00050 void Atom::InsertDefect()
00051 {
00052 TThread::Lock();
00053 SetMarkerStyle(pLattice->defectShape);
00054 SetMarkerSize(pLattice->defectSize);
00055 SetMarkerColor(pLattice->defectColor);
00056 bDefect = kTRUE;
00057 if ((pLattice->defects->IndexOf(this) == -1) && bLink) {
00058 pLattice->defects->AddAtFree(this);
00059 pLattice->defArrayCount++;
00060 }
00061 pLattice->defCount++;
00062
00063 if (bLink && bBorderAtom) {
00064 linkedAtom->SetLink(kFALSE);
00065 linkedAtom->InsertDefect();
00066 }
00067 else if (bLink && bCornerAtom) {
00068 linkedAtoms[0]->SetLink(kFALSE);
00069 linkedAtoms[0]->InsertDefect();
00070 linkedAtoms[1]->SetLink(kFALSE);
00071 linkedAtoms[1]->InsertDefect();
00072 linkedAtoms[2]->SetLink(kFALSE);
00073 linkedAtoms[2]->InsertDefect();
00074 }
00075
00076 if (pLattice->bInfo)
00077 pLattice->pLayer->GetMainFrame()->SetInfoDefects(pLattice->GetNUniqueDefects());
00078
00079 bLink = kTRUE;
00080 TThread::UnLock();
00081 }
00082
00083 void Atom::CompPartEnergy()
00084 {
00085 cout << pLattice->pLayer->CompPartEnergy(this) << endl;
00086 }
00087
00088 void Atom::RemoveDefect()
00089 {
00090 TThread::Lock();
00091 SetMarkerStyle(pLattice->atomShape);
00092 SetMarkerSize(pLattice->atomSize);
00093 SetMarkerColor(pLattice->atomColor);
00094 bDefect = kFALSE;
00095 if (pLattice->defects->Remove(this))
00096 pLattice->defArrayCount--;
00097 pLattice->defCount--;
00098
00099 if (bLink && bBorderAtom) {
00100 linkedAtom->SetLink(kFALSE);
00101 linkedAtom->RemoveDefect();
00102 }
00103 else if (bLink && bCornerAtom){
00104 linkedAtoms[0]->SetLink(kFALSE);
00105 linkedAtoms[0]->RemoveDefect();
00106 linkedAtoms[1]->SetLink(kFALSE);
00107 linkedAtoms[1]->RemoveDefect();
00108 linkedAtoms[2]->SetLink(kFALSE);
00109 linkedAtoms[2]->RemoveDefect();
00110 }
00111
00112 if (pLattice->bInfo)
00113 pLattice->pLayer->GetMainFrame()->SetInfoDefects(pLattice->GetNUniqueDefects());
00114
00115 bLink = kTRUE;
00116
00117 pLattice->defects->Compress();
00118
00119 TThread::UnLock();
00120 }
00121
00122
00123 Lattice::Lattice()
00124 {
00125 Nx = Ny = N = Nu = defCount = defArrayCount = 0;
00126 c = 0;
00127 pLayer = 0;
00128 atoms = 0;
00129 defects = 0;
00130 atomShape = defectShape = 0;
00131 atomSize = defectSize = 0;
00132 atomColor = defectColor = 0;
00133 bInfo = kTRUE;
00134
00135 srand((UInt_t)time(NULL));
00136 }
00137
00138 Lattice::Lattice(Layer *pLayer, Int_t Nx, Int_t Ny, Double_t c)
00139 {
00140 Configuration *config = pLayer->GetConfig();
00141
00142 this->pLayer = pLayer;
00143 this->Nx = Nx;
00144 this->Ny = Ny;
00145 this->c = c;
00146 atoms = 0;
00147 defects = 0;
00148 Nu = defCount = defArrayCount = 0;
00149 atomShape = config->GetAtomShape();
00150 atomSize = config->GetAtomSize();
00151 atomColor = config->GetAtomColor();
00152 defectShape = config->GetDefectShape();
00153 defectSize = config->GetDefectSize();
00154 defectColor = config->GetDefectColor();
00155 bInfo = kTRUE;
00156
00157 srand((UInt_t)time(NULL));
00158 }
00159
00160 Lattice::~Lattice()
00161 {
00162 if (defects) delete defects;
00163
00164 if (atoms) {
00165 for (Int_t i = 0; i < N; i++)
00166 delete atoms[i];
00167 delete [] atoms;
00168 }
00169 }
00170
00171 void Lattice::SetBorderMode(Atom* atom, Atom* a, UChar_t p)
00172 {
00173 atom->bBorderAtom = kTRUE;
00174 atom->linkedAtom = a;
00175 atom->pos = p;
00176 }
00177
00178 void Lattice::SetCornerMode(Atom* atom, Atom* a0, Atom* a1, Atom* a2, UChar_t p)
00179 {
00180 atom->bCornerAtom = kTRUE;
00181 atom->linkedAtoms[0] = a0;
00182 atom->linkedAtoms[1] = a1;
00183 atom->linkedAtoms[2] = a2;
00184 atom->pos = p;
00185 }
00186
00187
00188 void Lattice::ShowLattice()
00189 {
00190 pLayer->cd();
00191
00192 for (Int_t i = 0; i < N; i++)
00193 atoms[i]->SetMarkerColor(kBlack);
00194 }
00195
00196 void Lattice::SetAtomStyle(Style_t style, Size_t size, Color_t color)
00197 {
00198 pLayer->cd();
00199
00200 atomShape = style;
00201 atomSize = size;
00202 atomColor = color;
00203
00204 for (Int_t i = 0; i < N; i++) {
00205 atoms[i]->SetMarkerStyle(style);
00206 atoms[i]->SetMarkerSize(size);
00207 atoms[i]->SetMarkerColor(color);
00208 }
00209
00210 gPad->Modified();
00211 gPad->Update();
00212 }
00213
00214 void Lattice::SetDefectStyle(Style_t style, Size_t size, Color_t color)
00215 {
00216 Int_t i;
00217 Int_t m = defects->GetLast()+1;
00218
00219 pLayer->cd();
00220
00221 defectShape = style;
00222 defectSize = size;
00223 defectColor = color;
00224
00225 for (i = 0; i < m; i++) {
00226 ((Atom*)(*defects)[i])->SetMarkerStyle(style);
00227 ((Atom*)(*defects)[i])->SetMarkerSize(size);
00228 ((Atom*)(*defects)[i])->SetMarkerColor(color);
00229 }
00230
00231 gPad->Modified();
00232 gPad->Update();
00233 }
00234
00235 void Lattice::RndInsertDefect()
00236 {
00237 Int_t rnd;
00238
00239 if (defCount == N) return;
00240
00241 rnd = (Int_t)(((Double_t)(N))*rand()/(RAND_MAX+1.0));
00242 while (atoms[rnd]->bDefect)
00243 rnd = (Int_t)(((Double_t)(N))*rand()/(RAND_MAX+1.0));
00244
00245 atoms[rnd]->InsertDefect();
00246 }
00247
00248 void Lattice::RndRemoveDefect()
00249 {
00250 Int_t rnd;
00251
00252 if (defCount <= 0) return;
00253
00254 rnd = (Int_t)(((Double_t)(defects->GetLast()+1))*rand()/(RAND_MAX+1.0));
00255 ((Atom*)(*defects)[rnd])->RemoveDefect();
00256 }
00257
00258 void Lattice::RemoveAllDefects()
00259 {
00260 Int_t count = defects->GetLast()+1;
00261
00262 for (Int_t i = 0; i < count; i++)
00263 ((Atom*)(*defects)[0])->RemoveDefect();
00264
00265 pLayer->Modified();
00266 pLayer->Update();
00267 }
00268
00269 SquareLattice::SquareLattice(Layer *pLayer, Int_t Nx, Int_t Ny, Double_t c)
00270 : Lattice(pLayer, Nx, Ny, c)
00271 {
00272 N = (Nx+1)*(Ny+1);
00273 Nu = N - ((Nx-1)+(Ny-1)+3);
00274 pLayer->Range(0, 0, Nx*c, Ny*c);
00275 CreateLattice();
00276 ShowLattice();
00277 }
00278
00279 SquareLattice::~SquareLattice()
00280 {
00281 }
00282
00283 void SquareLattice::CreateLattice()
00284 {
00285 Int_t i, j, index;
00286 Atom *a0, *a1, *a2, *a3;
00287
00288 atoms = new (Atom*)[N];
00289 defects = new TObjArray(N/2);
00290
00291 for (i = 0; i <= Ny; i++)
00292 for (j = 0; j <= Nx; j++) {
00293 index = i*(Nx+1)+j;
00294 atoms[index] = new Atom(j*c, i*c, index, this);
00295 atoms[index]->Draw();
00296 }
00297
00298
00299 a0 = atoms[0];
00300 a1 = atoms[Nx];
00301 a2 = atoms[Ny*(Nx+1)];
00302 a3 = atoms[N-1];
00303 SetCornerMode(a0, a1, a2, a3, kAtomBottom | kAtomLeft);
00304 SetCornerMode(a1, a0, a2, a3, kAtomBottom | kAtomRight);
00305 SetCornerMode(a2, a0, a1, a3, kAtomTop | kAtomLeft);
00306 SetCornerMode(a3, a0, a1, a2, kAtomTop | kAtomRight);
00307
00308
00309 for (i = 1; i < Nx; i++) {
00310 SetBorderMode(atoms[i], atoms[(N-1)-(Nx-i)], kAtomBottom);
00311 SetBorderMode(atoms[(N-1)-(Nx-i)], atoms[i], kAtomTop);
00312 }
00313 for (j = Nx+1; j < Ny*(Nx+1); j += Nx+1) {
00314 SetBorderMode(atoms[j], atoms[j+Nx], kAtomLeft);
00315 SetBorderMode(atoms[j+Nx], atoms[j], kAtomRight);
00316 }
00317 }
00318
00319 Atom* SquareLattice::GetAtomNeighbor(Atom* atom)
00320 {
00321 UChar_t pos;
00322 Int_t rnd, index;
00323 Bool_t rn, an, ln, bn;
00324 Atom* neighbor;
00325
00326 rn = an = ln = bn = kFALSE;
00327
00328 index = GetAtomIndex(atom);
00329 pos = GetAtomPos(atom);
00330
00331 while (!(rn && an && ln && bn)) {
00332 rnd = (Int_t)(((Double_t)(4))*rand()/(RAND_MAX+1.0));
00333 switch (rnd) {
00334 case 0:
00335 if (pos & kAtomRight)
00336 neighbor = atoms[index - (Nx-1)];
00337 else
00338 neighbor = atoms[index + 1];
00339 if (!neighbor->IsDefect()) return neighbor;
00340 else rn = kTRUE;
00341 break;
00342 case 1:
00343 if (pos & kAtomTop)
00344 neighbor = atoms[index - (N-Nx-1)];
00345 else
00346 neighbor = atoms[index + (Nx+1)];
00347 if (!neighbor->IsDefect()) return neighbor;
00348 else an = kTRUE;
00349 break;
00350 case 2:
00351 if (pos & kAtomLeft)
00352 neighbor = atoms[index + (Nx-1)];
00353 else
00354 neighbor = atoms[index - 1];
00355 if (!neighbor->IsDefect()) return neighbor;
00356 else ln = kTRUE;
00357 break;
00358 case 3:
00359 if (pos & kAtomBottom)
00360 neighbor = atoms[index + (N-Nx-1)];
00361 else
00362 neighbor = atoms[index - (Nx+1)];
00363 if (!neighbor->IsDefect()) return neighbor;
00364 else bn = kTRUE;
00365 break;
00366 }
00367 }
00368
00369 return NULL;
00370 }
00371
00372
00373 HexLattice::HexLattice(Layer *pLayer, Int_t Nx, Int_t Ny, Double_t c)
00374 : Lattice(pLayer, Nx, Ny, c)
00375 {
00376 N = 2*Nx + 4*Nx*Ny + Ny;
00377 Nu = N - (2*Nx + Ny);
00378 pLayer->Range(0,0, 3*c*Nx, sqrt(3)*c*Ny);
00379 CreateLattice();
00380 ShowLattice();
00381 }
00382
00383 HexLattice::~HexLattice()
00384 {
00385 }
00386
00387 void HexLattice::CreateLattice()
00388 {
00389 Int_t i, j, index;
00390 Double_t x, y;
00391 Double_t dy;
00392
00393 dy = sqrt(3)/2 * c;
00394
00395 atoms = new (Atom*)[N];
00396 defects = new TObjArray(N/2);
00397
00398
00399 y = 0;
00400 for (i = 0; i < Nx; i++) {
00401 x = 3*c*i + c/2;
00402 atoms[2*i] = new Atom(x, y, 2*i, this);
00403 SetAtomType(atoms[2*i], kAtomRight);
00404 x += c;
00405 atoms[2*i+1] = new Atom(x, y, 2*i+1, this);
00406 SetAtomType(atoms[2*i+1], kAtomLeft);
00407 }
00408
00409
00410 for (j = 0; j < Ny; j++) {
00411 x = 0;
00412 y = 2*dy*j + dy;
00413 index = (4*Nx+1)*j + 2*Nx;
00414 atoms[index] = new Atom(x, y, index, this);
00415 SetAtomType(atoms[index], kAtomLeft | kAtomCenter);
00416 for (i = 0; i < Nx; i++) {
00417 x = 3*c*i + 2*c;
00418 atoms[index+2*i+1] = new Atom(x, y, index+2*i+1, this);
00419 SetAtomType(atoms[index+2*i+1], kAtomRight | kAtomCenter);
00420 x += c;
00421 atoms[index+2*i+2] = new Atom(x, y, index+2*i+2, this);
00422 SetAtomType(atoms[index+2*i+2], kAtomLeft | kAtomCenter);
00423 }
00424 y = 2*dy*j + 2*dy;
00425 for (i = 0; i < Nx; i++) {
00426 x = 3*c*i + c/2;
00427 index = (4*Nx+1)*(j+1)+2*i;
00428 atoms[index] = new Atom(x, y, index, this);
00429 SetAtomType(atoms[index], kAtomRight);
00430 x += c;
00431 atoms[index+1] = new Atom(x, y, index+1, this);
00432 SetAtomType(atoms[index+1], kAtomLeft);
00433 }
00434 }
00435
00436
00437 for (i = 0; i < Nx; i++) {
00438 SetBorderMode(atoms[2*i], atoms[N-2*Nx+2*i], kAtomBottom);
00439 SetBorderMode(atoms[N-2*Nx+2*i], atoms[2*i], kAtomTop);
00440 SetBorderMode(atoms[2*i+1], atoms[N-2*Nx+2*i+1], kAtomBottom);
00441 SetBorderMode(atoms[N-2*Nx+2*i+1], atoms[2*i+1], kAtomTop);
00442 }
00443
00444 for (j = 0; j < Ny; j++) {
00445 SetBorderMode(atoms[2*Nx+(4*Nx+1)*j], atoms[4*Nx+(4*Nx+1)*j], kAtomLeft);
00446 SetBorderMode(atoms[4*Nx+(4*Nx+1)*j], atoms[2*Nx+(4*Nx+1)*j], kAtomRight);
00447 }
00448
00449 for (i = 0; i < N; i++)
00450 atoms[i]->Draw();
00451 }
00452
00453 Atom* HexLattice::GetAtomNeighbor(Atom* atom)
00454 {
00455 UChar_t pos, type;
00456 Int_t rnd, index;
00457 Bool_t a, b, s;
00458 Atom* neighbor;
00459
00460 a = b = s = kFALSE;
00461
00462 index = GetAtomIndex(atom);
00463 pos = GetAtomPos(atom);
00464 type = GetAtomType(atom);
00465
00466 while (!(a && b && s)) {
00467 rnd = (Int_t)(((Double_t)(3))*rand()/(RAND_MAX+1.0));
00468 switch (rnd) {
00469 case 0:
00470 if (pos & kAtomRight)
00471 neighbor = atoms[index - 1];
00472 else if (pos & kAtomLeft)
00473 neighbor = atoms[index + 2*Nx - 1];
00474 else if (type & kAtomRight)
00475 neighbor = atoms[index + 1];
00476 else
00477 neighbor = atoms[index - 1];
00478
00479 if (!neighbor->IsDefect()) return neighbor;
00480 else s = kTRUE;
00481 break;
00482 case 1:
00483 if (pos & kAtomTop)
00484 neighbor = atoms[index - (N - 4*Nx)];
00485 else if (type & kAtomCenter)
00486 neighbor = atoms[index + (2*Nx+1)];
00487 else
00488 neighbor = atoms[index + 2*Nx];
00489
00490 if (!neighbor->IsDefect()) return neighbor;
00491 else a = kTRUE;
00492 break;
00493 case 2:
00494 if (pos & kAtomBottom)
00495 neighbor = atoms[index + (N-4*Nx-1)];
00496 else if (type & kAtomCenter)
00497 neighbor = atoms[index - 2*Nx];
00498 else
00499 neighbor = atoms[index - (2*Nx+1)];
00500
00501 if (!neighbor->IsDefect()) return neighbor;
00502 else b = kTRUE;
00503 break;
00504 }
00505 }
00506
00507 return NULL;
00508 }