PlasCom2  1.0
XPACC Multi-physics simluation application
TestProbe.C
Go to the documentation of this file.
1 #include "Testing.H"
2 #include "Simulation.H"
3 
4 void TestProbe(ix::test::results &serialUnitResults){
5 
6 
7  // ======= Set up some test data =======
8  simulation::state::base testState1;
9  simulation::state::base testState2;
10 
11  size_t numX = 10;
12  size_t numY = 10;
13  size_t numZ = 10;
14  size_t numNodes = numX*numY*numZ;
15 
16  // unitless scalar test field at nodes
17  testState1.AddField("U",'n',1,8,"");
18  testState1.AddField("W",'n',1,8,"");
19  testState2.AddField("Z",'n',2,8,"");
20 
21  // create buffer(s) for numNodes nodes , 0 cells
22  testState1.Create(1000,0);
23  testState2.Create(1000,0);
24 
25  // testing data, init'd to 0.0
26  std::vector<double> uVector(1000,0.0);
27  std::vector<double> wVector(1000,0.0);
28  std::vector<double> zVector(2000,0.0);
29  // Replace state buffers with this local array
30  testState1.SetFieldBuffer("U",&uVector[0]);
31  testState1.SetFieldBuffer("W",&wVector[0]);
32  testState2.SetFieldBuffer("Z",&zVector[0]);
33 
34  // Initialize state data simply to node index
35  for(size_t iNode = 0;iNode < numNodes;iNode++){
36  uVector[iNode] = static_cast<double>(iNode);
37  wVector[iNode] = static_cast<double>(iNode+numNodes);
38  zVector[iNode] = static_cast<double>(iNode+2*numNodes);
39  zVector[iNode+numNodes] = static_cast<double>(iNode+3*numNodes);
40  }
41 
42  // Create grid Interval to define the shape of the data
43  pcpp::IndexIntervalType gridInterval;
44  std::vector<size_t> gridSize(3,0);
45  gridSize[0] = numX;
46  gridSize[1] = numY;
47  gridSize[2] = numZ;
48  gridInterval.InitSimple(gridSize);
49 
50  // Create an interval for the probe - this will
51  // indicate where the state should be probed
52  pcpp::IndexIntervalType probeInterval;
53  std::vector<size_t> probeStart(3,5);
54  probeStart[0] = 0;
55  std::vector<size_t> probeSize(3,1);
56  probeSize[0] = 10;
57  probeInterval.Init(probeStart,probeSize);
58 
59  std::vector<std::string> probeFieldNames;
60  probeFieldNames.push_back("U");
61  // ------------ Set up done ----------------
62 
63  // ======== Tests for probes ===============
64 
65  bool probeDefaultConstructor = true;
67  serialUnitResults.UpdateResult("Probe:DefaultConstructor",probeDefaultConstructor);
68 
69  // Tell the probe the shape of the data array
70  myProbe.SetDataInterval(gridInterval);
71  // Set the shape of the probe
72  myProbe.SetProbeInterval(probeInterval);
73  // Tell the probe which fields to probe
74  myProbe.SetProbeFields(probeFieldNames);
75  // Set the state to probe
76  myProbe.SetState(testState1);
77 
78  bool probeWorks = true;
79  std::ostringstream probeStream;
80  int errorCode = myProbe.Probe(probeStream);
81  if(errorCode){
82  std::cout << "Probe returned error code: " << errorCode << std::endl;
83  probeWorks = false;
84  }
85  if(!probeWorks)
86  return;
87 
88  // The probeStream should now contain a string of values
89  // that are the values of the state at the probe locations.
90  // Check that this is true.
91  bool probeScalarField = true;
92  if(probeWorks){
93  std::istringstream probeInStream(probeStream.str());
94  // There is a more convenient way to do the loop below using Intervals. Check out the
95  // next test for an example.
96  for(size_t probeZ = probeInterval[2].first;probeZ <= probeInterval[2].second;probeZ++){
97  size_t zDataIndex = probeZ*numX*numY;
98  for(size_t probeY = probeInterval[1].first;probeY <= probeInterval[1].second;probeY++){
99  size_t yDataIndex = zDataIndex + probeY*numX;
100  for(size_t probeX = probeInterval[0].first;probeX <= probeInterval[0].second;probeX++){
101  size_t stateDataIndex = yDataIndex + probeX;
102  double probeValue;
103  probeInStream >> probeValue;
104  if(probeValue != uVector[stateDataIndex])
105  probeScalarField = false;
106  }
107  }
108  }
109  }
110  pcpp::io::RenewStream(probeStream);
111  if(!probeScalarField)
112  return;
113  serialUnitResults.UpdateResult("Probe:ProbeScalarField",probeScalarField);
114 
115  // This test will indicate both whether switching fields, and
116  // probing vector fields work
117  bool switchProbeField = true;
118  bool probeVectorField = true;
119  bool detectWrongField = true;
120 
121  // get the flat array indices for the probe data for more
122  // convenient access than a triple nested loop
123  std::vector<size_t> probeDataIndices;
124  gridInterval.GetFlatIndices(probeInterval,probeDataIndices);
125  size_t numProbeNodes = probeDataIndices.size();
126 
127  if(probeScalarField){
128  // attempt to probe field U out of testState2, which has
129  // only vector field Z.
130  int errorCode = myProbe.Probe(testState2,probeStream);
131  if(errorCode != 2)
132  detectWrongField = false;
133  // let's probe the correct field now (it's a vector field)
134  probeFieldNames[0] = "Z";
135  myProbe.SetProbeFields(probeFieldNames);
136  errorCode = myProbe.Probe(probeStream);
137  if(errorCode){
138  switchProbeField = false;
139  return;
140  }
141  serialUnitResults.UpdateResult("Probe:SwitchProbeField",switchProbeField);
142  std::istringstream probeInStream(probeStream.str());
143  for(size_t iNode = 0;iNode < numProbeNodes;iNode++){
144  double probeComp1, probeComp2;
145  size_t probeDataIndex = probeDataIndices[iNode];
146  probeInStream >> probeComp1 >> probeComp2;
147  if(probeComp1 != zVector[probeDataIndex] &&
148  probeComp2 != zVector[probeDataIndex+numNodes])
149  probeVectorField = false;
150  }
151  if(!probeVectorField)
152  return;
153  serialUnitResults.UpdateResult("Probe:ProbeVectorField",probeVectorField);
154  pcpp::io::RenewStream(probeStream);
155  }
156  if(probeVectorField){
157  bool probeMultipleFields = true;
158  probeFieldNames[0] = "W";
159  probeFieldNames.push_back("U");
160  myProbe.SetProbeFields(probeFieldNames);
161  errorCode = myProbe.Probe(testState1,probeStream);
162  if(errorCode){
163  std::cout << "Probe returned errorcode = " << errorCode << std::endl;
164  probeMultipleFields = false;
165  return;
166  }
167  std::istringstream probeInStream(probeStream.str());
168  for(size_t iNode = 0;iNode < numProbeNodes;iNode++){
169  double probeFieldW, probeFieldU;
170  size_t probeDataIndex = probeDataIndices[iNode];
171  probeInStream >> probeFieldW >> probeFieldU;
172  if(probeFieldW != wVector[probeDataIndex] &&
173  probeFieldU != uVector[probeDataIndex])
174  probeMultipleFields = false;
175  }
176  if(!probeMultipleFields)
177  return;
178  serialUnitResults.UpdateResult("Probe:ProbeMultipleFields",probeMultipleFields);
179  pcpp::io::RenewStream(probeStream);
180  }
181  serialUnitResults.UpdateResult("Probe:Works",probeWorks);
182 }
void GetFlatIndices(const sizeextent &extent, ContainerType &indices) const
Definition: IndexUtil.H:302
void SetProbeInterval(const pcpp::IndexIntervalType &inInterval)
Definition: State.C:1662
void SetState(const simulation::state::base &inState)
Definition: State.C:1651
int Probe(const simulation::state::base &inState, std::ostream &outStream)
Definition: State.C:1668
void RenewStream(std::ostringstream &outStream)
void SetProbeFields(const std::vector< std::string > &inFields)
Definition: State.C:1641
virtual size_t Create(size_t number_of_nodes=0, size_t number_of_cells=0)
void TestProbe(ix::test::results &serialUnitResults)
Definition: TestProbe.C:4
void SetDataInterval(const pcpp::IndexIntervalType &inInterval)
Definition: State.C:1656
Encapsulating class for collections of test results.
Definition: Testing.H:18
Testing constructs for unit testing.
void Init(const ContainerType &inflatextent)
Definition: IndexUtil.H:133
void UpdateResult(const std::string &name, const ValueType &result)
Updates an existing test result.
Definition: Testing.H:55
Simple Block Structured Mesh object.
Definition: IndexUtil.H:21
void AddField(const std::string &name, char loc, unsigned int ncomp, unsigned int dsize, const std::string &unit)
void SetFieldBuffer(const std::string &name, void *buf)
void InitSimple(const ContainerType &inSize)
Definition: IndexUtil.H:169