Nektar++
ProcessInnerProduct.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: ProcessInnerProduct.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 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Compute inner product between two fields.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
35 #include <iostream>
36 #include <string>
37 using namespace std;
38 
39 #include <boost/core/ignore_unused.hpp>
40 
43 
44 #include "ProcessInnerProduct.h"
45 
46 namespace Nektar
47 {
48 namespace FieldUtils
49 {
50 
51 ModuleKey ProcessInnerProduct::className =
53  ModuleKey(eProcessModule, "innerproduct"), ProcessInnerProduct::create,
54  "take inner product between two fields and return value.");
55 
56 ProcessInnerProduct::ProcessInnerProduct(FieldSharedPtr f) : ProcessModule(f)
57 {
58  m_config["fromfld"] = ConfigOption(
59  false, "NotSet", "Fld file form which to interpolate field");
60  m_config["fields"] =
61  ConfigOption(false, "All", "field id's to be used in inner product");
62  m_config["multifldids"] =
63  ConfigOption(false, "NotSet",
64  "Take inner product of multiple field fields with "
65  "ids given in string. i.e. file_0.chk file_1.chk ...");
66  m_config["allfromflds"] =
67  ConfigOption(true, "0",
68  "Take inner product between all fromflds, "
69  "requires multifldids to be set");
70 }
71 
73 {
74 }
75 
76 void ProcessInnerProduct::v_Process(po::variables_map &vm)
77 {
78  m_f->SetUpExp(vm);
79 
80  // Skip in case of empty partition
81  if (m_f->m_exp[0]->GetNumElmts() == 0)
82  {
83  return;
84  }
85 
86  string fromfld = m_config["fromfld"].as<string>();
87  FieldSharedPtr fromField = std::shared_ptr<Field>(new Field());
88 
89  ASSERTL0(m_config["fromfld"].as<string>() != "NotSet",
90  "The config parameter "
91  "fromfld needs to be defined");
92 
93  // Set up ElementGIDs in case of parallel processing
94  Array<OneD, int> ElementGIDs(m_f->m_exp[0]->GetExpSize());
95  for (int i = 0; i < m_f->m_exp[0]->GetExpSize(); ++i)
96  {
97  ElementGIDs[i] = m_f->m_exp[0]->GetExp(i)->GetGeom()->GetGlobalID();
98  }
99 
100  int nfields = m_f->m_variables.size();
101  int nphys = m_f->m_exp[0]->GetTotPoints();
102  NekDouble totiprod;
103  string fields = m_config["fields"].as<string>();
104  vector<unsigned int> processFields;
105  string multifldidsstr = m_config["multifldids"].as<string>();
106  vector<unsigned int> multiFldIds;
107  vector<string> fromfiles;
108  bool allfromflds = m_config["allfromflds"].as<bool>();
109 
110  if (fields.compare("All") == 0)
111  {
112  for (int i = 0; i < nfields; ++i)
113  {
114  processFields.push_back(i);
115  }
116  }
117  else
118  {
119  ASSERTL0(ParseUtils::GenerateVector(fields, processFields),
120  "Failed to interpret field string in module innerproduct");
121  }
122 
123  if (multifldidsstr.compare("NotSet") == 0)
124  {
125  fromfiles.push_back(fromfld);
126  }
127  else
128  {
129  ASSERTL0(
130  ParseUtils::GenerateSeqVector(multifldidsstr, multiFldIds),
131  "Failed to interpret multifldids string in module innerproduct");
132  int end = fromfld.find_first_of('.', 0);
133  string endstr = fromfld.substr(end, fromfld.size());
134  string bodystr = fromfld.substr(0, end);
135  for (int i = 0; i < multiFldIds.size(); ++i)
136  {
137  string infile = bodystr + "_" +
138  boost::lexical_cast<string>(multiFldIds[i]) +
139  endstr;
140  fromfiles.push_back(infile);
141  }
142  }
143 
144  Array<OneD, Array<OneD, NekDouble>> SaveFld(processFields.size());
145  for (int j = 0; j < processFields.size(); ++j)
146  {
147  int fid = processFields[j];
148  SaveFld[j] = Array<OneD, NekDouble>(nphys);
149  m_f->m_exp[fid]->BwdTrans(m_f->m_exp[fid]->GetCoeffs(), SaveFld[j]);
150  }
151 
152  if (allfromflds == false)
153  {
154 
155  for (int f = 0; f < fromfiles.size(); ++f)
156  {
157  m_f->FieldIOForFile(fromfiles[f])
158  ->Import(fromfiles[f], fromField->m_fielddef, fromField->m_data,
160 
161  totiprod = IProduct(processFields, fromField, SaveFld);
162 
163  if (m_f->m_comm->GetSpaceComm()->GetRank() == 0)
164  {
165  cout << "Inner Product WRT " << fromfiles[f] << " : "
166  << totiprod << endl;
167  }
168  }
169  }
170  else // evaluate all from fields, first by loading them all up and then
171  // calling IProduct
172  {
173 
174  // Load all from fields.
175  Array<OneD, FieldSharedPtr> allFromField(fromfiles.size());
176  for (int i = 0; i < fromfiles.size(); ++i)
177  {
178  allFromField[i] = std::shared_ptr<Field>(new Field());
179 
180  m_f->FieldIOForFile(fromfiles[i])
181  ->Import(fromfiles[i], allFromField[i]->m_fielddef,
182  allFromField[i]->m_data,
184  }
185 
186  for (int g = 0; g < fromfiles.size(); ++g)
187  {
188  for (int j = 0; j < processFields.size(); ++j)
189  {
190  int fid = processFields[j];
191  Array<OneD, NekDouble> coeffs(m_f->m_exp[fid]->GetNcoeffs());
192  // load new field
193  for (int i = 0; i < allFromField[g]->m_data.size(); ++i)
194  {
195  m_f->m_exp[fid]->ExtractDataToCoeffs(
196  allFromField[g]->m_fielddef[i],
197  allFromField[g]->m_data[i], m_f->m_variables[fid],
198  coeffs);
199  }
200 
201  m_f->m_exp[fid]->BwdTrans(coeffs, SaveFld[j]);
202  }
203 
204  // take inner product from this g field with all other above
205  for (int f = g; f < fromfiles.size(); ++f)
206  {
207  totiprod = IProduct(processFields, allFromField[f], SaveFld);
208 
209  if (m_f->m_comm->GetSpaceComm()->GetRank() == 0)
210  {
211  cout << "Inner Product of " << fromfiles[g] << " WRT "
212  << fromfiles[f] << " : " << totiprod << endl;
213  }
214  }
215  }
216  }
217 }
218 
220  vector<unsigned int> &processFields, FieldSharedPtr &fromField,
221  Array<OneD, const Array<OneD, NekDouble>> &SaveFld)
222 {
223  int nphys = m_f->m_exp[0]->GetTotPoints();
224  NekDouble totiprod = 0.0;
225 
226  for (int j = 0; j < processFields.size(); ++j)
227  {
228  int fid = processFields[j];
229 
230  Array<OneD, NekDouble> coeffs(m_f->m_exp[fid]->GetNcoeffs());
231  Array<OneD, NekDouble> phys(m_f->m_exp[fid]->GetTotPoints());
232 
233  // load new field
234  for (int i = 0; i < fromField->m_data.size(); ++i)
235  {
236  m_f->m_exp[fid]->ExtractDataToCoeffs(fromField->m_fielddef[i],
237  fromField->m_data[i],
238  m_f->m_variables[fid], coeffs);
239  }
240 
241  m_f->m_exp[fid]->BwdTrans(coeffs, phys);
242 
243  Vmath::Vmul(nphys, SaveFld[j], 1, phys, 1, phys, 1);
244 
245  NekDouble iprod = m_f->m_exp[fid]->Integral(phys);
246 
247  totiprod += iprod;
248  }
249  return totiprod;
250 }
251 } // namespace FieldUtils
252 } // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
FieldSharedPtr m_f
Field object.
Definition: Module.h:234
std::map< std::string, ConfigOption > m_config
List of configuration values.
Definition: Module.h:263
NekDouble IProduct(std::vector< unsigned int > &processFields, FieldSharedPtr &fromField, Array< OneD, const Array< OneD, NekDouble >> &SaveFld)
virtual void v_Process(po::variables_map &vm) override
Write mesh to output file.
Abstract base class for processing modules.
Definition: Module.h:292
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Definition: ParseUtils.cpp:131
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
Definition: ParseUtils.cpp:105
std::shared_ptr< Field > FieldSharedPtr
Definition: Field.hpp:991
std::pair< ModuleType, std::string > ModuleKey
Definition: Module.h:317
ModuleFactory & GetModuleFactory()
Definition: Module.cpp:49
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:53
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:209
Represents a command-line configuration option.
Definition: Module.h:131