Intrepid
test_02.cpp
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Pavel Bochev (pbboche@sandia.gov)
38 // Denis Ridzal (dridzal@sandia.gov), or
39 // Kara Peterson (kjpeter@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
50 #include "Intrepid_HGRAD_TET_Cn_FEM_ORTH.hpp"
53 #include "Intrepid_ArrayTools.hpp"
55 #include "Intrepid_CellTools.hpp"
56 #include "Teuchos_oblackholestream.hpp"
57 #include "Teuchos_RCP.hpp"
58 #include "Teuchos_GlobalMPISession.hpp"
59 #include "Teuchos_SerialDenseMatrix.hpp"
60 #include "Teuchos_SerialDenseVector.hpp"
61 #include "Teuchos_LAPACK.hpp"
62 
63 using namespace std;
64 using namespace Intrepid;
65 
66 void rhsFunc(FieldContainer<double> &, const FieldContainer<double> &, int, int, int);
67 void neumann(FieldContainer<double> & ,
68  const FieldContainer<double> & ,
69  const FieldContainer<double> & ,
70  const shards::CellTopology & ,
71  int, int, int, int);
72 void u_exact(FieldContainer<double> &, const FieldContainer<double> &, int, int, int);
73 
75 void rhsFunc(FieldContainer<double> & result,
76  const FieldContainer<double> & points,
77  int xd,
78  int yd,
79  int zd) {
80 
81  int x = 0, y = 1, z = 2;
82 
83  // second x-derivatives of u
84  if (xd > 1) {
85  for (int cell=0; cell<result.dimension(0); cell++) {
86  for (int pt=0; pt<result.dimension(1); pt++) {
87  result(cell,pt) = - xd*(xd-1)*std::pow(points(cell,pt,x), xd-2) *
88  std::pow(points(cell,pt,y), yd) * std::pow(points(cell,pt,z), zd);
89  }
90  }
91  }
92 
93  // second y-derivatives of u
94  if (yd > 1) {
95  for (int cell=0; cell<result.dimension(0); cell++) {
96  for (int pt=0; pt<result.dimension(1); pt++) {
97  result(cell,pt) -= yd*(yd-1)*std::pow(points(cell,pt,y), yd-2) *
98  std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,z), zd);
99  }
100  }
101  }
102 
103  // second z-derivatives of u
104  if (zd > 1) {
105  for (int cell=0; cell<result.dimension(0); cell++) {
106  for (int pt=0; pt<result.dimension(1); pt++) {
107  result(cell,pt) -= zd*(zd-1)*std::pow(points(cell,pt,z), zd-2) *
108  std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,y), yd);
109  }
110  }
111  }
112 
113  // add u
114  for (int cell=0; cell<result.dimension(0); cell++) {
115  for (int pt=0; pt<result.dimension(1); pt++) {
116  result(cell,pt) += std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,y), yd) * std::pow(points(cell,pt,z), zd);
117  }
118  }
119 
120 }
121 
122 
124 void neumann(FieldContainer<double> & result,
125  const FieldContainer<double> & points,
126  const FieldContainer<double> & jacs,
127  const shards::CellTopology & parentCell,
128  int sideOrdinal, int xd, int yd, int zd) {
129 
130  int x = 0, y = 1, z = 2;
131 
132  int numCells = result.dimension(0);
133  int numPoints = result.dimension(1);
134 
135  FieldContainer<double> grad_u(numCells, numPoints, 3);
136  FieldContainer<double> side_normals(numCells, numPoints, 3);
137  FieldContainer<double> normal_lengths(numCells, numPoints);
138 
139  // first x-derivatives of u
140  if (xd > 0) {
141  for (int cell=0; cell<numCells; cell++) {
142  for (int pt=0; pt<numPoints; pt++) {
143  grad_u(cell,pt,x) = xd*std::pow(points(cell,pt,x), xd-1) *
144  std::pow(points(cell,pt,y), yd) * std::pow(points(cell,pt,z), zd);
145  }
146  }
147  }
148 
149  // first y-derivatives of u
150  if (yd > 0) {
151  for (int cell=0; cell<numCells; cell++) {
152  for (int pt=0; pt<numPoints; pt++) {
153  grad_u(cell,pt,y) = yd*std::pow(points(cell,pt,y), yd-1) *
154  std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,z), zd);
155  }
156  }
157  }
158 
159  // first z-derivatives of u
160  if (zd > 0) {
161  for (int cell=0; cell<numCells; cell++) {
162  for (int pt=0; pt<numPoints; pt++) {
163  grad_u(cell,pt,z) = zd*std::pow(points(cell,pt,z), zd-1) *
164  std::pow(points(cell,pt,x), xd) * std::pow(points(cell,pt,y), yd);
165  }
166  }
167  }
168 
169  CellTools<double>::getPhysicalSideNormals(side_normals, jacs, sideOrdinal, parentCell);
170 
171  // scale normals
172  RealSpaceTools<double>::vectorNorm(normal_lengths, side_normals, NORM_TWO);
173  FunctionSpaceTools::scalarMultiplyDataData<double>(side_normals, normal_lengths, side_normals, true);
174 
175  FunctionSpaceTools::dotMultiplyDataData<double>(result, grad_u, side_normals);
176 
177 }
178 
180 void u_exact(FieldContainer<double> & result, const FieldContainer<double> & points, int xd, int yd, int zd) {
181  int x = 0, y = 1, z = 2;
182  for (int cell=0; cell<result.dimension(0); cell++) {
183  for (int pt=0; pt<result.dimension(1); pt++) {
184  result(cell,pt) = std::pow(points(pt,x), xd)*std::pow(points(pt,y), yd)*std::pow(points(pt,z), zd);
185  }
186  }
187 }
188 
189 
190 
191 
192 int main(int argc, char *argv[]) {
193 
194  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
195 
196  // This little trick lets us print to std::cout only if
197  // a (dummy) command-line argument is provided.
198  int iprint = argc - 1;
199  Teuchos::RCP<std::ostream> outStream;
200  Teuchos::oblackholestream bhs; // outputs nothing
201  if (iprint > 0)
202  outStream = Teuchos::rcp(&std::cout, false);
203  else
204  outStream = Teuchos::rcp(&bhs, false);
205 
206  // Save the format state of the original std::cout.
207  Teuchos::oblackholestream oldFormatState;
208  oldFormatState.copyfmt(std::cout);
209 
210  *outStream \
211  << "===============================================================================\n" \
212  << "| |\n" \
213  << "| Unit Test (Basis_HGRAD_TET_Cn_FEM_ORTH) |\n" \
214  << "| |\n" \
215  << "| 1) Patch test involving mass and stiffness matrices, |\n" \
216  << "| for the Neumann problem on a tetrahedral patch |\n" \
217  << "| Omega with boundary Gamma. |\n" \
218  << "| |\n" \
219  << "| - div (grad u) + u = f in Omega, (grad u) . n = g on Gamma |\n" \
220  << "| |\n" \
221  << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" \
222  << "| Denis Ridzal (dridzal@sandia.gov), |\n" \
223  << "| Kara Peterson (kjpeter@sandia.gov). |\n" \
224  << "| |\n" \
225  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
226  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
227  << "| |\n" \
228  << "===============================================================================\n"\
229  << "| TEST 1: Patch test |\n"\
230  << "===============================================================================\n";
231 
232 
233  int errorFlag = 0;
234 
235  outStream -> precision(16);
236 
237 
238  try {
239 #ifdef KOKKOS_ENABLE_CUDA //to reduce test time for CUDA
240  int max_order=1;
241 #else
242  int max_order = 7; // max total order of polynomial solution
243 #endif
244  DefaultCubatureFactory<double> cubFactory; // create factory
245  shards::CellTopology cell(shards::getCellTopologyData< shards::Tetrahedron<> >()); // create parent cell topology
246  shards::CellTopology side(shards::getCellTopologyData< shards::Triangle<> >()); // create relevant subcell (side) topology
247  int cellDim = cell.getDimension();
248  int sideDim = side.getDimension();
249 
250  // Define array containing points at which the solution is evaluated, on the reference tet.
251  int numIntervals = 10;
252  int numInterpPoints = ((numIntervals + 1)*(numIntervals + 2)*(numIntervals + 3))/6;
253  FieldContainer<double> interp_points_ref(numInterpPoints, 3);
254  int counter = 0;
255  for (int k=0; k<=numIntervals; k++) {
256  for (int j=0; j<=numIntervals; j++) {
257  for (int i=0; i<=numIntervals; i++) {
258  if (i+j+k <= numIntervals) {
259  interp_points_ref(counter,0) = i*(1.0/numIntervals);
260  interp_points_ref(counter,1) = j*(1.0/numIntervals);
261  interp_points_ref(counter,2) = k*(1.0/numIntervals);
262  counter++;
263  }
264  }
265  }
266  }
267  /* Definition of parent cell. */
268  FieldContainer<double> cell_nodes(1, 4, cellDim);
269  // funky tet
270  cell_nodes(0, 0, 0) = -1.0;
271  cell_nodes(0, 0, 1) = -2.0;
272  cell_nodes(0, 0, 2) = 0.0;
273  cell_nodes(0, 1, 0) = 6.0;
274  cell_nodes(0, 1, 1) = 2.0;
275  cell_nodes(0, 1, 2) = 0.0;
276  cell_nodes(0, 2, 0) = -5.0;
277  cell_nodes(0, 2, 1) = 1.0;
278  cell_nodes(0, 2, 2) = 0.0;
279  cell_nodes(0, 3, 0) = -4.0;
280  cell_nodes(0, 3, 1) = -1.0;
281  cell_nodes(0, 3, 2) = 3.0;
282  // perturbed reference tet
283  /*cell_nodes(0, 0, 0) = 0.1;
284  cell_nodes(0, 0, 1) = -0.1;
285  cell_nodes(0, 0, 2) = 0.2;
286  cell_nodes(0, 1, 0) = 1.2;
287  cell_nodes(0, 1, 1) = -0.1;
288  cell_nodes(0, 1, 2) = 0.05;
289  cell_nodes(0, 2, 0) = 0.0;
290  cell_nodes(0, 2, 1) = 0.9;
291  cell_nodes(0, 2, 2) = 0.1;
292  cell_nodes(0, 3, 0) = 0.1;
293  cell_nodes(0, 3, 1) = -0.1;
294  cell_nodes(0, 3, 2) = 1.1;*/
295  // reference tet
296  /*cell_nodes(0, 0, 0) = 0.0;
297  cell_nodes(0, 0, 1) = 0.0;
298  cell_nodes(0, 0, 2) = 0.0;
299  cell_nodes(0, 1, 0) = 1.0;
300  cell_nodes(0, 1, 1) = 0.0;
301  cell_nodes(0, 1, 2) = 0.0;
302  cell_nodes(0, 2, 0) = 0.0;
303  cell_nodes(0, 2, 1) = 1.0;
304  cell_nodes(0, 2, 2) = 0.0;
305  cell_nodes(0, 3, 0) = 0.0;
306  cell_nodes(0, 3, 1) = 0.0;
307  cell_nodes(0, 3, 2) = 1.0;*/
308 
309  FieldContainer<double> interp_points(1, numInterpPoints, cellDim);
310  CellTools<double>::mapToPhysicalFrame(interp_points, interp_points_ref, cell_nodes, cell);
311  interp_points.resize(numInterpPoints, cellDim);
312  for (int x_order=0; x_order <= max_order; x_order++) {
313  for (int y_order=0; y_order <= max_order-x_order; y_order++) {
314  for (int z_order=0; z_order <= max_order-x_order-y_order; z_order++) {
315 
316  // evaluate exact solution
317  FieldContainer<double> exact_solution(1, numInterpPoints);
318  u_exact(exact_solution, interp_points, x_order, y_order, z_order);
319 
320  int total_order = std::max(x_order + y_order + z_order, 1);
321 
322  for (int basis_order=total_order; basis_order <= max_order; basis_order++) {
323 
324  // set test tolerance;
325  double zero = basis_order*basis_order*basis_order*100*INTREPID_TOL;
326 
327  //create basis
328  Teuchos::RCP<Basis<double,FieldContainer<double> > > basis =
329  Teuchos::rcp(new Basis_HGRAD_TET_Cn_FEM_ORTH<double,FieldContainer<double> >(basis_order) );
330  int numFields = basis->getCardinality();
331 
332  // create cubatures
333  Teuchos::RCP<Cubature<double> > cellCub = cubFactory.create(cell, 2*basis_order);
334  Teuchos::RCP<Cubature<double> > sideCub = cubFactory.create(side, 2*basis_order);
335  int numCubPointsCell = cellCub->getNumPoints();
336  int numCubPointsSide = sideCub->getNumPoints();
337 
338  /* Computational arrays. */
339  /* Section 1: Related to parent cell integration. */
340  FieldContainer<double> cub_points_cell(numCubPointsCell, cellDim);
341  FieldContainer<double> cub_points_cell_physical(1, numCubPointsCell, cellDim);
342  FieldContainer<double> cub_weights_cell(numCubPointsCell);
343  FieldContainer<double> jacobian_cell(1, numCubPointsCell, cellDim, cellDim);
344  FieldContainer<double> jacobian_inv_cell(1, numCubPointsCell, cellDim, cellDim);
345  FieldContainer<double> jacobian_det_cell(1, numCubPointsCell);
346  FieldContainer<double> weighted_measure_cell(1, numCubPointsCell);
347 
348  FieldContainer<double> value_of_basis_at_cub_points_cell(numFields, numCubPointsCell);
349  FieldContainer<double> transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
350  FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
351  FieldContainer<double> grad_of_basis_at_cub_points_cell(numFields, numCubPointsCell, cellDim);
352  FieldContainer<double> transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
353  FieldContainer<double> weighted_transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
354  FieldContainer<double> fe_matrix(1, numFields, numFields);
355 
356  FieldContainer<double> rhs_at_cub_points_cell_physical(1, numCubPointsCell);
357  FieldContainer<double> rhs_and_soln_vector(1, numFields);
358 
359  /* Section 2: Related to subcell (side) integration. */
360  unsigned numSides = 4;
361  FieldContainer<double> cub_points_side(numCubPointsSide, sideDim);
362  FieldContainer<double> cub_weights_side(numCubPointsSide);
363  FieldContainer<double> cub_points_side_refcell(numCubPointsSide, cellDim);
364  FieldContainer<double> cub_points_side_physical(1, numCubPointsSide, cellDim);
365  FieldContainer<double> jacobian_side_refcell(1, numCubPointsSide, cellDim, cellDim);
366  FieldContainer<double> jacobian_det_side_refcell(1, numCubPointsSide);
367  FieldContainer<double> weighted_measure_side_refcell(1, numCubPointsSide);
368 
369  FieldContainer<double> value_of_basis_at_cub_points_side_refcell(numFields, numCubPointsSide);
370  FieldContainer<double> transformed_value_of_basis_at_cub_points_side_refcell(1, numFields, numCubPointsSide);
371  FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_side_refcell(1, numFields, numCubPointsSide);
372  FieldContainer<double> neumann_data_at_cub_points_side_physical(1, numCubPointsSide);
373  FieldContainer<double> neumann_fields_per_side(1, numFields);
374 
375  /* Section 3: Related to global interpolant. */
376  FieldContainer<double> value_of_basis_at_interp_points_ref(numFields, numInterpPoints);
377  FieldContainer<double> transformed_value_of_basis_at_interp_points_ref(1, numFields, numInterpPoints);
378  FieldContainer<double> interpolant(1, numInterpPoints);
379 
380  FieldContainer<int> ipiv(numFields);
381 
382 
383 
384  /******************* START COMPUTATION ***********************/
385 
386  // get cubature points and weights
387  cellCub->getCubature(cub_points_cell, cub_weights_cell);
388 
389  // compute geometric cell information
390  CellTools<double>::setJacobian(jacobian_cell, cub_points_cell, cell_nodes, cell);
391  CellTools<double>::setJacobianInv(jacobian_inv_cell, jacobian_cell);
392  CellTools<double>::setJacobianDet(jacobian_det_cell, jacobian_cell);
393 
394  // compute weighted measure
395  FunctionSpaceTools::computeCellMeasure<double>(weighted_measure_cell, jacobian_det_cell, cub_weights_cell);
396 
398  // Computing mass matrices:
399  // tabulate values of basis functions at (reference) cubature points
400  basis->getValues(value_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_VALUE);
401 
402  // transform values of basis functions
403  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_cell,
404  value_of_basis_at_cub_points_cell);
405 
406  // multiply with weighted measure
407  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_cell,
408  weighted_measure_cell,
409  transformed_value_of_basis_at_cub_points_cell);
410 
411  // compute mass matrices
412  FunctionSpaceTools::integrate<double>(fe_matrix,
413  transformed_value_of_basis_at_cub_points_cell,
414  weighted_transformed_value_of_basis_at_cub_points_cell,
415  COMP_BLAS);
417 
419  // Computing stiffness matrices:
420  // tabulate gradients of basis functions at (reference) cubature points
421  basis->getValues(grad_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_GRAD);
422 
423  // transform gradients of basis functions
424  FunctionSpaceTools::HGRADtransformGRAD<double>(transformed_grad_of_basis_at_cub_points_cell,
425  jacobian_inv_cell,
426  grad_of_basis_at_cub_points_cell);
427 
428  // multiply with weighted measure
429  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_grad_of_basis_at_cub_points_cell,
430  weighted_measure_cell,
431  transformed_grad_of_basis_at_cub_points_cell);
432 
433  // compute stiffness matrices and sum into fe_matrix
434  FunctionSpaceTools::integrate<double>(fe_matrix,
435  transformed_grad_of_basis_at_cub_points_cell,
436  weighted_transformed_grad_of_basis_at_cub_points_cell,
437  COMP_BLAS,
438  true);
440 
442  // Computing RHS contributions:
443  // map cell (reference) cubature points to physical space
444  CellTools<double>::mapToPhysicalFrame(cub_points_cell_physical, cub_points_cell, cell_nodes, cell);
445 
446  // evaluate rhs function
447  rhsFunc(rhs_at_cub_points_cell_physical, cub_points_cell_physical, x_order, y_order, z_order);
448 
449  // compute rhs
450  FunctionSpaceTools::integrate<double>(rhs_and_soln_vector,
451  rhs_at_cub_points_cell_physical,
452  weighted_transformed_value_of_basis_at_cub_points_cell,
453  COMP_BLAS);
454 
455  // compute neumann b.c. contributions and adjust rhs
456  sideCub->getCubature(cub_points_side, cub_weights_side);
457  for (unsigned i=0; i<numSides; i++) {
458  // compute geometric cell information
459  CellTools<double>::mapToReferenceSubcell(cub_points_side_refcell, cub_points_side, sideDim, (int)i, cell);
460  CellTools<double>::setJacobian(jacobian_side_refcell, cub_points_side_refcell, cell_nodes, cell);
461  CellTools<double>::setJacobianDet(jacobian_det_side_refcell, jacobian_side_refcell);
462 
463  // compute weighted face measure
464  FunctionSpaceTools::computeFaceMeasure<double>(weighted_measure_side_refcell,
465  jacobian_side_refcell,
466  cub_weights_side,
467  i,
468  cell);
469 
470  // tabulate values of basis functions at side cubature points, in the reference parent cell domain
471  basis->getValues(value_of_basis_at_cub_points_side_refcell, cub_points_side_refcell, OPERATOR_VALUE);
472  // transform
473  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_side_refcell,
474  value_of_basis_at_cub_points_side_refcell);
475 
476  // multiply with weighted measure
477  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_side_refcell,
478  weighted_measure_side_refcell,
479  transformed_value_of_basis_at_cub_points_side_refcell);
480 
481  // compute Neumann data
482  // map side cubature points in reference parent cell domain to physical space
483  CellTools<double>::mapToPhysicalFrame(cub_points_side_physical, cub_points_side_refcell, cell_nodes, cell);
484  // now compute data
485  neumann(neumann_data_at_cub_points_side_physical, cub_points_side_physical, jacobian_side_refcell,
486  cell, (int)i, x_order, y_order, z_order);
487 
488  FunctionSpaceTools::integrate<double>(neumann_fields_per_side,
489  neumann_data_at_cub_points_side_physical,
490  weighted_transformed_value_of_basis_at_cub_points_side_refcell,
491  COMP_BLAS);
492 
493  // adjust RHS
494  RealSpaceTools<double>::add(rhs_and_soln_vector, neumann_fields_per_side);;
495  }
497 
499  // Solution of linear system:
500  int info = 0;
501  Teuchos::LAPACK<int, double> solver;
502  solver.GESV(numFields, 1, &fe_matrix[0], numFields, &ipiv(0), &rhs_and_soln_vector[0], numFields, &info);
504 
506  // Building interpolant:
507  // evaluate basis at interpolation points
508  basis->getValues(value_of_basis_at_interp_points_ref, interp_points_ref, OPERATOR_VALUE);
509  // transform values of basis functions
510  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_interp_points_ref,
511  value_of_basis_at_interp_points_ref);
512  FunctionSpaceTools::evaluate<double>(interpolant, rhs_and_soln_vector, transformed_value_of_basis_at_interp_points_ref);
514 
515  /******************* END COMPUTATION ***********************/
516 
517  RealSpaceTools<double>::subtract(interpolant, exact_solution);
518 
519  *outStream << "\nRelative norm-2 error between exact solution polynomial of order ("
520  << x_order << ", " << y_order << ", " << z_order
521  << ") and finite element interpolant of order " << basis_order << ": "
522  << RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
523  RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) << "\n";
524 
525  if (RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
526  RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) > zero) {
527  *outStream << "\n\nPatch test failed for solution polynomial order ("
528  << x_order << ", " << y_order << ", " << z_order << ") and basis order " << basis_order << "\n\n";
529  errorFlag++;
530  }
531  } // end for basis_order
532  } // end for z_order
533  } // end for y_order
534  } // end for x_order
535  }
536 
537  // Catch unexpected errors
538  catch (std::logic_error err) {
539  *outStream << err.what() << "\n\n";
540  errorFlag = -1000;
541  };
542 
543 
544  if (errorFlag != 0)
545  std::cout << "End Result: TEST FAILED\n";
546  else
547  std::cout << "End Result: TEST PASSED\n";
548 
549  // reset format state of std::cout
550  std::cout.copyfmt(oldFormatState);
551 
552  return errorFlag;
553 }
Implementation of basic linear algebra functionality in Euclidean space.
Header file for the Intrepid::CellTools class.
int dimension(const int whichDim) const
Returns the specified dimension.
Header file for utility class to provide multidimensional containers.
Header file for utility class to provide array tools, such as tensor contractions, etc.
Header file for the abstract base class Intrepid::DefaultCubatureFactory.
Header file for the Intrepid::FunctionSpaceTools class.
Header file for classes providing basic linear algebra functionality in 1D, 2D and 3D...
A factory class that generates specific instances of cubatures.
Teuchos::RCP< Cubature< Scalar, ArrayPoint, ArrayWeight > > create(const shards::CellTopology &cellTopology, const std::vector< int > &degree)
Factory method.
Implementation of the default H(grad)-compatible orthogonal basis of arbitrary degree on tetrahedron...
A stateless class for operations on cell data. Provides methods for: