PageRenderTime 23ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/pyGDM2/EO1/models.py

https://gitlab.com/wiechapeter/pyGDM2-dirty
Python | 973 lines | 935 code | 9 blank | 29 comment | 3 complexity | 43db24a2fa765d9fa12ad60312a57eb5 MD5 | raw file
  1. # encoding: utf-8
  2. """
  3. Collection of structure models for the EO submodule of pyGDM2
  4. Copyright (C) 2017, P. R. Wiecha
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. """
  16. import numpy as np
  17. import time
  18. import locale
  19. import copy
  20. import sys
  21. import warnings
  22. from ..tools import print_sim_info
  23. from .. import structures
  24. ## del all duplicates with same x/y coordinates
  25. def unique_rows_3D(a):
  26. a = np.ascontiguousarray(a)
  27. unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
  28. return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))
  29. # a = np.ascontiguousarray(a)
  30. # unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
  31. # return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))
  32. #==============================================================================
  33. # Base class
  34. #==============================================================================
  35. class BaseModel(object):
  36. """Base class describing a structure model for evolutionary optimization
  37. Model classes must take at least a pyGDM2 simulation object as input parameter
  38. Mandatory functions for re-implementation :
  39. ---------------
  40. `get_dim(self)` : no argmuents
  41. returns dimensionality of problem (integer)
  42. `get_bounds(self)` : no argmuents
  43. returns dimensionality of problem (integer)
  44. `generate_structure(self, params)` : input `params`
  45. `params`: list of length corresponding to the problem's dimensionality.
  46. resets `self.sim.struct` with the generated structre
  47. """
  48. def __init__(self, sim):
  49. self.sim = sim
  50. self.step = sim.struct.step
  51. def set_step(self, step):
  52. """set the stepsize of the geometry
  53. may also be used as optimization-parameter (in `generate_structure`)
  54. """
  55. self.step = step
  56. self.sim.struct.step = step
  57. #==============================================================================
  58. # Mandatory for reimplementation
  59. #==============================================================================
  60. def get_dim(self):
  61. """return dimension of problem"""
  62. raise NotImplementedError("'models.BaseModel.get_dim' not re-implemented!")
  63. def get_bounds(self):
  64. """return lower and upper bounds as required by pyGMO models"""
  65. raise NotImplementedError("'models.BaseModel.get_bounds' not re-implemented!")
  66. def generate_structure(self, params):
  67. """the main structure generator"""
  68. raise NotImplementedError("'models.BaseModel.generate_structure' not re-implemented!")
  69. #==============================================================================
  70. # Optional for reimplementation: Information output
  71. #==============================================================================
  72. ## --- Randomize structure
  73. def random_structure(self):
  74. """generate a randomized structure"""
  75. N_dim = self.get_dim()
  76. lbnds, ubnds = self.get_bounds()
  77. if not hasattr(lbnds, '__iter__'):
  78. lbnds = [lbnds] * N_dim
  79. ubnds = [ubnds] * N_dim
  80. random_parameters = ( (np.array(ubnds) - np.array(lbnds)) *
  81. np.random.random(N_dim) + np.array(lbnds) )
  82. self.generate_structure(random_parameters)
  83. ## --- Replace structure in `core.simulation` object
  84. def set_structure(self, geometry):
  85. """replace structure-geometry in `core.simulation` object"""
  86. if hasattr(self.sim.struct.material, '__iter__'):
  87. material = self.sim.struct.material[0]
  88. else:
  89. material = self.sim.struct.material
  90. struct = structures.struct(self.sim.struct.step,
  91. geometry, material, # <-- the updated values
  92. self.sim.struct.n1, self.sim.struct.n2,
  93. self.sim.struct.normalization,
  94. n3=self.sim.struct.n3,
  95. spacing=self.sim.struct.spacing)
  96. self.sim.struct = struct
  97. self.sim.struct.setDtype(self.sim.dtypef, self.sim.dtypec)
  98. ## --- Information output
  99. def print_info(self):
  100. """print information about structure to `stdout`"""
  101. warnings.warn("'models.BaseModel.print_info' not re-implemented! Only printing simulation info.")
  102. print_sim_info(self.sim)
  103. def plot_structure(self, interactive=True, show=True, **kwargs):
  104. """plot the structure (2D, matplotlib)
  105. **kwargs are passed to `pyGMD2.visu.structure`
  106. """
  107. warnings.warn("'models.BaseModel.plot_structure' not re-implemented! Using `pyGDM2.visu.structure`.")
  108. import matplotlib.pyplot as plt
  109. from ..visu import structure as plt_struct
  110. if interactive:
  111. plt.ion()
  112. plt_struct(self.sim, show=show, **kwargs)
  113. #==============================================================================
  114. # Simple structures
  115. #==============================================================================
  116. class RectangularAntenna(BaseModel):
  117. """optimization-model for simple geometry, consisting of one rectangular antenna
  118. free parameters: width W, length L, x_offset X, y_offset Y
  119. - W,L : units of `stepsize`
  120. - X,Y : units of nm
  121. Note :
  122. The purpose of this model is merely for demonstration.
  123. """
  124. def __init__(self, sim, limits_W, limits_L, limits_pos, height):
  125. """
  126. """
  127. ## --- init basemodel with simulation instance
  128. super(self.__class__, self).__init__(sim)
  129. print "Rectangular Antenna optimziation model: Note that this simple model is rather intended for testing and demonstration purposes."
  130. ## --- width and length limits for rectrangular antenna
  131. self.limits_W = limits_W
  132. self.limits_L = limits_L
  133. ## --- position boundaries (same for x and y)
  134. self.limits_pos = limits_pos
  135. ## --- fixed parameters
  136. self.height = height # height of rectangular antenna
  137. ## --- init with random values. `set_step`and `random_structure` are
  138. ## defined in `BaseModel`
  139. self.set_step(self.sim.struct.step)
  140. self.random_structure()
  141. def get_dim(self):
  142. """four free parameters: width / length / posX / posY"""
  143. return 4
  144. def get_bounds(self):
  145. """Return lower and upper boundaries for parameters as required by pyGMO models"""
  146. self.lbnds = [self.limits_W[0], self.limits_L[0], self.limits_pos[0], self.limits_pos[0]]
  147. self.ubnds = [self.limits_W[1], self.limits_L[1], self.limits_pos[1], self.limits_pos[1]]
  148. return self.lbnds, self.ubnds
  149. def generate_structure(self, params):
  150. """generate the structure"""
  151. ## --- order of `params` must correspond to boundary order defined by `get_bounds`
  152. W, L, pos_x, pos_y = params
  153. from pyGDM2 import structures
  154. geometry = structures.rect_wire(self.sim.struct.step, L, self.height, W)
  155. geometry.T[0] += pos_x
  156. geometry.T[1] += pos_y
  157. ## -- set new structure-geometry (`set_structure` is a `BaseModel` function)
  158. self.set_structure(geometry)
  159. class CrossAntenna(BaseModel):
  160. """optimization-model for simple geometry, consisting of a cross-shaped structure
  161. free parameters: 2 widths W1, W2; 2 lengths L1, L2, x_offset X, y_offset Y
  162. - Wi,Li : units of `stepsize`
  163. - X,Y : units of nm
  164. Note :
  165. The purpose of this model is merely for demonstration.
  166. """
  167. def __init__(self, sim, limits_W, limits_L, limits_pos, height):
  168. """
  169. """
  170. ## --- init basemodel with simulation instance
  171. super(self.__class__, self).__init__(sim)
  172. ## --- width and length limits for rectrangular antenna
  173. self.limits_W = limits_W
  174. self.limits_L = limits_L
  175. ## --- position boundaries (same for x and y)
  176. self.limits_pos = limits_pos
  177. ## --- fixed parameters
  178. self.height = height # height of rectangular antenna
  179. ## --- init with random values. `set_step`and `random_structure` are
  180. ## defined in `BaseModel`
  181. self.set_step(self.sim.struct.step)
  182. self.random_structure()
  183. def get_dim(self):
  184. """four free parameters: 2 x width / 2 x length / posX / posY"""
  185. return 6
  186. def get_bounds(self):
  187. """Return lower and upper boundaries for parameters as required by pyGMO models"""
  188. self.lbnds = [self.limits_W[0], self.limits_W[0], self.limits_L[0], self.limits_L[0],
  189. self.limits_pos[0], self.limits_pos[0]]
  190. self.ubnds = [self.limits_W[1], self.limits_W[1], self.limits_L[1], self.limits_L[1],
  191. self.limits_pos[1], self.limits_pos[1]]
  192. return self.lbnds, self.ubnds
  193. def generate_structure(self, params):
  194. """generate the structure"""
  195. ## --- order of `params` must correspond to boundary order defined by `get_bounds`
  196. W1, W2, L1, L2, pos_x, pos_y = params
  197. from pyGDM2 import structures
  198. wire1 = structures.rect_wire(self.sim.struct.step, L=L1, H=self.height, W=W1)
  199. wire2 = structures.rect_wire(self.sim.struct.step, L=L2, H=self.height, W=W2)
  200. geometry = np.concatenate([wire1, wire2])
  201. geometry.T[0] += pos_x
  202. geometry.T[1] += pos_y
  203. ## --- delete duplicates
  204. geometry = unique_rows_3D(geometry)
  205. ## -- set new structure-geometry (`set_structure` is a `BaseModel` function)
  206. self.set_structure(geometry)
  207. #==============================================================================
  208. # More complex structure models
  209. #==============================================================================
  210. class MultiRectAntenna(BaseModel):
  211. """optimization-model for geometry consisting of multiple rectangular pads
  212. free parameters: N times (width; length; x_pos; y_pos)
  213. - N: number of rectangles
  214. - all parameters in units of `stepsize`
  215. """
  216. def __init__(self, sim, N_antennas, limits_W, limits_L, limits_pos_x,
  217. limits_pos_y, height):
  218. """
  219. """
  220. ## --- init basemodel with simulation instance
  221. super(self.__class__, self).__init__(sim)
  222. ## --- width and length limits for each rectrangular sub-antenna
  223. self.limits_W = limits_W
  224. self.limits_L = limits_L
  225. ## --- position boundaries
  226. self.limits_pos_x = limits_pos_x
  227. self.limits_pos_y = limits_pos_y
  228. ## --- fixed parameters
  229. self.N = int(N_antennas) # Number of rectangular sub-antenna
  230. self.height = height # height of rectangular antenna
  231. ## --- init with random values
  232. self.set_step(self.sim.struct.step)
  233. self.random_structure()
  234. def get_dim(self):
  235. """four free parameters: 2 x width / 2 x length / posX / posY"""
  236. return self.N * 4
  237. def get_bounds(self):
  238. """Return lower and upper boundaries for parameters as required by pyGMO models"""
  239. self.lbnds = [self.limits_W[0], self.limits_L[0], self.limits_pos_x[0],
  240. self.limits_pos_y[0]] * self.N
  241. self.ubnds = [self.limits_W[1], self.limits_L[1], self.limits_pos_x[1],
  242. self.limits_pos_y[1]] * self.N
  243. return self.lbnds, self.ubnds
  244. def generate_structure(self, params):
  245. """generate the structure"""
  246. ## --- get 4-tuples describing each rectangular sub-antenna
  247. params_rects = [params[i:i + 4] for i in xrange(0, len(params), 4)]
  248. from pyGDM2 import structures
  249. for i, p in enumerate(params_rects):
  250. W, L = int(round(p[0])), int(round(p[1]))
  251. rect = structures.rect_wire(self.sim.struct.step, L=L, H=self.height, W=W)
  252. rect.T[0] += int(round(p[2])) * self.sim.struct.step
  253. rect.T[1] += int(round(p[3])) * self.sim.struct.step
  254. if i == 0:
  255. geometry = rect
  256. else:
  257. geometry = np.concatenate([geometry, rect])
  258. ## --- delete duplicates
  259. geometry = unique_rows_3D(geometry)
  260. ## -- set new structure-geometry (`set_structure` is a `BaseModel` function)
  261. self.set_structure(geometry)
  262. class BlockModel(BaseModel):
  263. """structure consisting of `N` blocks of variable positions
  264. """
  265. def __init__(self, sim,
  266. N, block_nx,block_ny,block_nz, area_limits,
  267. forbidden=[],
  268. symmetric=False, fit_offset=False):
  269. """
  270. """
  271. super(self.__class__, self).__init__(sim)
  272. ## config structure
  273. self.N_blocks = N
  274. self.block_nx = block_nx
  275. self.block_ny = block_ny
  276. self.block_nz = block_nz
  277. ## --- list of forbidden meshpoint-positions [[x1,y1], [x2,y2] ... ]
  278. ## (index coordinates [=divided by 'step'])
  279. self.forbidden = forbidden
  280. ## --- symmtery-axis: X? If True: Mirror structure at lower y-limit
  281. self.symmetric = symmetric
  282. self.fit_offset = fit_offset
  283. self.area_min, self.area_max = area_limits[0], area_limits[1]
  284. self.x_offset = 0
  285. self.y_offset = 0
  286. ## --- init with random positions
  287. self.set_step(self.step)
  288. self.random_structure()
  289. def set_step(self, step):
  290. """set the stepsize"""
  291. self.step = step
  292. self.sim.struct.step = step
  293. self.step_grid_x = self.step*self.block_nx
  294. self.step_grid_y = self.step*self.block_ny
  295. self.generate_zero_block()
  296. def get_dim(self):
  297. if self.fit_offset:
  298. return 2 * self.N_blocks + 2
  299. else:
  300. return 2 * self.N_blocks
  301. def get_bounds(self):
  302. """Return lower and upper bounds as required by pyGMO models"""
  303. self.lbnds = self.area_min
  304. self.ubnds = self.area_max
  305. return self.lbnds, self.ubnds
  306. ## --------- structure generation
  307. def generate_zero_block(self):
  308. """generate a list describing the fundamental block meshpoints"""
  309. self.zeroblock = []
  310. for xi in np.arange(self.block_nx):
  311. for yi in np.arange(self.block_ny):
  312. for zi in np.arange(self.block_nz):
  313. self.zeroblock.append([xi, yi, zi+0.5])
  314. self.zeroblock = np.array(self.zeroblock)*self.step
  315. def get_position_tuples(self, params):
  316. """Generate position tuples (x,y) from the `params` list
  317. splitting up the `params` list:
  318. (x0,y0) = [params[0], params[1]], (x1,y1) = [params[2], params[3]], ...
  319. positions are given as (x,y) index-tuples (=divided by `step`)
  320. """
  321. POS=[]
  322. for i, val in enumerate(params):
  323. if i%2==0:
  324. POS.append([])
  325. ## convention for float-->int parameter conversion: int(round(value))
  326. val = int(round(val))
  327. POS[-1].append(val)
  328. return np.array(POS, dtype=np.float)
  329. def generate_structure(self, params):
  330. """generate the structure"""
  331. ## --- collect parameters, exception handling
  332. if self.fit_offset:
  333. positions = self.get_position_tuples(params[:-2])
  334. self.x_offset, self.y_offset = params[-2:]
  335. else:
  336. positions = self.get_position_tuples(params)
  337. self.x_offset, self.y_offset = 0, 0
  338. if len(positions) != self.N_blocks:
  339. raise ValueError("Number of Positions must equal number of Block!")
  340. ## --- assemble blocks
  341. self.t0 = time.time()
  342. dipoles = []
  343. for xi,yi in positions:
  344. block = np.copy(self.zeroblock).T
  345. block[0] += round(xi)*self.step_grid_x
  346. block[1] += round(yi)*self.step_grid_y
  347. for dp in block.T:
  348. dipoles.append(tuple(dp))
  349. else:
  350. pass
  351. ## --- If symmetric: shift to positive Y and Duplicate sutructure
  352. dipoles = np.array(dipoles)
  353. if self.symmetric:
  354. if dipoles.T[1].min() < 0:
  355. dipoles.T[1] -= dipoles.T[1].min() #+ np.ceil(self.block_ny/2.-1)*self.step
  356. dipoles_sym = copy.deepcopy(dipoles)
  357. dipoles_sym.T[1] *= -1
  358. ## --- shift down by number of y-meshpoints per block
  359. dipoles_sym.T[1] += (self.block_ny-1)*self.step
  360. dipoles = np.concatenate([dipoles, dipoles_sym])
  361. ## --- center
  362. dipoles.T[1] -= np.floor((self.block_ny + 1-self.block_ny%2)/2.) * self.step
  363. ## --- delete forbidden positions
  364. delete_list = []
  365. for idp, (dpx,dpy,dpz) in enumerate(dipoles):
  366. if [int(round(dpx/self.step_grid_x)), int(round(dpy/self.step_grid_y))] \
  367. in self.forbidden:
  368. delete_list.append(idp)
  369. dipoles = np.delete(dipoles, delete_list, 0)
  370. ## --- apply structure offset
  371. if self.fit_offset:
  372. dipoles.T[1] += round(self.y_offset) * self.step_grid_y
  373. dipoles.T[0] += round(self.x_offset) * self.step_grid_x
  374. ## --- delete duplicates
  375. self.len_original = len(dipoles)
  376. dipoles = unique_rows_3D(dipoles)
  377. ## --- replace structure in `self.sim`
  378. self.set_structure(dipoles)
  379. def print_info(self):
  380. """print model info"""
  381. print " ----------- N BLOCKS MODEL -----------"
  382. print '{} dipoles created.'.format(self.len_original)
  383. print '{} duplicate dipoles deleted.'.format(self.len_original - self.sim.struct.n_dipoles)
  384. print
  385. print "MATERIAL =", self.sim.struct.material[0].__name__
  386. print "STEPSIZE =", self.step
  387. print "BLOCK-SIZE =", self.block_nx*self.block_ny*self.block_nz, "(meshpoints)"
  388. print "NUMBER OF BLOCKS =", self.N_blocks,
  389. if self.symmetric:
  390. print "x2 (symmetric)"
  391. else:
  392. print ""
  393. print "AREA LIMITS (blocks) =", self.area_min,'-->', self.area_max
  394. print "MAX. POSSIBLE MESHPOINTS =", self.N_blocks*self.block_nx*self.block_ny*self.block_nz,
  395. if self.symmetric:
  396. print "x2 (symmetric)"
  397. else:
  398. print ""
  399. print
  400. print "TOTAL MESHPOINTS =", self.sim.struct.n_dipoles
  401. print " --------------------------------------"
  402. print
  403. print
  404. #### --------------------------------------------------------------------------
  405. ### -- N variable size Antennas Model
  406. #### --------------------------------------------------------------------------
  407. #class AntennaModel():
  408. # def __init__(self, step, nblocks, h, limg, lims):
  409. # self.tinit = time.time()
  410. ##==============================================================================
  411. ## config structure
  412. ##==============================================================================
  413. # self.setStep(step)
  414. # self.NBLOCKS = nblocks
  415. #
  416. # self.H = h
  417. #
  418. # self.LIM_GRID = np.array(limg)
  419. # self.LIM_SIZE = np.array(lims)
  420. #
  421. #
  422. # ## --- init at random positions
  423. # self.get_bounds()
  424. # self.random_positions()
  425. #
  426. # self.t_config = time.time()
  427. #
  428. #
  429. #
  430. # def setStep(self, step):
  431. # self.STEP = step
  432. #
  433. #
  434. # def get_dim(self):
  435. # return self.NBLOCKS*4
  436. #
  437. # def get_bounds(self):
  438. # """Return lower and upper bounds as required by pyGMO models"""
  439. # limgrid = self.LIM_GRID
  440. # limsize = self.LIM_SIZE
  441. # self.lbnds = self.NBLOCKS * [float(limgrid[0]), float(limgrid[0]),
  442. # float(limsize[0]), float(limsize[0])]
  443. # self.ubnds = self.NBLOCKS * [float(limgrid[1]), float(limgrid[1]),
  444. # float(limsize[1]), float(limsize[1])]
  445. #
  446. # return self.lbnds, self.ubnds
  447. #
  448. # def random_positions(self):
  449. # ## chose random start positions on defined area and generate random start structure
  450. # PARAMS = []
  451. # for i in range(self.NBLOCKS):
  452. # POS = np.round(np.random.random(2)*(self.LIM_GRID[1]-self.LIM_GRID[0]) +
  453. # self.LIM_GRID[0])
  454. # DIM = np.round(np.random.random(2)*(self.LIM_SIZE[1]-self.LIM_SIZE[0]) +
  455. # self.LIM_SIZE[0])
  456. # PARAMS.append(np.array([POS, DIM]).flatten())
  457. #
  458. # self.PARAMS = np.array(PARAMS).flatten()
  459. # self.generate_structure(self.PARAMS)
  460. #
  461. #
  462. # def generate_block(self, X,Y,L,D,H):
  463. # ## ------- Fundamental Brick
  464. # BLOCK = [[],[],[]]
  465. # for xi in np.arange(int(round(L))):
  466. # for yi in np.arange(int(round(D))):
  467. # for zi in np.arange(H):
  468. # BLOCK[0].append(xi+int(round(X)))
  469. # BLOCK[1].append(yi+int(round(Y)))
  470. # BLOCK[2].append(zi+0.5)
  471. #
  472. # return BLOCK
  473. #
  474. #
  475. #
  476. # def generate_structure(self, PARAMS):
  477. # ########################################################################
  478. # ## GENERATE STRUCTURE
  479. # ########################################################################
  480. # P = np.array(PARAMS).reshape((len(PARAMS)/4, 4))
  481. # #print P
  482. # if len(P) != self.NBLOCKS:
  483. # raise ValueError("Number of parameters must equal 4*(number of blocks)!")
  484. #
  485. # self.t0 = time.time()
  486. # ## ------- Generate Structure
  487. # xm = np.array([])
  488. # ym = np.array([])
  489. # zm = np.array([])
  490. # for p in P:
  491. # block = self.generate_block(p[0],p[1],p[2],p[3],self.H)
  492. # xm = np.concatenate([xm, block[0]])
  493. # ym = np.concatenate([ym, block[1]])
  494. # zm = np.concatenate([zm, block[2]])
  495. # xm = xm.flatten()
  496. # ym = ym.flatten()
  497. # zm = zm.flatten()
  498. #
  499. # self.STRUCT = np.transpose([xm,ym,zm])*self.STEP
  500. # self.t_build = time.time()
  501. #
  502. #
  503. # ## del all duplicates with same x/y coordinates
  504. # def unique_rows_3D(a):
  505. # a = np.ascontiguousarray(a)
  506. # unique_a = np.unique(a.view([('', a.dtype)]*a.shape[1]))
  507. # return unique_a.view(a.dtype).reshape((unique_a.shape[0], a.shape[1]))
  508. #
  509. # self.len_original = len(self.STRUCT)
  510. # self.STRUCT = unique_rows_3D(self.STRUCT)
  511. # len1 = len(self.STRUCT)
  512. # self.t_duplicates = time.time()
  513. #
  514. # self.NDipPlane = int(len1/self.H)
  515. #
  516. #
  517. # def get_individual_blocks(self, PARAMS):
  518. # """generate list of the individual blocks constituting the whole structure
  519. #
  520. # For analysis purpose (post-optimization)
  521. # """
  522. # ## --- check parameters
  523. # P = np.array(PARAMS).reshape((len(PARAMS)/4, 4))
  524. # if len(P) != self.NBLOCKS:
  525. # raise ValueError("Number of parameters must equal 4*(number of blocks)!")
  526. #
  527. # ## --- Constituents of structure
  528. # blocks = []
  529. # for p in P:
  530. # block = self.generateBlock(p[0], p[1], p[2], p[3], self.H)
  531. # blocks.append(np.transpose(block))
  532. #
  533. # return np.array(blocks)*self.STEP
  534. #
  535. #
  536. # def print_info(self):
  537. # ########################################################################
  538. # ## Print information
  539. # ########################################################################
  540. # print " ----- N-ANTENNA MODEL -----"
  541. # print '{} dipoles created.'.format(self.len_original)
  542. # print '{} duplicate dipoles deleted.'.format(self.len_original-len(self.STRUCT))
  543. # print
  544. # print
  545. # print 'Last structure update (ms):', round(1000*(self.t_duplicates - self.t0),1)
  546. # print ' - initial config Time (ms) :', round(1000*(self.t_config - self.tinit),1)
  547. # print ' - last build Time (ms) :', round(1000*(self.t_build - self.t0),1)
  548. # print ' - last duplicate Time (ms) :', round(1000*(self.t_duplicates - self.t_build),1)
  549. # print
  550. # print
  551. # print "STEPSIZE =", self.STEP
  552. # print "NUMBER OF BLOCKS =", self.NBLOCKS
  553. # print "AREA LIMITS (X; Y) =", self.LIM_GRID
  554. # print "SIZE LIMITS (X; Y) =", self.LIM_SIZE
  555. # print "TOTAL MESHPOINTS =", len(self.STRUCT)
  556. # print
  557. # print
  558. #
  559. #
  560. #
  561. # def plot_structure(self, interactive=True, show=True):
  562. # ########################################################################
  563. # ## plot structure
  564. # ########################################################################
  565. # import matplotlib.pyplot as plt
  566. # ## VERY IMPORTANT! IF LOCALE NOT SET HERE, FORTRAN FORMATTING IS BROKEN!
  567. # locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
  568. #
  569. # if show:
  570. # plt.clf()
  571. # if interactive:
  572. # plt.ion()
  573. #
  574. # XM,YM,ZM = self.STRUCT.T
  575. # plt.scatter(XM, YM, s=50)
  576. #
  577. # plt.xlim((self.LIM_GRID[0]-1)*self.STEP , self.STEP*(self.LIM_GRID[1]+self.LIM_SIZE[1]+1)); plt.xlabel("X (nm)")
  578. # plt.ylim((self.LIM_GRID[0]-1)*self.STEP , self.STEP*(self.LIM_GRID[1]+self.LIM_SIZE[1]+1)); plt.ylabel("Y (nm)")
  579. #
  580. #
  581. # if show:
  582. # if interactive:
  583. # plt.show()
  584. # plt.draw()
  585. # else:
  586. # plt.show()
  587. # if interactive:
  588. # plt.ion()
  589. #
  590. #
  591. #
  592. #
  593. #
  594. #
  595. #
  596. #### --------------------------------------------------------------------------
  597. ### -- Binary Array of Blocks Model
  598. #### --------------------------------------------------------------------------
  599. #class BinaryArrayModel():
  600. # def __init__(self, step, N, nx,ny,nz):
  601. # self.tinit = time.time()
  602. # ########################################################################
  603. # ## config structure
  604. # ########################################################################
  605. # """
  606. # binary array of (N x N) blocks of size (nx x ny x nz).
  607. # area from (0,0) to (N*step, N*step)
  608. # """
  609. # self.N = N
  610. #
  611. # self.NX_BLOCK = nx
  612. # self.NY_BLOCK = ny
  613. # self.NZ_BLOCK = nz
  614. #
  615. # self.set_step(step)
  616. #
  617. #
  618. # ## init at random positions
  619. # self.get_bounds()
  620. # self.random_positions()
  621. #
  622. # self.t_config = time.time()
  623. #
  624. # def get_dim(self):
  625. # return self.N**2
  626. #
  627. # def get_bounds(self):
  628. # """Return lower and upper bounds as required by pyGMO models"""
  629. # self.lbnds = self.get_dim()*[0]
  630. # self.ubnds = self.get_dim()*[1]
  631. #
  632. # return self.lbnds, self.ubnds
  633. #
  634. # def random_positions(self):
  635. # ## chose random start positions on defined area and generate random start structure
  636. # POSITIONS = np.random.randint(0, 2, self.get_dim())
  637. # self.generate_structure(POSITIONS)
  638. #
  639. # def set_step(self, step):
  640. # self.STEP = step
  641. # self.generate_zero_block()
  642. #
  643. #
  644. # def generate_zero_block(self):
  645. # ## ------- FUNDAMENTAL BLOCK
  646. # self.ZEROBLOCK = []
  647. # for xi in np.arange(self.NX_BLOCK):
  648. # for yi in np.arange(self.NY_BLOCK):
  649. # for zi in np.arange(self.NZ_BLOCK):
  650. # self.ZEROBLOCK.append([xi, yi, zi+0.5])
  651. # self.ZEROBLOCK = np.array(self.ZEROBLOCK)
  652. #
  653. #
  654. #
  655. # def generate_structure(self, POSITIONS):
  656. # ########################################################################
  657. # ## GENERATE STRUCTURE
  658. # ########################################################################
  659. # if len(POSITIONS) != self.get_dim():
  660. # raise ValueError("Number of Positions must equal size of array!")
  661. # self.POSITIONS = POSITIONS
  662. #
  663. # self.t0 = time.time()
  664. # ## ------- PUT BLOCKS AT EACH POSITION
  665. # dipoles = []
  666. # for i,BIN in enumerate(POSITIONS):
  667. # if BIN>=0.5:
  668. # BLOCK = np.copy(self.ZEROBLOCK).T
  669. #
  670. # BLOCK[0] += (i%self.N)*self.NX_BLOCK
  671. # BLOCK[1] += int(i/self.N)*self.NY_BLOCK
  672. # for dp in BLOCK.T:
  673. # dipoles.append(tuple(dp))
  674. #
  675. #
  676. # self.t_build = time.time()
  677. #
  678. # ## Fortran compatible arrays
  679. # self.dipoles = np.array(dipoles)*self.STEP
  680. # self.STRUCT = self.dipoles
  681. #
  682. # self.NDipPlane = int(len(self.STRUCT)/self.NZ_BLOCK)
  683. #
  684. #
  685. #
  686. # def print_info(self):
  687. # ########################################################################
  688. # ## Print information
  689. # ########################################################################
  690. # print " ----- N BLOCKS MODEL -----"
  691. # print '{} dipoles created.'.format(len(self.STRUCT))
  692. # print
  693. # print
  694. # print 'Last structure update (ms):', round(1000*(self.t_build - self.t0),1)
  695. # print ' - initial config Time (ms) :', round(1000*(self.t_config - self.tinit),1)
  696. # print ' - last build Time (ms) :', round(1000*(self.t_build - self.t0),1)
  697. # print
  698. # print
  699. # print "STEPSIZE =", self.STEP
  700. # print "BLOCK-SIZE =", self.NX_BLOCK*self.NY_BLOCK*self.NZ_BLOCK, "(meshpoints)"
  701. # print "NUMBER OF BLOCKS =", (self.N**2)
  702. # print "MAX. POSSIBLE MESHPOINTS =", (self.N**2)*self.NX_BLOCK*self.NY_BLOCK*self.NZ_BLOCK
  703. # print "TOTAL MESHPOINTS =", len(self.dipoles)
  704. # print
  705. # print
  706. #
  707. #
  708. #
  709. # def plot_structure(self, interactive=True, show=True):
  710. # ########################################################################
  711. # ## plot structure
  712. # ########################################################################
  713. # import matplotlib.pyplot as plt
  714. #
  715. # if show:
  716. # plt.clf()
  717. # if interactive:
  718. # plt.ion()
  719. # XM,YM,ZM = np.array(self.dipoles).T
  720. # plt.scatter(XM, YM, s=50)
  721. #
  722. # plt.xlim(-3*self.STEP, YM.max()+3*self.STEP); plt.xlabel("X (nm)")
  723. # plt.ylim(-3*self.STEP, XM.max()+3*self.STEP); plt.ylabel("Y (nm)")
  724. #
  725. # if show:
  726. # if interactive:
  727. # plt.show()
  728. # plt.draw()
  729. # else:
  730. # plt.show()
  731. #
  732. if __name__=='__main__':
  733. testModel = BlockModel(step=10., nblocks=40,
  734. nx=5,ny=5,nz=5,
  735. blim=[-10,10])
  736. # testModel = AntennaModel(step=10., nblocks=3,
  737. # h=2,
  738. # limg=[-10,10],lims=[2,6])
  739. #
  740. # testModel = BinaryArrayModel(step=10., N=10,
  741. # nx=2, ny=2, nz=2)
  742. #from mayavi import mlab
  743. #mlab.figure(size=(800,600), bgcolor=(1,1,1))
  744. #visu.plot2Dstruct(testModel.STRUCT)
  745. import matplotlib.pyplot as plt
  746. testModel.print_info()
  747. for i in range(2):
  748. testModel.random_positions()
  749. testModel.plot_structure(interactive=True)
  750. testModel.print_info()
  751. plt.pause(.1)
  752. plt.ioff()
  753. plt.show()