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>
37using namespace std;
38
39#include <boost/core/ignore_unused.hpp>
40
43
44#include "ProcessInnerProduct.h"
45
46namespace Nektar
47{
48namespace FieldUtils
49{
50
54 "take inner product between two fields and return value.");
55
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
76void 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
static std::shared_ptr< Module > create(FieldSharedPtr f)
Creates an instance of this class.
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:207
Represents a command-line configuration option.
Definition: Module.h:131