Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
face.cpp
Go to the documentation of this file.
1 /* *******************************************************************
2  * Illinois Open Source License *
3  * *
4  * University of Illinois/NCSA *
5  * Open Source License *
6  * *
7  * Copyright@2008, University of Illinois. All rights reserved. *
8  * *
9  * Developed by: *
10  * *
11  * Center for Simulation of Advanced Rockets *
12  * *
13  * University of Illinois *
14  * *
15  * www.csar.uiuc.edu *
16  * *
17  * Permission is hereby granted, free of charge, to any person *
18  * obtaining a copy of this software and associated documentation *
19  * files (the "Software"), to deal with the Software without *
20  * restriction, including without limitation the rights to use, *
21  * copy, modify, merge, publish, distribute, sublicense, and/or *
22  * sell copies of the Software, and to permit persons to whom the *
23  * Software is furnished to do so, subject to the following *
24  * conditions: *
25  * *
26  * *
27  * @ Redistributions of source code must retain the above copyright *
28  * notice, this list of conditions and the following disclaimers. *
29  * *
30  * @ Redistributions in binary form must reproduce the above *
31  * copyright notice, this list of conditions and the following *
32  * disclaimers in the documentation and/or other materials *
33  * provided with the distribution. *
34  * *
35  * @ Neither the names of the Center for Simulation of Advanced *
36  * Rockets, the University of Illinois, nor the names of its *
37  * contributors may be used to endorse or promote products derived *
38  * from this Software without specific prior written permission. *
39  * *
40  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
41  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
42  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
43  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
44  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
45  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
46  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
47  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
48  *********************************************************************
49  * Please acknowledge The University of Illinois Center for *
50  * Simulation of Advanced Rockets in works and publications *
51  * resulting from this software or its derivatives. *
52  *********************************************************************/
53 /*
54 A face is one side of a block of data, which
55 may be adjacent to many other faces and/or the
56 outside world.
57 Faces are split up into homogenous, rectangular
58 "patches" for output.
59 
60 Orion Sky Lawlor, olawlor@acm.org, 6/8/2001
61 */
62 #include <stdio.h>
63 #include "makeflo.h"
64 #include "face.h"
65 
66 
67 /*********** Orientation-matching utilities *********/
68 
69 //Return the index of the first nonzero coordinate
70 static int firstSet(const blockLoc &l)
71 {
72  for (int i=0;i<3;i++)
73  if (l[i]!=0)
74  return i;
75  //If we get here, all coordinates are zero-- very bad
76  fprintf(stderr,"ERROR! %s:%d> Orientation vector all zeros!\n",
77  __FILE__,__LINE__);
78  abort();
79  return -1;
80 }
81 
82 //Find the one number in {0,1,2} not equal to a or b
83 static int findOther(int a,int b)
84 {
85  int ret=0;
86  while (a==ret || b==ret)
87  ret++; //Keep looking
88  return ret; //Found it!
89 }
90 
91 //Match up the src and dest axis orientations
92 // for the given patch using the given directions,
93 // which point in the face X and Y directions in
94 // the source and dest blocks.
95 static void matchOrientations(orient_t &orient,
96  const blockLoc &sX,const blockLoc &sY,
97  const blockLoc &dX,const blockLoc &dY)
98 {
99  //Compute the block orientations in the face X and Y axes
100  int sOX=firstSet(sX),sOY=firstSet(sY);
101  int dOX=firstSet(dX),dOY=firstSet(dY);
102 
103  //Match up the orientations along the face
104  orient[sOX]=dOX;
105  orient[sOY]=dOY;
106 
107  //The remaining orientation is found by the
108  // process of elimination
109  orient[findOther(sOX,sOY)]=findOther(dOX,dOY);
110 }
111 
112 
114 {
115  int dir_z=findOther(dir_x,dir_y);
116  if (at[dir_z]!=span.start[dir_z]) return NULL; //Wrong z-plane
117  else return nodes[loc2node(at)];
118 }
119 
121 {
122  int i,len=patches.size();
123  for (i=0;i<len;i++)
124  if (patches[i]->srcSpan.contains(at))
125  return patches[i];
126  return NULL;
127 }
128 
129 /************** Face *************/
130 //Attach the block to all this face's nodes
132  vector<externalBCpatch> &extBCs_,int dir_x_,int dir_y_,
133  const blockSpan &span_)
134  :source(source_), extBCs(extBCs_), dir_x(dir_x_), dir_y(dir_y_),
135  span(span_)
136 {
140  { //Don't bother about this face-- it's the Z face of a 2D problem
141  nodes=NULL;
142  return;
143  }
144  nodes=new node*[nx*ny];
145  blockLoc i;
146  BLOCKSPAN_FOR(i,span) {
147  vector3d nodeLoc=source->getLoc(i);
148  node *nu=map.loc2node(nodeLoc);
149  nu->addFace(this,i);
150 
151  if (nu->getLength()>(3*8)) {
152  fprintf(stderr,"WARNING: multiply shared node %p: (%d,%d,%d) for block %d:",
153  nu,i[0],i[1],i[2],source->getOriginalNumber()+1);
154  nu->print();
155  }
156  nodes[loc2node(i)]=nu;
157  }
158 }
159 
161  delete[] nodes;
162  for (unsigned int i=0;i<patches.size();i++)
163  delete patches[i];
164 }
165 
166 //Return true if these two spans share no interior points
167 bool isDisjoint(const blockSpan &a,const blockSpan &b) {
168  for (int axis=0;axis<2;axis++) {
169  if (a.start[axis]>=b.end[axis]-1) return true;
170  if (b.start[axis]>=a.end[axis]-1) return true;
171  }
172  return false;//No separating axis-- must have a shared point
173 }
174 
175 
176 //Represents a face of a single element, bordered by 4 nodes.
177 // used only inside getPatches
178 class facet {
179  face *dest;//The face we're next to (NULL if an exterior facet)
180  bool patched; //Have we been covered by a patch yet?
181 public:
182  //Empty constructor for array allocation
183  facet() { }
184  facet(const node **nbor,const face *source) {
185  dest=node::intersect(nbor,source);
186  patched=false;
187  }
188  face *getFace(void) const {return dest;}
189  bool isPatched(void) const {return patched;}
190  void markPatched(void) {patched=true;}
191  bool matches(const facet &o) const {
192  if (patched) return false;
193  return dest==o.dest;
194  }
195 };
196 //Mark these facets as patched
197 int face::markPatched(facet *b,const blockSpan &span)
198 {
199  int ret=0;
200  int bx=nx-1; /* ,by=ny-1; */ //Size of facet array
201  const blockLoc &s=span.start, &e=span.end;
202  //Mark all those facets as patched
203  for (int y=s[dir_y];y<e[dir_y]-1;y++)
204  for (int x=s[dir_x];x<e[dir_x]-1;x++) {
205  if (b[x+bx*y].isPatched()) {
206  fprintf(stderr,"FATAL ERROR patching block %d> external boundary conditions overlap!\n",
207  source->getBlockNumber()+1);
208  exit(1);
209  }
210  b[x+bx*y].markPatched();
211  ret++;
212  }
213  return ret;
214 }
215 
216 //Check if this facet orientation matches the nodes around (x,y)
217 bool face::nodesMatch(int x,int y,
218  const face *dest,const facetOrientation &o) const
219 {
220  if (dest==NULL) return true;
221  return nodes[(x )+nx*(y )]->hasLoc(dest,o.getDestLoc(x ,y ))
222  && nodes[(x+1)+nx*(y+1)]->hasLoc(dest,o.getDestLoc(x+1,y+1));
223 }
224 
225 //Find all the patch structures for this face.
226 //Must be called *after* all faces have been created.
228 {
229 #if 0
230  //Doublecheck that our nodes agree with our location
231  for (int y=0;y<ny;y++)
232  for (int x=0;x<nx;x++) {
233  if (!nodes[(x )+nx*(y )]->hasLoc(this,getSourceLoc(x,y)))
234  {
235  fprintf(stderr,"ERROR! Face/node location disagreement!\n");
236  abort();
237  }
238  }
239 #endif
240  if (nodes==NULL) return; //Disabled face
241 
242  //Build an array showing the connected face
243  // for each *element's* face-- or "facet"
244  int x,y; //Loop indices
245  int bx=nx-1,by=ny-1; //Size of facet array
246  facet *b=new facet[bx*by];//2D facet array (bx x by)
247  for (y=0;y<by;y++)
248  for (x=0;x<bx;x++) {
249  const node *nbor[4];
250  fillNeighbors(x,y,nbor);
251  b[x+bx*y]=facet(nbor,this);
252  }
253 
254  //Keep track of the number of facets patched so far
255  int nFacets=bx*by;
256  int nPatched=0;
257 
258  //Apply the existant internal boundary conditions
259  for (unsigned int ep=0;ep<patches.size();ep++) {
260  nPatched+=markPatched(b,patches[ep]->srcSpan);
261  }
262 
263  //Apply the external boundary conditions
264  for (unsigned int ec=0;ec<extBCs.size();ec++) {
265  const externalBCpatch &ep=extBCs[ec];
266  patch *p=new externalBCpatch(ep);
267  p->setFace(this);
268  patches.push_back(p);
269  nPatched+=markPatched(b,ep.srcSpan);
270  }
271 
272  //Extract each patch from the facet array
273  int itCount=0;//Runaway loop leash
274  while (nPatched<nFacets) {
275  int startX=-1, startY=-1;
276  //Find the first facet not yet patched
277  for (y=0;y<by && startY==-1;y++)
278  for (x=0;x<bx && startX==-1;x++)
279  if (!b[x+bx*y].isPatched()) {
280  startX=x;
281  startY=y;
282  }
283  //This facet touches the face "dest"
284  const facet &destFacet=b[startX+bx*startY];
285  face *dest=destFacet.getFace();
286  const node *nbor[4];
287  fillNeighbors(startX,startY,nbor);
288  facetOrientation o(nbor,this,startX,startY);
289 
290  //Extend the patch as far right as it will go
291  x=startX;
292  y=startY;
293  while (x<bx && b[x+bx*y].matches(destFacet) &&
294  nodesMatch(x,y,dest,o))
295  x++;
296  int endX=x;
297  if (startX==endX) {
298  blockLoc badLoc=getSourceLoc(startX,startY);
299  blockLoc sz=source->getDim();
300  fprintf(stderr,"ERROR! Face of block %d is non-conformal at node (%d,%d,%d) of (%d,%d,%d)\n",1+source->getOriginalNumber(),badLoc[0],badLoc[1],badLoc[2],sz[0],sz[1],sz[2]);
301  abort();
302  }
303  //Extend the patch as far down as it will go,
304  // marking those facets as patched (face=NULL)
305  for (y=startY;y<by;y++) {
306  bool rowValid=true;
307  for (x=startX;x<endX;x++)
308  if (!(b[x+bx*y].matches(destFacet) &&
309  nodesMatch(x,y,dest,o)))
310  rowValid=false;
311  if (!rowValid)
312  break;//Another block encountered
313  //If we get this far, the row is valid-- mark it
314  for (x=startX;x<endX;x++)
315  b[x+bx*y].markPatched();
316  nPatched+=endX-startX;
317  }
318  int endY=y;
319 
320 
321  //Build and return a patch structure
322  patch *p=NULL;
323  blockSpan srcSpan(getSourceLoc(startX,startY),
324  getSourceLoc(endX,endY)+blockLoc(1,1,1)
325  );
326 
327 #if 1 //Make sure new patch is disjoint from all old patches
328  for (unsigned int otherP=0;otherP<patches.size();otherP++)
329  if (!isDisjoint(srcSpan,patches[otherP]->srcSpan)) {
330  fprintf(stderr,"ERROR! Patches not disjoint!\n");
331  abort();
332  }
333 #endif
334 
335  if (dest==NULL)
336  { //An (unexpected) external boundary condition
337  int bcNo=0;//Default boundary condition number
338  p=new externalBCpatch(this,source,srcSpan,bcNo);
339  /* Warn user that we've fabricated a BC */
340  printf("Makeflo WARNING: Missing boundary condition (using zero) for original block %d,\n"
341  " split block %d, %s face, cells (%d,%d,%d) - (%d,%d,%d)\n",
344  1+srcSpan.start[0],1+srcSpan.start[1],1+srcSpan.start[2],
345  srcSpan.end[0],srcSpan.end[1],srcSpan.end[2]);
346  }
347  else
348  { //An internal boundary-- find other block's location
349  //Match up the orientations
350  orient_t src2dest;
351  matchOrientations(src2dest,
352  getSourceLoc(1,0)-getSourceLoc(0,0),
353  getSourceLoc(0,1)-getSourceLoc(0,0),
354  o.getDestLoc(1,0)-o.getDestLoc(0,0),
355  o.getDestLoc(0,1)-o.getDestLoc(0,0)
356  );
357  blockSpan destSpan(
358  o.getDestLoc(startX,startY),
359  o.getDestLoc(endX,endY)+blockLoc(1,1,1)
360  );
361  p=new internalBCpatch(
362  this,source,dest->getBlock(),
363  srcSpan,destSpan,
364  src2dest);
365  orient_t dest2src=src2dest.inverse();
366  destSpan.orient(srcSpan,dest2src);
367  dest->patches.push_back(new internalBCpatch(
368  dest,dest->getBlock(),source,
369  destSpan,srcSpan,
370  dest2src
371  ));
372  }
373  //Return the new patch
374  patches.push_back(p);
375 
376  if (itCount++>2000)
377  { //There can't be 2000 actual patches-- must be an error
378  fprintf(stderr,"ERROR! Runaway patching loop (%s:%d)!\n",
379  __FILE__,__LINE__);
380  abort();
381  }
382  }
383 
384  //Free the temporary block array
385  delete[] b;
386 }
387 
388 
389 
390 
391 
392 
393 
394 
395 
~face()
Definition: face.cpp:160
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed by
Definition: roccomf90.h:7
bool isDisjoint(const blockSpan &a, const blockSpan &b)
Definition: face.cpp:167
int getOriginalNumber(void) const
Definition: adj.h:220
int skipAxis
Definition: makeflo.h:92
block * source
Definition: face.h:91
face(block *source_, nodeMatcher &map, vector< externalBCpatch > &extBCs_, int dir_x_, int dir_y_, const blockSpan &span_)
Definition: face.cpp:131
node ** nodes
Definition: face.h:97
Definition: face.h:90
void int int REAL REAL * y
Definition: read.cpp:74
void addFace(face *b, const blockLoc &l)
Definition: adj.cpp:105
static void matchOrientations(orient_t &orient, const blockLoc &sX, const blockLoc &sY, const blockLoc &dX, const blockLoc &dY)
Definition: face.cpp:95
double s
Definition: blastest.C:80
Definition: face.cpp:178
block * getBlock(void) const
Definition: face.h:140
static int firstSet(const blockLoc &l)
Definition: face.cpp:70
node * nodeForCoord(const blockLoc &at)
Definition: face.cpp:113
node * loc2node(const vector3d &loc)
Definition: adj.cpp:230
face * getFace(void) const
Definition: face.cpp:188
int markPatched(facet *b, const blockSpan &span)
Definition: face.cpp:197
blockSpan srcSpan
Definition: patch.h:79
void print(void) const
Definition: adj.cpp:120
int getFaceNo(const face *f)
Definition: adj.h:250
Definition: adj.h:150
face * dest
Definition: face.cpp:179
blockLoc getSourceLoc(int x, int y) const
Definition: face.h:121
orient_t inverse(void) const
Definition: gridutil.h:82
void setFace(face *f_)
Definition: patch.h:81
patch * patchForCoord(const blockLoc &at)
Definition: face.cpp:120
Definition: adj.h:203
Definition: patch.h:74
#define BLOCKSPAN_FOR(i, span)
Definition: gridutil.h:230
blockLoc getDestLoc(int x, int y) const
Definition: face.h:82
static const char * face2name[nFaces]
Definition: adj.h:236
bool nodesMatch(int x, int y, const face *dest, const facetOrientation &o) const
Definition: face.cpp:217
blockLoc start
Definition: gridutil.h:155
static int findOther(int a, int b)
Definition: face.cpp:83
const blockDim & getDim(void) const
Definition: adj.h:222
blockLoc i
Definition: read.cpp:79
bool patched
Definition: face.cpp:180
void fillNeighbors(int x, int y, const node **nbor) const
Definition: face.h:100
void int int REAL * x
Definition: read.cpp:74
blockLoc end
Definition: gridutil.h:156
bool hasLoc(const face *test, const blockLoc &l) const
Definition: adj.cpp:99
facet(const node **nbor, const face *source)
Definition: face.cpp:184
vector< externalBCpatch > extBCs
Definition: face.h:92
void markPatched(void)
Definition: face.cpp:190
int getLength(void) const
Definition: adj.cpp:87
const vector3d & getLoc(const blockLoc &l) const
Definition: adj.h:223
int orient[3]
Definition: gridutil.h:78
static face * intersect(const node **nodes, const face *notHim=NULL, blockLoc *loc=NULL, blockLoc *oX=NULL, blockLoc *oY=NULL)
Definition: adj.cpp:136
int ny
Definition: face.h:98
facet()
Definition: face.cpp:183
int dir_x
Definition: face.h:95
void buildPatches(void)
Definition: face.cpp:227
makefloParam parameters
Definition: makeflo.cpp:101
int nx
Definition: face.h:98
blockSpan span
Definition: face.h:96
vector< patch * > patches
Definition: face.h:93
bool isPatched(void) const
Definition: face.cpp:189
bool matches(const facet &o) const
Definition: face.cpp:191
int getBlockNumber(void) const
Definition: adj.h:219
int loc2node(const blockLoc &l) const
Definition: face.h:117
int dir_y
Definition: face.h:95