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_WEDGE_C1_FEM.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_WEDGE_C1_FEM) |\n" \
214  << "| |\n" \
215  << "| 1) Patch test involving mass and stiffness matrices, |\n" \
216  << "| for the Neumann problem on a wedge 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  << "| Mauro Perego (mperego@sandia.gov). |\n" \
225  << "| |\n" \
226  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
227  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
228  << "| |\n" \
229  << "===============================================================================\n"\
230  << "| TEST 1: Patch test |\n"\
231  << "===============================================================================\n";
232 
233 
234  int errorFlag = 0;
235 
236  outStream -> precision(16);
237 
238 
239  try {
240 
241  int max_order = 1; // max total order of polynomial solution
242  DefaultCubatureFactory<double> cubFactory; // create factory
243  shards::CellTopology cell(shards::getCellTopologyData< shards::Wedge<> >()); // create parent cell topology
244  shards::CellTopology sideQ(shards::getCellTopologyData< shards::Quadrilateral<> >()); // create relevant subcell (side) topology
245  shards::CellTopology sideT(shards::getCellTopologyData< shards::Triangle<> >());
246  int cellDim = cell.getDimension();
247  int sideQDim = sideQ.getDimension();
248  int sideTDim = sideT.getDimension();
249 
250  // Define array containing points at which the solution is evaluated, on the reference Wedge.
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 
268  /* Definition of parent cell. */
269  FieldContainer<double> cell_nodes(1, 6, cellDim);
270  // funky Wedge (affine mapping)
271  cell_nodes(0, 0, 0) = -3.0;
272  cell_nodes(0, 0, 1) = -5.0;
273  cell_nodes(0, 0, 2) = -5.0;
274  cell_nodes(0, 1, 0) = -1.0;
275  cell_nodes(0, 1, 1) = -4.0;
276  cell_nodes(0, 1, 2) = -4.0;
277  cell_nodes(0, 2, 0) = 0.0;
278  cell_nodes(0, 2, 1) = 0.0;
279  cell_nodes(0, 2, 2) = -5.0;
280  cell_nodes(0, 3, 0) = 5.0;
281  cell_nodes(0, 3, 1) = -1.0;
282  cell_nodes(0, 3, 2) = 1.0;
283  cell_nodes(0, 4, 0) = 7.0;
284  cell_nodes(0, 4, 1) = 0.0;
285  cell_nodes(0, 4, 2) = 2.0;
286  cell_nodes(0, 5, 0) = 8.0;
287  cell_nodes(0, 5, 1) = 4.0;
288  cell_nodes(0, 5, 2) = 1.0;
289 
290  // perturbed reference Wedge
291  /*cell_nodes(0, 0, 0) = 0.1;
292  cell_nodes(0, 0, 1) = 0.1;
293  cell_nodes(0, 0, 2) = -0.8;
294  cell_nodes(0, 1, 0) = 1.2;
295  cell_nodes(0, 1, 1) = 0.1;
296  cell_nodes(0, 1, 2) = -0.95;
297  cell_nodes(0, 2, 0) = 0.0;
298  cell_nodes(0, 2, 1) = 0.9;
299  cell_nodes(0, 2, 2) = -0.0;
300  cell_nodes(0, 3, 0) = 0.1;
301  cell_nodes(0, 3, 1) = 0.0;
302  cell_nodes(0, 3, 2) = 0.9;
303  cell_nodes(0, 4, 0) = 0.9;
304  cell_nodes(0, 4, 1) = 0.1;
305  cell_nodes(0, 4, 2) = 1.1;
306  cell_nodes(0, 5, 0) = -0.1;
307  cell_nodes(0, 5, 1) = 1.0;
308  cell_nodes(0, 5, 2) = 1.0;*/
309 
310  // reference Wedge
311  /*cell_nodes(0, 0, 0) = 0.0;
312  cell_nodes(0, 0, 1) = 0.0;
313  cell_nodes(0, 0, 2) = -1.0;
314  cell_nodes(0, 1, 0) = 1.0;
315  cell_nodes(0, 1, 1) = 0.0;
316  cell_nodes(0, 1, 2) = -1.0;
317  cell_nodes(0, 2, 0) = 0.0;
318  cell_nodes(0, 2, 1) = 1.0;
319  cell_nodes(0, 2, 2) = -1.0;
320  cell_nodes(0, 3, 0) = 0.0;
321  cell_nodes(0, 3, 1) = 0.0;
322  cell_nodes(0, 3, 2) = 1.0;
323  cell_nodes(0, 4, 0) = 1.0;
324  cell_nodes(0, 4, 1) = 0.0;
325  cell_nodes(0, 4, 2) = 1.0;
326  cell_nodes(0, 5, 0) = 0.0;
327  cell_nodes(0, 5, 1) = 1.0;
328  cell_nodes(0, 5, 2) = 1.0;*/
329 
330 
331  FieldContainer<double> interp_points(1, numInterpPoints, cellDim);
332  CellTools<double>::mapToPhysicalFrame(interp_points, interp_points_ref, cell_nodes, cell);
333  interp_points.resize(numInterpPoints, cellDim);
334 
335  for (int x_order=0; x_order <= max_order; x_order++) {
336  for (int y_order=0; y_order <= max_order-x_order; y_order++) {
337  for (int z_order=0; z_order <= max_order-x_order-y_order; z_order++) {
338 
339  // evaluate exact solution
340  FieldContainer<double> exact_solution(1, numInterpPoints);
341  u_exact(exact_solution, interp_points, x_order, y_order, z_order);
342 
343  int basis_order = 1;
344 
345  // set test tolerance;
346  double zero = basis_order*basis_order*basis_order*100*INTREPID_TOL;
347 
348  //create basis
349  Teuchos::RCP<Basis<double,FieldContainer<double> > > basis =
350  Teuchos::rcp(new Basis_HGRAD_WEDGE_C1_FEM<double,FieldContainer<double> >() );
351  int numFields = basis->getCardinality();
352 
353  // create cubatures
354  Teuchos::RCP<Cubature<double> > cellCub = cubFactory.create(cell, 2*basis_order);
355  Teuchos::RCP<Cubature<double> > sideQCub = cubFactory.create(sideQ, 2*basis_order);
356  Teuchos::RCP<Cubature<double> > sideTCub = cubFactory.create(sideT, 2*basis_order);
357  int numCubPointsCell = cellCub->getNumPoints();
358  int numCubPointsSideQ = sideQCub->getNumPoints();
359  int numCubPointsSideT = sideTCub->getNumPoints();
360 
361  /* Computational arrays. */
362  /* Section 1: Related to parent cell integration. */
363  FieldContainer<double> cub_points_cell(numCubPointsCell, cellDim);
364  FieldContainer<double> cub_points_cell_physical(1, numCubPointsCell, cellDim);
365  FieldContainer<double> cub_weights_cell(numCubPointsCell);
366  FieldContainer<double> jacobian_cell(1, numCubPointsCell, cellDim, cellDim);
367  FieldContainer<double> jacobian_inv_cell(1, numCubPointsCell, cellDim, cellDim);
368  FieldContainer<double> jacobian_det_cell(1, numCubPointsCell);
369  FieldContainer<double> weighted_measure_cell(1, numCubPointsCell);
370 
371  FieldContainer<double> value_of_basis_at_cub_points_cell(numFields, numCubPointsCell);
372  FieldContainer<double> transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
373  FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
374  FieldContainer<double> grad_of_basis_at_cub_points_cell(numFields, numCubPointsCell, cellDim);
375  FieldContainer<double> transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
376  FieldContainer<double> weighted_transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
377  FieldContainer<double> fe_matrix(1, numFields, numFields);
378 
379  FieldContainer<double> rhs_at_cub_points_cell_physical(1, numCubPointsCell);
380  FieldContainer<double> rhs_and_soln_vector(1, numFields);
381 
382  /* Section 2: Related to subcell (side) integration. */
383  unsigned numSides = 5;
384  unsigned numSidesQ = 3;
385  FieldContainer<double> cub_points_sideQ(numCubPointsSideQ, sideQDim);
386  FieldContainer<double> cub_points_sideT(numCubPointsSideT, sideTDim);
387  FieldContainer<double> cub_weights_sideQ(numCubPointsSideQ);
388  FieldContainer<double> cub_weights_sideT(numCubPointsSideT);
389  FieldContainer<double> cub_points_sideQ_refcell(numCubPointsSideQ, cellDim);
390  FieldContainer<double> cub_points_sideT_refcell(numCubPointsSideT, cellDim);
391  FieldContainer<double> cub_points_sideQ_physical(1, numCubPointsSideQ, cellDim);
392  FieldContainer<double> cub_points_sideT_physical(1, numCubPointsSideT, cellDim);
393  FieldContainer<double> jacobian_sideQ_refcell(1, numCubPointsSideQ, cellDim, cellDim);
394  FieldContainer<double> jacobian_sideT_refcell(1, numCubPointsSideT, cellDim, cellDim);
395  FieldContainer<double> jacobian_det_sideQ_refcell(1, numCubPointsSideQ);
396  FieldContainer<double> jacobian_det_sideT_refcell(1, numCubPointsSideT);
397  FieldContainer<double> weighted_measure_sideQ_refcell(1, numCubPointsSideQ);
398  FieldContainer<double> weighted_measure_sideT_refcell(1, numCubPointsSideT);
399 
400  FieldContainer<double> value_of_basis_at_cub_points_sideQ_refcell(numFields, numCubPointsSideQ);
401  FieldContainer<double> value_of_basis_at_cub_points_sideT_refcell(numFields, numCubPointsSideT);
402  FieldContainer<double> transformed_value_of_basis_at_cub_points_sideQ_refcell(1, numFields, numCubPointsSideQ);
403  FieldContainer<double> transformed_value_of_basis_at_cub_points_sideT_refcell(1, numFields, numCubPointsSideT);
404  FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_sideQ_refcell(1, numFields, numCubPointsSideQ);
405  FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_sideT_refcell(1, numFields, numCubPointsSideT);
406  FieldContainer<double> neumann_data_at_cub_points_sideQ_physical(1, numCubPointsSideQ);
407  FieldContainer<double> neumann_data_at_cub_points_sideT_physical(1, numCubPointsSideT);
408  FieldContainer<double> neumann_fields_per_side(1, numFields);
409 
410  /* Section 3: Related to global interpolant. */
411  FieldContainer<double> value_of_basis_at_interp_points_ref(numFields, numInterpPoints);
412  FieldContainer<double> transformed_value_of_basis_at_interp_points_ref(1, numFields, numInterpPoints);
413  FieldContainer<double> interpolant(1, numInterpPoints);
414 
415  FieldContainer<int> ipiv(numFields);
416 
417 
418 
419  /******************* START COMPUTATION ***********************/
420 
421  // get cubature points and weights
422  cellCub->getCubature(cub_points_cell, cub_weights_cell);
423 
424  // compute geometric cell information
425  CellTools<double>::setJacobian(jacobian_cell, cub_points_cell, cell_nodes, cell);
426  CellTools<double>::setJacobianInv(jacobian_inv_cell, jacobian_cell);
427  CellTools<double>::setJacobianDet(jacobian_det_cell, jacobian_cell);
428 
429  // compute weighted measure
430  FunctionSpaceTools::computeCellMeasure<double>(weighted_measure_cell, jacobian_det_cell, cub_weights_cell);
431 
433  // Computing mass matrices:
434  // tabulate values of basis functions at (reference) cubature points
435  basis->getValues(value_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_VALUE);
436 
437  // transform values of basis functions
438  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_cell,
439  value_of_basis_at_cub_points_cell);
440 
441  // multiply with weighted measure
442  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_cell,
443  weighted_measure_cell,
444  transformed_value_of_basis_at_cub_points_cell);
445 
446  // compute mass matrices
447  FunctionSpaceTools::integrate<double>(fe_matrix,
448  transformed_value_of_basis_at_cub_points_cell,
449  weighted_transformed_value_of_basis_at_cub_points_cell,
450  COMP_BLAS);
452 
454  // Computing stiffness matrices:
455  // tabulate gradients of basis functions at (reference) cubature points
456  basis->getValues(grad_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_GRAD);
457 
458  // transform gradients of basis functions
459  FunctionSpaceTools::HGRADtransformGRAD<double>(transformed_grad_of_basis_at_cub_points_cell,
460  jacobian_inv_cell,
461  grad_of_basis_at_cub_points_cell);
462 
463  // multiply with weighted measure
464  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_grad_of_basis_at_cub_points_cell,
465  weighted_measure_cell,
466  transformed_grad_of_basis_at_cub_points_cell);
467 
468  // compute stiffness matrices and sum into fe_matrix
469  FunctionSpaceTools::integrate<double>(fe_matrix,
470  transformed_grad_of_basis_at_cub_points_cell,
471  weighted_transformed_grad_of_basis_at_cub_points_cell,
472  COMP_BLAS,
473  true);
475 
477  // Computing RHS contributions:
478  // map cell (reference) cubature points to physical space
479  CellTools<double>::mapToPhysicalFrame(cub_points_cell_physical, cub_points_cell, cell_nodes, cell);
480 
481  // evaluate rhs function
482  rhsFunc(rhs_at_cub_points_cell_physical, cub_points_cell_physical, x_order, y_order, z_order);
483 
484  // compute rhs
485  FunctionSpaceTools::integrate<double>(rhs_and_soln_vector,
486  rhs_at_cub_points_cell_physical,
487  weighted_transformed_value_of_basis_at_cub_points_cell,
488  COMP_BLAS);
489 
490  // compute neumann b.c. contributions and adjust rhs
491  sideQCub->getCubature(cub_points_sideQ, cub_weights_sideQ);
492  sideTCub->getCubature(cub_points_sideT, cub_weights_sideT);
493 
494  for (unsigned i=0; i<numSidesQ; i++) {
495  // compute geometric cell information
496  CellTools<double>::mapToReferenceSubcell(cub_points_sideQ_refcell, cub_points_sideQ, sideQDim, (int)i, cell);
497  CellTools<double>::setJacobian(jacobian_sideQ_refcell, cub_points_sideQ_refcell, cell_nodes, cell);
498  CellTools<double>::setJacobianDet(jacobian_det_sideQ_refcell, jacobian_sideQ_refcell);
499 
500  // compute weighted face measure
501  FunctionSpaceTools::computeFaceMeasure<double>(weighted_measure_sideQ_refcell,
502  jacobian_sideQ_refcell,
503  cub_weights_sideQ,
504  i,
505  cell);
506 
507  // tabulate values of basis functions at side cubature points, in the reference parent cell domain
508  basis->getValues(value_of_basis_at_cub_points_sideQ_refcell, cub_points_sideQ_refcell, OPERATOR_VALUE);
509  // transform
510  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_sideQ_refcell,
511  value_of_basis_at_cub_points_sideQ_refcell);
512 
513  // multiply with weighted measure
514  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_sideQ_refcell,
515  weighted_measure_sideQ_refcell,
516  transformed_value_of_basis_at_cub_points_sideQ_refcell);
517 
518  // compute Neumann data
519  // map side cubature points in reference parent cell domain to physical space
520  CellTools<double>::mapToPhysicalFrame(cub_points_sideQ_physical, cub_points_sideQ_refcell, cell_nodes, cell);
521  // now compute data
522  neumann(neumann_data_at_cub_points_sideQ_physical, cub_points_sideQ_physical, jacobian_sideQ_refcell,
523  cell, (int)i, x_order, y_order, z_order);
524 
525  FunctionSpaceTools::integrate<double>(neumann_fields_per_side,
526  neumann_data_at_cub_points_sideQ_physical,
527  weighted_transformed_value_of_basis_at_cub_points_sideQ_refcell,
528  COMP_BLAS);
529 
530  // adjust RHS
531  RealSpaceTools<double>::add(rhs_and_soln_vector, neumann_fields_per_side);;
532  }
533 
534  for (unsigned i=numSidesQ; i<numSides; i++) {
535  // compute geometric cell information
536  CellTools<double>::mapToReferenceSubcell(cub_points_sideT_refcell, cub_points_sideT, sideTDim, (int)i, cell);
537  CellTools<double>::setJacobian(jacobian_sideT_refcell, cub_points_sideT_refcell, cell_nodes, cell);
538  CellTools<double>::setJacobianDet(jacobian_det_sideT_refcell, jacobian_sideT_refcell);
539 
540  // compute weighted face measure
541  FunctionSpaceTools::computeFaceMeasure<double>(weighted_measure_sideT_refcell,
542  jacobian_sideT_refcell,
543  cub_weights_sideT,
544  i,
545  cell);
546 
547  // tabulate values of basis functions at side cubature points, in the reference parent cell domain
548  basis->getValues(value_of_basis_at_cub_points_sideT_refcell, cub_points_sideT_refcell, OPERATOR_VALUE);
549  // transform
550  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_sideT_refcell,
551  value_of_basis_at_cub_points_sideT_refcell);
552 
553  // multiply with weighted measure
554  FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_sideT_refcell,
555  weighted_measure_sideT_refcell,
556  transformed_value_of_basis_at_cub_points_sideT_refcell);
557 
558  // compute Neumann data
559  // map side cubature points in reference parent cell domain to physical space
560  CellTools<double>::mapToPhysicalFrame(cub_points_sideT_physical, cub_points_sideT_refcell, cell_nodes, cell);
561  // now compute data
562  neumann(neumann_data_at_cub_points_sideT_physical, cub_points_sideT_physical, jacobian_sideT_refcell,
563  cell, (int)i, x_order, y_order, z_order);
564 
565  FunctionSpaceTools::integrate<double>(neumann_fields_per_side,
566  neumann_data_at_cub_points_sideT_physical,
567  weighted_transformed_value_of_basis_at_cub_points_sideT_refcell,
568  COMP_BLAS);
569 
570  // adjust RHS
571  RealSpaceTools<double>::add(rhs_and_soln_vector, neumann_fields_per_side);;
572  }
574 
576  // Solution of linear system:
577  int info = 0;
578  Teuchos::LAPACK<int, double> solver;
579  solver.GESV(numFields, 1, &fe_matrix[0], numFields, &ipiv(0), &rhs_and_soln_vector[0], numFields, &info);
581 
583  // Building interpolant:
584  // evaluate basis at interpolation points
585  basis->getValues(value_of_basis_at_interp_points_ref, interp_points_ref, OPERATOR_VALUE);
586  // transform values of basis functions
587  FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_interp_points_ref,
588  value_of_basis_at_interp_points_ref);
589  FunctionSpaceTools::evaluate<double>(interpolant, rhs_and_soln_vector, transformed_value_of_basis_at_interp_points_ref);
591 
592  /******************* END COMPUTATION ***********************/
593 
594  RealSpaceTools<double>::subtract(interpolant, exact_solution);
595 
596  *outStream << "\nRelative norm-2 error between exact solution polynomial of order ("
597  << x_order << ", " << y_order << ", " << z_order
598  << ") and finite element interpolant of order " << basis_order << ": "
599  << RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
600  RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) << "\n";
601 
602  if (RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
603  RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) > zero) {
604  *outStream << "\n\nPatch test failed for solution polynomial order ("
605  << x_order << ", " << y_order << ", " << z_order << ") and basis order " << basis_order << "\n\n";
606  errorFlag++;
607  }
608  } // end for z_order
609  } // end for y_order
610  } // end for x_order
611 
612  }
613  // Catch unexpected errors
614  catch (const std::logic_error & err) {
615  *outStream << err.what() << "\n\n";
616  errorFlag = -1000;
617  };
618 
619  if (errorFlag != 0)
620  std::cout << "End Result: TEST FAILED\n";
621  else
622  std::cout << "End Result: TEST PASSED\n";
623 
624  // reset format state of std::cout
625  std::cout.copyfmt(oldFormatState);
626 
627  return errorFlag;
628 }
Implementation of basic linear algebra functionality in Euclidean space.
Implementation of the default H(grad)-compatible FEM basis of degree 1 on Wedge cell.
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.
A stateless class for operations on cell data. Provides methods for: