CG  Version 25
interfaceMacros.h
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------
2 // This file contains macros used by the interface routines.
3 //------------------------------------------------------------------------------------
4 
5 
6 
7 // ===========================================================================
8 // Get/set the interface RHS for a heat flux interface
9 // ===========================================================================
10 #beginMacro heatFluxInterfaceRightHandSide(LABEL)
11 
12 real *a = info.a;
13 
14 if( debug() & 4 )
15 {
16  printP("LABEL::interfaceRHS:heatFlux %s RHS for (side,axis,grid)=(%i,%i,%i) a=[%5.2f,%5.2f]"
17  " t=%9.3e gfIndex=%i (current=%i)\n",
18  (option==0 ? "get" : "set"),side,axis,grid,a[0],a[1],t,gfIndex,current);
19 }
20 
21 const int tc = parameters.dbase.get<int >("tc");
22 assert( tc>=0 );
23 Range N(tc,tc);
24 
25 // We could optimize this for rectangular grids
26 mg.update(MappedGrid::THEvertexBoundaryNormal);
27 #ifdef USE_PPP
28 const realSerialArray & normal = mg.vertexBoundaryNormalArray(side,axis);
29 #else
30 const realSerialArray & normal = mg.vertexBoundaryNormal(side,axis);
31 #endif
32 
33 
34 if( option==setInterfaceRightHandSide )
35 {
36  // **** set the RHS *****
37  // (TZ is done below)
38 
39  bd(I1,I2,I3,tc)=f(I1,I2,I3,tc);
40  if( false )
41  {
42  ::display(bd(I1,I2,I3,tc)," RHS values","%4.2f ");
43  }
44 
45 }
46 else if( option==getInterfaceRightHandSide )
47 {
48 
49  // **** get the RHS ****
50 
51  realMappedGridFunction & u = gf[gfIndex].u[grid];
52 #ifdef USE_PPP
53  realSerialArray uLocal; getLocalArrayWithGhostBoundaries(u,uLocal);
54 #else
55  realSerialArray & uLocal = gf[gfIndex].u[grid];
56 #endif
57 
58 
59  f(I1,I2,I3,tc) = a[0]*uLocal(I1,I2,I3,tc);
60 
61  if( a[1]!=0. )
62  {
63  // add on a[1]*( nu*u.n ) on the boundary
64 
65  // **be careful** -- the normal changes sign on the two sides of the interface ---
66  MappedGridOperators & op = *(u.getOperators());
67 
68  realSerialArray ux(I1,I2,I3,N), uy(I1,I2,I3,N);
69 
70  op.derivative(MappedGridOperators::xDerivative,uLocal,ux,I1,I2,I3,N);
71  op.derivative(MappedGridOperators::yDerivative,uLocal,uy,I1,I2,I3,N);
72 
73  if( cg.numberOfDimensions()==2 )
74  {
75  f(I1,I2,I3,tc) += a[1]*( normal(I1,I2,I3,0)*ux + normal(I1,I2,I3,1)*uy );
76  }
77  else
78  {
79  realSerialArray uz(I1,I2,I3);
80  op.derivative(MappedGridOperators::zDerivative,uLocal,uz,I1,I2,I3,N);
81  f(I1,I2,I3,tc) += a[1]*( normal(I1,I2,I3,0)*ux + normal(I1,I2,I3,1)*uy + normal(I1,I2,I3,2)*uz );
82  }
83 
84  }
85 
86  if( debug() & 4 )
87  {
88  ::display(f(I1,I2,I3,tc) ,sPrintF("getRHS: %f*u + %f*( u.n ) ",a[0],a[1]));
89  }
90 
91 }
92 else
93 {
94  printF("LABEL::interfaceRightHandSide:ERROR: unknown option=%i\n",option);
95  Overture::abort("error");
96 }
97 
98 if( // false && // turn this off for testing the case where the same TZ holds across all domains
99  parameters.dbase.get<bool >("twilightZoneFlow") )
100 {
101  // ---add forcing for twlight-zone flow---
102 
103  OGFunction & e = *(parameters.dbase.get<OGFunction* >("exactSolution"));
104 
105  const bool isRectangular = false; // ** do this for now ** mg.isRectangular();
106 
107  if( !isRectangular )
108  mg.update(MappedGrid::THEcenter);
109 
110  realArray & x= mg.center();
111 #ifdef USE_PPP
112  realSerialArray xLocal;
113  if( !isRectangular )
114  getLocalArrayWithGhostBoundaries(x,xLocal);
115 #else
116  const realSerialArray & xLocal = x;
117 #endif
118 
119  realSerialArray ue(I1,I2,I3,N);
120  if( a[0]!=0. )
121  {
122  e.gd( ue ,xLocal,numberOfDimensions,isRectangular,0,0,0,0,I1,I2,I3,N,t); // exact solution
123 
124  ue(I1,I2,I3,N) = a[0]*ue(I1,I2,I3,N);
125  }
126  else
127  {
128  ue(I1,I2,I3,N) =0.;
129  }
130 
131  if( a[1]!=0. )
132  {
133  realSerialArray uex(I1,I2,I3,N), uey(I1,I2,I3,N);
134 
135  e.gd( uex ,xLocal,numberOfDimensions,isRectangular,0,1,0,0,I1,I2,I3,N,t);
136  e.gd( uey ,xLocal,numberOfDimensions,isRectangular,0,0,1,0,I1,I2,I3,N,t);
137  if( numberOfDimensions==2 )
138  {
139  ue(I1,I2,I3,N) += a[1]*( normal(I1,I2,I3,0)*uex + normal(I1,I2,I3,1)*uey );
140  }
141  else
142  {
143  realSerialArray uez(I1,I2,I3,N);
144  e.gd( uez ,xLocal,numberOfDimensions,isRectangular,0,0,0,1,I1,I2,I3,N,t);
145 
146  ue(I1,I2,I3,N) += a[1]*( normal(I1,I2,I3,0)*uex + normal(I1,I2,I3,1)*uey + normal(I1,I2,I3,2)*uez );
147  }
148  }
149 
150  if( option==getInterfaceRightHandSide )
151  { // get
152  // subtract off TZ flow:
153  // f <- f - ( a[0]*ue + a[1]*( nu*ue.n ) )
154  if( false )
155  {
156  ::display(f(I1,I2,I3,tc) ," a[0]*u + a[1]*( k u.n )");
157  ::display(ue(I1,I2,I3,tc)," a[0]*ue + a[1]*( k ue.n )");
158  }
159  f(I1,I2,I3,tc) -= ue(I1,I2,I3,N);
160  if( false )
161  {
162  ::display(f(I1,I2,I3,tc) ," a[0]*u + a[1]*( k u.n ) - [a[0]*ue + a[1]*( k ue.n )]");
163  }
164  }
165  else if( option==setInterfaceRightHandSide )
166  { // set
167  // add on TZ flow:
168  // bd <- bd + a[0]*ue + a[1]*( nu*ue.n )
169  bd(I1,I2,I3,tc) += ue(I1,I2,I3,N);
170 
171  if( false )
172  {
173  bd(I1,I2,I3,tc) = ue(I1,I2,I3,N);
174  }
175 
176 
177  }
178  else
179  {
180  Overture::abort("error");
181  }
182 
183 } // end if TZ
184 #endMacro