GRINS-0.8.0
List of all members | Public Member Functions | Private Member Functions | Private Attributes
GRINSTesting::IntegratedFunctionTest Class Reference
Inheritance diagram for GRINSTesting::IntegratedFunctionTest:
Inheritance graph
[legend]
Collaboration diagram for GRINSTesting::IntegratedFunctionTest:
Collaboration graph
[legend]

Public Member Functions

 CPPUNIT_TEST_SUITE (IntegratedFunctionTest)
 
 CPPUNIT_TEST (test_exact_answer)
 
 CPPUNIT_TEST (test_convergence)
 
 CPPUNIT_TEST (qoi_from_input_file)
 
 CPPUNIT_TEST (reinit_through_system)
 
 CPPUNIT_TEST_SUITE_END ()
 
void tearDown ()
 
void test_exact_answer ()
 Functions that can be integrated exactly using Gauss Quadrature. More...
 
void test_convergence ()
 A quartic convergence rate is identified by graphing log(error) vs. More...
 
void qoi_from_input_file ()
 
void reinit_through_system ()
 Here, we use CompositeQoI::reinit() to reinitialize the rayfire post-refinement. More...
 

Private Member Functions

void init_sim (const std::string &filename)
 Initialize the GetPot and Simulation class objects. More...
 

Private Attributes

GRINS::SharedPtr< GRINS::Simulation_sim
 
GRINS::SharedPtr< GetPot > _input
 

Additional Inherited Members

- Protected Member Functions inherited from GRINSTesting::RegressionHelper
libMesh::Real linear_slope (std::vector< libMesh::Real > x, std::vector< libMesh::Real > y, unsigned int start_index, unsigned int end_index)
 Slope $ m $ for linear regression. More...
 
libMesh::Real linear_intercept (std::vector< libMesh::Real > x, std::vector< libMesh::Real > y, unsigned int start_index, unsigned int end_index)
 y-intercept $ b $ for linear regression More...
 
void check_convergence_rate (std::vector< libMesh::Real > x, std::vector< libMesh::Real > y, unsigned int start_index, unsigned int end_index, libMesh::Real convergence_rate, libMesh::Real tol)
 Check the convergence rate of the supplied data to within the given absolute tolerance. More...
 

Detailed Description

Definition at line 59 of file integrated_function_test.C.

Member Function Documentation

GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST ( test_exact_answer  )
GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST ( test_convergence  )
GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST ( qoi_from_input_file  )
GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST ( reinit_through_system  )
GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST_SUITE ( IntegratedFunctionTest  )
GRINSTesting::IntegratedFunctionTest::CPPUNIT_TEST_SUITE_END ( )
void GRINSTesting::IntegratedFunctionTest::init_sim ( const std::string &  filename)
inlineprivate

Initialize the GetPot and Simulation class objects.

Definition at line 399 of file integrated_function_test.C.

References TestCommWorld.

Referenced by qoi_from_input_file(), reinit_through_system(), test_convergence(), and test_exact_answer().

400  {
401  _input.reset(new GetPot(filename));
402 
403  const char* const argv = "unit_driver";
404  GetPot empty_command_line( (const int)1,&argv );
405  GRINS::SimulationBuilder sim_builder;
406 
408  empty_command_line,
409  sim_builder,
410  *TestCommWorld );
411  }
libMesh::Parallel::Communicator * TestCommWorld
Definition: unit_driver.C:70
GRINS::SharedPtr< GRINS::Simulation > _sim
void GRINSTesting::IntegratedFunctionTest::qoi_from_input_file ( )
inline

Tests that an IntegratedFunction can be initialized and computed directly from the input file

Definition at line 306 of file integrated_function_test.C.

References _sim, and init_sim().

307  {
308  const std::string filename = std::string(GRINS_TEST_UNIT_INPUT_SRCDIR)+"/integrated_function_qoi_quad9.in";
309  this->init_sim(filename);
310 
311  libMesh::Real theta = 0.25;
312  libMesh::Real L = 10.0/std::cos(theta);
313  libMesh::Real costheta = std::cos(theta);
314 
315  // function: "(4/3)*(x^3)+10"
316 
317  libMesh::Real calc_answer = (4.0/12.0)*pow(costheta,3)*std::pow(L,4)+10*L;
318 
319  _sim->run();
320 
321  CPPUNIT_ASSERT_DOUBLES_EQUAL( calc_answer, _sim->get_qoi_value(0),libMesh::TOLERANCE );
322  }
GRINS::SharedPtr< GRINS::Simulation > _sim
void init_sim(const std::string &filename)
Initialize the GetPot and Simulation class objects.
void GRINSTesting::IntegratedFunctionTest::reinit_through_system ( )
inline

Here, we use CompositeQoI::reinit() to reinitialize the rayfire post-refinement.

Definition at line 325 of file integrated_function_test.C.

References _input, _sim, GRINS::CompositeQoI::add_qoi(), GRINS::CompositeQoI::get_qoi(), GRINS::CompositeQoI::init(), init_sim(), and GRINS::MultiphysicsSystem::reinit().

326  {
327  const std::string filename = std::string(GRINS_TEST_UNIT_INPUT_SRCDIR)+"/integrated_function_quad9.in";
328  this->init_sim(filename);
329 
330  libMesh::Point origin(0.0,0.0);
331  libMesh::Real theta = 0.0;
332 
333  GRINS::MultiphysicsSystem* system = _sim->get_multiphysics_system();
334  GRINS::SharedPtr<libMesh::EquationSystems> es = _sim->get_equation_system();
335 
336  libMesh::MeshRefinement mr(system->get_mesh());
337 
338  // build rayfire
339  GRINS::RayfireMesh * rayfire = new GRINS::RayfireMesh(origin,theta);
340 
341  // and now the CompositeQoI to do the evalutaion
342  GRINS::CompositeQoI comp_qoi;
343 
344  libMesh::Real costheta = std::cos(theta);
345 
346  // simple function
347  std::string function = "x";
348  libMesh::Real calc_answer = 0.5/costheta*3.0*3.0;
349 
350  GRINS::IntegratedFunction<libMesh::FunctionBase<libMesh::Real> > integ_func((unsigned int)3,new libMesh::ParsedFunction<libMesh::Real>(function),rayfire,"integrated_function");
351  comp_qoi.add_qoi(integ_func);
352 
353  comp_qoi.init(*_input,*system);
354  system->attach_qoi(&comp_qoi);
355 
356  // evaluate qoi
357  system->assemble_qoi();
358 
359  // ensure we get the correct answer
360  CPPUNIT_ASSERT_DOUBLES_EQUAL( calc_answer, _sim->get_qoi_value(0),libMesh::TOLERANCE );
361 
362  // get the IntegratedFunction object, since comp_qoi would have already been cloned
363  libMesh::DifferentiableQoI* diff_qoi = system->get_qoi();
364  GRINS::CompositeQoI* qoi = libMesh::cast_ptr<GRINS::CompositeQoI*>(diff_qoi);
365  GRINS::IntegratedFunction<libMesh::FunctionBase<libMesh::Real> > * integrated_func = libMesh::cast_ptr<GRINS::IntegratedFunction<libMesh::FunctionBase<libMesh::Real> > * >( &(qoi->get_qoi(0)) );
366 
367  // make sure we have exactly 3 elements along the rayfire
368  std::vector<libMesh::dof_id_type> elems_in_rayfire;
369  integrated_func->get_rayfire().elem_ids_in_rayfire(elems_in_rayfire);
370  unsigned int num_rayfire_elems = elems_in_rayfire.size();
371  CPPUNIT_ASSERT_EQUAL((unsigned int)3,num_rayfire_elems);
372 
373  for (unsigned int i=0; i<elems_in_rayfire.size(); i++)
374  system->get_mesh().elem_ref(elems_in_rayfire[i]).set_refinement_flag(libMesh::Elem::RefinementState::REFINE);
375 
376  mr.refine_elements();
377 
378  // this should trigger RayfireMesh::reinit()
379  es->reinit();
380 
381  // recalculate the qoi to make sure
382  // we still get the same answer
383  system->assemble_qoi();
384 
385  // after the refinement, we should now have 6 rayfire elements
386  std::vector<libMesh::dof_id_type> refined_elems_in_rayfire;
387  integrated_func->get_rayfire().elem_ids_in_rayfire(refined_elems_in_rayfire);
388  unsigned int num_refined_rayfire_elems = refined_elems_in_rayfire.size();
389  CPPUNIT_ASSERT_EQUAL((unsigned int)6,num_refined_rayfire_elems);
390  CPPUNIT_ASSERT_DOUBLES_EQUAL( calc_answer, _sim->get_qoi_value(0),libMesh::TOLERANCE );
391  }
RayfireMesh.
Definition: rayfire_mesh.h:65
const QoIBase & get_qoi(unsigned int qoi_index) const
virtual void reinit()
Override FEMSystem::reinit.
Interface with libMesh for solving Multiphysics problems.
virtual void add_qoi(const QoIBase &qoi)
Definition: composite_qoi.C:70
GRINS::SharedPtr< GRINS::Simulation > _sim
virtual void init(const GetPot &input, const MultiphysicsSystem &system)
Method to allow QoI to cache any system information needed for QoI calculation, for example...
Definition: composite_qoi.C:94
void init_sim(const std::string &filename)
Initialize the GetPot and Simulation class objects.
void GRINSTesting::IntegratedFunctionTest::tearDown ( )
inline

Definition at line 74 of file integrated_function_test.C.

References GRINS::GRINSPrivate::VariableWarehouse::clear().

75  {
76  // Clear out the VariableWarehouse so it doesn't interfere with other tests.
78  }
static void clear()
Clears the var_map()
void GRINSTesting::IntegratedFunctionTest::test_convergence ( )
inline

A quartic convergence rate is identified by graphing log(error) vs.

These functions cannot be integrated exactly wih Gauss Quadrature, and so we look for quartic convergence to the analytical solution

log(h), where h is the length of the longest rayfire elem. Linear regression is then used to fit a line to that data. For quartic convergence, this line should have a slope of 4. A 2% tolerance for the slope value is allowed in order to keep the test runtime from becoming excessive.

Definition at line 152 of file integrated_function_test.C.

References _input, _sim, GRINSTesting::RegressionHelper::check_convergence_rate(), init_sim(), and GRINS::CompositeQoI::reinit().

153  {
154  const std::string filename = std::string(GRINS_TEST_UNIT_INPUT_SRCDIR)+"/integrated_function_quad9.in";
155  this->init_sim(filename);
156 
157  libMesh::Point origin(0.0,0.0);
158 
159  // angles for rayfire
160  std::vector<libMesh::Real> theta;
161  theta.push_back(0.0);
162  theta.push_back(0.25);
163 
164  for (unsigned int t=0; t<theta.size(); t++)
165  {
166  libMesh::Real costheta = std::cos(theta[t]);
167  libMesh::Real sintheta = std::sin(theta[t]);
168  libMesh::Real L = 3.0/costheta;
169 
170  std::vector<std::string> functions; // parsed functions
171  std::vector<libMesh::Real> calc_answers; // analytical solutions
172  std::vector<libMesh::Real> tolerance; // absolute error tolerance
173  std::vector<bool> converged;
174 
175  // trig
176  functions.push_back("sin(x)+cos(y)");
177 
178  if (theta[t] == 0.0)
179  calc_answers.push_back( L-std::cos(L)+1.0 );
180  else
181  calc_answers.push_back( ( (std::sin(L*sintheta))/sintheta ) - ( (std::cos(L*costheta)-1.0)/costheta ) );
182 
183  tolerance.push_back(1e-9);
184  converged.push_back(false);
185 
186  // exponential
187  functions.push_back("exp(x)");
188  calc_answers.push_back( (std::exp(3.0) - 1.0) / costheta);
189  tolerance.push_back(1e-8);
190  converged.push_back(false);
191 
192  std::vector<std::vector<libMesh::Real> > errors(functions.size());
193  std::vector<std::vector<libMesh::Real> > h_vals(functions.size());
194 
195  GRINS::MultiphysicsSystem* system = _sim->get_multiphysics_system();
196  GRINS::SharedPtr<libMesh::EquationSystems> es = _sim->get_equation_system();
197 
198  CPPUNIT_ASSERT_EQUAL(functions.size(), calc_answers.size());
199 
200  // and now the CompositeQoI to do the evalutaion
201  GRINS::CompositeQoI comp_qoi;
202 
203  // all functions use the same mesh, so they have identical rayfires.
204  // instead of trying to access each of them directly, we create a reference rayfire that
205  // can be used for checking the number of rayfire elements and
206  // finding the longest rayfire element for calculating convergence
207  GRINS::SharedPtr<GRINS::RayfireMesh> ref_rayfire(new GRINS::RayfireMesh(origin,theta[t]));
208  ref_rayfire->init( system->get_mesh() );
209 
210  for (unsigned int i=0; i<functions.size(); i++)
211  {
212  GRINS::RayfireMesh * rayfire = new GRINS::RayfireMesh(origin,theta[t]);
213  GRINS::IntegratedFunction<libMesh::FunctionBase<libMesh::Real> > integ_func((unsigned int)3,new libMesh::ParsedFunction<libMesh::Real>(functions[i]),rayfire,"integrated_function");
214  comp_qoi.add_qoi(integ_func);
215  }
216 
217  comp_qoi.init(*_input,*system);
218  system->attach_qoi(&comp_qoi);
219 
220  libMesh::MeshRefinement mr(system->get_mesh());
221 
222  unsigned int num_converged = 0;
223  unsigned int iter = 0;
224 
225  // limit iterations to prevent excessive runtime
226  unsigned int max_iter = 7;
227 
228  // calculate qoi's, check error
229  // refine until all qoi's converge within their tolerance
230  do
231  {
232  std::vector<libMesh::dof_id_type> elems_in_rayfire;
233  ref_rayfire->elem_ids_in_rayfire(elems_in_rayfire);
234 
235  system->assemble_qoi();
236 
237  // get the length of the longest rayfire elem
238  libMesh::Real h = -1.0;
239  for (unsigned int i=0; i<elems_in_rayfire.size(); i++)
240  {
241  libMesh::Real l = (ref_rayfire->map_to_rayfire_elem(elems_in_rayfire[i]))->length(0,1);
242  if (l>h)
243  h=l;
244  }
245 
246  CPPUNIT_ASSERT(h > 0.0);
247 
248  // check for convergence
249  for (unsigned int i=0; i<calc_answers.size(); i++)
250  {
251  if (!converged[i])
252  {
253  libMesh::Real err = std::abs( _sim->get_qoi_value(i) - calc_answers[i] );
254  if (err < tolerance[i])
255  {
256  num_converged++;
257  converged[i] = true;
258  h_vals[i].push_back(std::log10(h));
259  errors[i].push_back(std::log10(err));
260  }
261  else
262  {
263  h_vals[i].push_back(std::log10(h));
264  errors[i].push_back(std::log10(err));
265  }
266  }
267  }
268 
269  // if all functions have not yet converged, refine along the rayfire
270  if (num_converged < calc_answers.size())
271  {
272  if (iter++ > max_iter+1 )
273  libmesh_error_msg("Exceeded maximum iterations");
274 
275  for (unsigned int i=0; i<elems_in_rayfire.size(); i++)
276  system->get_mesh().elem_ref(elems_in_rayfire[i]).set_refinement_flag(libMesh::Elem::RefinementState::REFINE);
277 
278  mr.refine_elements();
279 
280  // ensure all elems marked for refinement were actually refined
281  for (unsigned int i=0; i<elems_in_rayfire.size(); i++)
282  CPPUNIT_ASSERT( !( system->get_mesh().elem_ref(elems_in_rayfire[i]).active() ) );
283 
284  // need to manually reinit the reference rayfire
285  ref_rayfire->reinit(system->get_mesh());
286 
287  // and reinit the CompositeQoI (which will reinit all internal rayfires)
288  libMesh::DifferentiableQoI* diff_qoi = system->get_qoi();
289  GRINS::CompositeQoI* qoi = libMesh::cast_ptr<GRINS::CompositeQoI*>(diff_qoi);
290  qoi->reinit(*system);
291 
292  es->reinit();
293  }
294 
295  } while(num_converged < calc_answers.size());
296 
297  // verify that all functions had quartic convergence within 2%
298  for (unsigned int i=0; i<functions.size(); i++)
299  this->check_convergence_rate(h_vals[i],errors[i],0,errors[i].size()-1,4.0,0.08);
300 
301  } //for t
302  }
RayfireMesh.
Definition: rayfire_mesh.h:65
void check_convergence_rate(std::vector< libMesh::Real > x, std::vector< libMesh::Real > y, unsigned int start_index, unsigned int end_index, libMesh::Real convergence_rate, libMesh::Real tol)
Check the convergence rate of the supplied data to within the given absolute tolerance.
Interface with libMesh for solving Multiphysics problems.
GRINS::SharedPtr< GRINS::Simulation > _sim
void init_sim(const std::string &filename)
Initialize the GetPot and Simulation class objects.
virtual void reinit(MultiphysicsSystem &system)
Reinitialize qoi.
void GRINSTesting::IntegratedFunctionTest::test_exact_answer ( )
inline

Functions that can be integrated exactly using Gauss Quadrature.

Definition at line 81 of file integrated_function_test.C.

References _input, _sim, and init_sim().

82  {
83  const std::string filename = std::string(GRINS_TEST_UNIT_INPUT_SRCDIR)+"/integrated_function_quad9.in";
84  this->init_sim(filename);
85 
86  libMesh::Point origin(0.0,0.0);
87 
88  // angles for rayfire
89  std::vector<libMesh::Real> theta;
90  theta.push_back(0.0);
91  theta.push_back(0.25);
92 
93  for (unsigned int t=0; t<theta.size(); t++)
94  {
95  libMesh::Real L = 3.0/std::cos(theta[t]);
96  libMesh::Real sintheta = std::sin(theta[t]);
97  libMesh::Real costheta = std::cos(theta[t]);
98 
99  std::vector<std::string> functions;
100  std::vector<libMesh::Real> calc_answers;
101 
102  // constant
103  functions.push_back("1");
104  calc_answers.push_back(L);
105 
106  // linear
107  functions.push_back("x");
108  calc_answers.push_back(0.5/costheta*3.0*3.0);
109  functions.push_back("y");
110  calc_answers.push_back( sintheta/2.0*L*L );
111 
112  // polynomial
113  functions.push_back("x*(y^2)");
114  calc_answers.push_back(0.25*std::pow(L,4)*std::pow(sintheta,2)*costheta);
115  functions.push_back("(4/3)*(x^3)+10");
116  calc_answers.push_back( (4.0/12.0)*pow(costheta,3)*std::pow(L,4)+10*L );
117 
118  GRINS::MultiphysicsSystem* system = _sim->get_multiphysics_system();
119 
120  CPPUNIT_ASSERT_EQUAL(functions.size(), calc_answers.size());
121 
122  // and now the CompositeQoI to do the evalutaion
123  GRINS::CompositeQoI comp_qoi;
124 
125  for (unsigned int i=0; i<functions.size(); i++)
126  {
127  GRINS::RayfireMesh * rayfire = new GRINS::RayfireMesh(origin,theta[t]);
128  GRINS::IntegratedFunction<libMesh::FunctionBase<libMesh::Real> > integ_func((unsigned int)2,new libMesh::ParsedFunction<libMesh::Real>(functions[i]),rayfire,"integrated_function");
129  comp_qoi.add_qoi(integ_func);
130  }
131 
132  comp_qoi.init(*_input,*system);
133  system->attach_qoi(&comp_qoi);
134  system->assemble_qoi();
135 
136  for (unsigned int i=0; i<calc_answers.size(); i++)
137  CPPUNIT_ASSERT_DOUBLES_EQUAL( calc_answers[i], _sim->get_qoi_value(i),libMesh::TOLERANCE );
138 
139  } // for t
140  }
RayfireMesh.
Definition: rayfire_mesh.h:65
Interface with libMesh for solving Multiphysics problems.
GRINS::SharedPtr< GRINS::Simulation > _sim
void init_sim(const std::string &filename)
Initialize the GetPot and Simulation class objects.

Member Data Documentation

GRINS::SharedPtr<GetPot> GRINSTesting::IntegratedFunctionTest::_input
private
GRINS::SharedPtr<GRINS::Simulation> GRINSTesting::IntegratedFunctionTest::_sim
private

The documentation for this class was generated from the following file:

Generated on Tue Dec 19 2017 12:47:32 for GRINS-0.8.0 by  doxygen 1.8.9.1