NuTo
Numerics Tool
MoistureTransport_SimulationTest.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <boost/foreach.hpp>
5 
6 
8 template <int TDim>
9 std::string SimulationTest_GetTestName(std::array<bool, TDim>& rBS)
10 {
11  std::string testName = std::string("SimulationTest") + std::to_string(TDim) + "D";
12  if (TDim > 1)
13  {
14  testName += "_";
15  if (rBS[0])
16  {
17  testName += "X";
18  }
19  if (rBS[1])
20  {
21  testName += "Y";
22  }
23  }
24  if (TDim > 2)
25  {
26  if (rBS[2])
27  {
28  testName += "Z";
29  }
30  }
31  return testName;
32 }
33 
34 
35 template <int TDim>
36 void CompareResultsToPaper(NuTo::Structure& rS, std::vector<int> rN, std::vector<double> rL)
37 {
38  int NumActiveDimensions = 0;
39  int relevantDirection = 0;
40  for (int i = 0; i < TDim; ++i)
41  {
42  assert((rN[i] == 1 || rN[i] == 16) && "Only 16 or 1 element(s) in each direction allowed for this test");
43  if (rN[i] > 1)
44  {
45  ++NumActiveDimensions;
46  relevantDirection = i;
47  }
48  }
49  assert(NumActiveDimensions == 1 && "Results are only valid for one dimensional flows");
50 
51  // values fitted from Johannesson and Nyman(2010)
52  Eigen::VectorXd PaperValues(17);
53  PaperValues[0] = 0.06;
54  PaperValues[1] = 0.097;
55  PaperValues[2] = 0.116;
56  PaperValues[3] = 0.129;
57  PaperValues[4] = 0.138;
58  PaperValues[5] = 0.146;
59  PaperValues[6] = 0.148;
60  PaperValues[7] = 0.151;
61  PaperValues[8] = 0.152;
62  PaperValues[9] = PaperValues[7];
63  PaperValues[10] = PaperValues[6];
64  PaperValues[11] = PaperValues[5];
65  PaperValues[12] = PaperValues[4];
66  PaperValues[13] = PaperValues[3];
67  PaperValues[14] = PaperValues[2];
68  PaperValues[15] = PaperValues[1];
69  PaperValues[16] = PaperValues[0];
70 
71  typedef boost::ptr_map<int, NuTo::NodeBase> NodeMap;
72 
73  assert(rL[relevantDirection] == 0.16 &&
74  "The length in flow direction must be 0.16m for direct comparison with paper values");
75 
76  double tolerance = 0.005; // Tolerance because not all necessary value (sorption curve) are given in the paper and
77  // must be approximated
78  double deltaL = rL[relevantDirection] / rN[relevantDirection];
79  unsigned int numMismatchingValues = 0;
80 
81 
82  const NodeMap& nodePtrMap = rS.NodeGetNodeMap();
83  BOOST_FOREACH (NodeMap::const_iterator::value_type it, nodePtrMap)
84  {
85  const NuTo::NodeBase* nodePtr = it.second;
86 
87 
88  if (nodePtr->GetNum(NuTo::Node::eDof::WATERVOLUMEFRACTION) < 1)
89  {
90  continue; // Nodes without WVF cant be checked --- for example boundary control node
91  }
92 
93  double relevantNodeCoord = nodePtr->Get(NuTo::Node::eDof::COORDINATES)[relevantDirection];
94  int relevantIndex = static_cast<int>(std::round(relevantNodeCoord / deltaL));
95 
96  double nodalWVF = nodePtr->Get(NuTo::Node::eDof::WATERVOLUMEFRACTION)[0];
97  double paperWVF = PaperValues[relevantIndex];
98  if (nodalWVF < paperWVF - tolerance || nodalWVF > paperWVF + tolerance)
99  {
100  ++numMismatchingValues;
101  }
102  }
103  if (numMismatchingValues > 0)
104  {
105  throw NuTo::Exception(__PRETTY_FUNCTION__,
106  "One ore more calculated values exceeds the tolerance when compared to reference values");
107  }
108 }
109 
110 
117 template <int TDim>
118 void SimulationTest(std::vector<int> rN, std::vector<double> rL, std::array<bool, TDim> rBS,
119  std::map<NuTo::Node::eDof, NuTo::Interpolation::eTypeOrder> rDofIPTMap,
120  bool rTestInterpolationTypeCombi = false)
121 {
122  std::string testName = SimulationTest_GetTestName<TDim>(rBS);
123 
124  if (rTestInterpolationTypeCombi)
125  {
126  testName += "_TestInterpolationtypeCombi";
127  }
128 
129  std::cout << std::endl
130  << "--------------------------------------------------------------------------" << std::endl
131  << "Start test: " << testName << std::endl
132  << "--------------------------------------------------------------------------" << std::endl;
133 
134  NuTo::Structure S(TDim);
135  TimeControl timeControl;
136 
137  if (rTestInterpolationTypeCombi)
138  {
139  testName += "_TestInterpolationtypeCombi";
140  timeControl.t_final = 1.0 * 1.0 * 1.0 * 60.0;
141  timeControl.t_write = timeControl.t_final * 2;
142  timeControl.delta_t = timeControl.t_final;
143  }
144  else
145  {
146  timeControl.t_final = 293.0 * 24.0 * 60.0 * 60.0;
147  timeControl.t_write = timeControl.t_final;
148  timeControl.delta_t = timeControl.t_final / 5.0;
149  }
150 
151 
152  NuTo::NewmarkDirect TI(&S);
153 
154 
156  MT.InitialRelativeHumidity = 0.95;
157  MT.MassExchangeRate = 3.42e-7;
158  MT.DiffusionCoefficientRH = 3.9e-10;
159  MT.BoundaryEnvironmentalRH = 0.40;
160 
161 
163 
164  std::string resultDir = std::string("./ConstitutiveLawMoistureTransport_") + testName;
165 
166  SetupStructure<TDim>(S, testName);
167  auto SEC = SetupSection<TDim>(S);
168 
169  auto meshInfo = NuTo::MeshGenerator::Grid(S, rL, rN);
170 
171  for (auto it : rDofIPTMap)
172  S.InterpolationTypeAdd(meshInfo.second, it.first, it.second);
173 
174  S.ElementGroupSetSection(meshInfo.first, SEC);
175  S.ElementGroupSetConstitutiveLaw(meshInfo.first, MT.ConstitutiveLawID);
176 
177  SetupIntegrationType<TDim>(S, meshInfo.first);
178 
179  S.ElementTotalConvertToInterpolationType(); // old used values 1.0e-12,0.001
181 
182 
183  auto LambdaGetBoundaryNodes = [rL, rBS](NuTo::NodeBase* rNodePtr) -> bool {
184  double Tol = 1.e-6;
185  if (rNodePtr->GetNum(NuTo::Node::eDof::COORDINATES) > 0)
186  {
187  double x = rNodePtr->Get(NuTo::Node::eDof::COORDINATES)[0];
188  if (rBS[0] && ((x >= 0.0 - Tol && x <= 0.0 + Tol) || (x >= rL[0] - Tol && x <= rL[0] + Tol)))
189  {
190  return true;
191  }
192 
193  if (TDim > 1)
194  {
195  double y = rNodePtr->Get(NuTo::Node::eDof::COORDINATES)[1];
196  if (rBS[1] && ((y >= 0.0 - Tol && y <= 0.0 + Tol) || (y >= rL[1] - Tol && y <= rL[1] + Tol)))
197  {
198  return true;
199  }
200  }
201  if (TDim > 2)
202  {
203  double z = rNodePtr->Get(NuTo::Node::eDof::COORDINATES)[2];
204  if (rBS[2] && ((z >= 0.0 - Tol && z <= 0.0 + Tol) || (z >= rL[2] - Tol && z <= rL[2] + Tol)))
205  {
206  return true;
207  }
208  }
209  }
210  return false;
211  }; // GetBoundaryNodesLambda
212 
213 
214  auto LambdaTimeDepBoundaryRH = [&MT, &timeControl](double rTime) -> double {
215  if (rTime == 0.0)
216  {
217  return MT.InitialRelativeHumidity;
218  }
219  else
220  {
221  if (rTime < timeControl.BC_TransitionTime)
222  {
223  return MT.InitialRelativeHumidity -
224  sin(rTime / timeControl.BC_TransitionTime * 3.14 / 2.0) *
226  }
227  {
228  return MT.BoundaryEnvironmentalRH;
229  }
230  }
231  }; // TimeDepBoundaryRHLambda
232 
233 
234  SetupConstrainedNodeBoundaryElements<TDim>(S, LambdaGetBoundaryNodes, LambdaTimeDepBoundaryRH);
235 
236  MT.SetupStaticData();
237  S.NodeBuildGlobalDofs();
238 
240 
241  SetupVisualize(S);
242 
243  SetupTimeIntegration(TI, timeControl, resultDir);
244  NuTo::Timer timer(testName + " --- Timeintegration.Solve");
245  TI.Solve(timeControl.t_final);
246  if (!rTestInterpolationTypeCombi)
247  {
248  CompareResultsToPaper<TDim>(S, rN, rL);
249  }
250 }
int ConstitutiveLawID
Definition: MoistureTransport_Setup.h:97
double BoundaryEnvironmentalRH
Definition: MoistureTransport_Setup.h:85
Base class for all exceptions thrown in NuTo.
Definition: Exception.h:9
void SetupVisualize(NuTo::Structure &rS)
Definition: MoistureTransport_Setup.h:376
resultDir
Definition: GradingCurveFileIO.py:67
std::string SimulationTest_GetTestName(std::array< bool, TDim > &rBS)
Determines the name of the test.
Definition: MoistureTransport_SimulationTest.h:9
prints the lifetime of a Timer object on destruction
Definition: Timer.h:11
void SetupMultiProcessor(NuTo::Structure &rS)
Definition: MoistureTransport_Setup.h:290
void SetParametersConstitutiveLaw()
Definition: MoistureTransport_Setup.h:119
void CompareResultsToPaper(NuTo::Structure &rS, std::vector< int > rN, std::vector< double > rL)
Definition: MoistureTransport_SimulationTest.h:36
constexpr double tolerance
Definition: NewtonRaphsonBenchmark.cpp:11
void SetupTimeIntegration(NuTo::NewmarkDirect &rTI, const TimeControl &rTC, const std::string &rResultDir)
Definition: MoistureTransport_Setup.h:358
double InitialRelativeHumidity
Definition: MoistureTransport_Setup.h:73
double delta_t
Definition: MoistureTransport_Setup.h:58
void ApplyInitialNodalValues()
Definition: MoistureTransport_Setup.h:157
void SimulationTest(std::vector< int > rN, std::vector< double > rL, std::array< bool, TDim > rBS, std::map< NuTo::Node::eDof, NuTo::Interpolation::eTypeOrder > rDofIPTMap, bool rTestInterpolationTypeCombi=false)
performs a simulation in the desired dimension
Definition: MoistureTransport_SimulationTest.h:118
double BC_TransitionTime
Definition: MoistureTransport_Setup.h:61
void SetupStaticData()
Definition: MoistureTransport_Setup.h:176
Definition: MoistureTransport_Setup.h:68
double t_final
Definition: MoistureTransport_Setup.h:60
double MassExchangeRate
–> Calculated from relative humidity
Definition: MoistureTransport_Setup.h:75
Definition: MoistureTransport_Setup.h:56
double DiffusionCoefficientRH
Definition: MoistureTransport_Setup.h:77
double t_write
Definition: MoistureTransport_Setup.h:59
boost::ptr_map< int, NuTo::NodeBase > NodeMap
Definition: MultipleConstitutiveLaws.cpp:53