{"action":"created","issue":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/463","labels_url":"https://api.github.com/repos/mit-crpg/openmc/issues/463/labels{/name}","comments_url":"https://api.github.com/repos/mit-crpg/openmc/issues/463/comments","events_url":"https://api.github.com/repos/mit-crpg/openmc/issues/463/events","html_url":"https://github.com/mit-crpg/openmc/pull/463","id":108613698,"number":463,"title":"Support for complex cell regions","user":{"login":"paulromano","id":743095,"avatar_url":"https://avatars.githubusercontent.com/u/743095?v=3","gravatar_id":"","url":"https://api.github.com/users/paulromano","html_url":"https://github.com/paulromano","followers_url":"https://api.github.com/users/paulromano/followers","following_url":"https://api.github.com/users/paulromano/following{/other_user}","gists_url":"https://api.github.com/users/paulromano/gists{/gist_id}","starred_url":"https://api.github.com/users/paulromano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paulromano/subscriptions","organizations_url":"https://api.github.com/users/paulromano/orgs","repos_url":"https://api.github.com/users/paulromano/repos","events_url":"https://api.github.com/users/paulromano/events{/privacy}","received_events_url":"https://api.github.com/users/paulromano/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/mit-crpg/openmc/labels/Geometry","name":"Geometry","color":"CD6600"},{"url":"https://api.github.com/repos/mit-crpg/openmc/labels/Python%20API","name":"Python API","color":"bfd4f2"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/mit-crpg/openmc/milestones/13","html_url":"https://github.com/mit-crpg/openmc/milestones/v0.7.1","labels_url":"https://api.github.com/repos/mit-crpg/openmc/milestones/13/labels","id":1241744,"number":13,"title":"v0.7.1","description":"","creator":{"login":"paulromano","id":743095,"avatar_url":"https://avatars.githubusercontent.com/u/743095?v=3","gravatar_id":"","url":"https://api.github.com/users/paulromano","html_url":"https://github.com/paulromano","followers_url":"https://api.github.com/users/paulromano/followers","following_url":"https://api.github.com/users/paulromano/following{/other_user}","gists_url":"https://api.github.com/users/paulromano/gists{/gist_id}","starred_url":"https://api.github.com/users/paulromano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paulromano/subscriptions","organizations_url":"https://api.github.com/users/paulromano/orgs","repos_url":"https://api.github.com/users/paulromano/repos","events_url":"https://api.github.com/users/paulromano/events{/privacy}","received_events_url":"https://api.github.com/users/paulromano/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":12,"state":"open","created_at":"2015-08-05T10:36:36Z","updated_at":"2015-10-02T06:22:50Z","due_on":"2015-10-30T17:00:00Z","closed_at":null},"comments":7,"created_at":"2015-09-28T08:43:34Z","updated_at":"2015-10-02T17:03:22Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/mit-crpg/openmc/pulls/463","html_url":"https://github.com/mit-crpg/openmc/pull/463","diff_url":"https://github.com/mit-crpg/openmc/pull/463.diff","patch_url":"https://github.com/mit-crpg/openmc/pull/463.patch"},"body":"This pull request makes four major changes to OpenMC:\r\n\r\n1. It adds a new module `stl_vector` which mimics the std::vector sequence container from the C++ standard template library. It is a very good alternative to the singly-linked list we have current in list_header for a number of reasons:\r\n    - The vector can grow in amortized constant time whereas the linked-list grows in O(n) time.\r\n    - No pointers are used which means that a locally declared Vector* type will automatically be deallocated when it goes out of scope.\r\n    - Looking up a specific element of the vector is O(1), whereas it's O(n) for a linked-list.\r\n2. The way we handle different surfaces has been completely refactored. There is now a surface_header module which contains an abstract Surface type and concrete subtypes, e.g. SurfaceXPlane that implement the necessary procedures. Distance calculations, determining sense, and reflecting off a surface are all handled in this module. `sense` and `reflect` have been rewritten to be generic, i.e., you don't need to implement them for a specific surface. `sense` is now pure (free from side effects), in particular if the position is determined to be coincident with the surface, the dot product of the direction and the surface normal is inspected to see which side should be chosen. Before an ugly hack with TINY_BIT was used.\r\n3. Support for complex cells consisting of the complement, union, and intersection of half-spaces has been added. Complement is `~`, union is `^`, and intersection is ` ` (implicit whitespace), and of course you can group expressions with parentheses. The \"surfaces\" attribute/element of `<cell>` has been renamed \"region\" to more accurately describe the purpose. \"surfaces\" is accepted, but is deprecated and the user will receive a warning. See #60 for more discussion.\r\n4. A new `openmc.region` module was added to the Python API to support complex cells. In Python, regions are constructed as abstract syntax trees. The proposed syntax is explained in #60. The proper way to set the region for a cell is to use the `region` property. The old `add_surface` method is still accepted and now works by taking the intersection of the current Region and whatever was passed.\r\n\r\nTo briefly describe the implementation of complex cells, there are basically three steps:\r\n- First, an expression passed on `<cell region=\"...\" />` is \"tokenized\", i.e., turned into an array of integers, some of which hold special values representing operators. The tokenized expression is still in infix notation as it appears in the XML input. (`tokenize` in string.F90)\r\n- The infix notation as given in the tokenized expression is converted to postfix (reverse Polish notation) using the [shunting-yard algorithm](https://en.wikipedia.org/wiki/Shunting-yard_algorithm). (`generate_rpn` in input_xml.F90)\r\n- During the simulation, the postfix notation is used to determine whether a cell contains a given point. It is evaluated from left-to-right using a stack, much like the old RPN calculators of the 1970s and 1980s of the past did. (`cell_contains` in geometry.F90)\r\n\r\nOne of the natural questions is what to do when a particle hits an internal boundary in a complex cell. Rather than try to determine the real distance to the boundary of the cell, we allow particles to move to internal boundaries, and then simply sample a new distance and calculate the next boundary. This results in \"more\" work, but it requires essentially no changes to the distance-to-boundary routine.\r\n\r\nI've added a test problem that uses the new complex cell feature. The problem looks like this:\r\n![1_plot](https://cloud.githubusercontent.com/assets/743095/10130970/e2dba990-65f6-11e5-8128-be33f8f174a9.png)\r\nBefore, this geometry would have required at least 11 cells, whereas now it is done with the minimum of 4.\r\n\r\n## Remaining tasks\r\n- [x] Make sure we don't lose much performance\r\n- [ ] Beef up documentation to give some examples\r\n- [x] Update any inputs to use \"region\" rather than \"surfaces\"\r\n- [x] Update `openmc-update-inputs` to automatically change \"surfaces\" to \"region\"\r\n- [x] Fix OpenCG compatibility module in Python API"},"comment":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/comments/145087041","html_url":"https://github.com/mit-crpg/openmc/pull/463#issuecomment-145087041","issue_url":"https://api.github.com/repos/mit-crpg/openmc/issues/463","id":145087041,"user":{"login":"smharper","id":4622797,"avatar_url":"https://avatars.githubusercontent.com/u/4622797?v=3","gravatar_id":"","url":"https://api.github.com/users/smharper","html_url":"https://github.com/smharper","followers_url":"https://api.github.com/users/smharper/followers","following_url":"https://api.github.com/users/smharper/following{/other_user}","gists_url":"https://api.github.com/users/smharper/gists{/gist_id}","starred_url":"https://api.github.com/users/smharper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smharper/subscriptions","organizations_url":"https://api.github.com/users/smharper/orgs","repos_url":"https://api.github.com/users/smharper/repos","events_url":"https://api.github.com/users/smharper/events{/privacy}","received_events_url":"https://api.github.com/users/smharper/received_events","type":"User","site_admin":false},"created_at":"2015-10-02T17:03:22Z","updated_at":"2015-10-02T17:03:22Z","body":"I've been testing the functionality and everything looks good so far.  I was able to model one of my old complex geometries with 2 cells rather than 10\r\n<img src=\"https://cloud.githubusercontent.com/assets/4622797/10252208/fc1863e8-6903-11e5-9df9-70e6b61d918e.png\" width=\"300\">\r\n<img src=\"https://cloud.githubusercontent.com/assets/4622797/10252212/0259b1c6-6904-11e5-8538-68300d296fa7.png\" width=\"300\">\r\n\r\nAlso, I believe that the ability to define a complement cell like `c302.region = Complement(c301.region)` would have saved me many days of debugging when I was modelling the LR-0 experiment.\r\n\r\nThat said, the Python syntax is a bit bulky.  What do you think about:\r\n* Defining `__neg__` and `__pos__` for surfaces which would return the negative and positive halfspaces, respectively.\r\n* Defining `__and__`, `__xor__`, and, `__neg__` for regions for the intersection, union, and complement operators."}}