• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

utSurfaceElement.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 #include <Teuchos_UnitTestHarness.hpp>
00007 #include <Teuchos_ParameterList.hpp>
00008 #include <Epetra_MpiComm.h>
00009 #include <Phalanx.hpp>
00010 #include <Intrepid_MiniTensor.h>
00011 #include "Intrepid_DefaultCubatureFactory.hpp"
00012 #include "PHAL_AlbanyTraits.hpp"
00013 #include "Albany_Utils.hpp"
00014 #include "SurfaceBasis.hpp"
00015 #include "SurfaceVectorGradient.hpp"
00016 #include "SurfaceVectorResidual.hpp"
00017 #include "SurfaceVectorJump.hpp"
00018 #include "SurfaceScalarJump.hpp"
00019 #include "SurfaceScalarGradient.hpp"
00020 #include "SurfaceScalarGradientOperator.hpp"
00021 #include "SurfaceDiffusionResidual.hpp"
00022 #include "SurfaceCohesiveResidual.hpp"
00023 #include "SetField.hpp"
00024 #include "Albany_Layouts.hpp"
00025 #include "ConstitutiveModelInterface.hpp"
00026 #include "ConstitutiveModelParameters.hpp"
00027 #include "FieldNameMap.hpp"
00028 
00029 using namespace std;
00030 
00031 namespace
00032 {
00033 
00034 typedef PHX::MDField<PHAL::AlbanyTraits::Residual::ScalarT>::size_type size_type;
00035 typedef PHAL::AlbanyTraits::Residual Residual;
00036 typedef PHAL::AlbanyTraits::Residual::ScalarT ScalarT;
00037 typedef PHAL::AlbanyTraits Traits;
00038 typedef Intrepid::FieldContainer<RealType> FC;
00039 typedef shards::CellTopology CT;
00040 using Teuchos::RCP;
00041 using Teuchos::rcp;
00042 using Teuchos::ArrayRCP;
00043 using Intrepid::Vector;
00044 using Intrepid::Tensor;
00045 using Intrepid::bun;
00046 using Intrepid::norm;
00047 using Intrepid::eye;
00048 
00049 TEUCHOS_UNIT_TEST( SurfaceElement, Basis )
00050 {
00051   // set tolerance once and for all
00052   double tolerance = 1.0e-15;
00053 
00054   const int worksetSize = 1;
00055   const int numQPts = 4;
00056   const int numDim = 3;
00057   const int numVertices = 8;
00058   const int numNodes = 8;
00059   const RCP<Albany::Layouts> dl =
00060       rcp(new Albany::Layouts(worksetSize, numVertices,
00061           numNodes, numQPts, numDim));
00062 
00063   //--------------------------------------------------------------------------
00064   // reference coordinates
00065   ArrayRCP<ScalarT> referenceCoords(24);
00066   // Node 0
00067   referenceCoords[0] = -0.5;
00068   referenceCoords[1] = 0.0;
00069   referenceCoords[2] = -0.5;
00070   // Node 1
00071   referenceCoords[3] = -0.5;
00072   referenceCoords[4] = 0.0;
00073   referenceCoords[5] = 0.5;
00074   // Node 2
00075   referenceCoords[6] = 0.5;
00076   referenceCoords[7] = 0.0;
00077   referenceCoords[8] = 0.5;
00078   // Node 3
00079   referenceCoords[9] = 0.5;
00080   referenceCoords[10] = 0.0;
00081   referenceCoords[11] = -0.5;
00082   // Node 4
00083   referenceCoords[12] = -0.5;
00084   referenceCoords[13] = 0.0;
00085   referenceCoords[14] = -0.5;
00086   // Node 5
00087   referenceCoords[15] = -0.5;
00088   referenceCoords[16] = 0.0;
00089   referenceCoords[17] = 0.5;
00090   // Node 6
00091   referenceCoords[18] = 0.5;
00092   referenceCoords[19] = 0.0;
00093   referenceCoords[20] = 0.5;
00094   // Node 7
00095   referenceCoords[21] = 0.5;
00096   referenceCoords[22] = 0.0;
00097   referenceCoords[23] = -0.5;
00098 
00099   // SetField evaluator, which will be used to manually assign values to the
00100   // reference coordiantes field
00101   Teuchos::ParameterList rcPL;
00102   rcPL.set<string>("Evaluated Field Name", "Reference Coordinates");
00103   rcPL.set<ArrayRCP<ScalarT> >("Field Values", referenceCoords);
00104   rcPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00105       dl->vertices_vector);
00106   RCP<LCM::SetField<Residual, Traits> > setFieldRefCoords =
00107       rcp(new LCM::SetField<Residual, Traits>(rcPL));
00108 
00109   //--------------------------------------------------------------------------
00110   // current coordinates
00111   ArrayRCP<ScalarT> currentCoords(24);
00112   double eps = 0.01;
00113   // Node 0
00114   currentCoords[0] = referenceCoords[0];
00115   currentCoords[1] = referenceCoords[1];
00116   currentCoords[2] = referenceCoords[2];
00117   // Node 1
00118   currentCoords[3] = referenceCoords[3];
00119   currentCoords[4] = referenceCoords[4];
00120   currentCoords[5] = referenceCoords[5];
00121   // Node 2
00122   currentCoords[6] = referenceCoords[6];
00123   currentCoords[7] = referenceCoords[7];
00124   currentCoords[8] = referenceCoords[8];
00125   // Node 3
00126   currentCoords[9] = referenceCoords[9];
00127   currentCoords[10] = referenceCoords[10];
00128   currentCoords[11] = referenceCoords[11];
00129   // Node 4
00130   currentCoords[12] = referenceCoords[12];
00131   currentCoords[13] = referenceCoords[13] + eps;
00132   currentCoords[14] = referenceCoords[14];
00133   // Node 5
00134   currentCoords[15] = referenceCoords[15];
00135   currentCoords[16] = referenceCoords[16] + eps;
00136   currentCoords[17] = referenceCoords[17];
00137   // Node 6
00138   currentCoords[18] = referenceCoords[18];
00139   currentCoords[19] = referenceCoords[19] + eps;
00140   currentCoords[20] = referenceCoords[20];
00141   // Node 7
00142   currentCoords[21] = referenceCoords[21];
00143   currentCoords[22] = referenceCoords[22] + eps;
00144   currentCoords[23] = referenceCoords[23];
00145 
00146   // SetField evaluator, which will be used to manually assign values to the
00147   // reference coordinates field
00148   Teuchos::ParameterList ccPL;
00149   ccPL.set<string>("Evaluated Field Name", "Current Coordinates");
00150   ccPL.set<ArrayRCP<ScalarT> >("Field Values", currentCoords);
00151   ccPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00152       dl->node_vector);
00153   RCP<LCM::SetField<Residual, Traits> > setFieldCurCoords =
00154       rcp(new LCM::SetField<Residual, Traits>(ccPL));
00155 
00156   //--------------------------------------------------------------------------
00157   // intrepid basis and cubature
00158   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
00159   intrepidBasis =
00160       rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
00161   RCP<CT> cellType =
00162       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
00163   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00164   RCP<Intrepid::Cubature<RealType> > cubature =
00165       cubFactory.create(*cellType, 3);
00166 
00167   //--------------------------------------------------------------------------
00168   // SurfaceBasis evaluator
00169   Teuchos::ParameterList sbPL;
00170   sbPL.set<string>("Reference Coordinates Name", "Reference Coordinates");
00171   sbPL.set<string>("Current Coordinates Name", "Current Coordinates");
00172   sbPL.set<string>("Current Basis Name", "Current Basis");
00173   sbPL.set<string>("Reference Basis Name", "Reference Basis");
00174   sbPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
00175   sbPL.set<string>("Reference Normal Name", "Reference Normal");
00176   sbPL.set<string>("Reference Area Name", "Reference Area");
00177   sbPL.set<RCP<Intrepid::Cubature<RealType> > >
00178   ("Cubature", cubature);
00179   sbPL.set<RCP<Intrepid::Basis<RealType, FC> > >
00180   ("Intrepid Basis", intrepidBasis);
00181   RCP<LCM::SurfaceBasis<Residual, Traits> > sb =
00182       rcp(new LCM::SurfaceBasis<Residual, Traits>(sbPL, dl));
00183 
00184   // Instantiate a field manager.
00185   PHX::FieldManager<Traits> fieldManager;
00186 
00187   // Register the evaluators with the field manager
00188   fieldManager.registerEvaluator<Residual>(setFieldRefCoords);
00189   fieldManager.registerEvaluator<Residual>(setFieldCurCoords);
00190   fieldManager.registerEvaluator<Residual>(sb);
00191 
00192   // Set the evaluated fields as required fields
00193   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
00194       sb->evaluatedFields().begin();
00195       it != sb->evaluatedFields().end();
00196       it++)
00197     fieldManager.requireField<Residual>(**it);
00198 
00199   // Call postRegistrationSetup on the evaluators
00200   // JTO - I don't know what "Test String" is meant for...
00201   PHAL::AlbanyTraits::SetupData setupData = "Test String";
00202   fieldManager.postRegistrationSetup(setupData);
00203 
00204   // Create a workset
00205   PHAL::Workset workset;
00206   workset.numCells = worksetSize;
00207 
00208   // Call the evaluators, evaluateFields() computes things
00209   fieldManager.preEvaluate<Residual>(workset);
00210   fieldManager.evaluateFields<Residual>(workset);
00211   fieldManager.postEvaluate<Residual>(workset);
00212 
00213   //--------------------------------------------------------------------------
00214   // Pull the current basis from the FieldManager
00215   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> curBasis("Current Basis",
00216       dl->qp_tensor);
00217   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
00218       curBasis);
00219 
00220   // Record the expected current basis
00221   Tensor<ScalarT> expectedCurBasis(0.0, 0.0, 0.5,
00222       0.5, 0.0, 0.0,
00223       0.0, 1.0, 0.0);
00224 
00225   for (size_type cell = 0; cell < worksetSize; ++cell)
00226     for (size_type pt = 0; pt < numQPts; ++pt)
00227       for (size_type i = 0; i < numDim; ++i)
00228         for (size_type j = 0; j < numDim; ++j)
00229           TEST_COMPARE(fabs(curBasis(cell, pt, i, j) - expectedCurBasis(i, j)),
00230               <=, tolerance);
00231 
00232   //--------------------------------------------------------------------------
00233   // Pull the reference basis from the FieldManager
00234   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> refBasis("Reference Basis",
00235       dl->qp_tensor);
00236   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
00237       refBasis);
00238 
00239   // Record the expected reference basis
00240   Tensor<ScalarT> expectedRefBasis(0.0, 0.0, 0.5,
00241       0.5, 0.0, 0.0,
00242       0.0, 1.0, 0.0);
00243 
00244   for (size_type cell = 0; cell < worksetSize; ++cell)
00245     for (size_type pt = 0; pt < numQPts; ++pt)
00246       for (size_type i = 0; i < numDim; ++i)
00247         for (size_type j = 0; j < numDim; ++j)
00248           TEST_COMPARE(fabs(refBasis(cell, pt, i, j) - expectedRefBasis(i, j)),
00249               <=, tolerance);
00250 
00251   //--------------------------------------------------------------------------
00252   // Pull the reference dual basis from the FieldManager
00253   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> refDualBasis(
00254       "Reference Dual Basis",
00255       dl->qp_tensor);
00256   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
00257       refDualBasis);
00258 
00259   // Record the expected reference dual basis
00260   Tensor<ScalarT> expectedRefDualBasis(0.0, 0.0, 2.0,
00261       2.0, 0.0, 0.0,
00262       0.0, 1.0, 0.0);
00263 
00264   for (size_type cell = 0; cell < worksetSize; ++cell)
00265     for (size_type pt = 0; pt < numQPts; ++pt)
00266       for (size_type i = 0; i < numDim; ++i)
00267         for (size_type j = 0; j < numDim; ++j)
00268           TEST_COMPARE(fabs(refDualBasis(cell, pt, i, j) -
00269               expectedRefDualBasis(i, j)),
00270               <=, tolerance);
00271 
00272   //--------------------------------------------------------------------------
00273   // Pull the reference normal from the FieldManager
00274   PHX::MDField<ScalarT, Cell, QuadPoint, Dim> refNormal("Reference Normal",
00275       dl->qp_vector);
00276   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim>(refNormal);
00277 
00278   // Record the expected reference normal
00279   Vector<ScalarT> expectedRefNormal(0.0, 1.0, 0.0);
00280 
00281   for (size_type cell = 0; cell < worksetSize; ++cell)
00282     for (size_type pt = 0; pt < numQPts; ++pt)
00283       for (size_type i = 0; i < numDim; ++i)
00284         TEST_COMPARE(fabs(refNormal(cell, pt, i) - expectedRefNormal(i)),
00285             <=, tolerance);
00286 
00287   //--------------------------------------------------------------------------
00288   // Pull the reference area from the FieldManager
00289   PHX::MDField<ScalarT, Cell, QuadPoint> refArea("Reference Area",
00290       dl->qp_scalar);
00291   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint>(refArea);
00292 
00293   // Record the expected reference area
00294   ScalarT expectedRefArea(0.25);
00295 
00296   for (size_type cell = 0; cell < worksetSize; ++cell)
00297     for (size_type pt = 0; pt < numQPts; ++pt)
00298       TEST_COMPARE(fabs(refArea(cell, pt) - expectedRefArea), <=, tolerance);
00299 
00300   //--------------------------------------------------------------------------
00301   // compute a deformation gradient for the membrane
00302   for (size_type cell = 0; cell < worksetSize; ++cell) {
00303     for (size_type pt = 0; pt < numQPts; ++pt) {
00304       Vector<ScalarT> g_0(3, &curBasis(cell, pt, 0, 0));
00305       Vector<ScalarT> g_1(3, &curBasis(cell, pt, 1, 0));
00306       Vector<ScalarT> g_2(3, &curBasis(cell, pt, 2, 0));
00307       Vector<ScalarT> G0(3, &refDualBasis(cell, pt, 0, 0));
00308       Vector<ScalarT> G1(3, &refDualBasis(cell, pt, 1, 0));
00309       Vector<ScalarT> G2(3, &refDualBasis(cell, pt, 2, 0));
00310       Tensor<ScalarT> F(bun(g_0, G0) + bun(g_1, G1) + bun(g_2, G2));
00311       Tensor<ScalarT> I(eye<ScalarT>(3));
00312       TEST_COMPARE(norm(F - I), <=, tolerance);
00313     }
00314   }
00315 
00316   //-----------------------------------------------------------------------------------
00317   // Now test in-plane shear
00318   //-----------------------------------------------------------------------------------
00319   // Node 0
00320   currentCoords[0] = referenceCoords[0];
00321   currentCoords[1] = referenceCoords[1];
00322   currentCoords[2] = referenceCoords[2];
00323   // Node 1
00324   currentCoords[3] = referenceCoords[3] + eps;
00325   currentCoords[4] = referenceCoords[4];
00326   currentCoords[5] = referenceCoords[5];
00327   // Node 2
00328   currentCoords[6] = referenceCoords[6] + eps;
00329   currentCoords[7] = referenceCoords[7];
00330   currentCoords[8] = referenceCoords[8];
00331   // Node 3
00332   currentCoords[9] = referenceCoords[9];
00333   currentCoords[10] = referenceCoords[10];
00334   currentCoords[11] = referenceCoords[11];
00335   // Node 4
00336   currentCoords[12] = referenceCoords[12];
00337   currentCoords[13] = referenceCoords[13];
00338   currentCoords[14] = referenceCoords[14];
00339   // Node 5
00340   currentCoords[15] = referenceCoords[15] + eps;
00341   currentCoords[16] = referenceCoords[16];
00342   currentCoords[17] = referenceCoords[17];
00343   // Node 6
00344   currentCoords[18] = referenceCoords[18] + eps;
00345   currentCoords[19] = referenceCoords[19];
00346   currentCoords[20] = referenceCoords[20];
00347   // Node 7
00348   currentCoords[21] = referenceCoords[21];
00349   currentCoords[22] = referenceCoords[22];
00350   currentCoords[23] = referenceCoords[23];
00351 
00352   // Call the evaluators, evaluateFields() computes things
00353   fieldManager.preEvaluate<Residual>(workset);
00354   fieldManager.evaluateFields<Residual>(workset);
00355   fieldManager.postEvaluate<Residual>(workset);
00356 
00357   //--------------------------------------------------------------------------
00358   // Grab the current basis and the ref dual basis
00359   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
00360       curBasis);
00361   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
00362       refDualBasis);
00363 
00364   //--------------------------------------------------------------------------
00365   // compute a deformation gradient for the membrane
00366   for (size_type cell = 0; cell < worksetSize; ++cell) {
00367     for (size_type pt = 0; pt < numQPts; ++pt) {
00368       Vector<ScalarT> g_0(3, &curBasis(cell, pt, 0, 0));
00369       Vector<ScalarT> g_1(3, &curBasis(cell, pt, 1, 0));
00370       Vector<ScalarT> g_2(3, &curBasis(cell, pt, 2, 0));
00371       Vector<ScalarT> G0(3, &refDualBasis(cell, pt, 0, 0));
00372       Vector<ScalarT> G1(3, &refDualBasis(cell, pt, 1, 0));
00373       Vector<ScalarT> G2(3, &refDualBasis(cell, pt, 2, 0));
00374       Tensor<ScalarT> F(bun(g_0, G0) + bun(g_1, G1) + bun(g_2, G2));
00375       Tensor<ScalarT> expectedF(eye<ScalarT>(3));
00376       expectedF(0, 2) = eps;
00377       TEST_COMPARE(norm(F - expectedF), <=, tolerance);
00378     }
00379   }
00380 
00381 }
00382 
00383 TEUCHOS_UNIT_TEST( SurfaceElement, ScalarJump )
00384 {
00385   // Set up the data layout
00386   const int worksetSize = 1;
00387   const int numQPts = 4;
00388   const int numDim = 3;
00389   const int numVertices = 8;
00390   const int numNodes = 8;
00391   const RCP<Albany::Layouts> dl =
00392       rcp(
00393           new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
00394               numDim));
00395 
00396   //--------------------------------------------------------------------------
00397   // nodal value of the scalar (usually a scalar solution field such as
00398   // pressure, temperature..etc)
00399   ArrayRCP<ScalarT> currentScalar(8);
00400   double eps = 0.05;
00401   currentScalar[0] = 0.5;
00402   currentScalar[1] = 0.5;
00403   currentScalar[2] = 0.5;
00404   currentScalar[3] = 0.5;
00405 
00406   currentScalar[4] = 0.5 + eps;
00407   currentScalar[5] = 0.5 + eps;
00408   currentScalar[6] = 0.5 + eps;
00409   currentScalar[7] = 0.5 + eps;
00410 
00411   // SetField evaluator, which will be used to manually assign a value to the
00412   // current scalar field
00413   Teuchos::ParameterList csPL;
00414   csPL.set<string>("Evaluated Field Name", "Temperature");
00415   csPL.set<ArrayRCP<ScalarT> >("Field Values", currentScalar);
00416   csPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00417       dl->node_scalar);
00418   RCP<LCM::SetField<Residual, Traits> > setFieldCurrentScalar =
00419       rcp(new LCM::SetField<Residual, Traits>(csPL));
00420 
00421   //--------------------------------------------------------------------------
00422   // intrepid basis and cubature
00423   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
00424   intrepidBasis =
00425       rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
00426   RCP<CT> cellType =
00427       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
00428   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00429   RCP<Intrepid::Cubature<RealType> > cubature =
00430       cubFactory.create(*cellType, 3);
00431 
00432   //--------------------------------------------------------------------------
00433   // SurfaceScalarJump evaluator
00434   Teuchos::ParameterList sjPL;
00435   sjPL.set<string>("Nodal Temperature Name", "Temperature");
00436   sjPL.set<string>("Jump of Temperature Name", "Scalar Jump");
00437   sjPL.set<string>("MidPlane Temperature Name", "Scalar Avg");
00438   sjPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
00439   sjPL.set<RCP<Intrepid::Basis<RealType, FC> > >
00440   ("Intrepid Basis", intrepidBasis);
00441   RCP<LCM::SurfaceScalarJump<Residual, Traits> > sj =
00442       rcp(new LCM::SurfaceScalarJump<Residual, Traits>(sjPL, dl));
00443 
00444   // Instantiate a field manager.
00445   PHX::FieldManager<Traits> fieldManager;
00446 
00447   // Register the evaluators with the field manager
00448   fieldManager.registerEvaluator<Residual>(setFieldCurrentScalar);
00449   fieldManager.registerEvaluator<Residual>(sj);
00450 
00451   // Set the evaluated fields as required fields
00452   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
00453       sj->evaluatedFields().begin(); it != sj->evaluatedFields().end(); it++)
00454     fieldManager.requireField<Residual>(**it);
00455 
00456   // Call postRegistrationSetup on the evaluators
00457   // JTO - I don't know what "Test String" is meant for...
00458   PHAL::AlbanyTraits::SetupData setupData = "Test String";
00459   fieldManager.postRegistrationSetup(setupData);
00460 
00461   // Create a workset
00462   PHAL::Workset workset;
00463   workset.numCells = worksetSize;
00464 
00465   // Call the evaluators, evaluateFields() is the function that computes things
00466   fieldManager.preEvaluate<Residual>(workset);
00467   fieldManager.evaluateFields<Residual>(workset);
00468   fieldManager.postEvaluate<Residual>(workset);
00469 
00470   // Pull the vector jump from the FieldManager
00471   PHX::MDField<ScalarT, Cell, QuadPoint, Dim> jumpField("Scalar Jump",
00472       dl->qp_scalar);
00473   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint>(jumpField);
00474 
00475   // Record the expected vector jump, which will be used to check the
00476   // computed vector jump
00477   double expectedJump(eps);
00478 
00479   // Check the computed jump
00480   std::cout << endl;
00481   std::cout << "Perpendicular case:" << endl;
00482   for (size_type cell = 0; cell < worksetSize; ++cell) {
00483     for (size_type pt = 0; pt < numQPts; ++pt) {
00484 
00485       std::cout << "Jump Scalar at cell " << cell
00486           << ", quadrature point " << pt << ":" << endl;
00487       std::cout << "  " << fabs(jumpField(cell, pt)) << endl;
00488 
00489       std::cout << "Expected result:" << endl;
00490       std::cout << "  " << expectedJump << endl;
00491 
00492       std::cout << endl;
00493 
00494       double tolerance = 1.0e-9;
00495 
00496       TEST_COMPARE(jumpField(cell, pt) - expectedJump, <=, tolerance);
00497 
00498     }
00499   }
00500   std::cout << endl;
00501 
00502   //--------------------------------------------------------------------------
00503   // now test a different scalar field
00504   eps = 0.05;
00505   currentScalar[0] = 0.5;
00506   currentScalar[1] = 0.5;
00507   currentScalar[4] = 0.5;
00508   currentScalar[5] = 0.5;
00509 
00510   currentScalar[2] = 0.5 + eps;
00511   currentScalar[3] = 0.5 + eps;
00512   currentScalar[6] = 0.5 + eps;
00513   currentScalar[7] = 0.5 + eps;
00514 
00515   // Call the evaluators, evaluateFields() computes things
00516   fieldManager.preEvaluate<Residual>(workset);
00517   fieldManager.evaluateFields<Residual>(workset);
00518   fieldManager.postEvaluate<Residual>(workset);
00519 
00520   // Pull the vector jump from the FieldManager
00521   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint>(jumpField);
00522 
00523   // Record the expected vector jump, which will be used to check the
00524   // computed vector jump
00525   expectedJump = 0.0;
00526 
00527   // Check the computed jump
00528   std::cout << endl;
00529   std::cout << "Parallel case:" << endl;
00530   for (size_type cell = 0; cell < worksetSize; ++cell) {
00531     for (size_type pt = 0; pt < numQPts; ++pt) {
00532 
00533       std::cout << "Jump Scalar at cell " << cell
00534           << ", quadrature point " << pt << ":" << endl;
00535       std::cout << "  " << fabs(jumpField(cell, pt)) << endl;
00536 
00537       std::cout << "Expected result:" << endl;
00538       std::cout << "  " << expectedJump << endl;
00539 
00540       std::cout << endl;
00541 
00542       double tolerance = 1.0e-9;
00543 
00544       TEST_COMPARE(jumpField(cell, pt) - expectedJump, <=, tolerance);
00545 
00546     }
00547   }
00548   std::cout << endl;
00549 
00550 }
00551 
00552 TEUCHOS_UNIT_TEST( SurfaceElement, VectorJump )
00553 {
00554   // Set up the data layout
00555   const int worksetSize = 1;
00556   const int numQPts = 4;
00557   const int numDim = 3;
00558   const int numVertices = 8;
00559   const int numNodes = 8;
00560   const RCP<Albany::Layouts> dl =
00561       rcp(
00562           new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
00563               numDim));
00564 
00565   //--------------------------------------------------------------------------
00566   // nodal displacement jump
00567   ArrayRCP<ScalarT> referenceCoords(24);
00568   referenceCoords[0] = -0.5;
00569   referenceCoords[1] = 0.0;
00570   referenceCoords[2] = -0.5;
00571 
00572   referenceCoords[3] = -0.5;
00573   referenceCoords[4] = 0.0;
00574   referenceCoords[5] = 0.5;
00575 
00576   referenceCoords[6] = 0.5;
00577   referenceCoords[7] = 0.0;
00578   referenceCoords[8] = 0.5;
00579 
00580   referenceCoords[9] = 0.5;
00581   referenceCoords[10] = 0.0;
00582   referenceCoords[11] = -0.5;
00583 
00584   referenceCoords[12] = -0.5;
00585   referenceCoords[13] = 0.0;
00586   referenceCoords[14] = -0.5;
00587 
00588   referenceCoords[15] = -0.5;
00589   referenceCoords[16] = 0.0;
00590   referenceCoords[17] = 0.5;
00591 
00592   referenceCoords[18] = 0.5;
00593   referenceCoords[19] = 0.0;
00594   referenceCoords[20] = 0.5;
00595 
00596   referenceCoords[21] = 0.5;
00597   referenceCoords[22] = 0.0;
00598   referenceCoords[23] = -0.5;
00599 
00600   ArrayRCP<ScalarT> currentCoords(24);
00601   double eps = 0.01;
00602   currentCoords[0] = referenceCoords[0];
00603   currentCoords[1] = referenceCoords[1];
00604   currentCoords[2] = referenceCoords[2];
00605 
00606   currentCoords[3] = referenceCoords[3];
00607   currentCoords[4] = referenceCoords[4];
00608   currentCoords[5] = referenceCoords[5];
00609 
00610   currentCoords[6] = referenceCoords[6];
00611   currentCoords[7] = referenceCoords[7];
00612   currentCoords[8] = referenceCoords[8];
00613 
00614   currentCoords[9] = referenceCoords[9];
00615   currentCoords[10] = referenceCoords[10];
00616   currentCoords[11] = referenceCoords[11];
00617 
00618   currentCoords[12] = referenceCoords[12];
00619   currentCoords[13] = referenceCoords[13] + eps;
00620   currentCoords[14] = referenceCoords[14];
00621 
00622   currentCoords[15] = referenceCoords[15];
00623   currentCoords[16] = referenceCoords[16] + eps;
00624   currentCoords[17] = referenceCoords[17];
00625 
00626   currentCoords[18] = referenceCoords[18];
00627   currentCoords[19] = referenceCoords[19] + eps;
00628   currentCoords[20] = referenceCoords[20];
00629 
00630   currentCoords[21] = referenceCoords[21];
00631   currentCoords[22] = referenceCoords[22] + eps;
00632   currentCoords[23] = referenceCoords[23];
00633 
00634   // SetField evaluator, which will be used to manually assign a value to the
00635   // currentCoords field
00636   Teuchos::ParameterList ccPL;
00637   ccPL.set<string>("Evaluated Field Name", "Current Coordinates");
00638   ccPL.set<ArrayRCP<ScalarT> >("Field Values", currentCoords);
00639   ccPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00640       dl->node_vector);
00641   RCP<LCM::SetField<Residual, Traits> > setFieldCurrentCoords =
00642       rcp(new LCM::SetField<Residual, Traits>(ccPL));
00643 
00644   //--------------------------------------------------------------------------
00645   // intrepid basis and cubature
00646   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
00647   intrepidBasis = rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
00648   RCP<CT> cellType =
00649       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
00650   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00651   RCP<Intrepid::Cubature<RealType> > cubature =
00652       cubFactory.create(*cellType, 3);
00653 
00654   //--------------------------------------------------------------------------
00655   // SurfaceVectorJump evaluator
00656   Teuchos::ParameterList svjPL;
00657   svjPL.set<string>("Vector Name", "Current Coordinates");
00658   svjPL.set<string>("Vector Jump Name", "Vector Jump");
00659   svjPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
00660   svjPL.set<RCP<Intrepid::Basis<RealType, FC> > >("Intrepid Basis",
00661       intrepidBasis);
00662   RCP<LCM::SurfaceVectorJump<Residual, Traits> > svj =
00663       rcp(new LCM::SurfaceVectorJump<Residual, Traits>(svjPL, dl));
00664 
00665   // Instantiate a field manager.
00666   PHX::FieldManager<Traits> fieldManager;
00667 
00668   // Register the evaluators with the field manager
00669   fieldManager.registerEvaluator<Residual>(setFieldCurrentCoords);
00670   fieldManager.registerEvaluator<Residual>(svj);
00671 
00672   // Set the evaluated fields as required fields
00673   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
00674       svj->evaluatedFields().begin();
00675       it != svj->evaluatedFields().end(); it++)
00676     fieldManager.requireField<Residual>(**it);
00677 
00678   // Call postRegistrationSetup on the evaluators
00679   // JTO - I don't know what "Test String" is meant for...
00680   PHAL::AlbanyTraits::SetupData setupData = "Test String";
00681   fieldManager.postRegistrationSetup(setupData);
00682 
00683   // Create a workset
00684   PHAL::Workset workset;
00685   workset.numCells = worksetSize;
00686 
00687   // Call the evaluators, evaluateFields() computes things
00688   fieldManager.preEvaluate<Residual>(workset);
00689   fieldManager.evaluateFields<Residual>(workset);
00690   fieldManager.postEvaluate<Residual>(workset);
00691 
00692   // Pull the vector jump from the FieldManager
00693   PHX::MDField<ScalarT, Cell, QuadPoint, Dim> jumpField("Vector Jump",
00694       dl->qp_vector);
00695   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim>(jumpField);
00696 
00697   // Record the expected vector jump, which will be used to check the
00698   // computed vector jump
00699   Vector<ScalarT> expectedJump(0.0, eps, 0.0);
00700 
00701   // Check the computed jump
00702   for (size_type cell = 0; cell < worksetSize; ++cell) {
00703     for (size_type pt = 0; pt < numQPts; ++pt) {
00704 
00705       std::cout << "Jump Vector at cell " << cell
00706           << ", quadrature point " << pt << ":" << endl;
00707       std::cout << "  " << fabs(jumpField(cell, pt, 0));
00708       std::cout << "  " << fabs(jumpField(cell, pt, 1));
00709       std::cout << "  " << fabs(jumpField(cell, pt, 2)) << endl;
00710 
00711       std::cout << "Expected result:" << endl;
00712       std::cout << "  " << expectedJump(0);
00713       std::cout << "  " << expectedJump(1);
00714       std::cout << "  " << expectedJump(2) << endl;
00715 
00716       std::cout << endl;
00717 
00718       double tolerance = 1.0e-6;
00719       for (size_type i = 0; i < numDim; ++i) {
00720         TEST_COMPARE(jumpField(cell, pt, i) - expectedJump(i),
00721             <=, tolerance);
00722       }
00723     }
00724   }
00725   std::cout << endl;
00726 }
00727 
00728 TEUCHOS_UNIT_TEST( SurfaceElement, ScalarGradient )
00729 {
00730   // set tolerance once and for all
00731   double tolerance = 1.0e-15;
00732 
00733   const int worksetSize = 1;
00734   const int numQPts = 4;
00735   const int numDim = 3;
00736   const int numVertices = 8;
00737   const int numNodes = 8;
00738   const RCP<Albany::Layouts> dl =
00739       rcp(
00740           new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
00741               numDim));
00742 
00743   //--------------------------------------------------------------------------
00744   // reference basis
00745   ArrayRCP<ScalarT> referenceDualBasis(numQPts * numDim * numDim);
00746   for (int i(0); i < numQPts; ++i) {
00747     // G_1
00748     referenceDualBasis[numDim * numDim * i + 0] = 0.0;
00749     referenceDualBasis[numDim * numDim * i + 1] = 0.0;
00750     referenceDualBasis[numDim * numDim * i + 2] = 0.5;
00751     // G_2
00752     referenceDualBasis[numDim * numDim * i + 3] = 0.5;
00753     referenceDualBasis[numDim * numDim * i + 4] = 0.0;
00754     referenceDualBasis[numDim * numDim * i + 5] = 0.0;
00755     // G_3
00756     referenceDualBasis[numDim * numDim * i + 6] = 0.0;
00757     referenceDualBasis[numDim * numDim * i + 7] = 1.0;
00758     referenceDualBasis[numDim * numDim * i + 8] = 0.0;
00759   }
00760 
00761   // SetField evaluator, which will be used to manually assign values to the
00762   // reference dual basis
00763   Teuchos::ParameterList rdbPL;
00764   rdbPL.set<string>("Evaluated Field Name", "Reference Dual Basis");
00765   rdbPL.set<ArrayRCP<ScalarT> >("Field Values", referenceDualBasis);
00766   rdbPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00767       dl->qp_tensor);
00768   RCP<LCM::SetField<Residual, Traits> > setFieldRefDualBasis =
00769       rcp(new LCM::SetField<Residual, Traits>(rdbPL));
00770 
00771   //----------------------------------------------------------------------------
00772   // reference normal
00773   ArrayRCP<ScalarT> refNormal(numQPts * numDim);
00774   for (int i(0); i < refNormal.size(); ++i)
00775     refNormal[i] = 0.0;
00776   refNormal[1] = refNormal[4] = refNormal[7] = refNormal[10] = 1.0;
00777 
00778   // SetField evaluator, which will be used to manually assign values to the
00779   // reference normal
00780   Teuchos::ParameterList rnPL;
00781   rnPL.set<string>("Evaluated Field Name", "Reference Normal");
00782   rnPL.set<ArrayRCP<ScalarT> >("Field Values", refNormal);
00783   rnPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_vector);
00784   RCP<LCM::SetField<Residual, Traits> > setFieldRefNormal =
00785       rcp(new LCM::SetField<Residual, Traits>(rnPL));
00786 
00787   //--------------------------------------------------------------------------
00788   // Nodal value of the scalar in localization element
00789   ArrayRCP<ScalarT> nodalScalar(numVertices);
00790   for (int i(0); i < nodalScalar.size(); ++i)
00791     nodalScalar[i] = 0.0;
00792   nodalScalar[4] = nodalScalar[5] = nodalScalar[6] = nodalScalar[7] = 1.0;
00793 
00794   // SetField evaluator, which will be used to manually assign values to the
00795   // nodal scalar field
00796   Teuchos::ParameterList nsvPL;
00797   nsvPL.set<string>("Evaluated Field Name", "Nodal Scalar");
00798   nsvPL.set<ArrayRCP<ScalarT> >("Field Values", nodalScalar);
00799   nsvPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
00800       dl->node_scalar);
00801   RCP<LCM::SetField<Residual, Traits> > setFieldNodalScalar =
00802       rcp(new LCM::SetField<Residual, Traits>(nsvPL));
00803 
00804   //--------------------------------------------------------------------------
00805   // jump
00806   ArrayRCP<ScalarT> jump(numQPts);
00807   for (int i(0); i < jump.size(); ++i)
00808     jump[i] = 1.0;
00809 
00810   // SetField evaluator, which will be used to manually assign values to the
00811   // jump
00812   Teuchos::ParameterList jPL;
00813   jPL.set<string>("Evaluated Field Name", "Jump");
00814   jPL.set<ArrayRCP<ScalarT> >("Field Values", jump);
00815   jPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_scalar);
00816   RCP<LCM::SetField<Residual, Traits> > setFieldJump =
00817       rcp(new LCM::SetField<Residual, Traits>(jPL));
00818 
00819   //--------------------------------------------------------------------------
00820   // intrepid basis and cubature
00821   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
00822   intrepidBasis = rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
00823   RCP<CT> cellType =
00824       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
00825   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
00826   RCP<Intrepid::Cubature<RealType> > cubature =
00827       cubFactory.create(*cellType, 3);
00828 
00829   //--------------------------------------------------------------------------
00830   // SurfaceScalarGradient evaluator
00831   Teuchos::ParameterList ssgPL;
00832   ssgPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
00833   ssgPL.set<string>("Reference Normal Name", "Reference Normal");
00834   ssgPL.set<string>("Scalar Jump Name", "Jump");
00835   ssgPL.set<string>("Nodal Scalar Name", "Nodal Scalar");
00836   ssgPL.set<string>("Surface Scalar Gradient Name", "Surface Scalar Gradient");
00837   ssgPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
00838   ssgPL.set<RCP<Intrepid::Basis<RealType, FC> > >
00839   ("Intrepid Basis", intrepidBasis);
00840   ssgPL.set<double>("thickness", 0.1);
00841   RCP<LCM::SurfaceScalarGradient<Residual, Traits> > ssg =
00842       rcp(new LCM::SurfaceScalarGradient<Residual, Traits>(ssgPL, dl));
00843 
00844   // instantiate a field manager.
00845   PHX::FieldManager<Traits> fieldManager;
00846 
00847   // Register the evaluators with the field manager
00848   fieldManager.registerEvaluator<Residual>(setFieldRefDualBasis);
00849   fieldManager.registerEvaluator<Residual>(setFieldRefNormal);
00850   fieldManager.registerEvaluator<Residual>(setFieldJump);
00851   fieldManager.registerEvaluator<Residual>(setFieldNodalScalar);
00852   fieldManager.registerEvaluator<Residual>(ssg);
00853 
00854   // Set the evaluated fields as required fields
00855   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
00856       ssg->evaluatedFields().begin();
00857       it != ssg->evaluatedFields().end(); it++)
00858     fieldManager.requireField<Residual>(**it);
00859 
00860   // Call postRegistrationSetup on the evaluators
00861   // JTO - I don't know what "Test String" is meant for...
00862   PHAL::AlbanyTraits::SetupData setupData = "Test String";
00863   fieldManager.postRegistrationSetup(setupData);
00864 
00865   // Create a workset
00866   PHAL::Workset workset;
00867   workset.numCells = worksetSize;
00868 
00869   // Call the evaluators, evaluateFields() is the function that computes things
00870   fieldManager.preEvaluate<Residual>(workset);
00871   fieldManager.evaluateFields<Residual>(workset);
00872   fieldManager.postEvaluate<Residual>(workset);
00873 
00874   //--------------------------------------------------------------------------
00875   // Pull the scalar gradient from the FieldManager
00876   PHX::MDField<ScalarT, Cell, QuadPoint, Dim> scalarGrad(
00877       "Surface Scalar Gradient",
00878       dl->qp_vector);
00879   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim>(
00880       scalarGrad);
00881 
00882   // Record the expected gradient
00883   Vector<ScalarT> expectedScalarGrad(0.0, 10.0, 0.0);
00884 
00885   std::cout << "\n Perpendicular case: \n" << expectedScalarGrad << std::endl;
00886   std::cout << "\n expected scalar gradient:\n" << expectedScalarGrad
00887       << std::endl;
00888 
00889   std::cout << "scalar gradient:\n" << std::endl;
00890   for (size_type cell = 0; cell < worksetSize; ++cell)
00891     for (size_type pt = 0; pt < numQPts; ++pt)
00892       std::cout << Vector<ScalarT>(3, &scalarGrad(cell, pt, 0)) << std::endl;
00893 
00894   for (size_type cell = 0; cell < worksetSize; ++cell)
00895     for (size_type pt = 0; pt < numQPts; ++pt)
00896       for (size_type i = 0; i < numDim; ++i)
00897         TEST_COMPARE(fabs(scalarGrad(cell, pt, i) - expectedScalarGrad(i)),
00898             <=, tolerance);
00899 
00900   //--------------------------------------------------------------------------
00901   // Now test  gradient in parallel direction
00902 
00903   double pert(0.3);
00904   //--------------------------------------------------------------------------
00905   // Nodal value of the scalar in localization element
00906   for (int i(0); i < nodalScalar.size(); ++i)
00907     nodalScalar[i] = 0.0;
00908   nodalScalar[1] = nodalScalar[2] = nodalScalar[5] = nodalScalar[6] = pert;
00909 
00910   // jump
00911   for (int i(0); i < jump.size(); ++i)
00912     jump[i] = 0.0;
00913 
00914   // Call the evaluators, evaluateFields() is the function that computes things
00915   fieldManager.preEvaluate<Residual>(workset);
00916   fieldManager.evaluateFields<Residual>(workset);
00917   fieldManager.postEvaluate<Residual>(workset);
00918 
00919   //--------------------------------------------------------------------------
00920   // Pull the scalar gradient from the FieldManager
00921   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim>(
00922       scalarGrad);
00923 
00924   // Record the expected gradient
00925   Vector<ScalarT> expectedScalarGrad2(0.0, 0.0, pert);
00926 
00927   std::cout << "\n Parallel case: \n" << expectedScalarGrad2 << std::endl;
00928   std::cout << "\n expected scalar gradient:\n" << expectedScalarGrad2
00929       << std::endl;
00930 
00931   std::cout << "\n scalar gradient:\n" << std::endl;
00932   for (size_type cell = 0; cell < worksetSize; ++cell)
00933     for (size_type pt = 0; pt < numQPts; ++pt)
00934       std::cout << Vector<ScalarT>(3, &scalarGrad(cell, pt, 0))
00935           << std::endl;
00936 
00937   for (size_type cell = 0; cell < worksetSize; ++cell)
00938     for (size_type pt = 0; pt < numQPts; ++pt)
00939       for (size_type i = 0; i < numDim; ++i)
00940         TEST_COMPARE(fabs(scalarGrad(cell, pt, i) - expectedScalarGrad2(i)),
00941             <=, tolerance);
00942 
00943 } // end of scalar gradient test
00944 
00945 TEUCHOS_UNIT_TEST( SurfaceElement, VectorGradient )
00946 {
00947   // set tolerance once and for all
00948   double tolerance = 1.0e-15;
00949 
00950   const int worksetSize = 1;
00951   const int numQPts = 4;
00952   const int numDim = 3;
00953   const int numVertices = 8;
00954   const int numNodes = 8;
00955   const RCP<Albany::Layouts> dl =
00956       rcp(
00957           new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
00958               numDim));
00959 
00960   //--------------------------------------------------------------------------
00961   // current basis
00962   ArrayRCP<ScalarT> currentBasis(numQPts * numDim * numDim);
00963   for (int i(0); i < numQPts; ++i) {
00964     // g_1
00965     currentBasis[numDim * numDim * i + 0] = 0.0;
00966     currentBasis[numDim * numDim * i + 1] = 0.0;
00967     currentBasis[numDim * numDim * i + 2] = 0.5;
00968     // g_2
00969     currentBasis[numDim * numDim * i + 3] = 0.5;
00970     currentBasis[numDim * numDim * i + 4] = 0.0;
00971     currentBasis[numDim * numDim * i + 5] = 0.0;
00972     // g_3
00973     currentBasis[numDim * numDim * i + 6] = 0.0;
00974     currentBasis[numDim * numDim * i + 7] = 1.0;
00975     currentBasis[numDim * numDim * i + 8] = 0.0;
00976   }
00977 
00978   // SetField evaluator, which will be used to manually assign values to the
00979   // current basis
00980   Teuchos::ParameterList cbPL;
00981   cbPL.set<string>("Evaluated Field Name", "Current Basis");
00982   cbPL.set<ArrayRCP<ScalarT> >("Field Values", currentBasis);
00983   cbPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_tensor);
00984   RCP<LCM::SetField<Residual, Traits> > setFieldCurBasis =
00985       rcp(new LCM::SetField<Residual, Traits>(cbPL));
00986 
00987   //--------------------------------------------------------------------------
00988   // reference dual basis
00989   ArrayRCP<ScalarT> refDualBasis(numQPts * numDim * numDim);
00990   for (int i(0); i < numQPts; ++i) {
00991     // G^1
00992     refDualBasis[numDim * numDim * i + 0] = 0.0;
00993     refDualBasis[numDim * numDim * i + 1] = 0.0;
00994     refDualBasis[numDim * numDim * i + 2] = 2.0;
00995     //G^2
00996     refDualBasis[numDim * numDim * i + 3] = 2.0;
00997     refDualBasis[numDim * numDim * i + 4] = 0.0;
00998     refDualBasis[numDim * numDim * i + 5] = 0.0;
00999     //G^3
01000     refDualBasis[numDim * numDim * i + 6] = 0.0;
01001     refDualBasis[numDim * numDim * i + 7] = 1.0;
01002     refDualBasis[numDim * numDim * i + 8] = 0.0;
01003   }
01004 
01005   // SetField evaluator, which will be used to manually assign values to the
01006   // reference dual basis
01007   Teuchos::ParameterList rdbPL;
01008   rdbPL.set<string>("Evaluated Field Name", "Reference Dual Basis");
01009   rdbPL.set<ArrayRCP<ScalarT> >("Field Values", refDualBasis);
01010   rdbPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
01011       dl->qp_tensor);
01012   RCP<LCM::SetField<Residual, Traits> > setFieldRefDualBasis =
01013       rcp(new LCM::SetField<Residual, Traits>(rdbPL));
01014 
01015   //-----------------------------------------------------------------------------------
01016   // reference normal
01017   ArrayRCP<ScalarT> refNormal(numQPts * numDim);
01018   for (int i(0); i < refNormal.size(); ++i)
01019     refNormal[i] = 0.0;
01020   refNormal[1] = refNormal[4] = refNormal[7] = refNormal[10] = 1.0;
01021 
01022   // SetField evaluator, which will be used to manually assign values to the
01023   // reference normal
01024   Teuchos::ParameterList rnPL;
01025   rnPL.set<string>("Evaluated Field Name", "Reference Normal");
01026   rnPL.set<ArrayRCP<ScalarT> >("Field Values", refNormal);
01027   rnPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_vector);
01028   RCP<LCM::SetField<Residual, Traits> > setFieldRefNormal =
01029       rcp(new LCM::SetField<Residual, Traits>(rnPL));
01030 
01031   //--------------------------------------------------------------------------
01032   // jump
01033   ArrayRCP<ScalarT> jump(numQPts * numDim);
01034   for (int i(0); i < jump.size(); ++i)
01035     jump[i] = 0.0;
01036   jump[1] = jump[4] = jump[7] = jump[10] = 0.01;
01037 
01038   // SetField evaluator, which will be used to manually assign values to the
01039   //jump
01040   Teuchos::ParameterList jPL;
01041   jPL.set<string>("Evaluated Field Name", "Jump");
01042   jPL.set<ArrayRCP<ScalarT> >("Field Values", jump);
01043   jPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_vector);
01044   RCP<LCM::SetField<Residual, Traits> > setFieldJump =
01045       rcp(new LCM::SetField<Residual, Traits>(jPL));
01046 
01047   //--------------------------------------------------------------------------
01048   // weights (reference area)
01049   ArrayRCP<ScalarT> weights(numQPts);
01050   weights[0] = weights[1] = weights[2] = weights[3] = 0.5;
01051 
01052   // SetField evaluator, which will be used to manually assign values to the
01053   // weights
01054   Teuchos::ParameterList wPL;
01055   wPL.set<string>("Evaluated Field Name", "Weights");
01056   wPL.set<ArrayRCP<ScalarT> >("Field Values", weights);
01057   wPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_scalar);
01058   RCP<LCM::SetField<Residual, Traits> > setFieldWeights =
01059       rcp(new LCM::SetField<Residual, Traits>(wPL));
01060 
01061   //--------------------------------------------------------------------------
01062   // intrepid basis and cubature
01063   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
01064   intrepidBasis = rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
01065   RCP<CT> cellType =
01066       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
01067   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
01068   RCP<Intrepid::Cubature<RealType> > cubature =
01069       cubFactory.create(*cellType, 3);
01070 
01071   //--------------------------------------------------------------------------
01072   // SurfaceVectorGradient evaluator
01073   Teuchos::ParameterList svgPL;
01074   svgPL.set<string>("Current Basis Name", "Current Basis");
01075   svgPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
01076   svgPL.set<string>("Reference Normal Name", "Reference Normal");
01077   svgPL.set<string>("Vector Jump Name", "Jump");
01078   svgPL.set<string>("Weights Name", "Weights");
01079   svgPL.set<string>("Surface Vector Gradient Name", "F");
01080   svgPL.set<string>("Surface Vector Gradient Determinant Name", "J");
01081   svgPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01082   svgPL.set<double>("thickness", 0.1);
01083   RCP<LCM::SurfaceVectorGradient<Residual, Traits> > svg =
01084       rcp(new LCM::SurfaceVectorGradient<Residual, Traits>(svgPL, dl));
01085 
01086   // Instantiate a field manager.
01087   PHX::FieldManager<Traits> fieldManager;
01088 
01089   // Register the evaluators with the field manager
01090   fieldManager.registerEvaluator<Residual>(setFieldCurBasis);
01091   fieldManager.registerEvaluator<Residual>(setFieldRefDualBasis);
01092   fieldManager.registerEvaluator<Residual>(setFieldRefNormal);
01093   fieldManager.registerEvaluator<Residual>(setFieldJump);
01094   fieldManager.registerEvaluator<Residual>(setFieldWeights);
01095   fieldManager.registerEvaluator<Residual>(svg);
01096 
01097   // Set the evaluated fields as required fields
01098   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
01099       svg->evaluatedFields().begin();
01100       it != svg->evaluatedFields().end(); it++)
01101     fieldManager.requireField<Residual>(**it);
01102 
01103   // Call postRegistrationSetup on the evaluators
01104   // JTO - I don't know what "Test String" is meant for...
01105   PHAL::AlbanyTraits::SetupData setupData = "Test String";
01106   fieldManager.postRegistrationSetup(setupData);
01107 
01108   // Create a workset
01109   PHAL::Workset workset;
01110   workset.numCells = worksetSize;
01111 
01112   // Call the evaluators, evaluateFields() is the function that computes things
01113   fieldManager.preEvaluate<Residual>(workset);
01114   fieldManager.evaluateFields<Residual>(workset);
01115   fieldManager.postEvaluate<Residual>(workset);
01116 
01117   //--------------------------------------------------------------------------
01118   // Pull the deformation gradient from the FieldManager
01119   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> defGrad("F", dl->qp_tensor);
01120   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
01121       defGrad);
01122 
01123   // Record the expected current basis
01124   Tensor<ScalarT>
01125   expectedDefGrad(1.0, 0.0, 0.0, 0.0, 1.1, 0.0, 0.0, 0.0, 1.0);
01126 
01127   std::cout << "expected F:\n" << expectedDefGrad << std::endl;
01128 
01129   std::cout << "F:\n" << std::endl;
01130   for (size_type cell = 0; cell < worksetSize; ++cell)
01131     for (size_type pt = 0; pt < numQPts; ++pt)
01132       std::cout << Tensor<ScalarT>(3, &defGrad(cell, pt, 0, 0))
01133           << std::endl;
01134 
01135   for (size_type cell = 0; cell < worksetSize; ++cell)
01136     for (size_type pt = 0; pt < numQPts; ++pt)
01137       for (size_type i = 0; i < numDim; ++i)
01138         for (size_type j = 0; j < numDim; ++j)
01139           TEST_COMPARE(fabs(defGrad(cell, pt, i, j) - expectedDefGrad(i, j)),
01140               <=, tolerance);
01141 }
01142 
01143 TEUCHOS_UNIT_TEST( SurfaceElement, CohesiveForce )
01144 {
01145   // Set up the data layout
01146   const int worksetSize = 1;
01147   const int numQPts = 4;
01148   const int numDim = 3;
01149   const int numVertices = 8;
01150   const int numNodes = 8;
01151   const int numPlaneNodes = numNodes / 2;
01152   const RCP<Albany::Layouts> dl =
01153       rcp(
01154           new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
01155               numDim));
01156 
01157   //--------------------------------------------------------------------------
01158   // manually create evaluator field for cohesive traction
01159   ArrayRCP<ScalarT> cohesiveTraction(numQPts * numDim);
01160   // manually fill the cohesiveTraction field
01161   for (int i(0); i < numQPts * numDim; ++i)
01162     cohesiveTraction[i] = 0.0;
01163   const double T0 = 2.0;
01164   cohesiveTraction[1] = T0;
01165   cohesiveTraction[4] = 0.2 * T0;
01166   cohesiveTraction[7] = 0.4 * T0;
01167   cohesiveTraction[10] = 0.6 * T0;
01168 
01169   // SetField evaluator, which will be used to manually assign a value to the
01170   // cohesiveTraction field
01171   Teuchos::ParameterList ctPL("SetFieldCohesiveTraction");
01172   ctPL.set<string>("Evaluated Field Name", "Cohesive Traction");
01173   ctPL.set<ArrayRCP<ScalarT> >("Field Values", cohesiveTraction);
01174   ctPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout", dl->qp_vector);
01175   RCP<LCM::SetField<Residual, Traits> > setFieldCohesiveTraction =
01176       rcp(new LCM::SetField<Residual, Traits>(ctPL));
01177 
01178   //--------------------------------------------------------------------------
01179   // manually create evaluator field for refArea
01180   ArrayRCP<ScalarT> refArea(numQPts);
01181   // manually fill the refArea field, for this unit squre, refArea = 0.25;
01182   for (int i(0); i < numQPts; ++i)
01183     refArea[i] = 0.25;
01184 
01185   // SetField evaluator, which will be used to manually assign a value to the
01186   // reference area field
01187   Teuchos::ParameterList refAPL;
01188   refAPL.set<string>("Evaluated Field Name", "Reference Area");
01189   refAPL.set<ArrayRCP<ScalarT> >("Field Values", refArea);
01190   refAPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
01191       dl->qp_scalar);
01192   RCP<LCM::SetField<Residual, Traits> > setFieldRefArea =
01193       rcp(new LCM::SetField<Residual, Traits>(refAPL));
01194 
01195   //----------------------------------------------------------------------------
01196   // intrepid basis and cubature
01197   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
01198   intrepidBasis = rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
01199   RCP<CT> cellType =
01200       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
01201   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
01202   RCP<Intrepid::Cubature<RealType> > cubature = cubFactory.create(*cellType, 3);
01203 
01204   //----------------------------------------------------------------------------
01205   // SurfaceCohesiveResidual evaluator
01206   Teuchos::ParameterList scrPL;
01207   scrPL.set<string>("Reference Area Name", "Reference Area");
01208   scrPL.set<string>("Cohesive Traction Name", "Cohesive Traction");
01209   scrPL.set<string>("Surface Cohesive Residual Name", "Force");
01210   scrPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01211   scrPL.set<RCP<Intrepid::Basis<RealType, FC> > >("Intrepid Basis",
01212       intrepidBasis);
01213   RCP<LCM::SurfaceCohesiveResidual<Residual, Traits> > scr =
01214       rcp(new LCM::SurfaceCohesiveResidual<Residual, Traits>(scrPL, dl));
01215 
01216   // Instantiate a field manager.
01217   PHX::FieldManager<Traits> fieldManager;
01218 
01219   // Register the evaluators with the field manager
01220   fieldManager.registerEvaluator<Residual>(setFieldCohesiveTraction);
01221   fieldManager.registerEvaluator<Residual>(setFieldRefArea);
01222   fieldManager.registerEvaluator<Residual>(scr);
01223 
01224   // Set the evaluated fields as required fields
01225   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
01226       scr->evaluatedFields().begin();
01227       it != scr->evaluatedFields().end(); it++)
01228     fieldManager.requireField<Residual>(**it);
01229 
01230   // Call postRegistrationSetup on the evaluators
01231   // JTO - I don't know what "Test String" is meant for...
01232   PHAL::AlbanyTraits::SetupData setupData = "Test String";
01233   fieldManager.postRegistrationSetup(setupData);
01234 
01235   // Create a workset
01236   PHAL::Workset workset;
01237   workset.numCells = worksetSize;
01238 
01239   // Call the evaluators, evaluateFields() is the function that computes things
01240   fieldManager.preEvaluate<Residual>(workset);
01241   fieldManager.evaluateFields<Residual>(workset);
01242   fieldManager.postEvaluate<Residual>(workset);
01243 
01244   // Pull the nodal force from the FieldManager
01245   PHX::MDField<ScalarT, Cell, Node, Dim> forceField("Force", dl->node_vector);
01246   fieldManager.getFieldData<ScalarT, Residual, Cell, Node, Dim>(forceField);
01247 
01248   // Record the expected nodal forces, used to check the computed force
01249   // only y component for this particular test
01250   ArrayRCP<ScalarT> expectedForceBottom(numPlaneNodes);
01251   expectedForceBottom[0] = -0.2589316;
01252   expectedForceBottom[1] = -0.2622008;
01253   expectedForceBottom[2] = -0.3744017;
01254   expectedForceBottom[3] = -0.2044658;
01255 
01256   // Check the computed force
01257   for (size_type cell = 0; cell < worksetSize; ++cell) {
01258     for (size_type node = 0; node < numPlaneNodes; ++node) {
01259 
01260       std::cout << "Bottom Nodal forceY at cell " << cell
01261           << ", node " << node << ":" << endl;
01262       std::cout << "  " << forceField(cell, node, 1) << endl;
01263 
01264       std::cout << "Expected result:" << endl;
01265       std::cout << "  " << expectedForceBottom[node] << endl;
01266 
01267       std::cout << endl;
01268 
01269       double tolerance = 1.0e-6;
01270       TEST_COMPARE(forceField(cell, node, 1) - expectedForceBottom[node],
01271           <=, tolerance);
01272     }
01273   }
01274   std::cout << endl;
01275 } // end SurfaceCohesiveResidual unitTest
01276 
01277 TEUCHOS_UNIT_TEST( SurfaceElement, Complete )
01278 {
01279   // set tolerance once and for all
01280   double tolerance = 1.0e-15;
01281 
01282   const int worksetSize = 1;
01283   const int numQPts = 4;
01284   const int numDim = 3;
01285   const int numVertices = 8;
01286   const int numNodes = 8;
01287   const RCP<Albany::Layouts> dl =
01288     rcp( new Albany::Layouts(worksetSize, numVertices, numNodes, numQPts,
01289         numDim));
01290 
01291   const double thickness = 0.01;
01292 
01293   //----------------------------------------------------------------------------
01294   // reference coordinates
01295   ArrayRCP<ScalarT> referenceCoords(24);
01296   // Node 0
01297   referenceCoords[0] = -0.5;
01298   referenceCoords[1] = 0.0;
01299   referenceCoords[2] = -0.5;
01300   // Node 1
01301   referenceCoords[3] = -0.5;
01302   referenceCoords[4] = 0.0;
01303   referenceCoords[5] = 0.5;
01304   // Node 2
01305   referenceCoords[6] = 0.5;
01306   referenceCoords[7] = 0.0;
01307   referenceCoords[8] = 0.5;
01308   // Node 3
01309   referenceCoords[9] = 0.5;
01310   referenceCoords[10] = 0.0;
01311   referenceCoords[11] = -0.5;
01312   // Node 4
01313   referenceCoords[12] = -0.5;
01314   referenceCoords[13] = 0.0;
01315   referenceCoords[14] = -0.5;
01316   // Node 5
01317   referenceCoords[15] = -0.5;
01318   referenceCoords[16] = 0.0;
01319   referenceCoords[17] = 0.5;
01320   // Node 6
01321   referenceCoords[18] = 0.5;
01322   referenceCoords[19] = 0.0;
01323   referenceCoords[20] = 0.5;
01324   // Node 7
01325   referenceCoords[21] = 0.5;
01326   referenceCoords[22] = 0.0;
01327   referenceCoords[23] = -0.5;
01328 
01329   // SetField evaluator, which will be used to manually assign values to the
01330   // reference coordiantes field
01331   Teuchos::ParameterList rcPL;
01332   rcPL.set<string>("Evaluated Field Name", "Reference Coordinates");
01333   rcPL.set<ArrayRCP<ScalarT> >("Field Values", referenceCoords);
01334   rcPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
01335       dl->vertices_vector);
01336   RCP<LCM::SetField<Residual, Traits> > setFieldRefCoords =
01337       rcp(new LCM::SetField<Residual, Traits>(rcPL));
01338 
01339   //----------------------------------------------------------------------------
01340   // current coordinates
01341   ArrayRCP<ScalarT> currentCoords(24);
01342   // Node 0
01343   currentCoords[0] = referenceCoords[0];
01344   currentCoords[1] = referenceCoords[1];
01345   currentCoords[2] = referenceCoords[2];
01346   // Node 1
01347   currentCoords[3] = referenceCoords[3];
01348   currentCoords[4] = referenceCoords[4];
01349   currentCoords[5] = referenceCoords[5];
01350   // Node 2
01351   currentCoords[6] = referenceCoords[6];
01352   currentCoords[7] = referenceCoords[7];
01353   currentCoords[8] = referenceCoords[8];
01354   // Node 3
01355   currentCoords[9] = referenceCoords[9];
01356   currentCoords[10] = referenceCoords[10];
01357   currentCoords[11] = referenceCoords[11];
01358   // Node 4
01359   currentCoords[12] = referenceCoords[12];
01360   currentCoords[13] = referenceCoords[13];
01361   currentCoords[14] = referenceCoords[14];
01362   // Node 5
01363   currentCoords[15] = referenceCoords[15];
01364   currentCoords[16] = referenceCoords[16];
01365   currentCoords[17] = referenceCoords[17];
01366   // Node 6
01367   currentCoords[18] = referenceCoords[18];
01368   currentCoords[19] = referenceCoords[19];
01369   currentCoords[20] = referenceCoords[20];
01370   // Node 7
01371   currentCoords[21] = referenceCoords[21];
01372   currentCoords[22] = referenceCoords[22];
01373   currentCoords[23] = referenceCoords[23];
01374 
01375   // SetField evaluator, which will be used to manually assign values to the
01376   // reference coordiantes field
01377   Teuchos::ParameterList ccPL;
01378   ccPL.set<string>("Evaluated Field Name", "Current Coordinates");
01379   ccPL.set<ArrayRCP<ScalarT> >("Field Values", currentCoords);
01380   ccPL.set<RCP<PHX::DataLayout> >("Evaluated Field Data Layout",
01381       dl->node_vector);
01382   RCP<LCM::SetField<Residual, Traits> > setFieldCurCoords =
01383       rcp(new LCM::SetField<Residual, Traits>(ccPL));
01384 
01385   //----------------------------------------------------------------------------
01386   // intrepid basis and cubature
01387   RCP<Intrepid::Basis<RealType, FC> > intrepidBasis;
01388   intrepidBasis = rcp(new Intrepid::Basis_HGRAD_QUAD_C1_FEM<RealType, FC>());
01389   RCP<CT> cellType =
01390       rcp(new CT(shards::getCellTopologyData<shards::Quadrilateral<4> >()));
01391   Intrepid::DefaultCubatureFactory<RealType> cubFactory;
01392   RCP<Intrepid::Cubature<RealType> > cubature =
01393       cubFactory.create(*cellType, 3);
01394 
01395   Intrepid::FieldContainer<double> refPoints(numQPts, 2);
01396   Intrepid::FieldContainer<double> refWeights(numQPts);
01397   cubature->getCubature(refPoints, refWeights);
01398 
01399   //----------------------------------------------------------------------------
01400   // SurfaceBasis evaluator
01401   Teuchos::ParameterList sbPL;
01402   sbPL.set<string>("Reference Coordinates Name", "Reference Coordinates");
01403   sbPL.set<string>("Current Coordinates Name", "Current Coordinates");
01404   sbPL.set<string>("Current Basis Name", "Current Basis");
01405   sbPL.set<string>("Reference Basis Name", "Reference Basis");
01406   sbPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
01407   sbPL.set<string>("Reference Normal Name", "Reference Normal");
01408   sbPL.set<string>("Reference Area Name", "Reference Area");
01409   sbPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01410   sbPL.set<RCP<Intrepid::Basis<RealType, FC> > >
01411   ("Intrepid Basis", intrepidBasis);
01412   RCP<LCM::SurfaceBasis<Residual, Traits> > sb =
01413       rcp(new LCM::SurfaceBasis<Residual, Traits>(sbPL, dl));
01414 
01415   //----------------------------------------------------------------------------
01416   // SurfaceVectorJump evaluator
01417   Teuchos::ParameterList svjP;
01418   svjP.set<string>("Vector Name", "Current Coordinates");
01419   svjP.set<string>("Vector Jump Name", "Vector Jump");
01420   svjP.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01421   svjP.set<RCP<Intrepid::Basis<RealType, FC> > >
01422   ("Intrepid Basis", intrepidBasis);
01423   RCP<LCM::SurfaceVectorJump<Residual, Traits> > svj =
01424       rcp(new LCM::SurfaceVectorJump<Residual, Traits>(svjP, dl));
01425 
01426   //----------------------------------------------------------------------------
01427   // SurfaceVectorGradient evaluator
01428   Teuchos::ParameterList svgPL;
01429   svgPL.set<string>("Current Basis Name", "Current Basis");
01430   svgPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
01431   svgPL.set<string>("Reference Normal Name", "Reference Normal");
01432   svgPL.set<string>("Vector Jump Name", "Vector Jump");
01433   svgPL.set<string>("Weights Name", "Reference Area");
01434   svgPL.set<string>("Surface Vector Gradient Name", "F");
01435   svgPL.set<string>("Surface Vector Gradient Determinant Name", "J");
01436   svgPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01437   svgPL.set<double>("thickness", thickness);
01438   RCP<LCM::SurfaceVectorGradient<Residual, Traits> > svg =
01439       rcp(new LCM::SurfaceVectorGradient<Residual, Traits>(svgPL, dl));
01440 
01441   //----------------------------------------------------------------------------
01442   // create field name strings
01443   LCM::FieldNameMap field_name_map(false);
01444   Teuchos::RCP<std::map<std::string, std::string> > fnm =
01445     field_name_map.getMap();
01446 
01447   //----------------------------------------------------------------------------
01448   // Constitutive Model Parameters
01449   Teuchos::ParameterList paramList("Material Parameters");
01450   Teuchos::ParameterList& modelList = paramList.sublist("Material Model");
01451   modelList.set("Model Name", "Saint Venant Kirchhoff");
01452   Teuchos::ParameterList& emodList = paramList.sublist("Elastic Modulus");
01453   emodList.set("Elastic Modulus Type", "Constant");
01454   emodList.set("Value", 100.0E3);
01455   Teuchos::ParameterList& prList = paramList.sublist("Poissons Ratio");
01456   prList.set("Poissons Ratio Type", "Constant");
01457   prList.set("Value", 0.0);
01458   Teuchos::ParameterList cmpPL;
01459   paramList.set<Teuchos::RCP<std::map<std::string, std::string> > >
01460     ("Name Map", fnm);
01461   cmpPL.set<Teuchos::ParameterList*>("Material Parameters", &paramList);
01462   std::cout << paramList;
01463   RCP<LCM::ConstitutiveModelParameters<Residual, Traits> > CMP =
01464       rcp(new LCM::ConstitutiveModelParameters<Residual, Traits>(cmpPL, dl));
01465 
01466   //----------------------------------------------------------------------------
01467   // Constitutive Model Interface Evaluator
01468   Teuchos::ParameterList cmiPL;
01469   cmiPL.set<Teuchos::ParameterList*>("Material Parameters", &paramList);
01470   Teuchos::RCP<LCM::ConstitutiveModelInterface<Residual, Traits> > CMI =
01471       Teuchos::rcp(
01472           new LCM::ConstitutiveModelInterface<Residual, Traits>(cmiPL, dl));
01473 
01474   //----------------------------------------------------------------------------
01475   // SurfaceVectorResidual evaluator
01476   Teuchos::ParameterList svrPL;
01477   svrPL.set<double>("thickness", thickness);
01478   svrPL.set<string>("DefGrad Name", "F");
01479   svrPL.set<string>("Stress Name", "Cauchy_Stress");
01480   svrPL.set<string>("Current Basis Name", "Current Basis");
01481   svrPL.set<string>("Reference Dual Basis Name", "Reference Dual Basis");
01482   svrPL.set<string>("Reference Normal Name", "Reference Normal");
01483   svrPL.set<string>("Reference Area Name", "Reference Area");
01484   svrPL.set<string>("Surface Vector Residual Name", "Force");
01485   svrPL.set<RCP<Intrepid::Cubature<RealType> > >("Cubature", cubature);
01486   svrPL.set<RCP<Intrepid::Basis<RealType, FC> > >
01487   ("Intrepid Basis", intrepidBasis);
01488   RCP<LCM::SurfaceVectorResidual<Residual, Traits> > svr =
01489       rcp(new LCM::SurfaceVectorResidual<Residual, Traits>(svrPL, dl));
01490 
01491   // Instantiate a field manager.
01492   PHX::FieldManager<Traits> fieldManager;
01493 
01494   // Register the evaluators with the field manager
01495   fieldManager.registerEvaluator<Residual>(setFieldRefCoords);
01496   fieldManager.registerEvaluator<Residual>(setFieldCurCoords);
01497   fieldManager.registerEvaluator<Residual>(CMP);
01498   fieldManager.registerEvaluator<Residual>(CMI);
01499   fieldManager.registerEvaluator<Residual>(sb);
01500   fieldManager.registerEvaluator<Residual>(svj);
01501   fieldManager.registerEvaluator<Residual>(svg);
01502   fieldManager.registerEvaluator<Residual>(svr);
01503 
01504   // Set the evaluated fields as required fields
01505   for (std::vector<RCP<PHX::FieldTag> >::const_iterator it =
01506       svr->evaluatedFields().begin();
01507       it != svr->evaluatedFields().end(); it++)
01508     fieldManager.requireField<Residual>(**it);
01509 
01510   // Call postRegistrationSetup on the evaluators
01511   // JTO - I don't know what "Test String" is meant for...
01512   PHAL::AlbanyTraits::SetupData setupData = "Test String";
01513   fieldManager.postRegistrationSetup(setupData);
01514 
01515   // Create a workset
01516   PHAL::Workset workset;
01517   workset.numCells = worksetSize;
01518 
01519   // Call the evaluators, evaluateFields() is the function that computes things
01520   fieldManager.preEvaluate<Residual>(workset);
01521   fieldManager.evaluateFields<Residual>(workset);
01522   fieldManager.postEvaluate<Residual>(workset);
01523 
01524   // set MDfields
01525   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim>
01526     defGradField("F", dl->qp_tensor);
01527   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim>
01528     stressField("Cauchy_Stress",dl->qp_tensor);
01529   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim>
01530     curBasisField("Current Basis", dl->qp_tensor);
01531   PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim>
01532     refDualBasisField("Reference Dual Basis", dl->qp_tensor);
01533   PHX::MDField<ScalarT, Cell, QuadPoint, Dim>
01534     refNormalField("Reference Normal", dl->qp_vector);
01535   PHX::MDField<ScalarT, Cell, QuadPoint>
01536     refAreaField("Reference Area", dl->qp_scalar);
01537   PHX::MDField<ScalarT, Cell, Node, Dim>
01538     forceField("Force", dl->node_vector);
01539 
01540   // Pull the nodal force from the FieldManager
01541   fieldManager.getFieldData<ScalarT, Residual, Cell, Node, Dim>(forceField);
01542   // Check the computed force
01543   for (size_type cell = 0; cell < worksetSize; ++cell) {
01544     for (size_type node = 0; node < numNodes; ++node) {
01545       for (size_type i = 0; i < numDim; ++i) {
01546         TEST_COMPARE(fabs(fabs(forceField(cell, node, i)) - 0.0), <=, tolerance);
01547       }
01548     }
01549   }
01550   std::cout << endl;
01551 
01552   //----------------------------------------------------------------------------
01553   // perturbing the current coordinates
01554   double eps = 0.01;
01555 
01556   // Node 0
01557   currentCoords[0] = referenceCoords[0];
01558   currentCoords[1] = referenceCoords[1];
01559   currentCoords[2] = referenceCoords[2];
01560   // Node 1
01561   currentCoords[3] = referenceCoords[3];
01562   currentCoords[4] = referenceCoords[4];
01563   currentCoords[5] = referenceCoords[5];
01564   // Node 2
01565   currentCoords[6] = referenceCoords[6];
01566   currentCoords[7] = referenceCoords[7];
01567   currentCoords[8] = referenceCoords[8];
01568   // Node 3
01569   currentCoords[9] = referenceCoords[9];
01570   currentCoords[10] = referenceCoords[10];
01571   currentCoords[11] = referenceCoords[11];
01572   // Node 4
01573   currentCoords[12] = referenceCoords[12];
01574   currentCoords[13] = referenceCoords[13] + eps;
01575   currentCoords[14] = referenceCoords[14];
01576   // Node 5
01577   currentCoords[15] = referenceCoords[15];
01578   currentCoords[16] = referenceCoords[16] + eps;
01579   currentCoords[17] = referenceCoords[17];
01580   // Node 6
01581   currentCoords[18] = referenceCoords[18];
01582   currentCoords[19] = referenceCoords[19] + eps;
01583   currentCoords[20] = referenceCoords[20];
01584   // Node 7
01585   currentCoords[21] = referenceCoords[21];
01586   currentCoords[22] = referenceCoords[22] + eps;
01587   currentCoords[23] = referenceCoords[23];
01588 
01589   // Call the evaluators, evaluateFields() is the function that computes things
01590   fieldManager.preEvaluate<Residual>(workset);
01591   fieldManager.evaluateFields<Residual>(workset);
01592   fieldManager.postEvaluate<Residual>(workset);
01593 
01594   // Pull the current basis
01595   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
01596       curBasisField);
01597   // Pull the ref dual basis
01598   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
01599       refDualBasisField);
01600   // Pull the ref normal
01601   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim>(
01602       refNormalField);
01603   // Pull the ref area
01604   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint>(refAreaField);
01605   // Pull the deformation gradient
01606   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
01607       defGradField);
01608   // Pull the stress
01609   fieldManager.getFieldData<ScalarT, Residual, Cell, QuadPoint, Dim, Dim>(
01610       stressField);
01611   // Pull the forces
01612   fieldManager.getFieldData<ScalarT, Residual, Cell, Node, Dim>(forceField);
01613 
01614   //----------------------------------------------------------------------------
01615   // Record the expected current basis vectors
01616   std::vector<Tensor<ScalarT> > expectedg(numQPts);
01617   expectedg[0] = Tensor<ScalarT>(0.0, 0.0, 0.5,
01618       0.5, 0.0, 0.0,
01619       0.0, 1.0, 0.0);
01620   // Check the dual basis vectors
01621   for (size_type cell = 0; cell < worksetSize; ++cell)
01622     for (size_type pt = 0; pt < numQPts; ++pt)
01623       for (size_type i = 0; i < numDim; ++i)
01624         for (size_type j = 0; j < numDim; ++j)
01625           TEST_COMPARE(fabs(curBasisField(cell, pt, i, j) - expectedg[0](i, j)),
01626               <=, tolerance);
01627 
01628   //----------------------------------------------------------------------------
01629   // Record the expected ref dual basis vectors
01630   std::vector<Tensor<ScalarT> > expectedDG(numQPts);
01631   expectedDG[0] = Tensor<ScalarT>(0.0, 0.0, 2.0,
01632       2.0, 0.0, 0.0,
01633       0.0, 1.0, 0.0);
01634   // Check the dual basis vectors
01635   for (size_type cell = 0; cell < worksetSize; ++cell)
01636     for (size_type pt = 0; pt < numQPts; ++pt)
01637       for (size_type i = 0; i < numDim; ++i)
01638         for (size_type j = 0; j < numDim; ++j)
01639           TEST_COMPARE(
01640               fabs(refDualBasisField(cell, pt, i, j) - expectedDG[0](i, j)),
01641               <=, tolerance);
01642 
01643   //----------------------------------------------------------------------------
01644   // Record the expected reference Normal
01645   std::vector<Vector<ScalarT> > expectedN(numQPts);
01646   expectedN[0] = Vector<ScalarT>(0.0, 1.0, 0.0);
01647 
01648   // Check the reference normal
01649   for (size_type cell = 0; cell < worksetSize; ++cell)
01650     for (size_type pt = 0; pt < numQPts; ++pt)
01651       for (size_type i = 0; i < numDim; ++i)
01652         TEST_COMPARE(fabs(refNormalField(cell, pt, i) - expectedN[0](i)),
01653             <=, tolerance);
01654 
01655   //----------------------------------------------------------------------------
01656   // Record the expected reference area
01657   std::vector<ScalarT> expectedA(numQPts);
01658   expectedA[0] = 0.25;
01659 
01660   // Check the reference area
01661   for (size_type cell = 0; cell < worksetSize; ++cell)
01662     for (size_type pt = 0; pt < numQPts; ++pt)
01663       TEST_COMPARE(fabs(refAreaField(cell, pt) - expectedA[0]), <=, tolerance);
01664 
01665   //----------------------------------------------------------------------------
01666   // Record the expected deformation gradient
01667   std::vector<Tensor<ScalarT> > expectedF(numQPts);
01668   expectedF[0] = Tensor<ScalarT>(1.0, 0.0, 0.0,
01669       0.0, 2.0, 0.0,
01670       0.0, 0.0, 1.0);
01671   // Check the deformation gradient
01672   for (size_type cell = 0; cell < worksetSize; ++cell)
01673     for (size_type pt = 0; pt < numQPts; ++pt)
01674       for (size_type i = 0; i < numDim; ++i)
01675         for (size_type j = 0; j < numDim; ++j)
01676           TEST_COMPARE(fabs(defGradField(cell, pt, i, j) - expectedF[0](i, j)),
01677               <=, tolerance);
01678 
01679   //----------------------------------------------------------------------------
01680   // Record the expected stress
01681   std::vector<Tensor<ScalarT> > expectedStress(numQPts);
01682   expectedStress[0] = Tensor<ScalarT>(0.0, 0.0, 0.0,
01683       0.0, 300000.0, 0.0,
01684       0.0, 0.0, 0.0);
01685   // Check the deformation gradient
01686   for (size_type cell = 0; cell < worksetSize; ++cell)
01687     for (size_type pt = 0; pt < numQPts; ++pt)
01688       for (size_type i = 0; i < numDim; ++i)
01689         for (size_type j = 0; j < numDim; ++j)
01690           TEST_COMPARE(
01691               fabs(stressField(cell, pt, i, j) - expectedStress[0](i, j)),
01692               <=, tolerance);
01693 
01694   //----------------------------------------------------------------------------
01695   // Record the expected nodal forces, which will be used to check the
01696   // computed force
01697   std::vector<Vector<ScalarT> > expectedForce(numNodes);
01698   expectedForce[0] = Vector<ScalarT>(0.0, -75000., 0.0);
01699   expectedForce[1] = Vector<ScalarT>(0.0, -75000., 0.0);
01700   expectedForce[2] = Vector<ScalarT>(0.0, -75000., 0.0);
01701   expectedForce[3] = Vector<ScalarT>(0.0, -75000., 0.0);
01702   expectedForce[4] = Vector<ScalarT>(0.0, 75000., 0.0);
01703   expectedForce[5] = Vector<ScalarT>(0.0, 75000., 0.0);
01704   expectedForce[6] = Vector<ScalarT>(0.0, 75000., 0.0);
01705   expectedForce[7] = Vector<ScalarT>(0.0, 75000., 0.0);
01706 
01707   // Check the computed force
01708   for (size_type cell = 0; cell < worksetSize; ++cell) {
01709     for (size_type node = 0; node < numNodes; ++node) {
01710       for (size_type i = 0; i < numDim; ++i) {
01711         ScalarT err = fabs(forceField(cell, node, i) - expectedForce[node](i));
01712         TEST_COMPARE(err, <=, 1.0e-6);
01713       }
01714     }
01715   }
01716   std::cout << endl;
01717 
01718 }
01719 } // namespace

Generated on Wed Mar 26 2014 18:36:46 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1