MFMv2.0.10
Movable Feast Machine Simulator 2.0.10
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AbstractElement_Xtal.h
Go to the documentation of this file.
1 /* -*- mode:C++ -*-
2  AbstractElement_Xtal.h Common attributes of simple Xtal forms
3  Copyright (C) 2014 The Regents of the University of New Mexico. All rights reserved.
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
27 #ifndef ABSTRACTELEMENT_XTAL_H
28 #define ABSTRACTELEMENT_XTAL_H
29 
30 #include "Element.h"
31 #include "EventWindow.h"
32 #include "ElementTable.h"
33 #include "itype.h"
34 #include "P3Atom.h"
35 #include "Element_Res.h"
36 
37 namespace MFM
38 {
39  template <class CC>
40  class AbstractElement_Xtal : public Element<CC>
41  {
42  public:
43 
44  // Extract short names for parameter types
45  typedef typename CC::ATOM_TYPE T;
46  typedef typename CC::PARAM_CONFIG P;
47  enum {
48  R = P::EVENT_WINDOW_RADIUS,
49  SITES = EVENT_WINDOW_SITES(R),
50  BITS = P::BITS_PER_ATOM,
51 
53  // Element state fields
54 
55  XTAL_FIRST_FREE_POS = P3Atom<P>::P3_STATE_BITS_POS
56 
57  };
58 
60 
61  static u32 GetIndex(const SPoint coord)
62  {
63  const MDist<R> & md = MDist<R>::get();
64  s32 idx = md.FromPoint(coord, R);
65  if (idx < 0)
66  {
67  FAIL(ARRAY_INDEX_OUT_OF_BOUNDS);
68  }
69  return (u32) idx;
70  }
71 
72  static bool ReadBit(const XtalSites & sites, const SPoint coord)
73  {
74  return sites.ReadBit(GetIndex(coord));
75  }
76 
77  static void WriteBit(XtalSites & sites, const SPoint coord, bool val)
78  {
79  sites.WriteBit(GetIndex(coord), val);
80  }
81 
82  virtual void GetSites(T & atom, XtalSites & xites, EventWindow<CC>& window) const = 0;
83 
92  virtual bool IsSameXtal(T & self, const T & otherAtom, EventWindow<CC>& window) const
93  {
94  return true;
95  }
96 
97  virtual u32 GetSymI(T &atom, EventWindow<CC>& window) const = 0;
98 
99  AbstractElement_Xtal(const UUID & uuid) : Element<CC>(uuid)
100  {
101  }
102 
106  virtual u32 Diffusability(EventWindow<CC> & ew, SPoint nowAt, SPoint maybeAt) const
107  {
108  return this->NoDiffusability(ew, nowAt, maybeAt);
109  }
110 
111  virtual u32 PercentMovable(const T& you, const T& me, const SPoint& offset) const
112  {
113  return 0;
114  }
115 
116  bool IsAbstractXtalType(EventWindow<CC>& window, u32 type) const
117  {
118  const Element<CC> * elt = window.GetTile().GetElement(type);
119  return dynamic_cast<const AbstractElement_Xtal<CC>*>(elt) != 0;
120  }
121 
122  struct SiteSampler {
123  Random & random;
124  u32 count;
125  SPoint sampleSite;
126  T sampleSiteContents;
127  SiteSampler(Random & rand) : random(rand), count(0) { }
128  void Sample(const SPoint & place, const T & content) {
129  if (random.OneIn(++count))
130  {
131  sampleSite = place;
132  sampleSiteContents = content;
133  }
134  }
135  };
136 
137  virtual void Behavior(EventWindow<CC>& window) const
138  {
139  Random & random = window.GetRandom();
140  const u32 ourType = this->GetType();
141  const MDist<R> & md = MDist<R>::get();
142 
143  T self = window.GetCenterAtom();
144 
145  // Find out what this Xtal looks like
146  XtalSites xtalSites;
147  GetSites(self, xtalSites, window);
148 
149  // Establish our symmetry before non-self access through window
150  u32 symi = this->GetSymI(self, window);
151  window.SetSymmetry((PointSymmetry) symi);
152 
153  // Xtal windows are considered to consist of two types of sites:
154  // (1) 'Point' sites, which should ideally be occupied by xtals like us
155  // We count and sample empty, res, non-us-xtal and non-xtal point sites separately
156  u32 totalPointSiteCount = 0;
157  u32 totalConsistentPointSiteCount = 0;
158  SiteSampler inconsistentEmptyPointSites(random);
159  SiteSampler inconsistentResPointSites(random);
160  SiteSampler inconsistentXtalPointSites(random);
161  SiteSampler inconsistentNonxtalPointSites(random);
162 
163  // (2) 'Field' sites, which should ideally be empty or Res, but
164  // surely not xtal. We count and sample empty, res, us,
165  // and non-us-xtal field sites separately
166  u32 totalFieldSiteCount = 0;
167  SiteSampler emptyFieldSites(random);
168  SiteSampler resFieldSites(random);
169  SiteSampler usFieldSites(random);
170  SiteSampler nonusXtalFieldSites(random);
171 
172  // Scan event window _including_ self site
173  for (u32 idx = md.GetFirstIndex(0); idx <= md.GetLastIndex(R); ++idx) {
174  const SPoint sp = md.GetPoint(idx);
175 
176  // First question: Is this a live site?
177  if (!window.IsLiveSite(sp))
178  continue;
179 
180  // Second question: Is this a point site or a field site?
181  bool isPoint = xtalSites.ReadBit(idx) !=0 ;
182 
183  const T other = window.GetRelativeAtom(sp);
184  const u32 otherType = other.GetType();
185 
186  if (isPoint) {
187  ++totalPointSiteCount;
188 
189  // Next question: Is point site empty and thus potential growth spot?
190 
191  bool isEmpty = Element_Empty<CC>::THE_INSTANCE.IsType(otherType);
192 
193  if (isEmpty)
194  {
195  inconsistentEmptyPointSites.Sample(sp, other);
196  }
197  else
198  {
199  bool isRes = otherType == Element_Res<CC>::TYPE();
200  if (isRes)
201  {
202  inconsistentResPointSites.Sample(sp, other);
203  }
204  else
205  {
206  // Next question: Is occupied point site _really_ one of us?
207  if (otherType == ourType && this->IsSameXtal(self, other, window))
208  {
209  // Yes
210  ++totalConsistentPointSiteCount;
211  }
212  else
213  {
214  // They are not one of us. Are they _any_ std xtal?
215  bool isXtal = IsAbstractXtalType(window, otherType);
216 
217  if (isXtal)
218  {
219  inconsistentXtalPointSites.Sample(sp, other);
220  }
221  else
222  {
223  inconsistentNonxtalPointSites.Sample(sp, other);
224  }
225  }
226  }
227  }
228  }
229  else
230  {
231  // This is a field site. We'd like it to be empty or Res,
232  // but we'd really like it not to be us-xtal
233  ++totalFieldSiteCount;
234 
235  bool isRes = otherType == Element_Res<CC>::TYPE();
236  if (isRes)
237  {
238  resFieldSites.Sample(sp, other);
239  }
240  else
241  {
242  bool isEmpty = Element_Empty<CC>::THE_INSTANCE.IsType(otherType);
243 
244  if (isEmpty)
245  {
246  emptyFieldSites.Sample(sp, other);
247  }
248  else
249  {
250  // Neither res nor empty. Are they us?
251  if (otherType == ourType && this->IsSameXtal(self, other, window))
252  {
253  usFieldSites.Sample(sp, other);
254  }
255  else
256  {
257  // No, are they any other std xtal?
258  bool isXtal = IsAbstractXtalType(window, otherType);
259  if (isXtal)
260  {
261  nonusXtalFieldSites.Sample(sp, other);
262  }
263  }
264  }
265  }
266  }
267  }
268 
269  // Scan finished. Let's decide what to do.
270 
271  // Cases in priority order: Do the first that applies, then
272  // done.
273  //
274  // (0) Are we strictly more inconsistent (usFieldSites.count)
275  // than consistent (totalConsistentPointSiteCount) with our
276  // own kind? If so, assume we're the problem, and res out.
277  if (usFieldSites.count > totalConsistentPointSiteCount)
278  {
280  }
281  // (1) Is there a field us and a point empty? If so, swap them
282  else if (usFieldSites.count > 0 && inconsistentEmptyPointSites.count > 0)
283  {
284  window.SwapAtoms(usFieldSites.sampleSite, inconsistentEmptyPointSites.sampleSite);
285  }
286  // (2) Is there a point res? If so, make it us
287  else if (inconsistentResPointSites.count > 0)
288  {
289  window.SetRelativeAtom(inconsistentResPointSites.sampleSite, self);
290  }
291  // (3) Is there a point empty and a field res? If so, swap and make the point us
292  else if (resFieldSites.count > 0 && inconsistentEmptyPointSites.count > 0)
293  {
294  window.SwapAtoms(resFieldSites.sampleSite, inconsistentEmptyPointSites.sampleSite);
295  window.SetRelativeAtom(inconsistentEmptyPointSites.sampleSite, self);
296  }
297  // (4) Is there a point non-us-xtal? If so, res it out
298  else if (inconsistentXtalPointSites.count > 0 && inconsistentEmptyPointSites.count > 0)
299  {
300  window.SetRelativeAtom(inconsistentXtalPointSites.sampleSite,
302  }
303 
304  /*
305  if (inconsistentCount > 0)
306  {
307  // Next question: Are we strictly more consistent than inconsistent?
308  if (consistentCount > inconsistentCount && !random.OneIn(xtalSiteCount + 1))
309  {
310  // Yes. Punish selected loser
311  window.SetRelativeAtom(anInconsistent, unmakeGuy);
312  }
313  else if (inconsistentCount > consistentCount)
314  {
315  // If we're strictly more inconsistent, res out and let them have us
316  window.SetCenterAtom(Element_Res<CC>::THE_INSTANCE.GetDefaultAtom());
317  }
318  }
319  else
320  {
321  // No inconsistencies. Do we have something to make, and eat?
322  if (makeCount > 0 && eatCount > 0)
323  {
324  window.SetRelativeAtom(toMake, makeGuy);
325  window.SetRelativeAtom(toEat, Element_Empty<CC>::THE_INSTANCE.GetDefaultAtom());
326  }
327  }
328  */
329  }
330  };
331 }
332 
333 #endif /* ABSTRACTELEMENT_XTAL_H */
u32 GetFirstIndex(const u32 radius) const
Definition: MDist.h:112
u32 GetType() const
Definition: Element.h:290
Definition: Element_Empty.h:41
Definition: Random.h:45
u32 GetLastIndex(const u32 radius) const
Definition: MDist.h:129
void SetSymmetry(const PointSymmetry psym)
Definition: EventWindow.h:110
void SetCenterAtom(const T &atom)
Definition: EventWindow.h:220
u32 NoDiffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: Element.h:508
Tile< CC > & GetTile()
Definition: EventWindow.h:132
virtual bool IsSameXtal(T &self, const T &otherAtom, EventWindow< CC > &window) const
Definition: AbstractElement_Xtal.h:92
void WriteBit(u32 idx, bool bit)
Definition: BitVector.tcc:41
bool IsLiveSite(const SPoint &location) const
Definition: EventWindow.h:148
bool OneIn(u32 odds)
Definition: Random.h:96
Random & GetRandom()
Definition: EventWindow.h:122
const T & GetRelativeAtom(const SPoint &offset) const
Definition: EventWindow.tcc:26
s32 FromPoint(const Point< s32 > &offset, u32 radius) const
Definition: MDist.tcc:201
const T & GetCenterAtom() const
Definition: EventWindow.h:209
virtual const T & GetDefaultAtom() const
Definition: Element.h:382
virtual u32 Diffusability(EventWindow< CC > &ew, SPoint nowAt, SPoint maybeAt) const
Definition: AbstractElement_Xtal.h:106
Definition: MDist.h:69
bool IsType(u32 type) const
Definition: Element.h:345
Definition: AbstractElement_Xtal.h:40
static MDist< R > & get()
Definition: MDist.tcc:193
bool ReadBit(u32 idx)
Definition: BitVector.tcc:65
Definition: Element_Res.h:48
Definition: ElementTable.h:43
#define EVENT_WINDOW_SITES(radius)
Definition: MDist.h:46
Definition: UUID.h:44
Definition: AbstractElement_Xtal.h:122
bool SetRelativeAtom(const SPoint &offset, const T &atom)
Definition: EventWindow.tcc:15
virtual u32 PercentMovable(const T &you, const T &me, const SPoint &offset) const
Definition: AbstractElement_Xtal.h:111
virtual void Behavior(EventWindow< CC > &window) const
Definition: AbstractElement_Xtal.h:137
Definition: P3Atom.h:44
Definition: Atom.h:43
void SwapAtoms(const SPoint &locA, const SPoint &locB)
Definition: EventWindow.tcc:40