Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FldAddScalGrad.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <cstdlib>
3 
4 #include <MultiRegions/ExpList.h>
10 
11 using namespace Nektar;
12 
13 int main(int argc, char *argv[])
14 {
15  int i,j;
16  int surfID;
17 
18  if(argc != 5)
19  {
20  fprintf(stderr,"Usage: FldAddScalGrad meshfile infld outfld BoundaryID\n");
21  exit(1);
22  }
23 
24  surfID = boost::lexical_cast<int>(argv[argc - 1]);
25 
26  argv[argc -1] = argv[argc - 2];
27 
30 
31  //----------------------------------------------
32  // Read in mesh from input file
33  string meshfile(argv[argc-4]);
35  //----------------------------------------------
36 
37  //----------------------------------------------
38  // Import field file.
39  string fieldfile(argv[argc-3]);
40  vector<LibUtilities::FieldDefinitionsSharedPtr> fielddef;
41  vector<vector<NekDouble> > fielddata;
42  LibUtilities::Import(fieldfile,fielddef,fielddata);
43  //----------------------------------------------
44 
45  //----------------------------------------------
46  // Define Expansion
47  int expdim = graphShPt->GetMeshDimension();
48  int nfields = 1;
49  int addfields = 1;
50  Array<OneD, MultiRegions::ExpListSharedPtr> exp(nfields + addfields);
51  MultiRegions::AssemblyMapCGSharedPtr m_locToGlobalMap;
52 
53  switch(expdim)
54  {
55  case 1:
56  {
57  ASSERTL0(false,"Expansion dimension not recognised");
58  }
59  break;
60  case 2:
61  {
62  ASSERTL0(false,"Expansion dimension not recognised");
63  }
64  break;
65  case 3:
66  {
69  ::AllocateSharedPtr(vSession, graphShPt,
70  vSession->GetVariable(0));
71 
72  m_locToGlobalMap = originalfield->GetLocalToGlobalMap();
73 
74  exp[0] = originalfield;
75 
77  ::AllocateSharedPtr(*originalfield, graphShPt,
78  vSession->GetVariable(0));
79  }
80  break;
81  default:
82  ASSERTL0(false,"Expansion dimension not recognised");
83  break;
84  }
85  //----------------------------------------------
86 
87  //----------------------------------------------
88  // Copy data from field file
89  for(j = 0; j < nfields+addfields; ++j)
90  {
91  for(int i = 0; i < fielddata.size(); ++i)
92  {
93  exp[j]->ExtractDataToCoeffs(fielddef [i],
94  fielddata[i],
95  fielddef [i]->m_fields[0],
96  exp[j]->UpdateCoeffs());
97  }
98 
99  exp[j]->BwdTrans(exp[j]->GetCoeffs(),exp[j]->UpdatePhys());
100  }
101 
102 
103  //----------------------------------------------
104 
105  //----------------------------------------------
106  int n, cnt, elmtid, nq, offset, nt, boundary, nfq;
107  nt = exp[0]->GetNpoints();
108  Array<OneD, Array<OneD, NekDouble> > grad(expdim);
109  Array<OneD, Array<OneD, NekDouble> > fgrad(expdim);
110 
111  // Set up mapping from Boundary condition to element details.
114  Array<OneD, int> BoundarytoElmtID;
115  Array<OneD, int> BoundarytoTraceID;
116  Array<OneD, MultiRegions::ExpListSharedPtr> BndExp;
117  Array<OneD, const NekDouble> U(nt);
118  Array<OneD, NekDouble> values;
119  Array<OneD, NekDouble> outvalues;
120 
121  exp[0]->GetBoundaryToElmtMap(BoundarytoElmtID,BoundarytoTraceID);
122 
123  //get boundary expansions for each field
124  BndExp = exp[0]->GetBndCondExpansions();
125 
126  // loop over the types of boundary conditions
127  for(cnt = n = 0; n < BndExp.num_elements(); ++n)
128  {
129  // identify boundary which the user wanted
130  if(n == surfID)
131  {
132  for(i = 0; i < BndExp[n]->GetExpSize(); ++i, cnt++)
133  {
134  // find element and face of this expansion.
135  elmtid = BoundarytoElmtID[cnt];
136  elmt = exp[0]->GetExp(elmtid);
137  nq = elmt->GetTotPoints();
138  offset = exp[0]->GetPhys_Offset(elmtid);
139 
140  // Initialise local arrays for the velocity gradients
141  // size of total number of quadrature points for each element (hence local).
142  for(j = 0; j < expdim; ++j)
143  {
144  grad[j] = Array<OneD, NekDouble>(nq);
145  }
146 
147  if(expdim == 2)
148  {
149  //identify boundary of element
150  boundary = BoundarytoTraceID[cnt];
151 
152  //Extract scalar field
153  U = exp[0]->GetPhys() + offset;
154 
155  //Compute gradients (velocity correction scheme method)
156  elmt->PhysDeriv(MultiRegions::DirCartesianMap[0],U,grad[0]);
157  elmt->PhysDeriv(MultiRegions::DirCartesianMap[1],U,grad[1]);
158 
159  // Get face 2D expansion from element expansion
160  bc = boost::dynamic_pointer_cast<StdRegions::StdExpansion2D> (BndExp[n]->GetExp(i));
161 
162 
163  for(j = 0; j < expdim; ++j)
164  {
165  fgrad[j] = Array<OneD, NekDouble>(nq);
166  }
167 
168  //identify boundary of element looking at.
169  boundary = BoundarytoTraceID[cnt];
170 
171  // Get face stress values.
172  for(j = 0; j < expdim; ++j)
173  {
174  elmt->GetFacePhysVals(boundary,bc,grad[j],fgrad[j]);
175  }
176 
177 
178  // calcuate wss, and update velocity coefficients in the elemental boundary expansion
179  values = BndExp[n]->UpdateCoeffs()+BndExp[n]->GetCoeff_Offset(i);
180  bc->NormVectorIProductWRTBase(fgrad[0],fgrad[1],values);
181  }
182  else
183  {
184  // Get face 2D expansion from element expansion
185  bc = boost::dynamic_pointer_cast<StdRegions::StdExpansion2D> (BndExp[n]->GetExp(i));
186 
187  // Number of face quadrature points
188  nfq = bc->GetTotPoints();
189 
190  //identify boundary of element
191  boundary = BoundarytoTraceID[cnt];
192 
193  //Extract scalar field
194  U = exp[0]->GetPhys() + offset;
195 
196  //Compute gradients
197  elmt->PhysDeriv(U,grad[0],grad[1],grad[2]);
198 
199  for(j = 0; j < expdim; ++j)
200  {
201  fgrad[j] = Array<OneD, NekDouble>(nfq);
202  }
203 
204  // Get gradient at the quadrature points of the face
205  for(j = 0; j < expdim; ++j)
206  {
207  elmt->GetFacePhysVals(boundary,bc,grad[j],fgrad[j]);
208  }
209 
210  const SpatialDomains::GeomFactorsSharedPtr m_metricinfo=bc->GetMetricInfo();
211 
212  const Array<OneD, const Array<OneD, NekDouble> > normals
213  = elmt->GetFaceNormal(boundary);
214 
215  Array<OneD, NekDouble> gradnorm(nfq);
216 
217  // calcuate gradient and update coefficients in the elemental boundary expansion
218  values = BndExp[n]->UpdateCoeffs() + BndExp[n]->GetCoeff_Offset(i);
219 
220  if (m_metricinfo->GetGtype() == SpatialDomains::eDeformed)
221  {
222  Vmath::Vvtvvtp(nfq,normals[0],1,fgrad[0],1,
223  normals[1],1,fgrad[1],1,gradnorm,1);
224  Vmath::Vvtvp (nfq,normals[2],1,fgrad[2],1,gradnorm,1,gradnorm,1);
225  }
226  else
227  {
228  Vmath::Svtsvtp(nfq,normals[0][0],fgrad[0],1,
229  normals[1][0],fgrad[1],1,gradnorm,1);
230  Vmath::Svtvp(nfq,normals[2][0],fgrad[2],1,gradnorm,1,gradnorm,1);
231  }
232 
233  //gradient (grad(u) n)
234  Vmath::Smul(nfq,-1.0,gradnorm,1,gradnorm,1);
235  bc->FwdTrans(gradnorm,values);
236  }
237  }
238 
239  }
240  else
241  {
242  cnt += BndExp[n]->GetExpSize();
243  }
244  }
245 
246  int ncoeffs = exp[1]->GetNcoeffs();
247  Array<OneD, NekDouble> output(ncoeffs);
248 
249  output=exp[1]->UpdateCoeffs();
250 
251  int nGlobal=m_locToGlobalMap->GetNumGlobalCoeffs();
252  Array<OneD, NekDouble> outarray(nGlobal,0.0);
253 
254  int bndcnt=0;
255 
256  const Array<OneD,const int>& map = m_locToGlobalMap->GetBndCondCoeffsToGlobalCoeffsMap();
257 
258  for(i = 0; i < BndExp.num_elements(); ++i)
259  {
260  if(i==surfID)
261  {
262  const Array<OneD,const NekDouble>& coeffs = BndExp[i]->GetCoeffs();
263  for(int k = 0; k < (BndExp[i])->GetNcoeffs(); ++k)
264  {
265  outarray[map[bndcnt++]] = coeffs[k];
266  }
267  }
268  else
269  {
270  bndcnt += BndExp[i]->GetNcoeffs();
271  }
272  }
273  m_locToGlobalMap->GlobalToLocal(outarray,output);
274 
275  //-----------------------------------------------
276  // Write solution to file with additional computed fields
277  string out(argv[argc-2]);
278  std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef
279  = exp[0]->GetFieldDefinitions();
280  std::vector<std::vector<NekDouble> > FieldData(FieldDef.size());
281 
282  vector<string > outname;
283 
284  outname.push_back("gradient");
285 
286 
287  for(j = 0; j < nfields+addfields; ++j)
288  {
289  for(i = 0; i < FieldDef.size(); ++i)
290  {
291  if (j >= nfields)
292  {
293  FieldDef[i]->m_fields.push_back(outname[j-nfields]);
294  }
295  else
296  {
297  FieldDef[i]->m_fields.push_back(fielddef[i]->m_fields[j]);
298  }
299  exp[j]->AppendFieldData(FieldDef[i], FieldData[i]);
300  }
301  }
302 
303  LibUtilities::Write(out, FieldDef, FieldData);
304  //-----------------------------------------------
305 
306  return 0;
307 }