Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
OutputFld.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: OutputFld.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: FLD file format output.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <set>
37 #include <string>
38 using namespace std;
39 
40 #include "OutputFld.h"
41 
42 namespace Nektar
43 {
44 namespace Utilities
45 {
46 
47 ModuleKey OutputFld::m_className[2] = {
49  ModuleKey(eOutputModule, "fld"), OutputFld::create,
50  "Writes a Fld file."),
52  ModuleKey(eOutputModule, "chk"), OutputFld::create,
53  "Writes a Fld file."),
54 };
55 
56 OutputFld::OutputFld(FieldSharedPtr f) : OutputModule(f)
57 {
58 }
59 
61 {
62 }
63 
64 void OutputFld::Process(po::variables_map &vm)
65 {
66  // Extract the output filename and extension
67  string filename = m_config["outfile"].as<string>();
68 
69  if (m_f->m_writeBndFld)
70  {
71  ModuleKey module;
72 
73  // Extract data to boundaryconditions
74  if (m_f->m_fldToBnd)
75  {
76  for (int i = 0; i < m_f->m_exp.size(); ++i)
77  {
78  m_f->m_exp[i]->FillBndCondFromField();
79  }
80  }
81 
82  if (m_f->m_verbose)
83  {
84  cout << "OutputFld: Writing boundary file(s): ";
85  for(int i = 0; i < m_f->m_bndRegionsToWrite.size(); ++i)
86  {
87  if(i < m_f->m_bndRegionsToWrite.size()-1)
88  {
89  cout << ",";
90  }
91  }
92  cout << endl;
93  }
94 
95  int nfields = m_f->m_exp.size();
96  Array<OneD, Array<OneD, const MultiRegions::ExpListSharedPtr> >
97  BndExp(nfields);
98  for (int i = 0; i < nfields; ++i)
99  {
100  BndExp[i] = m_f->m_exp[i]->GetBndCondExpansions();
101  }
102 
103  // get hold of partition boundary regions so we can match it to desired
104  // region extraction
106  m_f->m_exp[0]->GetGraph());
108  bcs.GetBoundaryRegions();
109  SpatialDomains::BoundaryRegionCollection::const_iterator breg_it;
110  map<int,int> BndRegionMap;
111  int cnt =0;
112  for(breg_it = bregions.begin(); breg_it != bregions.end();
113  ++breg_it, ++cnt)
114  {
115  BndRegionMap[breg_it->first] = cnt;
116  }
117 
118  // find ending of output file and insert _b1, _b2
119  int dot = filename.find_last_of('.') + 1;
120  string ext = filename.substr(dot, filename.length() - dot);
121  string name = filename.substr(0, dot-1);
122 
124  m_f->m_session->GetBndRegionOrdering();
125 
126  for(int i = 0; i < m_f->m_bndRegionsToWrite.size(); ++i)
127  {
128  string outname = name + "_b"
129  + boost::lexical_cast<string>(m_f->m_bndRegionsToWrite[i])
130  + "." + ext;
131 
132  std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
133  std::vector<std::vector<NekDouble> > FieldData;
134 
135  if(BndRegionMap.count(m_f->m_bndRegionsToWrite[i]) == 1)
136  {
137  int Border = BndRegionMap[m_f->m_bndRegionsToWrite[i]];
138 
139  FieldDef = BndExp[0][Border]->GetFieldDefinitions();
140  FieldData.resize(FieldDef.size());
141 
142  for (int j = 0; j < nfields; ++j)
143  {
144  for (int k = 0; k < FieldDef.size(); ++k)
145  {
146  BndExp[j][Border]->AppendFieldData(FieldDef[k],
147  FieldData[k]);
148 
149  FieldDef[k]->m_fields.push_back(m_f->m_fielddef[0]->
150  m_fields[j]);
151  }
152  }
153 
154  // output error for regression checking.
155  if (vm.count("error"))
156  {
157  int rank = m_f->m_session->GetComm()->GetRank();
158 
159  for (int j = 0; j < nfields; ++j)
160  {
161  BndExp[j][Border]->BwdTrans(BndExp[j][Border]->GetCoeffs(),
162  BndExp[j][Border]->UpdatePhys());
163 
164  //Note currently these calls will
165  //hange since not all partitions will
166  //call error.
167  NekDouble l2err = BndExp[j][Border]
168  ->L2(BndExp[j][Border]->GetPhys());
169 
170  NekDouble linferr = BndExp[j][Border]
171  ->Linf(BndExp[j][Border]->GetPhys());
172 
173  if (rank == 0)
174  {
175  cout << "L 2 error (variable "
176  << FieldDef[0]->m_fields[j]
177  << ") : " << l2err << endl;
178 
179  cout << "L inf error (variable "
180  << FieldDef[0]->m_fields[j]
181  << ") : " << linferr << endl;
182  }
183  }
184  }
185  }
186 
187  m_f->m_fld->Write(outname, FieldDef, FieldData);
188 
189  }
190  }
191  else
192  {
193  if (m_f->m_verbose)
194  {
195  cout << "OutputFld: Writing file..." << endl;
196  }
197 
198  // Write the output file
199  m_f->m_fld->Write(filename, m_f->m_fielddef, m_f->m_data);
200 
201 
202  // output error for regression checking.
203  if (vm.count("error"))
204  {
205  int rank = m_f->m_session->GetComm()->GetRank();
206 
207  for (int j = 0; j < m_f->m_exp.size(); ++j)
208  {
209  if (m_f->m_exp[j]->GetPhysState() == false)
210  {
211  m_f->m_exp[j]->BwdTrans(
212  m_f->m_exp[j]->GetCoeffs(),
213  m_f->m_exp[j]->UpdatePhys());
214  }
215 
216  NekDouble l2err = m_f->m_exp[j]->L2(
217  m_f->m_exp[j]->GetPhys());
218 
219  NekDouble linferr = m_f->m_exp[j]->Linf(
220  m_f->m_exp[j]->GetPhys());
221  if (rank == 0)
222  {
223  cout << "L 2 error (variable "
224  << m_f->m_fielddef[0]->m_fields[j]
225  << ") : " << l2err << endl;
226 
227  cout << "L inf error (variable "
228  << m_f->m_fielddef[0]->m_fields[j]
229  << ") : " << linferr << endl;
230  }
231  }
232  }
233 
234  }
235 }
236 
237 }
238 }