Nektar++
TestVarcoeffHashing.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: TestVarcoeffHashing.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: Unit test for varcoeff hashing
32//
33///////////////////////////////////////////////////////////////////////////////
34
36
40
41#include <boost/test/unit_test.hpp>
42
44{
45using namespace MultiRegions;
46
47// Forward declare global variables for all tests
48fs::path pathGlobal;
51
54
55// Define session file for the tests
56// Ideally use a session-free approach in the future
57static const std::string sessionfile =
58 R"END(<?xml version="1.0" encoding="UTF-8"?>
59<NEKTAR>
60 <GEOMETRY DIM="2" SPACE="2">
61
62 <VERTEX>
63 <V ID="0"> 0.0 0.0 0.0 </V>
64 <V ID="1"> 0.5 0.0 0.0 </V>
65 <V ID="2"> 1.0 0.0 0.0 </V>
66 <V ID="3"> 0.0 0.5 0.0 </V>
67 <V ID="4"> 0.5 0.5 0.0 </V>
68 <V ID="5"> 1.0 0.5 0.0 </V>
69 <V ID="6"> 0.0 1.0 0.0 </V>
70 <V ID="7"> 0.5 1.0 0.0 </V>
71 <V ID="8"> 1.0 1.0 0.0 </V>
72 </VERTEX>
73
74 <EDGE>
75 <E ID="0"> 0 1 </E>
76 <E ID="1"> 1 2 </E>
77 <E ID="2"> 0 3 </E>
78 <E ID="3"> 1 4 </E>
79 <E ID="4"> 2 5 </E>
80 <E ID="5"> 3 4 </E>
81 <E ID="6"> 4 5 </E>
82 <E ID="7"> 3 6 </E>
83 <E ID="8"> 4 7 </E>
84 <E ID="9"> 5 8 </E>
85 <E ID="10"> 6 7 </E>
86 <E ID="11"> 7 8 </E>
87 </EDGE>
88
89 <ELEMENT>
90 <Q ID="0"> 0 3 5 2 </Q>
91 <Q ID="1"> 1 4 6 3 </Q>
92 <Q ID="2"> 5 8 10 7 </Q>
93 <Q ID="3"> 6 9 11 8 </Q>
94 </ELEMENT>
95
96 <COMPOSITE>
97 <C ID="0"> Q[0-3] </C>
98 <C ID="1"> E[0,1] </C> <!-- Lower wall -->
99 <C ID="2"> E[2,7] </C> <!-- Inflow -->
100 <C ID="3"> E[4,9] </C> <!-- Outflow -->
101 <C ID="4"> E[10,11] </C> <!-- Upper wall -->
102 </COMPOSITE>
103
104 <DOMAIN> C[0] </DOMAIN>
105
106 </GEOMETRY>
107
108 <EXPANSIONS>
109 <E COMPOSITE="C[0]" FIELDS="u" TYPE="MODIFIED" NUMMODES="3"/>
110 </EXPANSIONS>
111
112 <CONDITIONS>
113
114 <PARAMETERS>
115 <P> lambda = 1.0 </P>
116 </PARAMETERS>
117 <VARIABLES>
118 <V ID="0"> u </V>
119 </VARIABLES>
120
121 <BOUNDARYREGIONS>
122 <B ID="0"> C[1] </B>
123 <B ID="1"> C[2] </B>
124 <B ID="2"> C[3] </B>
125 <B ID="3"> C[4] </B>
126 </BOUNDARYREGIONS>
127
128 <BOUNDARYCONDITIONS>
129 <REGION REF="0"> <!-- Stationary -->
130 <D VAR="u" VALUE="0" />
131 </REGION>
132 <REGION REF="1"> <!-- Inflow -->
133 <D VAR="u" VALUE="y" />
134 </REGION>
135 <REGION REF="2"> <!-- Outflow -->
136 <N VAR="u" VALUE="0" />
137 </REGION>
138 <REGION REF="3"> <!-- Moving -->
139 <D VAR="u" VALUE="1" />
140 </REGION>
141 </BOUNDARYCONDITIONS>
142
143 <FUNCTION NAME="d00">
144 <E VAR="u" VALUE="0.1*y" />
145 </FUNCTION>
146
147 <FUNCTION NAME="d00B">
148 <E VAR="u" VALUE="0.5*y" />
149 </FUNCTION>
150
151 <FUNCTION NAME="Forcing">
152 <E VAR="u" VALUE="sin(y)" />
153 </FUNCTION>
154
155 <FUNCTION NAME="ExactSolution">
156 <E VAR="u" VALUE="y" />
157 </FUNCTION>
158
159 </CONDITIONS>
160
161</NEKTAR>
162)END";
163
164/*
165 * Create the session file at working directory
166 * TODO Use session-free approach to save effort on this test
167 */
168void createSessionFile(fs::path &ph)
169{
170 // Create temporary directory
171 ph = fs::temp_directory_path() / LibUtilities::UniquePath("varctest");
172 fs::create_directories(ph);
173
174 // Create file in working directory
175 ph /= "TestVarcoeffHashing.xml"; // append filename
176 std::ofstream sfile(ph);
177 sfile << sessionfile;
178 sfile.close();
179}
180
181/*
182 * Setup for generic ContField solve
183 * Read session file, setup contfield and
184 * auxilliary functions for forcing and varcoeffs
185 */
186void setupContFieldSolve(fs::path &ph,
190{
191#ifdef _WIN32
192 // Prepare input file name - convert wstring to string to support Windows
193 const std::wstring input_file_wstr(ph.c_str());
194 const std::string input_file_str(input_file_wstr.begin(),
195 input_file_wstr.end());
196 char *input_file = (char *)input_file_str.c_str();
197#else
198 char *input_file = (char *)ph.c_str();
199#endif
200
201 // Setup parameters for call to IncNavierStokesSolver
202 int argc = 2;
203 char *argv[] = {(char *)("IncNavierStokesSolver"), input_file, nullptr};
204
205 // Read Session, MeshGraph and create ContField
210 Session, Graph, Session->GetVariable(0));
212
213 // Read functons for varcoeffs and Forcing
214 LibUtilities::EquationSharedPtr d00func = Session->GetFunction("d00", 0);
215 LibUtilities::EquationSharedPtr d00Bfunc = Session->GetFunction("d00B", 0);
216 LibUtilities::EquationSharedPtr ffunc = Session->GetFunction("Forcing", 0);
217
218 // Get coordinates to evaluate functions
219 unsigned int npoints = Exp->GetNpoints();
220 unsigned int coordim = Exp->GetCoordim(0);
221 Array<OneD, NekDouble> x0(npoints), x1(npoints), x2(npoints);
222 Array<OneD, NekDouble> d00(npoints, 0.0), d00B(npoints, 0.0),
223 fcePhys(npoints);
224
225 // Define lambda
226 factors[StdRegions::eFactorLambda] = Session->GetParameter("lambda");
227 Exp->GetCoords(x0, x1, x2);
228
229 // Define 1st varcoeff
230 d00func->Evaluate(x0, x1, x2, d00);
232
233 // Define 2nd varcoeff
234 d00Bfunc->Evaluate(x0, x1, x2, d00B);
236
237 // Define Forcing
238 ffunc->Evaluate(x0, x1, x2, fcePhys);
239 Fce->SetPhys(fcePhys);
240
241 // Define Advection velocities and add to varcoeff1 or 2
245 for (int i = 0; i < coordim; i++)
246 {
247 varcoeffs1[varcoefftypes[i]] = Array<OneD, NekDouble>(npoints, 0.1);
248 varcoeffs2[varcoefftypes[i]] = Array<OneD, NekDouble>(npoints, 0.2);
249 }
250
251 // Clear solution
252 Vmath::Zero(Exp->GetNcoeffs(), Exp->UpdateCoeffs(), 1);
253}
254
255BOOST_AUTO_TEST_CASE(TestVarcoeffHashing)
256{
257 // Create session file and setup Contfield
260
261 // Check no initial GlobalLinSys i.e. count == 0
262 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 0);
263
264 // Create GlobalLinSys(varcoeff1)
265 contfield->HelmSolve(forcefield->GetPhys(), contfield->UpdateCoeffs(),
267
268 // Check count == 1
269 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 1);
270
271 // Create new GlobalLinSys(varcoeff2)
272 contfield->HelmSolve(forcefield->GetPhys(), contfield->UpdateCoeffs(),
274
275 // Check count == 2
276 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 2);
277
278 // Again use 2nd GlobalLinSys(varcoeff2)
279 contfield->HelmSolve(forcefield->GetPhys(), contfield->UpdateCoeffs(),
281
282 // Check count still == 2
283 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 2);
284
285 // Again use 1st GlobalLinSys(varcoeff1)
286 contfield->HelmSolve(forcefield->GetPhys(), contfield->UpdateCoeffs(),
288
289 // Check count still == 2
290 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 2);
291
292 // Clear for next tests
293 contfield->ClearGlobalLinSysManager();
294}
295
296BOOST_AUTO_TEST_CASE(TestUnsetGlobalLinSys)
297{
298 // Check that the test setup is clear i.e. count == 0
299 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 0);
300
301 // Create 1st GlobalLinSys
302 auto gkey1 = contfield->LinearAdvectionDiffusionReactionSolve(
303 forcefield->GetPhys(), contfield->UpdateCoeffs(), factors, varcoeffs1);
304
305 // Check count == 1
306 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 1);
307
308 // Create 2nd GlobalLinSys
309 auto gkey2 = contfield->LinearAdvectionDiffusionReactionSolve(
310 forcefield->GetPhys(), contfield->UpdateCoeffs(), factors, varcoeffs2);
311
312 // Check count == 2
313 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 2);
314
315 // Unset GlobalLinSys1
316 contfield->UnsetGlobalLinSys(gkey1, true);
317
318 // Check count == 1
319 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 1);
320
321 // Unset GlobalLinSys2
322 contfield->UnsetGlobalLinSys(gkey2, true);
323
324 // Check count == 0
325 BOOST_CHECK_EQUAL(contfield->GetPoolCount("GlobalLinSys"), 0);
326
327 // Clear for next tests
328 contfield->ClearGlobalLinSysManager();
329}
330} // namespace Nektar::VarcoeffHashingTest
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true, SpatialDomains::MeshGraphSharedPtr partitionedGraph=nullptr)
Definition: MeshGraphIO.cpp:53
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:125
static fs::path UniquePath(std::string specFileStem)
Create a unique (random) path, based on an input stem string. The returned string is a filename or di...
Definition: Filesystem.hpp:69
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:268
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::map< ConstFactorType, NekDouble > ConstFactorMap
Definition: StdRegions.hpp:430
std::map< StdRegions::VarCoeffType, VarCoeffEntry > VarCoeffMap
Definition: StdRegions.hpp:375
MultiRegions::ContFieldSharedPtr forcefield
void setupContFieldSolve(fs::path &ph, LibUtilities::SessionReaderSharedPtr &Session, MultiRegions::ContFieldSharedPtr &Exp, MultiRegions::ContFieldSharedPtr &Fce)
static const std::string sessionfile
MultiRegions::ContFieldSharedPtr contfield
BOOST_AUTO_TEST_CASE(TestVarcoeffHashing)
LibUtilities::SessionReaderSharedPtr lsession
StdRegions::VarCoeffMap varcoeffs1
StdRegions::VarCoeffMap varcoeffs2
StdRegions::ConstFactorMap factors
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273