SpECTRE Documentation Coverage Report
 Current view: top level - __w/spectre/spectre/docs/Tutorials - Orientation.md Hit Total Coverage Commit: 2db722c93a8e9b106e406b439b79c8e05c2057fb Lines: 0 1 0.0 % Date: 2021-03-03 22:01:00 Legend: Lines: hit not hit
  Line data Source code  1 0 : \cond NEVER 2 : Distributed under the MIT License. 3 : See LICENSE.txt for details. 4 : \endcond 5 : # OrientationMap {#tutorial_orientations} 6 : 7 : ### Introduction 8 : Each element in a domain has a set of internal directions which it uses 9 : for computations in its own local coordinate system. These are referred to 10 : as the logical directions \f$\xi\f$, \f$\eta\f$, and \f$\zeta\f$, where 11 : \f$\xi\f$ is the first dimension, \f$\eta\f$ is the second dimension, and 12 : \f$\zeta\f$ is the third dimension. In a 13 : domain with multiple elements, the logical directions are not necessarily 14 : aligned on the interfaces between two elements, as shown in the figure below. 15 : As certain operations (e.g. fluxes, limiting) communicate information across 16 : the boundaries of adjacent elements, there needs to be a class that takes 17 : into account the relative orientations of elements which neighbor each other. 18 : This class is OrientationMap. 19 : 20 : ### %OrientationMaps between %Blocks 21 : Each Block in a Domain has a set of BlockNeighbors, which each hold an 22 : OrientationMap. In this scenario, the Block is referred to as the host, and 23 : the OrientationMap held by each BlockNeighbor is referred to as "the 24 : orientation the BlockNeighbor has with respect to the host Block." This is 25 : a convention, so we give an example of constructing and assigning the correct 26 : OrientationMaps: 27 : 28 : \image html twocubes.png "Two neighboring blocks." 29 : 30 : In the image above, we see a domain decomposition into two Blocks, which have 31 : their logical axes rotated relative to one another. With the left block as 32 : the host Block, we see that it has a neighbor in the \f$+\xi\f$ direction. 33 : The host Block holds a std::unordered_map from Directions to BlockNeighbors; 34 : the BlockNeighbor itself holds an OrientationMap that determines the mapping 35 : from each logical direction in the host Block to that in the neighboring Block. 36 : That is, the OrientationMap takes as input local information (i.e. logical 37 : directions in the host's coordinate system) and returns neighbor information 38 : (i.e. logical directions in the neighbor's coordinate system). An 39 : OrientationMap is constructed by passing in the block neighbor directions that 40 : correspond to the \f$+\xi\f$, \f$+\eta\f$, \f$+\zeta\f$ directions in the host. 41 : In this case, these directions in the host map to the \f$+\zeta\f$, 42 : \f$+\xi\f$, \f$+\eta\f$ directions in the neighbor, respectively. 43 : This BlockNeighbor thus holds the OrientationMap constructed with the list 44 : (\f$+\zeta\f$, \f$+\xi\f$, \f$+\eta\f$). With the right block as the host 45 : block, we see that it has a BlockNeighbor in the \f$-\zeta\f$ direction, and 46 : the OrientationMap held by this BlockNeighbor is the one constructed with the 47 : array (\f$+\eta\f$, \f$+\zeta\f$, \f$+\xi\f$). For convenience, OrientationMap 48 : has a method inverse_map which returns the OrientationMap that takes as input 49 : neighbor information and returns local information. 50 : 51 : OrientationMaps need to be provided for each BlockNeighbor in each direction 52 : for each Block. This quickly becomes too large of a number to determine by 53 : hand as the number of Blocks and the number of dimensions increases. A remedy 54 : to this problem is the corner numbering scheme. 55 : 56 : ### Encoding BlockNeighbor information using Corner Orderings and Numberings 57 : The orientation of the \f${dim}\f$ logical directions within each element 58 : determines an ordering of the \f$2^{dim}\f$ vertices of that element. This is 59 : called the local corner numbering scheme (Local CNS) with respect to that 60 : element. We give the ordering of the local corners below for the case of a 61 : three-dimensional element: 62 : 63 : \image html onecube_numbered.png "The local corner numbering." 64 : 65 :  66 : Corner 0 is the location of the lower xi, lower eta, lower zeta corner. 67 : Corner 1 is the location of the upper xi, lower eta, lower zeta corner. 68 : Corner 2 is the location of the lower xi, upper eta, lower zeta corner. 69 : Corner 3 is the location of the upper xi, upper eta, lower zeta corner. 70 : Corner 4 is the location of the lower xi, lower eta, upper zeta corner. 71 : Corner 5 is the location of the upper xi, lower eta, upper zeta corner. 72 : Corner 6 is the location of the lower xi, upper eta, upper zeta corner. 73 : Corner 7 is the location of the upper xi, upper eta, upper zeta corner. 74 :  75 : 76 : What remains is to endow the domain decomposition with a global corner 77 : numbering (Global CNS). We give an example below: 78 : 79 : \image html twocubes_numbered.png "A global corner numbering." 80 : 81 : In the image above, we see that each vertex of the two-block domain has 82 : been assigned a number. Although each block has eight corners, four are 83 : shared among them, so there are only twelve unique corners in this domain. 84 : Any numbering may be used in the global corner numbering, so long as the 85 : each distinct corner is given a single distinct corner number. 86 : 87 : \note This Global CNS assumes that there is no additional identifying of faces 88 : with one another for periodic boundary conditions. That is, each element must 89 : have \f$2^{dim}\f$ distinct corner numbers. If you wish to additionally 90 : identify faces of the same block with each other, that must be done in an 91 : additional step. This step is explained in the "Setting Periodic Boundary 92 : Conditions" section. 93 : 94 : ### The Ordered Subset of the Global CNS (Subset CNS): 95 : With the Global CNS in hand, each Block inherits an ordered subset of Global 96 : CNS. The ordering in this set is determined by the ordering of the Local CNS, 97 : and the elements of the set determined by how one assigned the Global CNS to 98 : the Domain. For the image above, the Subset CNS corresponding to the left block 99 : is {0, 1, 3, 4, 6, 7, 9, 10}, while the Subset CNS corresponding to the right 100 : block is {1, 4, 7, 10, 2, 5, 8, 11}. This ordering of the Subset CNS encodes 101 : the relative orientations between each Block. Subset CNSs need to be provided 102 : for each Block in a Domain. It turns out that for very regular domains, 103 : (i.e. spherical or rectilinear) we can generate the appropriate Subset CNSs. 104 : As this is a conceptual tutorial, how to construct these domains in SpECTRE 105 : is described in the \ref tutorial_domain_creation tutorial. 106 : 107 : ### Explanation of the Algorithms in DomainHelpers: 108 : 109 : For illustrative purposes, we will use the following Domain composed of two 110 : Blocks as described above as an example. 111 : Because there are 12 corners in this Domain, we will arbitrarily assign a 112 : unique id to each corner. 113 : Knowing the orientation of the logical axes within a block, we construct a 114 : Subset CNS for each Block.
115 : Here is one possible result, given some relative orientation between the 116 : blocks: 117 : 118 :  119 : Block1: {0, 1, 3, 4, 6, 7, 9, 10} 120 : Block2: {1, 4, 7, 10, 2, 5, 8, 11} 121 :  122 : 123 : The values of the ids only serve to identify which corners are unique and which 124 : are shared. This is determined by the Global CNS. The order of the ids in the 125 : list is determined by the Local CNS. We take advantage of the fact that the 126 : array index of the global corner id is the number of the corner in the local 127 : CNS. 128 : 129 : The algorithm begins by determining the shared corners between the 130 : Blocks: 131 : 132 :  133 : result: {1, 4, 7, 10} 134 :  135 : 136 : The next step is to determine the local ids of these shared global ids: 137 : 138 :  139 : Block1 result: {1,3,5,7} 140 : Block2 result: {0,1,2,3} 141 :  142 : 143 : The next step is to convert these ids into their binary representation. 144 : For reference, we give the binary representation for each number 0-7: 145 : 146 :  147 : Corner 0: 000 148 : Corner 1: 001 149 : Corner 2: 010 150 : Corner 3: 011 151 : Corner 4: 100 152 : Corner 5: 101 153 : Corner 6: 110 154 : Corner 7: 111 155 :  156 : 157 : Here 0 and 1 indicate lower and upper in the corresponding axis (zeta, 158 : eta, xi), respectively, and the ordering has been reversed so that the 159 : rightmost column corresponds to the xi position and the leftmost column 160 : to the zeta position. Returning to the example at hand, we have: 161 : 162 : 163 :  164 : Block1 result: {001,011,101,111} 165 : Block2 result: {000,001,010,011} 166 :  167 : 168 : Note that we can now read off the shared face relative to each Block 169 : easily: 170 : 171 :  172 : Block1 result: Upper xi (All binary Block1 ids have a 1 in the third position) 173 : Block2 result: Lower zeta (All binary Block2 ids have a 0 in the first position) 174 :  175 : 176 : Now we know that Direction<3>::%upper_xi() 177 : in Block1 corresponds to Direction<3>::%lower_zeta().%opposite() in Block2. 178 : 179 : The use of .%opposite() is a result of the Directions to a Block face being 180 : anti-parallel because each Block lies on the opposite side of the shared face. 181 :
182 : 183 : The remaining two correspondences are given by the alignment of the shared 184 : face. It is useful to know the following information:
185 : In the Local CNS, if an edge lies along the xi direction, if one takes the 186 : two corners making up that edge and takes the difference of their ids, one 187 : always gets the result \f$\pm 1\f$. Similarly, if the edge lies in the eta 188 : direction, the result will be \f$\pm 2\f$. Finally, if the edge lies in the 189 : zeta direction, the result will be \f$\pm 4\f$. We use this information to 190 : determine the alignment of the shared face: 191 : 192 :  193 : Block1: 3-1=2 => This edge is in the +eta direction. 194 : Block2: 1-0=1 => This edge is in the +xi direction. 195 : Then, +eta in Block1 corresponds to +xi in Block2. 196 : 197 : Block1: 5-1=4 => This edge is in the +zeta direction. 198 : Block2: 2-0=2 => This edge is in the +eta direction. 199 : Then, +zeta in Block1 corresponds to +eta in Block2. 200 :  201 : 202 : The corresponding directions in each Block have now been deduced. 203 : 204 : To confirm, we can use the other ids as well and arrive at the same result:
205 : 206 :  207 : Block1: 7-5=2 => +eta 208 : Block2: 3-2=1 => +xi 209 : 210 : Block1: 7-3=4 => +zeta 211 : Block2: 3-1=2 => +eta 212 :  213 : 214 : ### Setting Periodic Boundary Conditions 215 : It is also possible to identify faces of a Block using the subset CNS. For 216 : example, to identify the lower zeta face with the upper zeta face of a Block 217 : where the corners are labeled {3,0,4,1,9,6,10,7}, one may supply the lists 218 : {3,0,4,1} and {9,6,10,7} to the set_identified_boundaries function. 219 : \note The set_identified_boundaries function is sensitive to the order of the 220 : corners in the lists supplied as arguments. This is because the function 221 : identifies corners and edges with each other as opposed to simply faces. This 222 : allows the user to specify more peculiar boundary conditions. For example, 223 : using {3,0,4,1} and {6,7,9,10} to set the periodic boundaries will identify 224 : the lower zeta face with the upper zeta face, but after a rotation of a 225 : quarter-turn. 226 : 227 : For reference, here are the corners to use for each face for a Block with 228 : corners labelled as {0,1,2,3,4,5,6,7} to set up periodic boundary conditions 229 : in each dimension, i.e. a \f$\mathrm{T}^3\f$ topology: 230 : 231 : Face | Corners 232 : ------|-------- 233 : upper xi| {1,3,5,7} 234 : lower xi| {0,2,4,6} 235 : upper eta| {2,3,6,7} 236 : lower eta| {0,1,4,5} 237 : upper zeta| {4,5,6,7} 238 : lower zeta| {0,1,2,3} 

 Generated by: LCOV version 1.14