TEUCHOS_UNIT_TEST(tTpetra_GlbEvalData, filtered_dofs)
{
  using Teuchos::RCP;
  using Teuchos::rcp;

  typedef Tpetra::Vector<double,int,panzer::Ordinal64> Tpetra_Vector;
  typedef Tpetra::Map<int,panzer::Ordinal64> Tpetra_Map;
  typedef Tpetra::Import<int,panzer::Ordinal64> Tpetra_Import;


  Teuchos::RCP<Teuchos::MpiComm<int> > comm = Teuchos::rcp(new Teuchos::MpiComm<int>(MPI_COMM_WORLD));

  // This is required
  TEST_ASSERT(comm->getSize()==2);

  std::vector<panzer::Ordinal64> ghosted(4);
  std::vector<panzer::Ordinal64> owned(2);

  // This is a line with 6 notes (numbered 0-5). The boundaries
  // are removed at 0 and 5.
  if(comm->getRank()==0) {
    owned[0] = 1;
    owned[1] = 2;

    ghosted[0] = 0;
    ghosted[1] = 1;
    ghosted[2] = 2;
    ghosted[3] = 3;
  }
  else {
    owned[0] = 3;
    owned[1] = 4;

    ghosted[0] = 2;
    ghosted[1] = 3;
    ghosted[2] = 4;
    ghosted[3] = 5;
  }

  RCP<const Tpetra_Map> ownedMap = rcp(new Tpetra_Map(-1,owned,0,comm));
  RCP<const Tpetra_Map> ghostedMap = rcp(new Tpetra_Map(-1,ghosted,0,comm));
  RCP<const Tpetra_Import> importer = rcp(new Tpetra_Import(ownedMap,ghostedMap));

  TpetraVector_ReadOnly_GlobalEvaluationData<double,int,panzer::Ordinal64> ged;
 
  std::vector<panzer::Ordinal64> constIndex(1);
 
  // setup filtered values
  constIndex[0] = 0;
  ged.useConstantValues(constIndex,2.0);

  constIndex[0] = 5;
  ged.useConstantValues(constIndex,3.0);

  ged.initialize(importer,ghostedMap,ownedMap);

  TEST_THROW(ged.useConstantValues(constIndex,4.0),std::logic_error);

  {
    RCP<Tpetra_Vector> ownedVecTp = rcp(new Tpetra_Vector(ownedMap));
    auto uv_2d = ownedVecTp->getLocalView<Kokkos::HostSpace> ();
    auto ownedVec = Kokkos::subview (uv_2d, Kokkos::ALL (), 0);

    if(comm->getRank()==0) {
      ownedVec(0) = 3.14;
      ownedVec(1) = 1.82;
    }
    else {
      ownedVec(0) = 2.72;
      ownedVec(1) = 6.23;
    }

    // set the owned vector, assure that const can be used
    ged.setOwnedVector_Tpetra(ownedVecTp.getConst());
  }

  // actually do something...
  ged.initializeData();
  ged.globalToGhost(0);

  // check values making sure that the constants are there
  {
    const Tpetra_Vector & ghostedVecTp = *ged.getGhostedVector_Tpetra();
    auto uv_2d = ghostedVecTp.getLocalView<Kokkos::HostSpace> ();
    auto ghostedVecKv = Kokkos::subview (uv_2d, Kokkos::ALL (), 0);

    if(comm->getRank()==0) {
      TEST_EQUALITY(ghostedVecKv(0),2.0);   // <= Replaced constant value
      TEST_EQUALITY(ghostedVecKv(1),3.14);
      TEST_EQUALITY(ghostedVecKv(2),1.82);
      TEST_EQUALITY(ghostedVecKv(3),2.72);
    }
    else {
      TEST_EQUALITY(ghostedVecKv(0),1.82);
      TEST_EQUALITY(ghostedVecKv(1),2.72);
      TEST_EQUALITY(ghostedVecKv(2),6.23);
      TEST_EQUALITY(ghostedVecKv(3),3.0);   // <= Replaced constant value
    }
  }
}
Beispiel #2
0
int main(int argc, char *argv[]) {

  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
Kokkos::initialize();
  // This little trick lets us print to std::cout only if
  // a (dummy) command-line argument is provided.
  int iprint     = argc - 1;
  Teuchos::RCP<std::ostream> outStream;
  Teuchos::oblackholestream bhs; // outputs nothing
  if (iprint > 0)
    outStream = Teuchos::rcp(&std::cout, false);
  else
    outStream = Teuchos::rcp(&bhs, false);

  // Save the format state of the original std::cout.
  Teuchos::oblackholestream oldFormatState;
  oldFormatState.copyfmt(std::cout);

  *outStream \
    << "===============================================================================\n" \
    << "|                                                                             |\n" \
    << "|                    Unit Test (Basis_HGRAD_TET_C1_FEM)                       |\n" \
    << "|                                                                             |\n" \
    << "|     1) Patch test involving mass and stiffness matrices,                    |\n" \
    << "|        for the Neumann problem on a tetrahedral patch                       |\n" \
    << "|        Omega with boundary Gamma.                                           |\n" \
    << "|                                                                             |\n" \
    << "|        - div (grad u) + u = f  in Omega,  (grad u) . n = g  on Gamma        |\n" \
    << "|                                                                             |\n" \
    << "|  Questions? Contact  Pavel Bochev  ([email protected]),                    |\n" \
    << "|                      Denis Ridzal  ([email protected]),                    |\n" \
    << "|                      Kara Peterson ([email protected]).                    |\n" \
    << "|                                                                             |\n" \
    << "|  Intrepid's website: http://trilinos.sandia.gov/packages/intrepid           |\n" \
    << "|  Trilinos website:   http://trilinos.sandia.gov                             |\n" \
    << "|                                                                             |\n" \
    << "===============================================================================\n"\
    << "| TEST 1: Patch test                                                          |\n"\
    << "===============================================================================\n";

  
  int errorFlag = 0;

  outStream -> precision(16);


  try {

    int max_order = 1;                                                                  // max total order of polynomial solution
    DefaultCubatureFactory<double>  cubFactory;                                         // create factory
    shards::CellTopology cell(shards::getCellTopologyData< shards::Tetrahedron<> >());  // create parent cell topology
    shards::CellTopology side(shards::getCellTopologyData< shards::Triangle<> >());     // create relevant subcell (side) topology
    int cellDim = cell.getDimension();
    int sideDim = side.getDimension();

    // Define array containing points at which the solution is evaluated, on the reference tet.
    int numIntervals = 10;
    int numInterpPoints = ((numIntervals + 1)*(numIntervals + 2)*(numIntervals + 3))/6;
    FieldContainer<double> interp_points_ref(numInterpPoints, 3);
    int counter = 0;
    for (int k=0; k<=numIntervals; k++) {
      for (int j=0; j<=numIntervals; j++) {
        for (int i=0; i<=numIntervals; i++) {
          if (i+j+k <= numIntervals) {
            interp_points_ref(counter,0) = i*(1.0/numIntervals);
            interp_points_ref(counter,1) = j*(1.0/numIntervals);
            interp_points_ref(counter,2) = k*(1.0/numIntervals);
            counter++;
          }
        }
      }
    }

    /* Definition of parent cell. */
    FieldContainer<double> cell_nodes(1, 4, cellDim);
    // funky tet
    cell_nodes(0, 0, 0) = -1.0;
    cell_nodes(0, 0, 1) = -2.0;
    cell_nodes(0, 0, 2) = 0.0;
    cell_nodes(0, 1, 0) = 6.0;
    cell_nodes(0, 1, 1) = 2.0;
    cell_nodes(0, 1, 2) = 0.0;
    cell_nodes(0, 2, 0) = -5.0;
    cell_nodes(0, 2, 1) = 1.0;
    cell_nodes(0, 2, 2) = 0.0;
    cell_nodes(0, 3, 0) = -4.0;
    cell_nodes(0, 3, 1) = -1.0;
    cell_nodes(0, 3, 2) = 3.0;
    // perturbed reference tet
    /*cell_nodes(0, 0, 0) = 0.1;
    cell_nodes(0, 0, 1) = -0.1;
    cell_nodes(0, 0, 2) = 0.2;
    cell_nodes(0, 1, 0) = 1.2;
    cell_nodes(0, 1, 1) = -0.1;
    cell_nodes(0, 1, 2) = 0.05;
    cell_nodes(0, 2, 0) = 0.0;
    cell_nodes(0, 2, 1) = 0.9;
    cell_nodes(0, 2, 2) = 0.1;
    cell_nodes(0, 3, 0) = 0.1;
    cell_nodes(0, 3, 1) = -0.1;
    cell_nodes(0, 3, 2) = 1.1;*/
    // reference tet
    /*cell_nodes(0, 0, 0) = 0.0;
    cell_nodes(0, 0, 1) = 0.0;
    cell_nodes(0, 0, 2) = 0.0;
    cell_nodes(0, 1, 0) = 1.0;
    cell_nodes(0, 1, 1) = 0.0;
    cell_nodes(0, 1, 2) = 0.0;
    cell_nodes(0, 2, 0) = 0.0;
    cell_nodes(0, 2, 1) = 1.0;
    cell_nodes(0, 2, 2) = 0.0;
    cell_nodes(0, 3, 0) = 0.0;
    cell_nodes(0, 3, 1) = 0.0;
    cell_nodes(0, 3, 2) = 1.0;*/

    FieldContainer<double> interp_points(1, numInterpPoints, cellDim);
    CellTools<double>::mapToPhysicalFrame(interp_points, interp_points_ref, cell_nodes, cell);
    interp_points.resize(numInterpPoints, cellDim);

    for (int x_order=0; x_order <= max_order; x_order++) {
      for (int y_order=0; y_order <= max_order-x_order; y_order++) {
        for (int z_order=0; z_order <= max_order-x_order-y_order; z_order++) {

          // evaluate exact solution
          FieldContainer<double> exact_solution(1, numInterpPoints);
          u_exact(exact_solution, interp_points, x_order, y_order, z_order);

          int basis_order = 1;

          // set test tolerance;
          double zero = basis_order*basis_order*basis_order*100*INTREPID_TOL;

          //create basis
          Teuchos::RCP<Basis<double,FieldContainer<double> > > basis =
            Teuchos::rcp(new Basis_HGRAD_TET_C1_FEM<double,FieldContainer<double> >() );
          int numFields = basis->getCardinality();

          // create cubatures
          Teuchos::RCP<Cubature<double> > cellCub = cubFactory.create(cell, 2*basis_order);
          Teuchos::RCP<Cubature<double> > sideCub = cubFactory.create(side, 2*basis_order);
          int numCubPointsCell = cellCub->getNumPoints();
          int numCubPointsSide = sideCub->getNumPoints();

          /* Computational arrays. */
          /* Section 1: Related to parent cell integration. */
          FieldContainer<double> cub_points_cell(numCubPointsCell, cellDim);
          FieldContainer<double> cub_points_cell_physical(1, numCubPointsCell, cellDim);
          FieldContainer<double> cub_weights_cell(numCubPointsCell);
          FieldContainer<double> jacobian_cell(1, numCubPointsCell, cellDim, cellDim);
          FieldContainer<double> jacobian_inv_cell(1, numCubPointsCell, cellDim, cellDim);
          FieldContainer<double> jacobian_det_cell(1, numCubPointsCell);
          FieldContainer<double> weighted_measure_cell(1, numCubPointsCell);

          FieldContainer<double> value_of_basis_at_cub_points_cell(numFields, numCubPointsCell);
          FieldContainer<double> transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
          FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell);
          FieldContainer<double> grad_of_basis_at_cub_points_cell(numFields, numCubPointsCell, cellDim);
          FieldContainer<double> transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
          FieldContainer<double> weighted_transformed_grad_of_basis_at_cub_points_cell(1, numFields, numCubPointsCell, cellDim);
          FieldContainer<double> fe_matrix(1, numFields, numFields);

          FieldContainer<double> rhs_at_cub_points_cell_physical(1, numCubPointsCell);
          FieldContainer<double> rhs_and_soln_vector(1, numFields);

          /* Section 2: Related to subcell (side) integration. */
          unsigned numSides = 4;
          FieldContainer<double> cub_points_side(numCubPointsSide, sideDim);
          FieldContainer<double> cub_weights_side(numCubPointsSide);
          FieldContainer<double> cub_points_side_refcell(numCubPointsSide, cellDim);
          FieldContainer<double> cub_points_side_physical(1, numCubPointsSide, cellDim);
          FieldContainer<double> jacobian_side_refcell(1, numCubPointsSide, cellDim, cellDim);
          FieldContainer<double> jacobian_det_side_refcell(1, numCubPointsSide);
          FieldContainer<double> weighted_measure_side_refcell(1, numCubPointsSide);

          FieldContainer<double> value_of_basis_at_cub_points_side_refcell(numFields, numCubPointsSide);
          FieldContainer<double> transformed_value_of_basis_at_cub_points_side_refcell(1, numFields, numCubPointsSide);
          FieldContainer<double> weighted_transformed_value_of_basis_at_cub_points_side_refcell(1, numFields, numCubPointsSide);
          FieldContainer<double> neumann_data_at_cub_points_side_physical(1, numCubPointsSide);
          FieldContainer<double> neumann_fields_per_side(1, numFields);

          /* Section 3: Related to global interpolant. */
          FieldContainer<double> value_of_basis_at_interp_points_ref(numFields, numInterpPoints);
          FieldContainer<double> transformed_value_of_basis_at_interp_points_ref(1, numFields, numInterpPoints);
          FieldContainer<double> interpolant(1, numInterpPoints);

          FieldContainer<int> ipiv(numFields);



          /******************* START COMPUTATION ***********************/

          // get cubature points and weights
          cellCub->getCubature(cub_points_cell, cub_weights_cell);

          // compute geometric cell information
          CellTools<double>::setJacobian(jacobian_cell, cub_points_cell, cell_nodes, cell);
          CellTools<double>::setJacobianInv(jacobian_inv_cell, jacobian_cell);
          CellTools<double>::setJacobianDet(jacobian_det_cell, jacobian_cell);

          // compute weighted measure
          FunctionSpaceTools::computeCellMeasure<double>(weighted_measure_cell, jacobian_det_cell, cub_weights_cell);

          ///////////////////////////
          // Computing mass matrices:
          // tabulate values of basis functions at (reference) cubature points
          basis->getValues(value_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_VALUE);

          // transform values of basis functions 
          FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_cell,
                                                          value_of_basis_at_cub_points_cell);

          // multiply with weighted measure
          FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_cell,
                                                      weighted_measure_cell,
                                                      transformed_value_of_basis_at_cub_points_cell);

          // compute mass matrices
          FunctionSpaceTools::integrate<double>(fe_matrix,
                                                transformed_value_of_basis_at_cub_points_cell,
                                                weighted_transformed_value_of_basis_at_cub_points_cell,
                                                COMP_BLAS);
          ///////////////////////////

          ////////////////////////////////
          // Computing stiffness matrices:
          // tabulate gradients of basis functions at (reference) cubature points
          basis->getValues(grad_of_basis_at_cub_points_cell, cub_points_cell, OPERATOR_GRAD);

          // transform gradients of basis functions 
          FunctionSpaceTools::HGRADtransformGRAD<double>(transformed_grad_of_basis_at_cub_points_cell,
                                                         jacobian_inv_cell,
                                                         grad_of_basis_at_cub_points_cell);

          // multiply with weighted measure
          FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_grad_of_basis_at_cub_points_cell,
                                                      weighted_measure_cell,
                                                      transformed_grad_of_basis_at_cub_points_cell);

          // compute stiffness matrices and sum into fe_matrix
          FunctionSpaceTools::integrate<double>(fe_matrix,
                                                transformed_grad_of_basis_at_cub_points_cell,
                                                weighted_transformed_grad_of_basis_at_cub_points_cell,
                                                COMP_BLAS,
                                                true);
          ////////////////////////////////

          ///////////////////////////////
          // Computing RHS contributions:
          // map cell (reference) cubature points to physical space
          CellTools<double>::mapToPhysicalFrame(cub_points_cell_physical, cub_points_cell, cell_nodes, cell);

          // evaluate rhs function
          rhsFunc(rhs_at_cub_points_cell_physical, cub_points_cell_physical, x_order, y_order, z_order);

          // compute rhs
          FunctionSpaceTools::integrate<double>(rhs_and_soln_vector,
                                                rhs_at_cub_points_cell_physical,
                                                weighted_transformed_value_of_basis_at_cub_points_cell,
                                                COMP_BLAS);

          // compute neumann b.c. contributions and adjust rhs
          sideCub->getCubature(cub_points_side, cub_weights_side);
          for (unsigned i=0; i<numSides; i++) {
            // compute geometric cell information
            CellTools<double>::mapToReferenceSubcell(cub_points_side_refcell, cub_points_side, sideDim, (int)i, cell);
            CellTools<double>::setJacobian(jacobian_side_refcell, cub_points_side_refcell, cell_nodes, cell);
            CellTools<double>::setJacobianDet(jacobian_det_side_refcell, jacobian_side_refcell);

            // compute weighted face measure
            FunctionSpaceTools::computeFaceMeasure<double>(weighted_measure_side_refcell,
                                                           jacobian_side_refcell,
                                                           cub_weights_side,
                                                           i,
                                                           cell);

            // tabulate values of basis functions at side cubature points, in the reference parent cell domain
            basis->getValues(value_of_basis_at_cub_points_side_refcell, cub_points_side_refcell, OPERATOR_VALUE);
            // transform 
            FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_cub_points_side_refcell,
                                                            value_of_basis_at_cub_points_side_refcell);

            // multiply with weighted measure
            FunctionSpaceTools::multiplyMeasure<double>(weighted_transformed_value_of_basis_at_cub_points_side_refcell,
                                                        weighted_measure_side_refcell,
                                                        transformed_value_of_basis_at_cub_points_side_refcell);

            // compute Neumann data
            // map side cubature points in reference parent cell domain to physical space
            CellTools<double>::mapToPhysicalFrame(cub_points_side_physical, cub_points_side_refcell, cell_nodes, cell);
            // now compute data
            neumann(neumann_data_at_cub_points_side_physical, cub_points_side_physical, jacobian_side_refcell,
                    cell, (int)i, x_order, y_order, z_order);

            FunctionSpaceTools::integrate<double>(neumann_fields_per_side,
                                                  neumann_data_at_cub_points_side_physical,
                                                  weighted_transformed_value_of_basis_at_cub_points_side_refcell,
                                                  COMP_BLAS);

            // adjust RHS
            RealSpaceTools<double>::add(rhs_and_soln_vector, neumann_fields_per_side);;
          }
          ///////////////////////////////

          /////////////////////////////
          // Solution of linear system:
          int info = 0;
          Teuchos::LAPACK<int, double> solver;
          solver.GESV(numFields, 1, &fe_matrix[0], numFields, &ipiv(0), &rhs_and_soln_vector[0], numFields, &info);
          /////////////////////////////

          ////////////////////////
          // Building interpolant:
          // evaluate basis at interpolation points
          basis->getValues(value_of_basis_at_interp_points_ref, interp_points_ref, OPERATOR_VALUE);
          // transform values of basis functions 
          FunctionSpaceTools::HGRADtransformVALUE<double>(transformed_value_of_basis_at_interp_points_ref,
                                                          value_of_basis_at_interp_points_ref);
          FunctionSpaceTools::evaluate<double>(interpolant, rhs_and_soln_vector, transformed_value_of_basis_at_interp_points_ref);
          ////////////////////////

          /******************* END COMPUTATION ***********************/
      
          RealSpaceTools<double>::subtract(interpolant, exact_solution);

          *outStream << "\nRelative norm-2 error between exact solution polynomial of order ("
                     << x_order << ", " << y_order << ", " << z_order
                     << ") and finite element interpolant of order " << basis_order << ": "
                     << RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
                        RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) << "\n";

          if (RealSpaceTools<double>::vectorNorm(&interpolant[0], interpolant.dimension(1), NORM_TWO) /
              RealSpaceTools<double>::vectorNorm(&exact_solution[0], exact_solution.dimension(1), NORM_TWO) > zero) {
            *outStream << "\n\nPatch test failed for solution polynomial order ("
                       << x_order << ", " << y_order << ", " << z_order << ") and basis order " << basis_order << "\n\n";
            errorFlag++;
          }
        } // end for z_order
      } // end for y_order
    } // end for x_order

  }
  // Catch unexpected errors
  catch (std::logic_error err) {
    *outStream << err.what() << "\n\n";
    errorFlag = -1000;
  };

  if (errorFlag != 0)
    std::cout << "End Result: TEST FAILED\n";
  else
    std::cout << "End Result: TEST PASSED\n";

  // reset format state of std::cout
  std::cout.copyfmt(oldFormatState);
Kokkos::finalize();
  return errorFlag;
}
TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(dof_pointfield,value,EvalType)
{
  PHX::KokkosDeviceSession session;

  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::rcp_dynamic_cast;

  // build a dummy workset
  //////////////////////////////////////////////////////////
  int numCells = 2;

  // build basis values
  Teuchos::RCP<shards::CellTopology> topo
    = Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >()));

  Teuchos::RCP<panzer::PureBasis> sourceBasis = Teuchos::rcp(new panzer::PureBasis("HGrad",1,numCells,topo));
  Teuchos::RCP<panzer::PureBasis> targetBasis = Teuchos::rcp(new panzer::PureBasis("HGrad",2,numCells,topo));

  Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
     = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>); 

  // add in some evaluators
  ///////////////////////////////////////////////////
  {
     // fill the basis with some dummy values
     Teuchos::ParameterList p;
     p.set("Name","Pressure");
     p.set("Basis",sourceBasis);
     RCP<panzer::DummyFieldEvaluator<EvalType,panzer::Traits> > e = 
       rcp(new panzer::DummyFieldEvaluator<EvalType,panzer::Traits>(p));

     fm->registerEvaluator<EvalType>(e);
  }

  // add evaluator under test
  ///////////////////////////////////////////////////

  {
    RCP<panzer::DOF_BasisToBasis<EvalType,panzer::Traits> > e = 
      rcp(new panzer::DOF_BasisToBasis<EvalType,panzer::Traits>("Pressure",*sourceBasis,*targetBasis));
    
    fm->registerEvaluator<EvalType>(e);
    
    Teuchos::RCP<PHX::FieldTag> ft = e->evaluatedFields()[0];
    fm->requireField<EvalType>(*ft);
  }

  Teuchos::RCP<panzer::Workset> workset = Teuchos::rcp(new panzer::Workset);
  workset->num_cells = numCells;

  panzer::Traits::SetupData setupData;
  setupData.worksets_ = rcp(new std::vector<panzer::Workset>);
  setupData.worksets_->push_back(*workset);

  std::vector<PHX::index_size_type> derivative_dimensions;
  derivative_dimensions.push_back(4);
  fm->setKokkosExtendedDataTypeDimensions<panzer::Traits::Jacobian>(derivative_dimensions);
  fm->postRegistrationSetup(setupData);

  //fm->writeGraphvizFile();

  panzer::Traits::PreEvalData preEvalData;

  fm->preEvaluate<EvalType>(preEvalData);
  fm->evaluateFields<EvalType>(*workset);
  fm->postEvaluate<EvalType>(0);

  typedef typename EvalType::ScalarT ScalarT;
  typedef typename PHX::MDFieldTypeTraits<PHX::MDField<ScalarT,Cell,BASIS> >::return_type  ScalarView;

  typename PHX::MDField<ScalarT,Cell,BASIS> s("Pressure",sourceBasis->functional);
  typename PHX::MDField<ScalarT,Cell,BASIS> t("Pressure",targetBasis->functional);

  fm->getFieldData<ScalarT,EvalType>(s);
  fm->getFieldData<ScalarT,EvalType>(t);

  typename Teuchos::ScalarTraits<ScalarT>::magnitudeType tol =
    100.0 * Teuchos::ScalarTraits<ScalarT>::eps();

  TEST_FLOATING_EQUALITY(ScalarT(t(0,0)),ScalarT(s(0,0)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,1)),ScalarT(s(0,1)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,2)),ScalarT(s(0,2)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,3)),ScalarT(s(0,3)),tol);

  TEST_FLOATING_EQUALITY(ScalarT(t(1,0)),ScalarT(s(1,0)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,1)),ScalarT(s(1,1)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,2)),ScalarT(s(1,2)),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,3)),ScalarT(s(1,3)),tol);

  TEST_FLOATING_EQUALITY(ScalarT(t(0,4)),ScalarT(1.5),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,5)),ScalarT(2.0),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,6)),ScalarT(1.5),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,7)),ScalarT(1.0),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(0,8)),ScalarT(1.5),tol);

  TEST_FLOATING_EQUALITY(ScalarT(t(1,4)),ScalarT(2.5),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,5)),ScalarT(3.0),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,6)),ScalarT(2.5),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,7)),ScalarT(2.0),tol);
  TEST_FLOATING_EQUALITY(ScalarT(t(1,8)),ScalarT(2.5),tol);
}
Beispiel #4
0
 void setVector(const Vector<Real>& vec) { 
   vec_->set(vec); 
 }
Beispiel #5
0
 void plus( const Vector<Real> &x ) {
   const RiskVector<Real> &xs = Teuchos::dyn_cast<const RiskVector<Real> >(
     Teuchos::dyn_cast<const Vector<Real> >(x));
   if (augmented_) { stat_ += xs.getStatistic(); }
   vec_->plus(*(xs.getVector()));
 }   
Beispiel #6
0
int main(int argc, char *argv[])
{

  // Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  // Create a communicator for Epetra objects
#ifdef HAVE_MPI
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  Teuchos::CommandLineProcessor clp( false );

  // Default run-time options that can be changed from the command line
  CouplingSolveMethod method          = MATRIX_FREE   ;
  bool                verbose         = true          ;
  int                 NumGlobalNodes  = 20            ;
  int                 probSizeRatio   = 1             ;
  bool                useMatlab       = false         ;
  bool                doOffBlocks     = false         ;
  std::string         solvType        = "seidel"      ;
  // Coupling parameters
  double              alpha           = 0.50          ;
  double              beta            = 0.40          ;
  // Physical parameters
  double              radiation       = 5.67          ;
  double              initVal         = 0.995         ;
  string              outputDir       = "."           ;
  string              goldDir         = "."           ;


  clp.setOption<CouplingSolveMethod>( "solvemethod", &method, 4, SolveMethodValues, SolveMethodNames, "Selects the coupling method to use");
  clp.setOption( "verbose", "no-verbose", &verbose, "Verbosity on or off." );
  clp.setOption( "n", &NumGlobalNodes, "Number of elements" );
  clp.setOption( "nratio", &probSizeRatio, "Ratio of size of problem 2 to problem 1" );
  clp.setOption( "offblocks", "no-offblocks", &doOffBlocks, "Include off-diagonal blocks in preconditioning matrix" );
  clp.setOption( "matlab", "no-matlab", &useMatlab, "Use Matlab debugging engine" );
  clp.setOption( "solvType", &solvType, "Solve Type.  Valid choices are: jacobi, seidel" );
  clp.setOption( "alpha", &alpha, "Interfacial coupling coefficient, alpha" );
  clp.setOption( "beta", &beta, "Interfacial coupling coefficient, beta" );
  clp.setOption( "radiation", &radiation, "Radiation source term coefficient, R" );
  clp.setOption( "initialval", &initVal, "Initial guess for solution values" );
  clp.setOption( "outputdir", &outputDir, "Directory to output mesh and results into. Default is \"./\"" );
  clp.setOption( "golddir", &goldDir, "Directory to read gold test from. Default is \"./\"" );

  Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);

  if( parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL ) 
    return parse_return;

  outputDir += "/";
  goldDir   += "/";

  // Create and reset the Timer
  Epetra_Time myTimer(Comm);
  double startWallTime = myTimer.WallTime();

  // Get the process ID and the total number of processors
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  NumGlobalNodes++; // convert #elements to #nodes

  // The number of unknowns must be at least equal to the number of processors.
  if (NumGlobalNodes < NumProc) 
  {
    cout << "numGlobalNodes = " << NumGlobalNodes 
	 << " cannot be < number of processors = " << NumProc << endl;
    exit(1);
  }

  // Begin Nonlinear Solver ************************************

  // NOTE: For now these parameters apply to all problems handled by
  // Problem_Manager.  Each problem could be made to have its own
  // parameter list as wwell as its own convergence test(s).

  // Create the top level parameter list
  Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr =
    Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::ParameterList& nlParams = *(nlParamsPtr.get());

  // Set the nonlinear solver method
  nlParams.set("Nonlinear Solver", "Line Search Based");

  // Set the printing parameters in the "Printing" sublist
  Teuchos::ParameterList& printParams = nlParams.sublist("Printing");
  printParams.set("MyPID", MyPID); 
  printParams.set("Output Precision", 3);
  printParams.set("Output Processor", 0);
  printParams.set("Output Information", 
			NOX::Utils::Warning                  +
			NOX::Utils::OuterIteration           + 
			NOX::Utils::InnerIteration           +
			NOX::Utils::Parameters               + 
			NOX::Utils::Details                  + 
			NOX::Utils::OuterIterationStatusTest + 
			NOX::Utils::LinearSolverDetails      + 
			NOX::Utils::TestDetails               );

  NOX::Utils outputUtils(printParams);

  // Sublist for line search 
  Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search");
  searchParams.set("Method", "Full Step");

  // Sublist for direction
  Teuchos::ParameterList& dirParams = nlParams.sublist("Direction");
  dirParams.set("Method", "Newton");
  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

  // Sublist for linear solver for the Newton method
  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
  lsParams.set("Aztec Solver", "GMRES");  
  lsParams.set("Max Iterations", 800);  
  lsParams.set("Tolerance", 1e-4);
  lsParams.set("Output Frequency", 50);    
  lsParams.set("Preconditioner", "AztecOO");   

  // Create the convergence tests
  // Note: as for the parameter list, both (all) problems use the same 
  // convergence test(s) for now, but each could have its own.
  Teuchos::RCP<NOX::StatusTest::NormF>          absresid  =
      Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8));
  Teuchos::RCP<NOX::StatusTest::NormUpdate>     update    = 
      Teuchos::rcp(new NOX::StatusTest::NormUpdate(1.0e-5));
  Teuchos::RCP<NOX::StatusTest::Combo>          converged = 
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
  converged->addStatusTest(absresid);
  //converged->addStatusTest(update);
  Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters = 
    Teuchos::rcp(new NOX::StatusTest::MaxIters(500));
  Teuchos::RCP<NOX::StatusTest::FiniteValue> finiteValue = 
    Teuchos::rcp(new NOX::StatusTest::FiniteValue);
  Teuchos::RCP<NOX::StatusTest::Combo> combo = 
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
  combo->addStatusTest(converged);
  combo->addStatusTest(maxiters);
  combo->addStatusTest(finiteValue);

  // Create the Problem Manager
  Problem_Manager problemManager(Comm, false, 0, useMatlab);

  // Note that each problem could contain its own nlParams list as well as
  // its own convergence test(s). 
  problemManager.registerParameters(nlParamsPtr);
  problemManager.registerStatusTest(combo);

  // Domain boundary temperaures
  double Tleft          = 0.98          ;
  double Tright         = 1.0           ;

  // Distinguish certain parameters needed for T1_analytic
  double peclet_1     	= 9.0           ;
  double peclet_2     	= 0.0           ;
  double kappa_1      	= 1.0           ;
  double kappa_2	= 0.1           ;

  double T1_analytic = ConvDiff_PDE::computeAnalyticInterfaceTemp( radiation, Tleft, Tright, kappa_2, peclet_1 );

  // Create Region 1 PDE
  string myName         = "Region_1"    ;
  double radiation_reg1 = 0.0           ;
  double xmin  		= 0.0           ;
  double xmax  		= 1.0           ;

  ConvDiff_PDE Reg1_PDE (
                  Comm, 
                  peclet_1,
                  radiation_reg1,
                  kappa_1,
                  alpha,
                  xmin,
                  xmax, 
                  Tleft,
                  T1_analytic,
                  NumGlobalNodes, 
                  myName  );

  // Override default initialization with values we want
  Reg1_PDE.initializeSolution(initVal);

  problemManager.addProblem(Reg1_PDE);


  // Create Region 2 PDE
  myName 		        = "Region_2"    ;
  xmin  		        = 1.0           ;
  xmax  		        = 2.0           ;

  ConvDiff_PDE Reg2_PDE (
                  Comm, 
                  peclet_2,
                  radiation,
                  kappa_2,
                  beta,
                  xmin,
                  xmax, 
                  T1_analytic,
                  Tright,
                  probSizeRatio*NumGlobalNodes, 
                  myName  );

  // For this problem involving interfacial coupling, the problems are given control
  // over whether or not and how to construct off-block contributions to the
  // Jacobian/Preconditioner matrix.  We explicitly told the problem manager to omit
  // off-blocks via the OffBlock_Manager class.  Here, we inform each problem.
  Reg1_PDE.setExpandJacobian( doOffBlocks );
  Reg2_PDE.setExpandJacobian( doOffBlocks );

  // Override default initialization with values we want
  Reg2_PDE.initializeSolution(initVal);

  problemManager.addProblem(Reg2_PDE);

  problemManager.createDependency(Reg1_PDE, Reg2_PDE);
  problemManager.createDependency(Reg2_PDE, Reg1_PDE);

  problemManager.registerComplete();

  // A consistencyy check associated with using BroydenOperator
  if( 0 )
  {
    Epetra_CrsGraph maskGraph(Copy, problemManager.getCompositeSoln()->Map(), 0);

    map<int, Teuchos::RCP<GenericEpetraProblem> >::iterator problemIter = problemManager.getProblems().begin();
    map<int, Teuchos::RCP<GenericEpetraProblem> >::iterator problemLast = problemManager.getProblems().end();

    // Loop over each problem being managed and ascertain its graph as well
    // as its graph from its dependencies
    for( ; problemIter != problemLast; ++problemIter ) 
    {
      GenericEpetraProblem & problem = *(*problemIter).second;
      int probId = problem.getId();

      // Get the indices map for copying data from this problem into 
      // the composite problem
      map<int, Teuchos::RCP<Epetra_IntVector> > & problemToCmpositeIndices = 
        problemManager.getProblemToCompositeIndices();
      Epetra_IntVector & problemIndices = *(problemToCmpositeIndices[probId]);

      // Get known dependencies on the other problem
      for( unsigned int k = 0; k < problem.getDependentProblems().size(); ++k) 
      {
        // Get the needed objects for the depend problem
        GenericEpetraProblem & dependProblem = *(problemManager.getProblems()[problem.getDependentProblems()[k]]);
        int dependId                         =  dependProblem.getId();
        Epetra_IntVector & dependIndices     = *(problemManager.getProblemToCompositeIndices()[dependId]);

        map<int, vector<int> > offBlockIndices;
        problem.getOffBlockIndices( offBlockIndices );

        map<int, vector<int> >::iterator indIter     = offBlockIndices.begin(),
                                         indIter_end = offBlockIndices.end()   ;

        for( ; indIter != indIter_end; ++indIter )
        {
          int compositeRow = problemIndices[(*indIter).first];
          vector<int> & colIndices = (*indIter).second;

          // Convert column indices to composite values
          for( unsigned int cols = 0; cols < colIndices.size(); ++cols )
            colIndices[cols] = dependIndices[ colIndices[cols] ];

          maskGraph.InsertGlobalIndices( compositeRow, colIndices.size(), &colIndices[0] );
        }
      }
    }
     maskGraph.FillComplete();

     cout << maskGraph << endl;

     NOX::Epetra::BroydenOperator * broydenOp = dynamic_cast<NOX::Epetra::BroydenOperator*>(
       problemManager.getJacobianOperator().get() );

    broydenOp->removeEntriesFromBroydenUpdate( maskGraph );
#ifdef HAVE_NOX_DEBUG
    broydenOp->outputActiveEntries();
#endif
  }

  problemManager.outputStatus(std::cout);

  cout << "\n\tAnalytic solution, T_1 = " << T1_analytic << "\n" << endl;

  // Print initial solution
  if( verbose )
    problemManager.outputSolutions( outputDir, 0 );

  // Identify the test problem
  if( outputUtils.isPrintType(NOX::Utils::TestDetails) )
    outputUtils.out() << "Starting epetra/MultiPhysics/example_yeckel.exe" << endl;

  // Identify processor information
#ifdef HAVE_MPI
  outputUtils.out() << "This test is broken in parallel." << endl;
  outputUtils.out() << "Test failed!" << endl;
  MPI_Finalize();
  return -1;
#else
  if (outputUtils.isPrintType(NOX::Utils::TestDetails))
    outputUtils.out() << "Serial Run" << endl;
#endif

  // Identify the test problem
  if( outputUtils.isPrintType(NOX::Utils::TestDetails) )
    outputUtils.out() << "Starting epetra/MultiPhysics/example_yeckel.exe" << endl;

  // Identify processor information
#ifdef HAVE_MPI
  outputUtils.out() << "This test is broken in parallel." << endl;
  outputUtils.out() << "Test failed!" << endl;
  MPI_Finalize();
  return -1;
#else
  if (outputUtils.isPrintType(NOX::Utils::TestDetails))
    outputUtils.out() << "Serial Run" << endl;
#endif

  // Solve the coupled problem
  switch( method ) 
  {
    case MATRIX_FREE :
      problemManager.solveMF(); // Need a status test check here ....
      break;

    case SCHUR_BASED :
      problemManager.solveSchurBased();
      break;

    case LOOSE_HARDCODED :
      problemManager.solve(); // Hard-coded loose coupling
      break;

    case LOOSE_LIBRARY :
    default            :
    {
      // Create the loose coupling solver manager
      Teuchos::RCP<vector<Teuchos::RCP<NOX::Solver::Generic> > > solversVec =
        Teuchos::rcp( new vector<Teuchos::RCP<NOX::Solver::Generic> > );

      map<int, Teuchos::RCP<NOX::Solver::Generic> >::iterator iter = problemManager.getSolvers().begin(),
                                                                  iter_end = problemManager.getSolvers().end()   ;
      for( ; iter_end != iter; ++iter )
      {
        cout << " ........  registered Solver::Manager # " << (*iter).first << endl;
        solversVec->push_back( (*iter).second );
      }

      // Package the Problem_Manager as the DataExchange::Intreface
      Teuchos::RCP<NOX::Multiphysics::DataExchange::Interface> dataExInterface =
        Teuchos::rcp( &problemManager, false );
      
      Teuchos::RCP<NOX::StatusTest::MaxIters> fixedPt_maxiters = 
        Teuchos::rcp(new NOX::StatusTest::MaxIters(20));

      if( "jacobi" == solvType )
        nlParamsPtr->sublist("Solver Options").set("Fixed Point Iteration Type", "Jacobi");

      NOX::Multiphysics::Solver::Manager cplSolv( solversVec, dataExInterface, fixedPt_maxiters, nlParamsPtr );

      cplSolv.solve();

      // Refresh all problems with solutions from solver
      problemManager.copyAllGroupXtoProblems();

      // Reset all solver groups to force recomputation of residuals
      problemManager.resetAllCurrentGroupX();
    }
  }
  
  // Output timing info
  if( 0 == MyPID )
    cout << "\nTimings :\n\tWallTime --> " << myTimer.WallTime() - startWallTime << " sec."
         << "\n\tElapsedTime --> " << myTimer.ElapsedTime() << " sec." << endl << endl;

  if( verbose )
    problemManager.outputSolutions( outputDir, 1 );

  // Create a TestCompare class
  int status = 0;
  NOX::TestCompare tester( outputUtils.out(), outputUtils );
  double abstol = 1.e-4;
  double reltol = 1.e-4 ;

  map<int, Teuchos::RCP<GenericEpetraProblem> >::iterator iter = problemManager.getProblems().begin(),
                                                              iter_end = problemManager.getProblems().end()   ;
  for( ; iter_end != iter; ++iter )
  {
    ConvDiff_PDE & problem = dynamic_cast<ConvDiff_PDE &>( *(*iter).second );
    string msg = "Numerical-to-Exact Solution comparison for problem \"" + problem.getName() + "\"";

    // Need NOX::Epetra::Vectors for tests
    NOX::Epetra::Vector numerical ( problem.getSolution()     , NOX::Epetra::Vector::CreateView );
    NOX::Epetra::Vector analytic  ( problem.getExactSolution(), NOX::Epetra::Vector::CreateView );

    status += tester.testVector( numerical, analytic, reltol, abstol, msg );
  }

  // Summarize test results  
  if( status == 0 )
    outputUtils.out() << "Test passed!" << endl;
  else 
    outputUtils.out() << "Test failed!" << endl;

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

  return 0 ;
}
Beispiel #7
0
 Teuchos::RCP<Vector<Real> > clone() const {
   Real stat = 0.0;
   Teuchos::RCP<Vector<Real> > vec = Teuchos::rcp_dynamic_cast<Vector<Real> >(
     Teuchos::rcp_const_cast<Vector<Real> >(vec_->clone()));
   return Teuchos::rcp( new RiskVector( vec, augmented_, stat ) );  
 }
int main(int argc, char **argv)
{
  try {

    // Basis of dimension 3, order 5
    const int d = 3;
    const int p = 5;
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(d); 
    for (int i=0; i<d; i++) {
      bases[i] = Teuchos::rcp(new Stokhos::PecosOneDOrthogPolyBasis<int,double>(Teuchos::rcp(new Pecos::HermiteOrthogPolynomial), "Hermite", p));
    }
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));

    // Quadrature method
    Teuchos::RCP<const Stokhos::Quadrature<int,double> > quad = 
        Teuchos::rcp(new Stokhos::TensorProductQuadrature<int,double>(basis));

    // Triple product tensor
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk =
      basis->computeTripleProductTensor(basis->size());

    // Expansion method
    Stokhos::QuadOrthogPolyExpansion<int,double> expn(basis, Cijk, quad);

    // Polynomial expansions
    Stokhos::OrthogPolyApprox<int,double> u(basis), v(basis), w(basis);
    u.term(0,0) = 1.0;
    for (int i=0; i<d; i++) {
      u.term(i,1) = 0.4 / d;
      u.term(i,2) = 0.06 / d;
      u.term(i,3) = 0.002 / d;
    }

    // Compute expansion
    expn.log(v,u);
    expn.times(w,v,v);
    expn.plusEqual(w,1.0);
    expn.divide(v,1.0,w);
    //expn.times(v,u,u);

    // Print u and v
    std::cout << "v = 1.0 / (log(u)^2 + 1):" << std::endl;
    std::cout << "\tu = ";
    u.print(std::cout);
    std::cout << "\tv = ";
    v.print(std::cout);

    // Compute moments
    double mean = v.mean();
    double std_dev = v.standard_deviation();

    // Evaluate PCE and function at a point = 0.25 in each dimension
    Teuchos::Array<double> pt(d); 
    for (int i=0; i<d; i++) 
      pt[i] = 0.25;
    double up = u.evaluate(pt);
    double vp = 1.0/(std::log(up)*std::log(up)+1.0);
    double vp2 = v.evaluate(pt);
    
    // Print results
    std::cout << "\tv mean         = " << mean << std::endl;
    std::cout << "\tv std. dev.    = " << std_dev << std::endl;
    std::cout << "\tv(0.25) (true) = " << vp << std::endl;
    std::cout << "\tv(0.25) (pce)  = " << vp2 << std::endl;
    
    // Check the answer
    if (std::abs(vp - vp2) < 1e-2)
      std::cout << "\nExample Passed!" << std::endl;
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
}
Beispiel #9
0
void CEigenLSS::solve()
{
#ifdef CF3_HAVE_TRILINOS
  Timer timer;
  const Uint nb_rows = size();
  cf3_assert(nb_rows == m_system_matrix.outerSize());

  Epetra_SerialComm comm;
  Epetra_Map map(nb_rows, 0, comm);

  Epetra_Vector ep_rhs(View, map, m_rhs.data());
  Epetra_Vector ep_sol(View, map, m_solution.data());

  // Count non-zeros
  std::vector<int> nnz(nb_rows, 0);
  for(int row=0; row < nb_rows; ++row)
  {
    for(MatrixT::InnerIterator it(m_system_matrix, row); it; ++it)
    {
      ++nnz[row];
    }
    cf3_assert(nnz[row]);
  }

  Epetra_CrsMatrix ep_A(Copy, map, &nnz[0]);
  time_matrix_construction = timer.elapsed(); timer.restart();

  // Fill the matrix
  for(int row=0; row < nb_rows; ++row)
  {
    std::vector<int> indices; indices.reserve(nnz[row]);
    std::vector<Real> values; values.reserve(nnz[row]);
    for(MatrixT::InnerIterator it(m_system_matrix, row); it; ++it)
    {
      indices.push_back(it.col());
      values.push_back(it.value());
    }
    ep_A.InsertGlobalValues(row, nnz[row], &values[0], &indices[0]);
  }

  ep_A.FillComplete();

  time_matrix_fill = timer.elapsed(); timer.restart();

///////////////////////////////////////////////////////////////////////////////////////////////
//BEGIN////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

  Teuchos::RCP<Epetra_CrsMatrix> epetra_A=Teuchos::rcpFromRef(ep_A);
  Teuchos::RCP<Epetra_Vector>    epetra_x=Teuchos::rcpFromRef(ep_sol);
  Teuchos::RCP<Epetra_Vector>    epetra_b=Teuchos::rcpFromRef(ep_rhs);

  const URI config_uri = options().option("config_file").value<URI>();
  const std::string config_path = config_uri.path();

  Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder(config_path); // the most important in general setup

  Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream(); // TODO: decouple from fancyostream to ostream or to C stdout when possible
  typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
  Teuchos::CommandLineProcessor  clp(false); // false: don't throw exceptions

  Teuchos::RCP<const Thyra::LinearOpBase<double> > A = Thyra::epetraLinearOp( epetra_A );
  Teuchos::RCP<Thyra::VectorBase<double> >         x = Thyra::create_Vector( epetra_x, A->domain() );
  Teuchos::RCP<const Thyra::VectorBase<double> >   b = Thyra::create_Vector( epetra_b, A->range() );

  // r = b - A*x, initial L2 norm
  double nrm_r=0.;
  Real systemResidual=-1.;
  {
    Epetra_Vector epetra_r(*epetra_b);
    Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap());
    epetra_A->Apply(*epetra_x,epetra_A_x);
    epetra_r.Update(-1.0,epetra_A_x,1.0);
    epetra_r.Norm2(&nrm_r);
  }

  // Reading in the solver parameters from the parameters file and/or from
  // the command line.  This was setup by the command-line options
  // set by the setupCLP(...) function above.
  linearSolverBuilder.readParameters(0); // out.get() if want confirmation about the xml file within trilinos
  Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = linearSolverBuilder.createLinearSolveStrategy(""); // create linear solver strategy
  lowsFactory->setVerbLevel(Teuchos::VERB_NONE); // set verbosity

//  // print back default and current settings
//  if (opts->trilinos.dumpDefault!=0) {
//    fflush(stdout); cout << flush;
//    _MMESSAGE_(0,1,"Dumping Trilinos/Stratimikos solver defaults to files: 'trilinos_default.txt' and 'trilinos_default.xml'...\n");
//    fflush(stdout); cout << flush;
//    std::ofstream ofs("./trilinos_default.txt");
//    linearSolverBuilder.getValidParameters()->print(ofs,PLPrintOptions().indent(2).showTypes(true).showDoc(true)); // the last true-false is the deciding about whether printing documentation to option or not
//    ofs.flush();ofs.close();
//    ofs.open("./trilinos_default.xml");
//    Teuchos::writeParameterListToXmlOStream(*linearSolverBuilder.getValidParameters(),ofs);
//    ofs.flush();ofs.close();
//  }
//  if (opts->trilinos.dumpCurrXML!=0) {
//    fflush(stdout); cout << flush;
//    _MMESSAGE_(0,1,"Dumping Trilinos/Stratimikos current settings to file: 'trilinos_current.xml'...\n");
//    fflush(stdout); cout << flush;
//    linearSolverBuilder.writeParamsFile(*lowsFactory,"./trilinos_current.xml");
//  }

  time_solver_setup = timer.elapsed(); timer.restart();

  // solve the matrix
  Teuchos::RCP<Thyra::LinearOpWithSolveBase<double> > lows = Thyra::linearOpWithSolve(*lowsFactory, A); // create solver
  lows->solve(Thyra::NOTRANS, *b, x.ptr()); // solve

  time_solve = timer.elapsed(); timer.restart();

  // r = b - A*x, final L2 norm
  {
    Epetra_Vector epetra_r(*epetra_b);
    Epetra_Vector epetra_A_x(epetra_A->OperatorRangeMap());
    epetra_A->Apply(*epetra_x,epetra_A_x);
    epetra_r.Update(-1.0,epetra_A_x,1.0);
    systemResidual=1./nrm_r;
    nrm_r=0.;
    epetra_r.Norm2(&nrm_r);
    systemResidual*=nrm_r;
  }

  time_residual = timer.elapsed();

///////////////////////////////////////////////////////////////////////////////////////////////
//END//////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

#else // no trilinos

#ifdef CF3_HAVE_SUPERLU
  Eigen::SparseMatrix<Real> A(m_system_matrix);
  Eigen::SparseLU<Eigen::SparseMatrix<Real>,Eigen::SuperLU> lu_of_A(A);
  if(!lu_of_A.solve(rhs(), &m_solution))
    throw common::FailedToConverge(FromHere(), "Solution failed.");
#else // no trilinos and no superlu
  RealMatrix A(m_system_matrix);
  Eigen::FullPivLU<RealMatrix> lu_of_A(A);
  m_solution = lu_of_A.solve(m_rhs);
#endif // end ifdef superlu

#endif // end ifdef trilinos

}
Teuchos::RCP<ROL::Vector<Real> > clone() const {
  return Teuchos::rcp( new ConDualStdVector( Teuchos::rcp(new std::vector<Element>(std_vec_->size())) ) );
}
int dimension() const {return static_cast<int>(std_vec_->size());}
void scale( const Real alpha ) {
  uint dimension = std_vec_->size();
  for (uint i=0; i<dimension; i++) {
    (*std_vec_)[i] *= alpha;
  }
}
Teuchos::RCP<ROL::Vector<Real> > clone() const {
  using Teuchos::rcp;
  return rcp( new OptStdVector( rcp( new vector(std_vec_->size()) ) ) );
}
TEUCHOS_UNIT_TEST(tTpetra_GlbEvalData, basic)
{
  using Teuchos::RCP;
  using Teuchos::rcp;

  typedef Thyra::VectorBase<double> Thyra_Vector;
  typedef Thyra::SpmdVectorBase<double> Thyra_SpmdVec;

  typedef Tpetra::Vector<double,int,panzer::Ordinal64> Tpetra_Vector;
  typedef Tpetra::Map<int,panzer::Ordinal64> Tpetra_Map;
  typedef Tpetra::Import<int,panzer::Ordinal64> Tpetra_Import;


  Teuchos::RCP<Teuchos::MpiComm<int> > comm = Teuchos::rcp(new Teuchos::MpiComm<int>(MPI_COMM_WORLD));

  // This is required
  TEST_ASSERT(comm->getSize()==2);

  std::vector<panzer::Ordinal64> ghosted(5);
  std::vector<panzer::Ordinal64> owned(3);

  if(comm->getRank()==0) {
    owned[0] = 0;
    owned[1] = 1;
    owned[2] = 2;

    ghosted[0] = 0;
    ghosted[1] = 1;
    ghosted[2] = 2;
    ghosted[3] = 3;
    ghosted[4] = 4;
  }
  else {
    owned[0] = 3;
    owned[1] = 4;
    owned[2] = 5;

    ghosted[0] = 1;
    ghosted[1] = 2;
    ghosted[2] = 3;
    ghosted[3] = 4;
    ghosted[4] = 5;
  }

  RCP<const Tpetra_Map> ownedMap = rcp(new Tpetra_Map(-1,owned,0,comm));
  RCP<const Tpetra_Map> ghostedMap = rcp(new Tpetra_Map(-1,ghosted,0,comm));
  RCP<const Tpetra_Import> importer = rcp(new Tpetra_Import(ownedMap,ghostedMap));

  TpetraVector_ReadOnly_GlobalEvaluationData<double,int,panzer::Ordinal64> ged;
 
  TEST_ASSERT(!ged.isInitialized());

  ged.initialize(importer,ghostedMap,ownedMap);

  TEST_ASSERT(ged.isInitialized());

  // test the ghosted vector sizing (we don't care what the entries are!)
  { 
    RCP<Tpetra_Vector> ghostedVecTp = ged.getGhostedVector_Tpetra();
    RCP<Thyra_Vector>  ghostedVecT = ged.getGhostedVector();

    TEST_ASSERT(ghostedVecTp!=Teuchos::null); 
    TEST_ASSERT(ghostedVecT!=Teuchos::null); 

    RCP<const Thyra::SpmdVectorSpaceBase<double> > ghostedSpace 
        = rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<double> >(ghostedVecT->space());
    
    TEST_EQUALITY(ghostedMap->getNodeNumElements(),ghostedVecTp->getLocalLength());
    TEST_EQUALITY(ghostedMap->getGlobalNumElements(),ghostedVecTp->getGlobalLength());

    TEST_EQUALITY(ghostedSpace->isLocallyReplicated(),false);
    TEST_EQUALITY(Teuchos::as<size_t>(ghostedSpace->localSubDim()),ghostedVecTp->getLocalLength());
  }

  // test setting an owned vector
  {
    RCP<Tpetra_Vector> ownedVec_tp = rcp(new Tpetra_Vector(ownedMap));
    auto uv_2d = ownedVec_tp->getLocalView<Kokkos::HostSpace> ();
    auto ownedVec = Kokkos::subview (uv_2d, Kokkos::ALL (), 0);

    if(comm->getRank()==0) {
      ownedVec(0) = 3.14;
      ownedVec(1) = 1.82;
      ownedVec(2) = -.91;
    }
    else {
      ownedVec(0) = 2.72;
      ownedVec(1) = 6.23;
      ownedVec(2) = -.17;
    }

    // set the owned vector, assure that const can be used
    ged.setOwnedVector_Tpetra(ownedVec_tp.getConst());
  }

  // test the owned vector sizing and thyra entries
  { 
    const Tpetra_Vector & ownedVecTp = *ged.getOwnedVector_Tpetra();
    auto uv_2d = ownedVecTp.getLocalView<Kokkos::HostSpace> ();
    auto ownedVecTpKv = Kokkos::subview (uv_2d, Kokkos::ALL (), 0);

    RCP<const Thyra_Vector>  ownedVecT = ged.getOwnedVector();

    TEST_ASSERT(ownedVecT!=Teuchos::null); 

    RCP<const Thyra::SpmdVectorSpaceBase<double> > ownedSpace 
        = rcp_dynamic_cast<const Thyra::SpmdVectorSpaceBase<double> >(ownedVecT->space());
    
    TEST_EQUALITY(ownedMap->getNodeNumElements(),ownedVecTp.getLocalLength());
    TEST_EQUALITY(ownedMap->getGlobalNumElements(),ownedVecTp.getGlobalLength());

    TEST_EQUALITY(ownedSpace->isLocallyReplicated(),false);
    TEST_EQUALITY(Teuchos::as<size_t>(ownedSpace->localSubDim()),ownedVecTp.getLocalLength());

    RCP<const Thyra_SpmdVec> spmdVec = rcp_dynamic_cast<const Thyra_SpmdVec>(ownedVecT);

    Teuchos::ArrayRCP<const double> thyraVec;
    spmdVec->getLocalData(Teuchos::ptrFromRef(thyraVec));

    TEST_EQUALITY(Teuchos::as<size_t>(thyraVec.size()),ownedVecTp.getLocalLength());

    if(comm->getRank()==0) {
      TEST_EQUALITY(ownedVecTpKv(0),3.14);
      TEST_EQUALITY(ownedVecTpKv(1),1.82);
      TEST_EQUALITY(ownedVecTpKv(2),-.91);
    }
    else {
      TEST_EQUALITY(ownedVecTpKv(0),2.72);
      TEST_EQUALITY(ownedVecTpKv(1),6.23);
      TEST_EQUALITY(ownedVecTpKv(2),-.17);
    }

    TEST_EQUALITY(ownedVecTpKv(0),thyraVec[0]);
    TEST_EQUALITY(ownedVecTpKv(1),thyraVec[1]);
    TEST_EQUALITY(ownedVecTpKv(2),thyraVec[2]);
  }

  // actually do something...
  ged.initializeData();
  ged.globalToGhost(0);

  {
    const Tpetra_Vector & ghostedVecTp = *ged.getGhostedVector_Tpetra();
    auto uv_2d = ghostedVecTp.getLocalView<Kokkos::HostSpace> ();
    auto ghostedVecKv = Kokkos::subview (uv_2d, Kokkos::ALL (), 0);

    RCP<Thyra_Vector>  ghostedVecT = ged.getGhostedVector();
    RCP<const Thyra_SpmdVec> spmdVec = rcp_dynamic_cast<const Thyra_SpmdVec>(ghostedVecT);

    Teuchos::ArrayRCP<const double> thyraVec;
    spmdVec->getLocalData(Teuchos::ptrFromRef(thyraVec));

    TEST_EQUALITY(Teuchos::as<size_t>(thyraVec.size()),ghostedVecTp.getLocalLength());

    if(comm->getRank()==0) {
      TEST_EQUALITY(ghostedVecKv(0),3.14);
      TEST_EQUALITY(ghostedVecKv(1),1.82);
      TEST_EQUALITY(ghostedVecKv(2),-.91);
      TEST_EQUALITY(ghostedVecKv(3),2.72);
      TEST_EQUALITY(ghostedVecKv(4),6.23);
    }
    else {
      TEST_EQUALITY(ghostedVecKv(0),1.82);
      TEST_EQUALITY(ghostedVecKv(1),-.91);
      TEST_EQUALITY(ghostedVecKv(2),2.72);
      TEST_EQUALITY(ghostedVecKv(3),6.23);
      TEST_EQUALITY(ghostedVecKv(4),-.17);
    }

    TEST_EQUALITY(ghostedVecKv(0),thyraVec[0]);
    TEST_EQUALITY(ghostedVecKv(1),thyraVec[1]);
    TEST_EQUALITY(ghostedVecKv(2),thyraVec[2]);
    TEST_EQUALITY(ghostedVecKv(3),thyraVec[3]);
    TEST_EQUALITY(ghostedVecKv(4),thyraVec[4]);
  }
}
Beispiel #15
0
int main(int argc, char *argv[]) {

  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
  Teuchos::RCP<const Teuchos::Comm<int> > comm
    = Teuchos::DefaultComm<int>::getComm();

  // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
  int iprint = argc - 1;
  bool print = (iprint>0);
  Teuchos::RCP<std::ostream> outStream;
  Teuchos::oblackholestream bhs; // outputs nothing
  if (print)
    outStream = Teuchos::rcp(&std::cout, false);
  else
    outStream = Teuchos::rcp(&bhs, false);
    
  bool print0 = print && !comm->getRank();
  Teuchos::RCP<std::ostream> outStream0;
  if (print0)
    outStream0 = Teuchos::rcp(&std::cout, false); 
  else
    outStream0 = Teuchos::rcp(&bhs, false);

  int errorFlag  = 0;

  // *** Example body.

  try {
    /*************************************************************************/
    /************* INITIALIZE BURGERS FEM CLASS ******************************/
    /*************************************************************************/
    int nx      = 256;   // Set spatial discretization.
    RealT alpha = 1.e-3; // Set penalty parameter.
    RealT nl    = 1.0;   // Nonlinearity parameter (1 = Burgers, 0 = linear).
    RealT cH1   = 1.0;   // Scale for derivative term in H1 norm.
    RealT cL2   = 0.0;   // Scale for mass term in H1 norm.
    Teuchos::RCP<BurgersFEM<RealT> > fem
      = Teuchos::rcp(new BurgersFEM<RealT>(nx,nl,cH1,cL2));
    fem->test_inverse_mass(*outStream0);
    fem->test_inverse_H1(*outStream0);
    /*************************************************************************/
    /************* INITIALIZE SIMOPT OBJECTIVE FUNCTION **********************/
    /*************************************************************************/
    Teuchos::RCP<std::vector<RealT> > ud_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx, 1.0) );
    Teuchos::RCP<ROL::Vector<RealT> > ud
      = Teuchos::rcp(new L2VectorPrimal<RealT>(ud_rcp,fem));
    Teuchos::RCP<ROL::Objective_SimOpt<RealT> > pobj
      = Teuchos::rcp(new Objective_BurgersControl<RealT>(fem,ud,alpha));
    /*************************************************************************/
    /************* INITIALIZE SIMOPT EQUALITY CONSTRAINT *********************/
    /*************************************************************************/
    bool hess = true;
    Teuchos::RCP<ROL::EqualityConstraint_SimOpt<RealT> > pcon
      = Teuchos::rcp(new EqualityConstraint_BurgersControl<RealT>(fem,hess));
    /*************************************************************************/
    /************* INITIALIZE VECTOR STORAGE *********************************/
    /*************************************************************************/
    // INITIALIZE CONTROL VECTORS
    Teuchos::RCP<std::vector<RealT> > z_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx+2, 1.0) );
    Teuchos::RCP<std::vector<RealT> > gz_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx+2, 1.0) );
    Teuchos::RCP<std::vector<RealT> > yz_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx+2, 1.0) );
    for (int i=0; i<nx+2; i++) {
      (*yz_rcp)[i] = 2.0*random<RealT>(comm)-1.0;
    }
    Teuchos::RCP<ROL::Vector<RealT> > zp
      = Teuchos::rcp(new PrimalControlVector(z_rcp,fem));
    Teuchos::RCP<ROL::Vector<RealT> > gzp
      = Teuchos::rcp(new DualControlVector(gz_rcp,fem));
    Teuchos::RCP<ROL::Vector<RealT> > yzp
      = Teuchos::rcp(new PrimalControlVector(yz_rcp,fem));
    std::vector<RealT> zvar(1,0.0*random<RealT>(comm));
    std::vector<RealT> gvar(1,random<RealT>(comm));
    std::vector<RealT> yvar(1,random<RealT>(comm));
    ROL::RiskVector<RealT> z(zp,zvar,true), g(gzp,gvar,true), y(yzp,yvar,true);
    // INITIALIZE STATE VECTORS
    Teuchos::RCP<std::vector<RealT> > u_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx, 1.0) );
    Teuchos::RCP<std::vector<RealT> > gu_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx, 1.0) );
    Teuchos::RCP<ROL::Vector<RealT> > up
      = Teuchos::rcp(new PrimalStateVector(u_rcp,fem));
    Teuchos::RCP<ROL::Vector<RealT> > gup
      = Teuchos::rcp(new DualStateVector(gu_rcp,fem));
    // INITIALIZE CONSTRAINT VECTORS
    Teuchos::RCP<std::vector<RealT> > c_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx, 1.0) );
    Teuchos::RCP<std::vector<RealT> > l_rcp
      = Teuchos::rcp( new std::vector<RealT> (nx, 1.0) );
    for (int i=0; i<nx; i++) {
      (*l_rcp)[i] = random<RealT>(comm);
    }
    Teuchos::RCP<ROL::Vector<RealT> > cp
      = Teuchos::rcp(new PrimalConstraintVector(c_rcp,fem));
    Teuchos::RCP<ROL::Vector<RealT> > lp
      = Teuchos::rcp(new DualConstraintVector(l_rcp,fem));
    /*************************************************************************/
    /************* INITIALIZE SAMPLE GENERATOR *******************************/
    /*************************************************************************/
    int dim = 4, nSamp = 1000;
    std::vector<RealT> tmp(2,0.0); tmp[0] = -1.0; tmp[1] = 1.0;
    std::vector<std::vector<RealT> > bounds(dim,tmp);
    Teuchos::RCP<ROL::BatchManager<RealT> > bman
      = Teuchos::rcp(new L2VectorBatchManager<RealT,int>(comm));
    Teuchos::RCP<ROL::SampleGenerator<RealT> > sampler
      = Teuchos::rcp(new ROL::MonteCarloGenerator<RealT>(
          nSamp,bounds,bman,false,false,100));
    /*************************************************************************/
    /************* INITIALIZE RISK-AVERSE OBJECTIVE FUNCTION *****************/
    /*************************************************************************/
    bool storage = true, fdhess = false;
    Teuchos::RCP<ROL::Objective<RealT> > robj
      = Teuchos::rcp(new ROL::Reduced_Objective_SimOpt<RealT>(
          pobj,pcon,up,zp,lp,gup,gzp,cp,storage,fdhess));
    RealT order = 2.0, prob = 0.95;
    Teuchos::RCP<ROL::Objective<RealT> > obj
      = Teuchos::rcp(new ROL::HMCRObjective<RealT>(
          robj,order,prob,sampler,storage));
    /*************************************************************************/
    /************* CHECK DERIVATIVES AND CONSISTENCY *************************/
    /*************************************************************************/
    // CHECK OBJECTIVE DERIVATIVES
    bool derivcheck = false;
    if (derivcheck) {
      int nranks = sampler->numBatches();
      for (int pid = 0; pid < nranks; pid++) {
        if ( pid == sampler->batchID() ) {
          for (int i = sampler->start(); i < sampler->numMySamples(); i++) {
            *outStream << "Sample " << i << "  Rank " << sampler->batchID() << "\n";
            *outStream << "(" << sampler->getMyPoint(i)[0] << ", "
                              << sampler->getMyPoint(i)[1] << ", "
                              << sampler->getMyPoint(i)[2] << ", "
                              << sampler->getMyPoint(i)[3] << ")\n";
            pcon->setParameter(sampler->getMyPoint(i));
            pcon->checkSolve(*up,*zp,*cp,print,*outStream);
            robj->setParameter(sampler->getMyPoint(i));
            *outStream << "\n";
            robj->checkGradient(*zp,*gzp,*yzp,print,*outStream);
            robj->checkHessVec(*zp,*gzp,*yzp,print,*outStream);
            *outStream << "\n\n";
          }
        }
        comm->barrier();
      }
    }
    obj->checkGradient(z,g,y,print0,*outStream0);
    obj->checkHessVec(z,g,y,print0,*outStream0);
    /*************************************************************************/
    /************* RUN OPTIMIZATION ******************************************/
    /*************************************************************************/
    // READ IN XML INPUT
    std::string filename = "input.xml";
    Teuchos::RCP<Teuchos::ParameterList> parlist
      = Teuchos::rcp( new Teuchos::ParameterList() );
    Teuchos::updateParametersFromXmlFile( filename, parlist.ptr() );
    // DEFINE ALGORITHM
    ROL::Algorithm<RealT> algo("Trust Region",*parlist,false);
    // RUN OPTIMIZATION
    z.zero();
    algo.run(z, g, *obj, print0, *outStream0);
    /*************************************************************************/
    /************* PRINT CONTROL AND STATE TO SCREEN *************************/
    /*************************************************************************/
    *outStream0 << "\n";
    for ( int i = 0; i < nx+2; i++ ) {
      *outStream0 << std::scientific << std::setprecision(10);
      *outStream0 << std::setw(20) << std::left << (RealT)i/((RealT)nx+1.0);
      *outStream0 << std::setw(20) << std::left << (*z_rcp)[i];
      *outStream0 << "\n";
    }
    *outStream0 << "\n";
    *outStream0 << "Scalar Parameter: " << z.getStatistic(0) << "\n";
  }
  catch (std::logic_error err) {
    *outStream << err.what() << "\n";
    errorFlag = -1000;
  }; // end try

  comm->barrier();
  if (errorFlag != 0)
    std::cout << "End Result: TEST FAILED\n";
  else
    std::cout << "End Result: TEST PASSED\n";

  return 0;
}
int main(int argc, char *argv[]) {

#ifdef HAVE_MPI
  // Initialize MPI
  //
  MPI_Init(&argc,&argv);
#endif

  bool success = false;
  try {
    // Create an Epetra communicator
    //
#ifdef HAVE_MPI
    Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
    Epetra_SerialComm Comm;
#endif

    // Create an Anasazi output manager
    //
    BasicOutputManager<double> printer;
    printer.stream(Errors) << Anasazi_Version() << std::endl << std::endl;

    // Get the sorting std::string from the command line
    //
    std::string which("LM");
    Teuchos::CommandLineProcessor cmdp(false,true);
    cmdp.setOption("sort",&which,"Targetted eigenvalues (SM or LM).");
    if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
      throw -1;
    }


    typedef Epetra_MultiVector MV;
    typedef Epetra_Operator OP;
    typedef MultiVecTraits<double, Epetra_MultiVector> MVT;

    // Number of dimension of the domain
    const int space_dim = 2;

    // Size of each of the dimensions of the domain
    std::vector<double> brick_dim( space_dim );
    brick_dim[0] = 1.0;
    brick_dim[1] = 1.0;

    // Number of elements in each of the dimensions of the domain
    std::vector<int> elements( space_dim );
    elements[0] = 10;
    elements[1] = 10;

    // Create problem
    Teuchos::RCP<ModalProblem> testCase =
      Teuchos::rcp( new ModeLaplace2DQ2(Comm, brick_dim[0], elements[0], brick_dim[1], elements[1]) );

    // Get the stiffness and mass matrices
    Teuchos::RCP<Epetra_CrsMatrix> K = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getStiffness()), false );
    Teuchos::RCP<Epetra_CrsMatrix> M = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getMass()), false );

    // Eigensolver parameters
    int nev = 10;
    int blockSize = 5;
    int maxIters = 500;
    double tol = 1.0e-8;

    Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(K->OperatorDomainMap(), blockSize) );
    ivec->Random();

    // Create the eigenproblem.
    Teuchos::RCP<BasicEigenproblem<double, MV, OP> > MyProblem =
      Teuchos::rcp( new BasicEigenproblem<double, MV, OP>(K, M, ivec) );

    // Inform the eigenproblem that the operator A is symmetric
    MyProblem->setHermitian(true);

    // Set the number of eigenvalues requested
    MyProblem->setNEV( nev );

    // Inform the eigenproblem that you are finishing passing it information
    bool boolret = MyProblem->setProblem();
    if (boolret != true) {
      printer.print(Errors,"Anasazi::BasicEigenproblem::setProblem() returned an error.\n");
      throw -1;
    }

    // Create parameter list to pass into the solver manager
    //
    Teuchos::ParameterList MyPL;
    MyPL.set( "Which", which );
    MyPL.set( "Block Size", blockSize );
    MyPL.set( "Maximum Iterations", maxIters );
    MyPL.set( "Convergence Tolerance", tol );
    MyPL.set( "Full Ortho", true );
    MyPL.set( "Use Locking", true );
    //
    // Create the solver manager
    LOBPCGSolMgr<double, MV, OP> MySolverMan(MyProblem, MyPL);

    // Solve the problem
    //
    ReturnType returnCode = MySolverMan.solve();

    // Get the eigenvalues and eigenvectors from the eigenproblem
    //
    Eigensolution<double,MV> sol = MyProblem->getSolution();
    std::vector<Value<double> > evals = sol.Evals;
    Teuchos::RCP<MV> evecs = sol.Evecs;

    // Compute residuals.
    //
    std::vector<double> normR(sol.numVecs);
    if (sol.numVecs > 0) {
      Teuchos::SerialDenseMatrix<int,double> T(sol.numVecs, sol.numVecs);
      Epetra_MultiVector Kvec( K->OperatorDomainMap(), evecs->NumVectors() );
      Epetra_MultiVector Mvec( M->OperatorDomainMap(), evecs->NumVectors() );
      T.putScalar(0.0);
      for (int i=0; i<sol.numVecs; i++) {
        T(i,i) = evals[i].realpart;
      }
      K->Apply( *evecs, Kvec );
      M->Apply( *evecs, Mvec );
      MVT::MvTimesMatAddMv( -1.0, Mvec, T, 1.0, Kvec );
      MVT::MvNorm( Kvec, normR );
    }

    // Print the results
    //
    std::ostringstream os;
    os.setf(std::ios_base::right, std::ios_base::adjustfield);
    os<<"Solver manager returned " << (returnCode == Converged ? "converged." : "unconverged.") << std::endl;
    os<<std::endl;
    os<<"------------------------------------------------------"<<std::endl;
    os<<std::setw(16)<<"Eigenvalue"
      <<std::setw(18)<<"Direct Residual"
      <<std::endl;
    os<<"------------------------------------------------------"<<std::endl;
    for (int i=0; i<sol.numVecs; i++) {
      os<<std::setw(16)<<evals[i].realpart
        <<std::setw(18)<<normR[i]/evals[i].realpart
        <<std::endl;
    }
    os<<"------------------------------------------------------"<<std::endl;
    printer.print(Errors,os.str());

    success = true;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Beispiel #17
0
//! Main subroutine of Rosenbrock.C
int main()
{
  // Print out the NOX code version number
  cout << "\n" << NOX::version() << endl;

  // Set up the problem interface
  Rosenbrock rosenbrock;
  
  // Create a group which uses that problem interface. The group will
  // be initialized to contain the default initial guess for the
  // specified problem.
  Teuchos::RCP<NOX::LAPACK::Group> grp = 
    Teuchos::rcp(new NOX::LAPACK::Group(rosenbrock));

  // Set up the status tests
  Teuchos::RCP<NOX::StatusTest::NormF> statusTestA = 
    Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-4));
  Teuchos::RCP<NOX::StatusTest::MaxIters> statusTestB = 
    Teuchos::rcp(new NOX::StatusTest::MaxIters(20));
  Teuchos::RCP<NOX::StatusTest::Combo> statusTestsCombo = 
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR,
					    statusTestA, statusTestB));

  // Create the list of solver parameters
  Teuchos::RCP<Teuchos::ParameterList> solverParametersPtr =
    Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::ParameterList& solverParameters = *solverParametersPtr;

  // Set the level of output (this is the default)
  solverParameters.sublist("Printing").set("Output Information", 
						    NOX::Utils::Warning + 
						    NOX::Utils::OuterIteration + 
						    NOX::Utils::InnerIteration + 
						    NOX::Utils::Parameters);

  // Set the solver (this is the default)
  solverParameters.set("Nonlinear Solver", "Line Search Based");

  // Create the line search parameters sublist
  Teuchos::ParameterList& lineSearchParameters = solverParameters.sublist("Line Search");

  // Set the line search method
  lineSearchParameters.set("Method","More'-Thuente");

  // Create the solver
  Teuchos::RCP<NOX::Solver::Generic> solver = 
    NOX::Solver::buildSolver(grp, statusTestsCombo, solverParametersPtr);

  // Solve the nonlinesar system
  NOX::StatusTest::StatusType status = solver->solve();

  // Warn user if solve failed
  if (status == NOX::StatusTest::Converged)
    cout << "Example Passed!" << endl;
  else
    cout << "Error: Solve failed to converge!" << endl;

  // Print the parameter list
  cout << "\n" << "-- Parameter List From Solver --" << "\n";
  solver->getList().print(cout);

  // Get the answer
  NOX::LAPACK::Group solnGrp = 
    dynamic_cast<const NOX::LAPACK::Group&>(solver->getSolutionGroup());
  
  // Print the answer
  cout << "\n" << "-- Final Solution From Solver --" << "\n";
  solnGrp.print();

  // Print the expected answer
  solnGrp.setX(rosenbrock.getSolution());
  solnGrp.computeF();
  cout << "\n" << "-- Expected Solution --" << "\n";
  solnGrp.print();
}
int main(int argc, char *argv[])
{
  Teuchos::GlobalMPISession mpiSession(&argc, &argv);

  bool success = false;
  bool verbose = false;
  try {
    // Parse the command line
    using Teuchos::CommandLineProcessor;
    CommandLineProcessor  clp;
    clp.throwExceptions(false);
    clp.addOutputSetupOptions(true);
    clp.setOption( "v", "disable-verbosity", &verbose, "Enable verbosity" );

    CommandLineProcessor::EParseCommandLineReturn
      parse_return = clp.parse(argc,argv,&std::cerr);

    if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL )
      return parse_return;

    if (verbose)
      std::cout << "Verbosity Activated" << std::endl;
    else
      std::cout << "Verbosity Disabled" << std::endl;

    // Create a communicator for Epetra objects
#ifdef HAVE_MPI
    Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
    Epetra_SerialComm Comm;
#endif

    const int num_elements = 400;

    // Check we have only one processor since this problem doesn't work
    // for more than one proc
    if (Comm.NumProc() > num_elements) {
      std::cerr << "Error! Number of elements must be greate than number of processors!"
        << std::endl;
      return EXIT_FAILURE;
    }

    // Create the model evaluator object
    double paramC = 0.99;
    Teuchos::RCP<ModelEvaluatorHeq<double> > model =
      modelEvaluatorHeq<double>(Teuchos::rcp(&Comm,false),num_elements,paramC);

    ::Stratimikos::DefaultLinearSolverBuilder builder;

    Teuchos::RCP<Teuchos::ParameterList> p =
      Teuchos::rcp(new Teuchos::ParameterList);
    p->set("Linear Solver Type", "AztecOO");
    p->sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve").sublist("AztecOO Settings").set("Output Frequency",20);
    p->set("Preconditioner Type", "Ifpack");
    builder.setParameterList(p);

    Teuchos::RCP< ::Thyra::LinearOpWithSolveFactoryBase<double> >
      lowsFactory = builder.createLinearSolveStrategy("");

    model->set_W_factory(lowsFactory);

    // Create the initial guess
    Teuchos::RCP< ::Thyra::VectorBase<double> >
      initial_guess = model->getNominalValues().get_x()->clone_v();

    Thyra::V_S(initial_guess.ptr(),Teuchos::ScalarTraits<double>::one());

    Teuchos::RCP<NOX::Thyra::Group> nox_group =
      Teuchos::rcp(new NOX::Thyra::Group(*initial_guess, model));
    //Teuchos::rcp(new NOX::Thyra::Group(*initial_guess, model, model->create_W_op(), lowsFactory, Teuchos::null, Teuchos::null));

    nox_group->computeF();

    // Create the NOX status tests and the solver
    // Create the convergence tests
    Teuchos::RCP<NOX::StatusTest::NormF> absresid =
      Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8));
    Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
      Teuchos::rcp(new NOX::StatusTest::NormWRMS(1.0e-2, 1.0e-8));
    Teuchos::RCP<NOX::StatusTest::Combo> converged =
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
    converged->addStatusTest(absresid);
    converged->addStatusTest(wrms);
    Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
      Teuchos::rcp(new NOX::StatusTest::MaxIters(20));
    Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
      Teuchos::rcp(new NOX::StatusTest::FiniteValue);
    Teuchos::RCP<NOX::StatusTest::Combo> combo =
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
    combo->addStatusTest(fv);
    combo->addStatusTest(converged);
    combo->addStatusTest(maxiters);

    // Create nox parameter list
    Teuchos::RCP<Teuchos::ParameterList> nl_params =
      Teuchos::rcp(new Teuchos::ParameterList);
    nl_params->set("Nonlinear Solver", "Anderson Accelerated Fixed-Point");
    nl_params->sublist("Anderson Parameters").set("Storage Depth", 5);
    nl_params->sublist("Anderson Parameters").set("Mixing Parameter", 1.0);
    nl_params->sublist("Anderson Parameters").set("Acceleration Start Iteration", 5);
    nl_params->sublist("Anderson Parameters").sublist("Preconditioning").set("Precondition", false);
    nl_params->sublist("Direction").sublist("Newton").sublist("Linear Solver").set("Tolerance", 1.0e-4);
    nl_params->sublist("Printing").sublist("Output Information").set("Details",true);
    nl_params->sublist("Printing").sublist("Output Information").set("Outer Iteration",true);
    //nl_params->sublist("Printing").sublist("Output Information").set("Outer Iteration StatusTest",true);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver =
      NOX::Solver::buildSolver(nox_group, combo, nl_params);
    NOX::StatusTest::StatusType solvStatus = solver->solve();

    // 1. Convergence
    int status = 0;
    if (solvStatus != NOX::StatusTest::Converged)
      status = 1;
    // 2. Number of iterations
    if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Output").get("Nonlinear Iterations", 0) != 14)
      status = 2;

    success = status==0;

    if (success)
      std::cout << "Test passed!" << std::endl;
    else
      std::cout << "Test failed!" << std::endl;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Beispiel #19
0
  // implementation of "toThyra" for full specialization on SC=double, LO=GO=int and NO=EpetraNode
  // We need the specialization in the cpp file due to a circle dependency in the .hpp files for BlockedCrsMatrix
  Teuchos::RCP<Thyra::LinearOpBase<double> >
  ThyraUtils<double, int, int, EpetraNode>::toThyra(const Teuchos::RCP<Xpetra::BlockedCrsMatrix<double, int, int, EpetraNode> >& mat) {

    int nRows = mat->Rows();
    int nCols = mat->Cols();

    Teuchos::RCP<Xpetra::Matrix<double, int, int, EpetraNode> > Ablock = mat->getMatrix(0,0);
    Teuchos::RCP<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode> > Ablock_wrap = Teuchos::rcp_dynamic_cast<Xpetra::CrsMatrixWrap<double, int, int, EpetraNode>>(Ablock);
    TEUCHOS_TEST_FOR_EXCEPT(Ablock_wrap.is_null() == true);

    bool bTpetra = false;
    bool bEpetra = false;
#ifdef HAVE_XPETRA_TPETRA
    // Note: Epetra is enabled
#if ((defined(EPETRA_HAVE_OMP)  && defined(HAVE_TPETRA_INST_OPENMP) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)) || \
     (!defined(EPETRA_HAVE_OMP) && defined(HAVE_TPETRA_INST_SERIAL) && defined(HAVE_TPETRA_INST_INT_INT) && defined(HAVE_TPETRA_INST_DOUBLE)))
    Teuchos::RCP<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > tpetraMat = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(Ablock_wrap->getCrsMatrix());
    if(tpetraMat!=Teuchos::null) bTpetra = true;
#else
    bTpetra = false;
#endif
#endif

#ifdef HAVE_XPETRA_EPETRA
    Teuchos::RCP<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> > epetraMat = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node> >(Ablock_wrap->getCrsMatrix());
    if(epetraMat!=Teuchos::null) bEpetra = true;
#endif

    TEUCHOS_TEST_FOR_EXCEPT(bTpetra == bEpetra); // we only allow Epetra OR Tpetra

    // create new Thyra blocked operator
    Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> > blockMat =
        Thyra::defaultBlockedLinearOp<Scalar>();

    blockMat->beginBlockFill(nRows,nCols);

    for (int r=0; r<nRows; ++r) {
      for (int c=0; c<nCols; ++c) {
        Teuchos::RCP<Matrix> xpmat = mat->getMatrix(r,c);
        Teuchos::RCP<CrsMatrixWrap> xpwrap = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(xpmat);
        TEUCHOS_TEST_FOR_EXCEPT(xpwrap.is_null() == true);

        Teuchos::RCP<Thyra::LinearOpBase<Scalar> > thBlock =
            Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(xpwrap->getCrsMatrix());
        std::stringstream label; label << "A" << r << c;
        blockMat->setBlock(r,c,thBlock);
      }
    }

    blockMat->endBlockFill();

    return blockMat;
  }
Beispiel #20
0
int main(int argc, char *argv[])
{

  // Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  // Create a communicator for Epetra objects
#ifdef HAVE_MPI
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  // Get the process ID and the total number of processors
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  // Check verbosity level
  bool verbose = false;
  if (argc > 1)
    if (argv[1][0]=='-' && argv[1][1]=='v')
      verbose = true;

  // Get the number of elements from the command line
  int NumGlobalElements = 0;
  if ((argc > 2) && (verbose))
    NumGlobalElements = atoi(argv[2]) + 1;
  else if ((argc > 1) && (!verbose))
    NumGlobalElements = atoi(argv[1]) + 1;
  else
    NumGlobalElements = 101;

  // The number of unknowns must be at least equal to the
  // number of processors.
  if (NumGlobalElements < NumProc) {
    std::cout << "numGlobalBlocks = " << NumGlobalElements
     << " cannot be < number of processors = " << NumProc << std::endl;
    std::cout << "Test failed!" << std::endl;
    throw "NOX Error";
  }

  // Create the interface between NOX and the application
  // This object is derived from NOX::Epetra::Interface
  Teuchos::RCP<Interface> interface =
    Teuchos::rcp(new Interface(NumGlobalElements, Comm));

  // Set the PDE factor (for nonlinear forcing term).  This could be specified
  // via user input.
  interface->setPDEfactor(1000.0);

  // Use a scaled vector space.  The scaling must also be registered
  // with the linear solver so the linear system is consistent!
  Teuchos::RCP<Epetra_Vector> scaleVec =
    Teuchos::rcp(new Epetra_Vector( *(interface->getSolution())));
  scaleVec->PutScalar(2.0);
  Teuchos::RCP<NOX::Epetra::Scaling> scaling =
    Teuchos::rcp(new NOX::Epetra::Scaling);
  scaling->addUserScaling(NOX::Epetra::Scaling::Left, scaleVec);

  // Use a weighted vector space for scaling all norms
  Teuchos::RCP<NOX::Epetra::VectorSpace> weightedVectorSpace =
    Teuchos::rcp(new NOX::Epetra::VectorSpaceScaledL2(scaling));

  // Get the vector from the Problem
  Teuchos::RCP<Epetra_Vector> soln = interface->getSolution();
  Teuchos::RCP<NOX::Epetra::Vector> noxSoln =
    Teuchos::rcp(new NOX::Epetra::Vector(soln,
                     NOX::Epetra::Vector::CreateCopy,
                     NOX::DeepCopy,
                     weightedVectorSpace));

  // Begin Nonlinear Solver ************************************

  // Create the top level parameter list
  Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr =
    Teuchos::rcp(new Teuchos::ParameterList);
  Teuchos::ParameterList& nlParams = *(nlParamsPtr.get());

  // Set the nonlinear solver method
  nlParams.set("Nonlinear Solver", "Line Search Based");

  // Set the printing parameters in the "Printing" sublist
  Teuchos::ParameterList& printParams = nlParams.sublist("Printing");
  printParams.set("MyPID", MyPID);
  printParams.set("Output Precision", 3);
  printParams.set("Output Processor", 0);
  if (verbose)
    printParams.set("Output Information",
                 NOX::Utils::OuterIteration +
                 NOX::Utils::OuterIterationStatusTest +
                 NOX::Utils::InnerIteration +
                 NOX::Utils::LinearSolverDetails +
                 NOX::Utils::Parameters +
                 NOX::Utils::Details +
                 NOX::Utils::Warning +
                             NOX::Utils::Debug +
                 NOX::Utils::TestDetails +
                 NOX::Utils::Error);
  else
    printParams.set("Output Information", NOX::Utils::Error +
                 NOX::Utils::TestDetails);

  // Create a print class for controlling output below
  NOX::Utils printing(printParams);

  // Sublist for line search
  Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search");
  searchParams.set("Method", "Full Step");

  // Sublist for direction
  Teuchos::ParameterList& dirParams = nlParams.sublist("Direction");
  dirParams.set("Method", "Newton");
  Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

  // Sublist for linear solver for the Newton method
  Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
  lsParams.set("Aztec Solver", "GMRES");
  lsParams.set("Max Iterations", 800);
  lsParams.set("Tolerance", 1e-4);

  // Various Preconditioner options
  //lsParams.set("Preconditioner", "AztecOO");
  lsParams.set("Preconditioner", "Ifpack");
  lsParams.set("Preconditioner Reuse Policy", "Reuse");
  lsParams.set("Max Age Of Prec", 5);

  // Add a user defined pre/post operator object
  Teuchos::RCP<NOX::Abstract::PrePostOperator> ppo =
    Teuchos::rcp(new UserPrePostOperator(printing));
  nlParams.sublist("Solver Options").set("User Defined Pre/Post Operator",
                     ppo);

  // Let's force all status tests to do a full check
  nlParams.sublist("Solver Options").set("Status Test Check Type", "Complete");

  // User supplied (Epetra_RowMatrix)
  Teuchos::RCP<Epetra_RowMatrix> Analytic = interface->getJacobian();

  // Create the linear system
  Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = interface;
  Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = interface;
  Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys =
    Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
                              iReq,
                              iJac, Analytic,
                              *noxSoln,
                              scaling));

  // Create the Group
  Teuchos::RCP<NOX::Epetra::Group> grpPtr =
    Teuchos::rcp(new NOX::Epetra::Group(printParams,
                    iReq,
                    *noxSoln,
                    linSys));
  NOX::Epetra::Group& grp = *grpPtr;

  // uncomment the following for loca supergroups
  //MF->setGroupForComputeF(*grpPtr);
  //FD->setGroupForComputeF(*grpPtr);

  // Create the convergence tests
  Teuchos::RCP<NOX::StatusTest::NormF> absresid =
    Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8));
  Teuchos::RCP<NOX::StatusTest::NormF> relresid =
    Teuchos::rcp(new NOX::StatusTest::NormF(grp, 1.0e-2));
  Teuchos::RCP<NOX::StatusTest::NormUpdate> update =
    Teuchos::rcp(new NOX::StatusTest::NormUpdate(1.0e-5));
  Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
    Teuchos::rcp(new NOX::StatusTest::NormWRMS(1.0e-2, 1.0e-8));
  Teuchos::RCP<NOX::StatusTest::Combo> converged =
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
  converged->addStatusTest(absresid);
  converged->addStatusTest(relresid);
  converged->addStatusTest(wrms);
  converged->addStatusTest(update);
  Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
    Teuchos::rcp(new NOX::StatusTest::MaxIters(20));
  Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
    Teuchos::rcp(new NOX::StatusTest::FiniteValue);
  Teuchos::RCP<NOX::StatusTest::Combo> combo =
    Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
  combo->addStatusTest(fv);
  combo->addStatusTest(converged);
  combo->addStatusTest(maxiters);

  // Create the solver
  Teuchos::RCP<NOX::Solver::Generic> solver =
    NOX::Solver::buildSolver(grpPtr, combo, nlParamsPtr);
  NOX::StatusTest::StatusType solvStatus = solver->solve();

  // End Nonlinear Solver **************************************

  // Get the Epetra_Vector with the final solution from the solver
  const NOX::Epetra::Group& finalGroup =
    dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
  const Epetra_Vector& finalSolution =
    (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).
    getEpetraVector();

  // Output the parameter list
  if (verbose) {
    if (printing.isPrintType(NOX::Utils::Parameters)) {
      printing.out() << std::endl << "Final Parameters" << std::endl
       << "****************" << std::endl;
      solver->getList().print(printing.out());
      printing.out() << std::endl;
    }
  }

  // Print solution
  char file_name[25];
  FILE *ifp;
  int NumMyElements = soln->Map().NumMyElements();
  (void) sprintf(file_name, "output.%d",MyPID);
  ifp = fopen(file_name, "w");
  for (int i=0; i<NumMyElements; i++)
    fprintf(ifp, "%d  %E\n", soln->Map().MinMyGID()+i, finalSolution[i]);
  fclose(ifp);


  // Tests
  int status = 0; // Converged

  // 1. Convergence
  if (solvStatus != NOX::StatusTest::Converged) {
      status = 1;
      if (printing.isPrintType(NOX::Utils::Error))
    printing.out() << "Nonlinear solver failed to converge!" << std::endl;
  }
#ifndef HAVE_MPI
  // 2. Linear solve iterations (53) - SERIAL TEST ONLY!
  //    The number of linear iterations changes with # of procs.
  if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Direction").sublist("Newton").sublist("Linear Solver").sublist("Output").get("Total Number of Linear Iterations",0) != 53) {
    status = 2;
  }
#endif
  // 3. Nonlinear solve iterations (10)
  if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Output").get("Nonlinear Iterations", 0) != 10)
    status = 3;
  // 4. Test the pre/post iterate options
  {
  UserPrePostOperator* ppoPtr = dynamic_cast<UserPrePostOperator*>(ppo.get());
  if (ppoPtr->getNumRunPreIterate() != 10)
    status = 4;
  if (ppoPtr->getNumRunPostIterate() != 10)
    status = 4;
  if (ppoPtr->getNumRunPreSolve() != 1)
    status = 4;
  if (ppoPtr->getNumRunPostSolve() != 1)
    status = 4;
  }
  // Summarize test results
  if (status == 0)
    printing.out() << "Test passed!" << std::endl;
  else
    printing.out() << "Test failed!" << std::endl;

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  // Final return value (0 = successfull, non-zero = failure)
  return status;
}
Beispiel #21
0
 const Vector<Real> &dual(void) const {
   dual_vec1_->set(vec_->dual());
   dual_vec_ = Teuchos::rcp(new RiskVector<Real>(dual_vec1_,augmented_,stat_));
   return *dual_vec_;
 }
// hide the original parental method AMET->evalModelImpl():
void
Aeras::HVDecorator::evalModelImpl(
    const Thyra::ModelEvaluatorBase::InArgs<ST>& inArgsT,
    const Thyra::ModelEvaluatorBase::OutArgs<ST>& outArgsT) const
{

  std::cout << "DEBUG WHICH HVDecorator: " << __PRETTY_FUNCTION__ << "\n";
	
  Teuchos::TimeMonitor Timer(*timer); //start timer
  //
  // Get the input arguments
  //
  const Teuchos::RCP<const Tpetra_Vector> xT =
    ConverterT::getConstTpetraVector(inArgsT.get_x());

  const Teuchos::RCP<const Tpetra_Vector> x_dotT =
    Teuchos::nonnull(inArgsT.get_x_dot()) ?
    ConverterT::getConstTpetraVector(inArgsT.get_x_dot()) :
    Teuchos::null;

  // AGS: x_dotdot time integrators not imlemented in Thyra ME yet
  //const Teuchos::RCP<const Tpetra_Vector> x_dotdotT =
  //  Teuchos::nonnull(inArgsT.get_x_dotdot()) ?
  //  ConverterT::getConstTpetraVector(inArgsT.get_x_dotdot()) :
  //  Teuchos::null;
  const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = Teuchos::null;


  const double alpha = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_alpha() : 0.0;
  // AGS: x_dotdot time integrators not imlemented in Thyra ME yet
  // const double omega = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_omega() : 0.0;
  const double omega = 0.0;
  const double beta = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_beta() : 1.0;
  const double curr_time = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_t() : 0.0;

  for (int l = 0; l < inArgsT.Np(); ++l) {
    const Teuchos::RCP<const Thyra::VectorBase<ST> > p = inArgsT.get_p(l);
    if (Teuchos::nonnull(p)) {
      const Teuchos::RCP<const Tpetra_Vector> pT = ConverterT::getConstTpetraVector(p);
      const Teuchos::ArrayRCP<const ST> pT_constView = pT->get1dView();

      ParamVec &sacado_param_vector = sacado_param_vec[l];
      for (unsigned int k = 0; k < sacado_param_vector.size(); ++k) {
        sacado_param_vector[k].baseValue = pT_constView[k];
      }
    }
  }

  //
  // Get the output arguments
  //
  const Teuchos::RCP<Tpetra_Vector> fT_out =
    Teuchos::nonnull(outArgsT.get_f()) ?
    ConverterT::getTpetraVector(outArgsT.get_f()) :
    Teuchos::null;

  const Teuchos::RCP<Tpetra_Operator> W_op_outT =
    Teuchos::nonnull(outArgsT.get_W_op()) ?
    ConverterT::getTpetraOperator(outArgsT.get_W_op()) :
    Teuchos::null;

#ifdef WRITE_MASS_MATRIX_TO_MM_FILE
  //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file
  const Teuchos::RCP<Tpetra_Operator> Mass =
    Teuchos::nonnull(outArgsT.get_W_op()) ?
    ConverterT::getTpetraOperator(outArgsT.get_W_op()) :
    Teuchos::null;
  //IK, 4/24/15: needed for writing mass matrix out to matrix market file
  const Teuchos::RCP<Tpetra_Vector> ftmp =
    Teuchos::nonnull(outArgsT.get_f()) ?
    ConverterT::getTpetraVector(outArgsT.get_f()) :
    Teuchos::null;
#endif

  // Cast W to a CrsMatrix, throw an exception if this fails
  const Teuchos::RCP<Tpetra_CrsMatrix> W_op_out_crsT =
    Teuchos::nonnull(W_op_outT) ?
    Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(W_op_outT, true) :
    Teuchos::null;

#ifdef WRITE_MASS_MATRIX_TO_MM_FILE
  //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file
  const Teuchos::RCP<Tpetra_CrsMatrix> Mass_crs =
    Teuchos::nonnull(Mass) ?
    Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(Mass, true) :
    Teuchos::null;
#endif

  //
  // Compute the functions
  //
  bool f_already_computed = false;

  // W matrix
  if (Teuchos::nonnull(W_op_out_crsT)) {
    app->computeGlobalJacobianT(
        alpha, beta, omega, curr_time, x_dotT.get(), x_dotdotT.get(),  *xT,
        sacado_param_vec, fT_out.get(), *W_op_out_crsT);
    f_already_computed = true;
  }

  // df/dp
  for (int l = 0; l < outArgsT.Np(); ++l) {
    const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dfdp_out =
      outArgsT.get_DfDp(l).getMultiVector();

    const Teuchos::RCP<Tpetra_MultiVector> dfdp_outT =
      Teuchos::nonnull(dfdp_out) ?
      ConverterT::getTpetraMultiVector(dfdp_out) :
      Teuchos::null;

    if (Teuchos::nonnull(dfdp_outT)) {
      const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]);

      app->computeGlobalTangentT(
          0.0, 0.0, 0.0, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT,
          sacado_param_vec, p_vec.get(),
          NULL, NULL, NULL, NULL, fT_out.get(), NULL,
          dfdp_outT.get());

      f_already_computed = true;
    }
  }

  // f
  if (app->is_adjoint) {
    const Thyra::ModelEvaluatorBase::Derivative<ST> f_derivT(
        outArgsT.get_f(),
        Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW);

    const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT;

    const int response_index = 0; // need to add capability for sending this in
    app->evaluateResponseDerivativeT(
        response_index, curr_time, x_dotT.get(), x_dotdotT.get(), *xT,
        sacado_param_vec, NULL,
        NULL, f_derivT, dummy_derivT, dummy_derivT, dummy_derivT);
  } else {
    if (Teuchos::nonnull(fT_out) && !f_already_computed) {
      app->computeGlobalResidualT(
          curr_time, x_dotT.get(), x_dotdotT.get(), *xT,
          sacado_param_vec, *fT_out);
    }
  }

  Teuchos::RCP<Tpetra_Vector> xtildeT = Teuchos::rcp(new Tpetra_Vector(xT->getMap())); 
  //compute xtildeT 
  applyLinvML(xT, xtildeT); 

#ifdef WRITE_TO_MATRIX_MARKET
  //writing to MatrixMarket for debug
  char name[100];  //create string for file name
  sprintf(name, "xT_%i.mm", mm_counter);
  Tpetra_MatrixMarket_Writer::writeDenseFile(name, xT);
  sprintf(name, "xtildeT_%i.mm", mm_counter);
  Tpetra_MatrixMarket_Writer::writeDenseFile(name, xtildeT);
  mm_counter++; 
#endif  

  //std::cout <<"in HVDec evalModelImpl a, b= " << alpha << "  "<< beta <<std::endl;

  if(Teuchos::nonnull(inArgsT.get_x_dot())){
	  std::cout <<"in the if-statement for the update" <<std::endl;
	  fT_out->update(1.0, *xtildeT, 1.0);
  }

  // Response functions
  for (int j = 0; j < outArgsT.Ng(); ++j) {
    const Teuchos::RCP<Thyra::VectorBase<ST> > g_out = outArgsT.get_g(j);
    Teuchos::RCP<Tpetra_Vector> gT_out =
      Teuchos::nonnull(g_out) ?
      ConverterT::getTpetraVector(g_out) :
      Teuchos::null;

    const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxT_out = outArgsT.get_DgDx(j);
    const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotT_out = outArgsT.get_DgDx_dot(j);
    // AGS: x_dotdot time integrators not imlemented in Thyra ME yet
    const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotdotT_out;
    sanitize_nans(dgdxT_out);
    sanitize_nans(dgdxdotT_out);
    sanitize_nans(dgdxdotdotT_out);

    // dg/dx, dg/dxdot
    if (!dgdxT_out.isEmpty() || !dgdxdotT_out.isEmpty()) {
      const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT;
      app->evaluateResponseDerivativeT(
          j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT,
          sacado_param_vec, NULL,
          gT_out.get(), dgdxT_out,
          dgdxdotT_out, dgdxdotdotT_out, dummy_derivT);
      // Set gT_out to null to indicate that g_out was evaluated.
      gT_out = Teuchos::null;
    }

    // dg/dp
    for (int l = 0; l < outArgsT.Np(); ++l) {
      const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dgdp_out =
        outArgsT.get_DgDp(j, l).getMultiVector();
      const Teuchos::RCP<Tpetra_MultiVector> dgdpT_out =
        Teuchos::nonnull(dgdp_out) ?
        ConverterT::getTpetraMultiVector(dgdp_out) :
        Teuchos::null;

      if (Teuchos::nonnull(dgdpT_out)) {
        const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]);
        app->evaluateResponseTangentT(
            j, alpha, beta, omega, curr_time, false,
            x_dotT.get(), x_dotdotT.get(), *xT,
            sacado_param_vec, p_vec.get(),
            NULL, NULL, NULL, NULL, gT_out.get(), NULL,
            dgdpT_out.get());
        gT_out = Teuchos::null;
      }
    }

    if (Teuchos::nonnull(gT_out)) {
      app->evaluateResponseT(
          j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT,
          sacado_param_vec, *gT_out);
    }
  }
}
Beispiel #23
0
 RiskVector( const Teuchos::RCP<Vector<Real> > &vec,
             const bool augmented = false,
             const Real stat = 0.)
   : stat_(stat), vec_(vec), augmented_(augmented) {
   dual_vec1_ = vec->dual().clone();
 }
Beispiel #24
0
bool run( const Teuchos::RCP<const Teuchos::Comm<int> > & comm ,
          const CMD & cmd)
{
  typedef typename Kokkos::Compat::KokkosDeviceWrapperNode<Device> NodeType;
  bool success = true;
  try {

  const int comm_rank = comm->getRank();

  // Create Tpetra Node -- do this first as it initializes host/device
  Teuchos::RCP<NodeType> node = createKokkosNode<NodeType>( cmd , *comm );

  // Set up stochastic discretization
  using Teuchos::Array;
  using Teuchos::RCP;
  using Teuchos::rcp;
  typedef Stokhos::OneDOrthogPolyBasis<int,double> one_d_basis;
  typedef Stokhos::LegendreBasis<int,double> legendre_basis;
  typedef Stokhos::LexographicLess< Stokhos::MultiIndex<int> > order_type;
  typedef Stokhos::TotalOrderBasis<int,double,order_type> product_basis;
  typedef Stokhos::Sparse3Tensor<int,double> Cijk;
  typedef Stokhos::Quadrature<int,double> quadrature;
  const int dim = cmd.CMD_USE_UQ_DIM;
  const int order = cmd.CMD_USE_UQ_ORDER ;
  Array< RCP<const one_d_basis> > bases(dim);
  for (int i=0; i<dim; i++)
    bases[i] = rcp(new legendre_basis(order, true));
  RCP<const product_basis> basis = rcp(new product_basis(bases));
  RCP<Cijk> cijk = basis->computeTripleProductTensor();

  typedef Stokhos::DynamicStorage<int,double,Device> Storage;
  typedef Sacado::UQ::PCE<Storage> Scalar;
  typename Scalar::cijk_type kokkos_cijk =
    Stokhos::create_product_tensor<Device>(*basis, *cijk);
  Kokkos::setGlobalCijkTensor(kokkos_cijk);

  // Create quadrature data used by assembly
  RCP<const quadrature> quad;
  if ( cmd.CMD_USE_SPARSE  ) {
    Stokhos::TotalOrderIndexSet<int> index_set(dim, order);
    quad =
      rcp(new Stokhos::SmolyakSparseGridQuadrature<int,double>(basis,
                                                                 index_set));
  }
  else
    quad = rcp(new Stokhos::TensorProductQuadrature<int,double>(basis));
  const int num_pce                         = basis->size();
  const int num_quad_points                 = quad->size();
  const Array<double>& quad_weights         = quad->getQuadWeights();
  const Array< Array<double> >& quad_points = quad->getQuadPoints();
  const Array< Array<double> >& quad_values = quad->getBasisAtQuadPoints();

  // Align number of quadrature points to ensemble size used in assembly
  const int align = 32;
  const int mask = align-1;
  const int num_quad_points_aligned = (num_quad_points + mask) & ~mask;

  // Copy quadrature data to view's for assembly kernels
  typedef Kokkos::Example::FENL::QuadratureData<Device> QD;
  typedef typename QD::quad_weights_type quad_weights_type;
  typedef typename QD::quad_values_type quad_values_type;
  QD qd;
  qd.weights_view =
    quad_weights_type( "quad weights", num_quad_points_aligned );
  qd.points_view =
    quad_values_type( "quad points", num_quad_points_aligned, dim );
  qd.values_view =
    quad_values_type( "quad values", num_quad_points_aligned, num_pce );
  typename quad_weights_type::HostMirror host_weights_view =
    Kokkos::create_mirror_view( qd.weights_view );
  typename quad_values_type::HostMirror host_points_view =
    Kokkos::create_mirror_view( qd.points_view );
  typename quad_values_type::HostMirror host_values_view =
    Kokkos::create_mirror_view( qd.values_view );
  for (int qp=0; qp<num_quad_points; ++qp) {
    host_weights_view(qp) = quad_weights[qp];
    for (int i=0; i<dim; ++i)
      host_points_view(qp,i) = quad_points[qp][i];
    for (int i=0; i<num_pce; ++i)
      host_values_view(qp,i) = quad_values[qp][i];
  }
  for (int qp=num_quad_points; qp<num_quad_points_aligned; ++qp) {
    host_weights_view(qp) = 0.0;
    for (int i=0; i<dim; ++i)
      host_points_view(qp,i) = quad_points[num_quad_points-1][i];
    for (int i=0; i<num_pce; ++i)
      host_values_view(qp,i) = quad_values[num_quad_points-1][i];
  }
  Kokkos::deep_copy( qd.weights_view, host_weights_view );
  Kokkos::deep_copy( qd.points_view, host_points_view );
  Kokkos::deep_copy( qd.values_view, host_values_view );

  // Print output headers
  const std::vector< size_t > widths =
    print_headers( std::cout , cmd , comm_rank );

  using Kokkos::Example::FENL::TrivialManufacturedSolution;
  using Kokkos::Example::FENL::ElementComputationKLCoefficient;
  using Kokkos::Example::BoxElemPart;
  using Kokkos::Example::FENL::fenl;
  using Kokkos::Example::FENL::Perf;

  const double bc_lower_value = 1 ;
  const double bc_upper_value = 2 ;
  const TrivialManufacturedSolution manufactured_solution;

  int nelem[3] = { cmd.CMD_USE_FIXTURE_X  ,
                   cmd.CMD_USE_FIXTURE_Y  ,
                   cmd.CMD_USE_FIXTURE_Z  };

  // Create KL diffusion coefficient
  const double kl_mean = cmd.CMD_USE_MEAN;
  const double kl_variance = cmd.CMD_USE_VAR;
  const double kl_correlation = cmd.CMD_USE_COR;
  typedef ElementComputationKLCoefficient< Scalar, double, Device > KL;
  KL diffusion_coefficient( kl_mean, kl_variance, kl_correlation, dim );
  typedef typename KL::RandomVariableView RV;
  typedef typename RV::HostMirror HRV;
  RV rv = diffusion_coefficient.getRandomVariables();
  HRV hrv = Kokkos::create_mirror_view(rv);

  // Set random variables
  // ith random variable \xi_i = \psi_I(\xi) / \psi_I(1.0)
  // where I is determined by the basis ordering (since the component basis
  // functions have unit two-norm, \psi_I(1.0) might not be 1.0).  We compute
  // this by finding the index of the multivariate term that is first order in
  // the ith slot, all other orders 0
  Teuchos::Array<double> point(dim, 1.0);
  Teuchos::Array<double> basis_vals(num_pce);
  basis->evaluateBases(point, basis_vals);
  for (int i=0; i<dim; ++i) {
    Stokhos::MultiIndex<int> term(dim, 0);
    term[i] = 1;
    int index = basis->index(term);
    hrv(i).fastAccessCoeff(index) = 1.0 / basis_vals[index];
  }
  Kokkos::deep_copy( rv, hrv );

  // Compute stochastic response using stochastic Galerkin method
  Scalar response = 0;
  Perf perf;
  if ( cmd.CMD_USE_FIXTURE_QUADRATIC  )
    perf = fenl< Scalar , Device , BoxElemPart::ElemQuadratic >
      ( comm , node , cmd.CMD_PRINT , cmd.CMD_USE_TRIALS ,
        cmd.CMD_USE_ATOMIC , cmd.CMD_USE_BELOS , cmd.CMD_USE_MUELU ,
        cmd.CMD_USE_MEANBASED ,
        nelem , diffusion_coefficient , manufactured_solution ,
        bc_lower_value , bc_upper_value ,
        false , response, qd );
  else
    perf = fenl< Scalar , Device , BoxElemPart::ElemLinear >
      ( comm , node , cmd.CMD_PRINT , cmd.CMD_USE_TRIALS ,
        cmd.CMD_USE_ATOMIC , cmd.CMD_USE_BELOS , cmd.CMD_USE_MUELU ,
        cmd.CMD_USE_MEANBASED ,
        nelem , diffusion_coefficient , manufactured_solution ,
        bc_lower_value , bc_upper_value ,
        false , response , qd );

  // std::cout << "newton count = " << perf.newton_iter_count
  //           << " cg count = " << perf.cg_iter_count << std::endl;
  perf.uq_count = num_quad_points;
  perf.newton_iter_count *= num_quad_points;
  perf.cg_iter_count *= num_pce;
  perf.map_ratio *= num_pce;
  perf.fill_node_set *= num_pce;
  perf.scan_node_count *= num_pce;
  perf.fill_graph_entries *= num_pce;
  perf.sort_graph_entries *= num_pce;
  perf.fill_element_graph *= num_pce;

  // Compute response mean, variance
  perf.response_mean = response.mean();
  perf.response_std_dev = response.standard_deviation();

  //std::cout << std::endl << response << std::endl;

  if ( 0 == comm_rank ) {
    print_perf_value( std::cout , cmd , widths , perf );
  }

  if ( cmd.CMD_SUMMARIZE  ) {
    Teuchos::TimeMonitor::report (comm.ptr (), std::cout);
  }

  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);

  return success;
}
Beispiel #25
0
 void axpy( const Real alpha, const Vector<Real> &x ) {
   const RiskVector<Real> &xs = Teuchos::dyn_cast<const RiskVector<Real> >(
     Teuchos::dyn_cast<const Vector<Real> >(x));
   if (augmented_) { stat_ += alpha*xs.getStatistic(); }
   vec_->axpy(alpha,*(xs.getVector()));
 }
int main(int argc, char *argv[])
{
  // Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  int status = 0; // Converged

  // Create a communicator for Epetra objects
#ifdef HAVE_MPI
  Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
  Epetra_SerialComm Comm;
#endif

  // Get the process ID and the total number of processors
  int MyPID = Comm.MyPID();
  int NumProc = Comm.NumProc();

  // Check verbosity level
  bool verbose = false;
  if (argc > 1)
    if (argv[1][0]=='-' && argv[1][1]=='v')
      verbose = true;

  // Get the number of elements from the command line
  int NumGlobalElements = 0;
  if ((argc > 2) && (verbose))
    NumGlobalElements = atoi(argv[2]) + 1;
  else if ((argc > 1) && (!verbose))
    NumGlobalElements = atoi(argv[1]) + 1;
  else
    NumGlobalElements = 200;

  bool success = false;
  try {
    // The number of unknowns must be at least equal to the
    // number of processors.
    if (NumGlobalElements < NumProc) {
      std::cout << "numGlobalBlocks = " << NumGlobalElements
        << " cannot be < number of processors = " << NumProc << std::endl;
      std::cout << "Test failed!" << std::endl;
      throw "NOX Error";
    }

    if (verbose)
      if (MyPID == 0)
        std::cout << "\n" << NOX::version() << std::endl;

    // Create the interface between NOX and the application
    // This object is derived from NOX::Epetra::Interface
    Teuchos::RCP<Interface> interface =
      Teuchos::rcp(new Interface(NumGlobalElements, Comm));

    // Get the vector from the Problem
    Teuchos::RCP<Epetra_Vector> soln = interface->getSolution();
    Teuchos::RCP<NOX::Epetra::Vector> noxSoln =
      Teuchos::rcp(new NOX::Epetra::Vector(soln, NOX::Epetra::Vector::CreateView));

    // Set the PDE factor (for nonlinear forcing term).  This could be specified
    // via user input.
    interface->setPDEfactor(1000.0);

    // Set the initial guess
    soln->PutScalar(1.0);

    // Begin Nonlinear Solver ************************************

    // Create the top level parameter list
    Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr =
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& nlParams = *(nlParamsPtr.get());

    // Set the nonlinear solver method
    nlParams.set("Nonlinear Solver", "Anderson Accelerated Fixed-Point");
    nlParams.sublist("Anderson Parameters").set("Storage Depth", 2);
    nlParams.sublist("Anderson Parameters").set("Mixing Parameter", -1.0);
    nlParams.sublist("Anderson Parameters").sublist("Preconditioning").set("Precondition", true);
    nlParams.sublist("Anderson Parameters").sublist("Preconditioning").set("Recompute Jacobian", true);

    //nlParams.set("Nonlinear Solver", "Line Search Based");

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = nlParams.sublist("Printing");
    printParams.set("MyPID", MyPID);
    printParams.set("Output Precision", 3);
    printParams.set("Output Processor", 0);
    if (verbose)
      printParams.set("Output Information",
          NOX::Utils::OuterIteration +
          NOX::Utils::OuterIterationStatusTest +
          NOX::Utils::InnerIteration +
          NOX::Utils::LinearSolverDetails +
          NOX::Utils::Parameters +
          NOX::Utils::Details +
          NOX::Utils::Warning +
          NOX::Utils::Debug +
          NOX::Utils::TestDetails +
          NOX::Utils::Error);
    else
      printParams.set("Output Information", NOX::Utils::Error +
          NOX::Utils::TestDetails);

    // Create a print class for controlling output below
    NOX::Utils printing(printParams);

    Teuchos::ParameterList& dirParams = nlParams.sublist("Direction");
    dirParams.set("Method", "Newton");
    Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
    lsParams.set("Aztec Solver", "GMRES");
    lsParams.set("Max Iterations", 800);
    lsParams.set("Tolerance", 1e-4);

    // This is an ML Preconditioner test.  If ML was not enabled,
    //   // just exit with success
#ifndef HAVE_NOX_ML_EPETRA
    printing.out() << "NOX not compiled with ML, exiting test!" << std::endl;
    printing.out() << "Test passed!" << std::endl;
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    return EXIT_SUCCESS;
#endif

    // Various Preconditioner options
#ifdef HAVE_NOX_ML_EPETRA
    // Comment out the previous Preconditioner spec and uncomment this line
    // to turn on ML
    lsParams.set("Preconditioner", "ML");
    lsParams.set("Preconditioner Operator", "Use Jacobian");
    // Create a parameter list for ML options
    Teuchos::ParameterList MLList;
#endif

#ifdef HAVE_NOX_ML_EPETRA
    if( lsParams.get("Preconditioner", "None") == "ML" ) {
      // This Teuchos parameter list is needed for ML

      // These specifications come straight from the example in
      // Trilinos/packages/ml/example/ml_example_epetra_preconditioner.cpp

      // set defaults for classic smoothed aggregation
      /*ML_Epetra::SetDefaults("SA",MLList);
      // maximum number of levels
      MLList.set("max levels",5);
      MLList.set("increasing or decreasing","decreasing");
      // use Uncoupled scheme to create the aggregate,
      // from level 3 use the better but more expensive MIS
      MLList.set("aggregation: type", "Uncoupled");
      MLList.set("aggregation: type (level 3)", "MIS");
      // smoother is Gauss-Seidel. Example file
      // ml_example_epetra_preconditioner_2level.cpp shows how to use
      // AZTEC's preconditioners as smoothers
      MLList.set("smoother: type","Gauss-Seidel");
      // use both pre and post smoothing
      MLList.set("smoother: pre or post", "both");
      // solve with serial direct solver KLU
      MLList.set("coarse: type","Jacobi");
      // Set ML output verbosity
      if( verbose )
      MLList.set("output", 10);
      else
      MLList.set("output", 0);*/
      MLList.set("PDE equations", 1);
      MLList.set("coarse: max size", 2000);
      MLList.set("coarse: type", "Amesos-KLU");
      //MLList.set("ML output", 10);
      lsParams.set("ML", MLList);
    }
#endif

    // Add a user defined pre/post operator object
    Teuchos::RCP<NOX::Abstract::PrePostOperator> ppo =
      Teuchos::rcp(new UserPrePostOperator(printing));
    nlParams.sublist("Solver Options").set("User Defined Pre/Post Operator",
        ppo);

    // Let's force all status tests to do a full check
    nlParams.sublist("Solver Options").set("Status Test Check Type", "Complete");

    // Create all possible Epetra_Operators.
    // 1. User supplied (Epetra_RowMatrix)
    Teuchos::RCP<Epetra_RowMatrix> Analytic = interface->getJacobian();

    // Create the linear system
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = interface;
    Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys =
      Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
            iReq,
            iJac, Analytic,
            //iPrec, Analytic,
            *soln));

    // Create the Group
    NOX::Epetra::Vector initialGuess(soln, NOX::Epetra::Vector::CreateView);
    Teuchos::RCP<NOX::Epetra::Group> grpPtr =
      Teuchos::rcp(new NOX::Epetra::Group(printParams,
            iReq,
            initialGuess,
            linSys));
    NOX::Epetra::Group& grp = *grpPtr;

    // Create the convergence tests
    Teuchos::RCP<NOX::StatusTest::NormF> absresid =
      Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8));
    Teuchos::RCP<NOX::StatusTest::NormF> relresid =
      Teuchos::rcp(new NOX::StatusTest::NormF(grp, 1.0e-2));
    Teuchos::RCP<NOX::StatusTest::NormUpdate> update =
      Teuchos::rcp(new NOX::StatusTest::NormUpdate(1.0e-5));
    Teuchos::RCP<NOX::StatusTest::NormWRMS> wrms =
      Teuchos::rcp(new NOX::StatusTest::NormWRMS(1.0e-2, 1.0e-8));
    Teuchos::RCP<NOX::StatusTest::Combo> converged =
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::AND));
    converged->addStatusTest(absresid);
    converged->addStatusTest(relresid);
    converged->addStatusTest(wrms);
    converged->addStatusTest(update);
    Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters =
      Teuchos::rcp(new NOX::StatusTest::MaxIters(100));
    Teuchos::RCP<NOX::StatusTest::FiniteValue> fv =
      Teuchos::rcp(new NOX::StatusTest::FiniteValue);
    Teuchos::RCP<NOX::StatusTest::Combo> combo =
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
    combo->addStatusTest(fv);
    combo->addStatusTest(converged);
    combo->addStatusTest(maxiters);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver =
      NOX::Solver::buildSolver(grpPtr, combo, nlParamsPtr);
    NOX::StatusTest::StatusType solvStatus = solver->solve();

    // End Nonlinear Solver **************************************

    // Get the Epetra_Vector with the final solution from the solver
    const NOX::Epetra::Group& finalGroup =
      dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
    const Epetra_Vector& finalSolution =
      (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).
      getEpetraVector();

    // Output the parameter list
    if (verbose) {
      if (printing.isPrintType(NOX::Utils::Parameters)) {
        printing.out() << std::endl << "Final Parameters" << std::endl
          << "****************" << std::endl;
        solver->getList().print(printing.out());
        printing.out() << std::endl;
      }
    }

    // Print solution
    char file_name[25];
    FILE *ifp;
    int NumMyElements = soln->Map().NumMyElements();
    (void) sprintf(file_name, "output.%d",MyPID);
    ifp = fopen(file_name, "w");
    for (int i=0; i<NumMyElements; i++)
      fprintf(ifp, "%d  %E\n", soln->Map().MinMyGID()+i, finalSolution[i]);
    fclose(ifp);


    // Tests

    // 1. Convergence
    if (solvStatus != NOX::StatusTest::Converged) {
      status = 1;
      if (printing.isPrintType(NOX::Utils::Error))
        printing.out() << "Nonlinear solver failed to converge!" << std::endl;
    }
    // 2. Nonlinear solve iterations (10)
    if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Output").get("Nonlinear Iterations", 0) != 11)
      status = 2;

    success = status==0;

    // Summarize test results
    if (success)
      printing.out() << "Test passed!" << std::endl;
    else
      printing.out() << "Test failed!" << std::endl;

    printing.out() << "Status = " << status << std::endl;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Beispiel #27
0
int main(int argc, char *argv[]) {

  //Check number of arguments
  if (argc < 4) {
    std::cout <<"\n>>> ERROR: Invalid number of arguments.\n\n";
    std::cout <<"Usage:\n\n";
    std::cout <<"  ./Intrepid_example_Drivers_Example_10.exe deg NX NY NZ verbose\n\n";
    std::cout <<" where \n";
    std::cout <<"   int deg             - polynomial degree to be used (assumed >= 1) \n";
    std::cout <<"   int NX              - num intervals in x direction (assumed box domain, 0,1) \n";
    std::cout <<"   int NY              - num intervals in y direction (assumed box domain, 0,1) \n";
    std::cout <<"   int NZ              - num intervals in y direction (assumed box domain, 0,1) \n";
    std::cout <<"   verbose (optional)  - any character, indicates verbose output \n\n";
    exit(1);
  }
  
  // This little trick lets us print to std::cout only if
  // a (dummy) command-line argument is provided.
  int iprint     = argc - 1;
  Teuchos::RCP<std::ostream> outStream;
  Teuchos::oblackholestream bhs; // outputs nothing
  if (iprint > 2)
    outStream = Teuchos::rcp(&std::cout, false);
  else
    outStream = Teuchos::rcp(&bhs, false);
  
  // Save the format state of the original std::cout.
  Teuchos::oblackholestream oldFormatState;
  oldFormatState.copyfmt(std::cout);
  
  *outStream								\
    << "===============================================================================\n" \
    << "|                                                                             |\n" \
    << "|  Example: Build Stiffness Matrix for                                        |\n" \
    << "|                   Poisson Equation on Hexahedral Mesh                       |\n" \
    << "|                                                                             |\n" \
    << "|  Questions? Contact  Pavel Bochev  ([email protected]),                    |\n" \
    << "|                      Denis Ridzal  ([email protected]),                    |\n" \
    << "|                      Kara Peterson ([email protected]).                    |\n" \
    << "|                                                                             |\n" \
    << "|  Intrepid's website: http://trilinos.sandia.gov/packages/intrepid           |\n" \
    << "|  Trilinos website:   http://trilinos.sandia.gov                             |\n" \
    << "|                                                                             |\n" \
    << "===============================================================================\n";

  
  // ************************************ GET INPUTS **************************************
  
  int deg          = atoi(argv[1]);  // polynomial degree to use
  int NX           = atoi(argv[2]);  // num intervals in x direction (assumed box domain, 0,1)
  int NY           = atoi(argv[3]);  // num intervals in y direction (assumed box domain, 0,1)
  int NZ           = atoi(argv[4]);  // num intervals in y direction (assumed box domain, 0,1)
  

  // *********************************** CELL TOPOLOGY **********************************
  
  // Get cell topology for base hexahedron
  typedef shards::CellTopology    CellTopology;
  CellTopology hex_8(shards::getCellTopologyData<shards::Hexahedron<8> >() );
  
  // Get dimensions 
  int numNodesPerElem = hex_8.getNodeCount();
  int spaceDim = hex_8.getDimension();
  
  // *********************************** GENERATE MESH ************************************
  
  *outStream << "Generating mesh ... \n\n";
  
  *outStream << "   NX" << "   NY" << "   NZ\n";
  *outStream << std::setw(5) << NX <<
    std::setw(5) << NY << std::setw(5) << NZ << "\n\n";
  
  // Print mesh information
  int numElems = NX*NY*NZ;
  int numNodes = (NX+1)*(NY+1)*(NZ+1);
  *outStream << " Number of Elements: " << numElems << " \n";
  *outStream << "    Number of Nodes: " << numNodes << " \n\n";
  
  // Cube
  double leftX = 0.0, rightX = 1.0;
  double leftY = 0.0, rightY = 1.0;
  double leftZ = 0.0, rightZ = 1.0;

  // Mesh spacing
  double hx = (rightX-leftX)/((double)NX);
  double hy = (rightY-leftY)/((double)NY);
  double hz = (rightZ-leftZ)/((double)NZ);

  // Get nodal coordinates
  FieldContainer<double> nodeCoord(numNodes, spaceDim);
  FieldContainer<int> nodeOnBoundary(numNodes);
  int inode = 0;
  for (int k=0; k<NZ+1; k++) 
    {
      for (int j=0; j<NY+1; j++) 
	{
	  for (int i=0; i<NX+1; i++) 
	    {
	      nodeCoord(inode,0) = leftX + (double)i*hx;
	      nodeCoord(inode,1) = leftY + (double)j*hy;
	      nodeCoord(inode,2) = leftZ + (double)k*hz;
	      if (k==0 || k==NZ || j==0 || i==0 || j==NY || i==NX)
		{
		  nodeOnBoundary(inode)=1;
		}
	      else 
		{
		  nodeOnBoundary(inode)=0;
		}
	      inode++;
	    }
	}
    }
#define DUMP_DATA
#ifdef DUMP_DATA
  // Print nodal coords
  ofstream fcoordout("coords.dat");
  for (int i=0; i<numNodes; i++) {
    fcoordout << nodeCoord(i,0) <<" ";
    fcoordout << nodeCoord(i,1) <<" ";
    fcoordout << nodeCoord(i,2) <<"\n";
  }
  fcoordout.close();
#endif
  
  
  // Element to Node map
  // We'll keep it around, but this is only the DOFMap if you are in the lowest order case.
  FieldContainer<int> elemToNode(numElems, numNodesPerElem);
  int ielem = 0;
  for (int k=0; k<NZ; k++) 
    {
      for (int j=0; j<NY; j++) 
	{
	  for (int i=0; i<NX; i++) 
	    {
 	      elemToNode(ielem,0) = k * ( NX + 1 ) * ( NY + 1 ) + j * ( NX + 1 ) + i;
 	      elemToNode(ielem,1) = k * ( NX + 1 ) * ( NY + 1 ) + j * ( NX + 1 ) + i + 1;
 	      elemToNode(ielem,2) = k * ( NX + 1 ) * ( NY + 1 ) + ( j + 1 ) * ( NX + 1 ) + i + 1;
 	      elemToNode(ielem,3) = k * ( NX + 1 ) * ( NY + 1 ) + ( j + 1 ) * ( NX + 1 ) + i;
 	      elemToNode(ielem,4) = ( k + 1 ) * ( NX + 1 ) * ( NY + 1 ) + j * ( NX + 1 ) + i;
 	      elemToNode(ielem,5) = ( k + 1 ) * ( NX + 1 ) * ( NY + 1 ) + j * ( NX + 1 ) + i + 1;
 	      elemToNode(ielem,6) = ( k + 1 ) * ( NX + 1 ) * ( NY + 1 ) + ( j + 1 ) * ( NX + 1 ) + i + 1;
 	      elemToNode(ielem,7) = ( k + 1 ) * ( NX + 1 ) * ( NY + 1 ) + ( j + 1 ) * ( NX + 1 ) + i;
	      ielem++;
	    }
	}
    }
#ifdef DUMP_DATA
  // Output connectivity
  ofstream fe2nout("elem2node.dat");
  for (int k=0;k<NZ;k++)
    {
      for (int j=0; j<NY; j++) 
	{
	  for (int i=0; i<NX; i++) 
	    {
	      int ielem = i + j * NX + k * NY * NY;
	      for (int m=0; m<numNodesPerElem; m++)
		{
		  fe2nout << elemToNode(ielem,m) <<"  ";
		}
	      fe2nout <<"\n";
	    }
	}
    }
  fe2nout.close();
#endif
  
  // ************************************ CUBATURE ************************************** 
  *outStream << "Getting cubature ... \n\n";
  
  // Get numerical integration points and weights
  DefaultCubatureFactory<double>  cubFactory;                                   
  int cubDegree = 2*deg;
  Teuchos::RCP<Cubature<double> > quadCub = cubFactory.create(hex_8, cubDegree); 
  
  int cubDim       = quadCub->getDimension();
  int numCubPoints = quadCub->getNumPoints();
  
  FieldContainer<double> cubPoints(numCubPoints, cubDim);
  FieldContainer<double> cubWeights(numCubPoints);
  
  quadCub->getCubature(cubPoints, cubWeights);
  

  // ************************************** BASIS ***************************************
  
  *outStream << "Getting basis ... \n\n";
  
  // Define basis 
  Basis_HGRAD_HEX_Cn_FEM<double, FieldContainer<double> > quadHGradBasis(deg,POINTTYPE_SPECTRAL);
  int numFieldsG = quadHGradBasis.getCardinality();
  FieldContainer<double> quadGVals(numFieldsG, numCubPoints); 
  FieldContainer<double> quadGrads(numFieldsG, numCubPoints, spaceDim); 
  
  // Evaluate basis values and gradients at cubature points
  quadHGradBasis.getValues(quadGVals, cubPoints, OPERATOR_VALUE);
  quadHGradBasis.getValues(quadGrads, cubPoints, OPERATOR_GRAD);

  // create the local-global mapping
  FieldContainer<int> ltgMapping(numElems,numFieldsG);
  const int numDOF = (NX*deg+1)*(NY*deg+1)*(NZ*deg+1);
  ielem=0;
  for (int k=0;k<NZ;k++) 
    {
      for (int j=0;j<NY;j++) 
	{
	  for (int i=0;i<NX;i++) 
	    {
	      const int start = k * ( NY * deg + 1 ) * ( NX * deg + 1 ) + j * ( NX * deg + 1 ) + i * deg;
	      // loop over local dof on this cell
	      int local_dof_cur=0;
	      for (int kloc=0;kloc<=deg;kloc++) 
		{
		  for (int jloc=0;jloc<=deg;jloc++) 
		    {
		      for (int iloc=0;iloc<=deg;iloc++)
			{
			  ltgMapping(ielem,local_dof_cur) = start 
			    + kloc * ( NX * deg + 1 ) * ( NY * deg + 1 )
			    + jloc * ( NX * deg + 1 )
			    + iloc;
			  local_dof_cur++;
			}
		    }
		}
	      ielem++;
	    }
	}
    }
#ifdef DUMP_DATA
  // Output ltg mapping 
  ielem = 0;
  ofstream ltgout("ltg.dat");
  for (int k=0;k<NZ;k++)  
    {
      for (int j=0; j<NY; j++) 
	{
	  for (int i=0; i<NX; i++) 
	    {
	      int ielem = i + j * NX + k * NX * NY;
	      for (int m=0; m<numFieldsG; m++)
		{
		  ltgout << ltgMapping(ielem,m) <<"  ";
		}
	      ltgout <<"\n";
	    }
	}
    }
  ltgout.close();
#endif

  // ********** DECLARE GLOBAL OBJECTS *************
  Epetra_SerialComm Comm;
  Epetra_Map globalMapG(numDOF, 0, Comm);
  Epetra_FEVector u(globalMapG);  u.Random();
  Epetra_FEVector Ku(globalMapG);

  // Let's preallocate the graph before we instantiate the matrix
  Epetra_Time graphTimer(Comm);
  Epetra_CrsGraph grph( Copy , globalMapG , 4 * numFieldsG );
  for (int k=0;k<numElems;k++) 
    {
      for (int i=0;i<numFieldsG;i++)
        {
          grph.InsertGlobalIndices(ltgMapping(k,i),numFieldsG,&ltgMapping(k,0));
        }
    }
  grph.FillComplete();
  const double graphTime = graphTimer.ElapsedTime();


  // time the instantiation 
  Epetra_Time instantiateTimer(Comm);
  Epetra_FECrsMatrix StiffMatrix(Copy,grph);
  const double instantiateTime = instantiateTimer.ElapsedTime();


  // ********** CONSTRUCT AND INSERT LOCAL STIFFNESS MATRICES ***********
  *outStream << "Building local stiffness matrices...\n\n";
  typedef CellTools<double>  CellTools;
  typedef FunctionSpaceTools fst;
  int numCells = numElems; 


  // jacobian information
  FieldContainer<double> refCellNodes(1,numNodesPerElem,spaceDim);
  FieldContainer<double> cellJacobian(1,numCubPoints,spaceDim,spaceDim);
  FieldContainer<double> cellJacobInv(1,numCubPoints,spaceDim,spaceDim);
  FieldContainer<double> cellJacobDet(1,numCubPoints);

  // element stiffness matrices and supporting storage space
  FieldContainer<double> localStiffMatrix(1, numFieldsG, numFieldsG);
  FieldContainer<double> transformedBasisGradients(1,numFieldsG,numCubPoints,spaceDim);
  FieldContainer<double> weightedTransformedBasisGradients(1,numFieldsG,numCubPoints,spaceDim);
  FieldContainer<double> weightedMeasure(1, numCubPoints);


  Epetra_Time localConstructTimer( Comm );
  refCellNodes(0,0,0) = 0.0;  refCellNodes(0,0,1) = 0.0;  refCellNodes(0,0,2) = 0.0;
  refCellNodes(0,1,0) = hx;   refCellNodes(0,1,1) = 0.0;  refCellNodes(0,1,2) = 0.0;
  refCellNodes(0,2,0) = hx;   refCellNodes(0,2,1) = hy;   refCellNodes(0,2,2) = 0.0;
  refCellNodes(0,3,0) = 0.0;  refCellNodes(0,3,1) = hy;   refCellNodes(0,3,2) = 0.0;
  refCellNodes(0,4,0) = 0.0;  refCellNodes(0,4,1) = 0.0;  refCellNodes(0,4,2) = hz;
  refCellNodes(0,5,0) = hx;   refCellNodes(0,5,1) = 0.0;  refCellNodes(0,5,2) = hz;
  refCellNodes(0,6,0) = hx;   refCellNodes(0,6,1) = hy;   refCellNodes(0,6,2) = hz;
  refCellNodes(0,7,0) = 0.0;  refCellNodes(0,7,1) = hy;   refCellNodes(0,7,2) = hz;

   
  // jacobian evaluation 
  CellTools::setJacobian(cellJacobian,cubPoints,refCellNodes,hex_8);
  CellTools::setJacobianInv(cellJacobInv, cellJacobian );
  CellTools::setJacobianDet(cellJacobDet, cellJacobian );

  // transform reference element gradients to each cell
  fst::HGRADtransformGRAD<double>(transformedBasisGradients, cellJacobInv, quadGrads);
      
  // compute weighted measure
  fst::computeCellMeasure<double>(weightedMeasure, cellJacobDet, cubWeights);

  // multiply values with weighted measure
  fst::multiplyMeasure<double>(weightedTransformedBasisGradients,
                               weightedMeasure, transformedBasisGradients);

  // integrate to compute element stiffness matrix
  fst::integrate<double>(localStiffMatrix,
                         transformedBasisGradients, weightedTransformedBasisGradients , COMP_BLAS);

  const double localConstructTime = localConstructTimer.ElapsedTime();


  Epetra_Time insertionTimer(Comm);

  // *** Element loop ***
  for (int k=0; k<numElems; k++) 
    {
      // assemble into global matrix
      StiffMatrix.InsertGlobalValues(numFieldsG,&ltgMapping(k,0),numFieldsG,&ltgMapping(k,0),&localStiffMatrix(0,0,0));
      
    }
  StiffMatrix.GlobalAssemble(); StiffMatrix.FillComplete();
  const double insertionTime = insertionTimer.ElapsedTime( );

  *outStream << "Time to construct matrix graph: " << graphTime << "\n";
  *outStream << "Time to instantiate global stiffness matrix: " << instantiateTime << "\n";
  *outStream << "Time to build local matrices (including Jacobian computation): "<< localConstructTime << "\n";
  *outStream << "Time to assemble global matrix from local matrices: " << insertionTime << "\n";
  *outStream << "Total construction time: " << graphTime + instantiateTime + localConstructTime + insertionTime << "\n";

  Epetra_Time applyTimer(Comm);
  StiffMatrix.Apply(u,Ku);
  const double multTime = applyTimer.ElapsedTime();
  *outStream << "Time to multiply onto a vector: " << multTime << "\n";

  *outStream << "End Result: TEST PASSED\n";
  
  // reset format state of std::cout
  std::cout.copyfmt(oldFormatState);
  
  return 0;
}
  void IsorropiaInterface<LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::Build(Level& level) const {
    FactoryMonitor m(*this, "Build", level);

    RCP<Matrix> A        = Get< RCP<Matrix> >(level, "A");
    GO          numParts = level.Get<GO>("number of partitions");

    RCP<const Map> rowMap = A->getRowMap();
    RCP<const Map> colMap = A->getColMap();

    if (numParts == 1) {
      // Running on one processor, so decomposition is the trivial one, all zeros.
      RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(rowMap, true);
      //Set(level, "Partition", decomposition);
      Set(level, "AmalgamatedPartition", decomposition);
      return;
    }

    // ok, reconstruct graph information of matrix A
    // Note, this is the non-rebalanced matrix A and we need the graph
    // of the non-rebalanced matrix A. We cannot make use of the "Graph"
    // that is/will be built for the aggregates later for several reasons
    // 1) the "Graph" for the aggregates is meant to be based on the rebalanced matrix A
    // 2) we cannot call a CoalesceDropFactory::Build here since this is very complicated and
    //    completely messes up the whole factory chain
    // 3) CoalesceDropFactory is meant to provide some minimal Graph information for the aggregation
    //    (LWGraph), but here we need the full CrsGraph for Isorropia as input

    // That is, why this code is somewhat redundant to CoalesceDropFactory

    LO blockdim = 1;                          // block dim for fixed size blocks
    GO indexBase = rowMap->getIndexBase();    // index base of maps
    GO offset    = 0;
    LO blockid          = -1;  // block id in strided map
    LO nStridedOffset   = 0;   // DOF offset for strided block id "blockid" (default = 0)
    LO stridedblocksize = blockdim; // size of strided block id "blockid" (default = fullblocksize, only if blockid!=-1 stridedblocksize <= fullblocksize)

    // 1) check for blocking/striding information
    //    fill above variables
    if(A->IsView("stridedMaps") &&
       Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap("stridedMaps")) != Teuchos::null) {
      Xpetra::viewLabel_t oldView = A->SwitchToView("stridedMaps"); // note: "stridedMaps are always non-overlapping (correspond to range and domain maps!)
      RCP<const StridedMap> strMap = Teuchos::rcp_dynamic_cast<const StridedMap>(A->getRowMap());
      TEUCHOS_TEST_FOR_EXCEPTION(strMap == Teuchos::null,Exceptions::BadCast,"MueLu::IsorropiaInterface::Build: cast to strided row map failed.");
      blockdim = strMap->getFixedBlockSize();
      offset   = strMap->getOffset();
      blockid  = strMap->getStridedBlockId();
      if (blockid > -1) {
        std::vector<size_t> stridingInfo = strMap->getStridingData();
        for (size_t j = 0; j < Teuchos::as<size_t>(blockid); j++)
          nStridedOffset += stridingInfo[j];
        stridedblocksize = Teuchos::as<LocalOrdinal>(stridingInfo[blockid]);

      } else {
        stridedblocksize = blockdim;
      }
      oldView = A->SwitchToView(oldView);
      GetOStream(Statistics0, -1) << "IsorropiaInterface::Build():" << " found blockdim=" << blockdim << " from strided maps (blockid=" << blockid << ", strided block size=" << stridedblocksize << "). offset=" << offset << std::endl;
    } else GetOStream(Statistics0, -1) << "IsorropiaInterface::Build(): no striding information available. Use blockdim=1 with offset=0" << std::endl;

    // 2) build (un)amalgamation information
    //    prepare generation of nodeRowMap (of amalgamated matrix)
    RCP<AmalgamationInfo> amalInfo = Get< RCP<AmalgamationInfo> >(level, "UnAmalgamationInfo");
    RCP<std::vector<GO> > gNodeIds = amalInfo->GetNodeGIDVector();
    GO cnt_amalRows = amalInfo->GetNumberOfNodes();

    // inter processor communication: sum up number of block ids
    GO num_blockids = 0;
    Teuchos::reduceAll<int,GO>(*(A->getRowMap()->getComm()),Teuchos::REDUCE_SUM, cnt_amalRows, Teuchos::ptr(&num_blockids) );
    GetOStream(Statistics0, -1) << "IsorropiaInterface::SetupAmalgamationData()" << " # of amalgamated blocks=" << num_blockids << std::endl;

    // 3) generate row map for amalgamated matrix (graph of A)
    //    with same distribution over all procs as row map of A

    Teuchos::ArrayRCP<GO> arr_gNodeIds = Teuchos::arcp( gNodeIds );
    Teuchos::RCP<Map> nodeMap = MapFactory::Build(A->getRowMap()->lib(), num_blockids, arr_gNodeIds(), indexBase, A->getRowMap()->getComm()); // note: nodeMap has same indexBase as row map of A (=dof map)
    GetOStream(Statistics0, -1) << "IsorropiaInterface: nodeMap " << nodeMap->getNodeNumElements() << "/" << nodeMap->getGlobalNumElements() << " local/global elements" << std::endl;

    // 4) create graph of amalgamated matrix
    RCP<CrsGraph> crsGraph = CrsGraphFactory::Build(nodeMap, 10, Xpetra::DynamicProfile);

    // 5) do amalgamation. generate graph of amalgamated matrix
    for(LO row=0; row<Teuchos::as<LO>(A->getRowMap()->getNodeNumElements()); row++) {
      // get global DOF id
      GO grid = rowMap->getGlobalElement(row);

      // translate grid to nodeid
      GO nodeId = AmalgamationFactory::DOFGid2NodeId(grid, blockdim, offset, indexBase);

      size_t nnz = A->getNumEntriesInLocalRow(row);
      Teuchos::ArrayView<const LO> indices;
      Teuchos::ArrayView<const SC> vals;
      A->getLocalRowView(row, indices, vals);
      //TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::as<size_t>(indices.size()) != nnz, Exceptions::RuntimeError, "MueLu::CoalesceFactory::Amalgamate: number of nonzeros not equal to number of indices? Error.");

      RCP<std::vector<GO> > cnodeIds = Teuchos::rcp(new std::vector<GO>);  // global column block ids
      LO realnnz = 0;
      for(LO col=0; col<Teuchos::as<LO>(nnz); col++) {
        //TEUCHOS_TEST_FOR_EXCEPTION(A->getColMap()->isNodeLocalElement(indices[col])==false,Exceptions::RuntimeError, "MueLu::CoalesceFactory::Amalgamate: Problem with columns. Error.");
        GO gcid = colMap->getGlobalElement(indices[col]); // global column id

        if(vals[col]!=0.0) {
          GO cnodeId = AmalgamationFactory::DOFGid2NodeId(gcid, blockdim, offset, indexBase);
          cnodeIds->push_back(cnodeId);
          realnnz++; // increment number of nnz in matrix row
        }
      }

      Teuchos::ArrayRCP<GO> arr_cnodeIds = Teuchos::arcp( cnodeIds );

      //TEUCHOS_TEST_FOR_EXCEPTION(crsGraph->getRowMap()->isNodeGlobalElement(nodeId)==false,Exceptions::RuntimeError, "MueLu::CoalesceFactory::Amalgamate: global row id does not belong to current proc. Error.");
      if(arr_cnodeIds.size() > 0 )
        crsGraph->insertGlobalIndices(nodeId, arr_cnodeIds());
    }
    // fill matrix graph
    crsGraph->fillComplete(nodeMap,nodeMap);

#ifdef HAVE_MPI
#ifdef HAVE_MUELU_ISORROPIA

    // prepare parameter list for Isorropia
    Teuchos::ParameterList paramlist;
    paramlist.set("NUM PARTS", toString(numParts));

    /*STRUCTURALLY SYMMETRIC [NO/yes] (is symmetrization required?)
    PARTITIONING METHOD [block/cyclic/random/rcb/rib/hsfc/graph/HYPERGRAPH]
    NUM PARTS [int k] (global number of parts)
    IMBALANCE TOL [float tol] (1.0 is perfect balance)
    BALANCE OBJECTIVE [ROWS/nonzeros]
    */
    Teuchos::ParameterList& sublist = paramlist.sublist("Zoltan");
    sublist.set("LB_APPROACH", "PARTITION");



#ifdef HAVE_MUELU_EPETRA
    RCP< Xpetra::EpetraCrsGraph> epCrsGraph = Teuchos::rcp_dynamic_cast<Xpetra::EpetraCrsGraph>(crsGraph);
    if(epCrsGraph != Teuchos::null) {
      RCP< const Epetra_CrsGraph> epetraCrsGraph = epCrsGraph->getEpetra_CrsGraph();

      RCP<Isorropia::Epetra::Partitioner> isoPart = Teuchos::rcp(new Isorropia::Epetra::Partitioner(epetraCrsGraph,paramlist));

      int size = 0;
      const int* array = NULL;
      isoPart->extractPartsView(size,array);

      TEUCHOS_TEST_FOR_EXCEPTION(size != Teuchos::as<int>(nodeMap->getNodeNumElements()), Exceptions::RuntimeError, "length of array returned from extractPartsView does not match local length of rowMap");

      RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(nodeMap, false);
      ArrayRCP<GO> decompEntries = decomposition->getDataNonConst(0);

      // fill vector with amalgamated information about partitioning
      for(int i = 0; i<size; i++) {
        decompEntries[i] = Teuchos::as<GO>(array[i]);
      }

      Set(level, "AmalgamatedPartition", decomposition);

    }
#endif // ENDIF HAVE_MUELU_EPETRA

#ifdef HAVE_MUELU_TPETRA
#ifdef HAVE_MUELU_INST_DOUBLE_INT_INT

    RCP< Xpetra::TpetraCrsGraph<LO, GO, Node, LocalMatOps> > tpCrsGraph = Teuchos::rcp_dynamic_cast<Xpetra::TpetraCrsGraph<LO, GO, Node, LocalMatOps> >(crsGraph);
    if(tpCrsGraph != Teuchos::null) {
#ifdef HAVE_ISORROPIA_TPETRA
      RCP< const Tpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> > tpetraCrsGraph = tpCrsGraph->getTpetra_CrsGraph();
      RCP<Isorropia::Tpetra::Partitioner<Node> > isoPart = rcp(new Isorropia::Tpetra::Partitioner<Node>(tpetraCrsGraph, paramlist));

      int size = 0;
      const int* array = NULL;
      isoPart->extractPartsView(size,array);

      TEUCHOS_TEST_FOR_EXCEPTION(size != Teuchos::as<int>(nodeMap->getNodeNumElements()), Exceptions::RuntimeError, "length of array returned from extractPartsView does not match local length of rowMap");

      RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(nodeMap, false);
      ArrayRCP<GO> decompEntries = decomposition->getDataNonConst(0);

      // fill vector with amalgamated information about partitioning
      // TODO: we assume simple block maps here
      // TODO: adapt this to usage of nodegid2dofgids
      for(int i = 0; i<size; i++) {
        decompEntries[i] = Teuchos::as<GO>(array[i]);
      }

      Set(level, "AmalgamatedPartition", decomposition);

#else
      TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "Tpetra is not enabled for Isorropia. Recompile Isorropia with Tpetra support.");
#endif // ENDIF HAVE_ISORROPIA_TPETRA
    }
#else
    TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "Isorropia is an interface to Zoltan which only has support for LO=GO=int and SC=double.");
#endif // ENDIF HAVE_MUELU_INST_DOUBLE_INT_INT
#endif // ENDIF HAVE_MUELU_TPETRA
#endif // HAVE_MUELU_ISORROPIA
#else  // if we don't have MPI


    // Running on one processor, so decomposition is the trivial one, all zeros.
    RCP<Xpetra::Vector<GO, LO, GO, NO> > decomposition = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(rowMap, true);
    Set(level, "AmalgamatedPartition", decomposition);

#endif // HAVE_MPI
    // throw a more helpful error message if something failed
    //TEUCHOS_TEST_FOR_EXCEPTION(!level.IsAvailable("AmalgamatedPartition"), Exceptions::RuntimeError, "IsorropiaInterface::Build : no \'Partition\' vector available on level. Isorropia failed to build a partition of the non-repartitioned graph of A. Please make sure, that Isorropia is correctly compiled (Epetra/Tpetra).");

  } //Build()
Beispiel #29
0
TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(gather_coordinates,integration,EvalType)
{
  PHX::KokkosDeviceSession session;

  // build global (or serial communicator)
  #ifdef HAVE_MPI
     Teuchos::RCP<Epetra_Comm> eComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
  #else
     Teuchos::RCP<Epetra_Comm> eComm = Teuchos::rcp(new Epetra_SerialComm());
  #endif
 
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::rcp_dynamic_cast;

  // panzer::pauseToAttach();

  // build a dummy workset
  //////////////////////////////////////////////////////////
  typedef Intrepid2::FieldContainer<double> FieldArray;
  int numCells = 2, numVerts = 4, dim = 2;
  Teuchos::RCP<panzer::Workset> workset = Teuchos::rcp(new panzer::Workset);

  // FieldArray & coords = workset->cell_vertex_coordinates;
  // coords.resize(numCells,numVerts,dim);

  MDFieldArrayFactory af("",true);
  workset->cell_vertex_coordinates = af.buildStaticArray<double,Cell,NODE,Dim>("coords",numCells,numVerts,dim);
  Workset::CellCoordArray coords = workset->cell_vertex_coordinates;
  coords(0,0,0) = 1.0; coords(0,0,1) = 0.0;
  coords(0,1,0) = 1.0; coords(0,1,1) = 1.0;
  coords(0,2,0) = 0.0; coords(0,2,1) = 1.0;
  coords(0,3,0) = 0.0; coords(0,3,1) = 0.0;

  coords(1,0,0) = 1.0; coords(1,0,1) = 1.0;
  coords(1,1,0) = 2.0; coords(1,1,1) = 2.0;
  coords(1,2,0) = 1.0; coords(1,2,1) = 3.0;
  coords(1,3,0) = 0.0; coords(1,3,1) = 2.0;

  // build topology, basis, integration rule, and basis layout
  int quadOrder = 5;
  Teuchos::RCP<shards::CellTopology> topo
    = Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >()));
  panzer::CellData cellData(2,1,topo);
  RCP<PureBasis> basis = rcp(new PureBasis("Q1",1,2,topo));
  Teuchos::RCP<panzer::IntegrationRule> quadRule = Teuchos::rcp(new panzer::IntegrationRule(quadOrder,cellData));
  RCP<BasisIRLayout> basisLayout = rcp(new BasisIRLayout(basis,*quadRule));

  RCP<IntegrationValues2<double> > quadValues = rcp(new IntegrationValues2<double>("",true));
  quadValues->setupArrays(quadRule);
  quadValues->evaluateValues(coords);

  RCP<BasisValues2<double> > basisValues = rcp(new BasisValues2<double>("",true));
  basisValues->setupArrays(basisLayout);
  basisValues->evaluateValues(quadValues->cub_points,
                              quadValues->jac,
                              quadValues->jac_det,
                              quadValues->jac_inv,
                              quadValues->weighted_measure,
                              coords);
                              // quadValues->node_coordinates);

  // setup generic workset stuff
  workset->cell_local_ids.push_back(0); workset->cell_local_ids.push_back(1);
  workset->num_cells = numCells;
  workset->block_id = "eblock-0_0";

  // setup integration rule
  workset->ir_degrees = Teuchos::rcp(new std::vector<int>);
  workset->ir_degrees->push_back(quadRule->cubature_degree);
  workset->int_rules.push_back(quadValues);

  // setup basis functions
  workset->basis_names = Teuchos::rcp(new std::vector<std::string>);
  workset->basis_names->push_back(basis->name());
  workset->bases.push_back(basisValues);

  Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm
     = Teuchos::rcp(new PHX::FieldManager<panzer::Traits>); 

  // typedef panzer::Traits::Residual EvalType;
  typedef Sacado::ScalarType<typename EvalType::ScalarT> ScalarType;
  typedef Sacado::ScalarValue<typename EvalType::ScalarT> ScalarValue;
  Teuchos::RCP<PHX::MDField<typename EvalType::ScalarT,panzer::Cell,panzer::Point,panzer::Dim> > fmCoordsPtr;
  Teuchos::RCP<PHX::DataLayout> dl_coords = quadRule->dl_vector;

  // add in some evaluators
  ///////////////////////////////////////////////////
  {
     RCP<panzer::GatherIntegrationCoordinates<EvalType,panzer::Traits> > eval 
        = rcp(new panzer::GatherIntegrationCoordinates<EvalType,panzer::Traits>(*quadRule));

     const std::vector<RCP<PHX::FieldTag> > & evalFields = eval->evaluatedFields();
     const std::vector<RCP<PHX::FieldTag> > & depFields = eval->dependentFields();

     TEST_EQUALITY(evalFields.size(),1);
     TEST_EQUALITY(depFields.size(), 0);
     std::string ref_fieldName = GatherIntegrationCoordinates<EvalType,panzer::Traits>::fieldName(quadRule->cubature_degree);
     TEST_EQUALITY(ref_fieldName,evalFields[0]->name());

     fm->registerEvaluator<EvalType>(eval);

     const PHX::FieldTag & ft = *evalFields[0];
     fm->requireField<EvalType>(ft);
     fmCoordsPtr = rcp(new
         PHX::MDField<typename EvalType::ScalarT,panzer::Cell,panzer::Point,panzer::Dim>(ft.name(),dl_coords));
  }

  PHX::MDField<typename EvalType::ScalarT,panzer::Cell,panzer::Point,panzer::Dim> & fmCoords = *fmCoordsPtr;

  panzer::Traits::SetupData setupData;
  setupData.worksets_ = rcp(new std::vector<panzer::Workset>);
  setupData.worksets_->push_back(*workset);
  std::vector<PHX::index_size_type> derivative_dimensions;
  derivative_dimensions.push_back(4);
  fm->setKokkosExtendedDataTypeDimensions<panzer::Traits::Jacobian>(derivative_dimensions);
#ifdef Panzer_BUILD_HESSIAN_SUPPORT
  fm->setKokkosExtendedDataTypeDimensions<panzer::Traits::Hessian>(derivative_dimensions);
#endif
  fm->postRegistrationSetup(setupData);

  panzer::Traits::PreEvalData preEvalData;

  fm->preEvaluate<EvalType>(preEvalData);
  fm->evaluateFields<EvalType>(*workset);
  fm->postEvaluate<EvalType>(0);

  fm->getFieldData<typename EvalType::ScalarT,EvalType>(fmCoords);

  fmCoords.print(out,true);

  for(int cell=0;cell<fmCoords.dimension_0();++cell)
    for(int pt=0;pt<fmCoords.dimension_1();++pt)
      for(int dim=0;dim<fmCoords.dimension_2();++dim)
	TEST_EQUALITY(ScalarValue::eval(fmCoords(cell,pt,dim)),quadValues->ip_coordinates(cell,pt,dim));
}
TEUCHOS_UNIT_TEST(tTpetra_GlbEvalData, blocked)
{
  using Teuchos::RCP;
  using Teuchos::rcp;

  typedef Thyra::SpmdVectorBase<double> Thyra_SpmdVec;

  typedef Tpetra::Map<int,panzer::Ordinal64> Tpetra_Map;
  typedef Tpetra::Import<int,panzer::Ordinal64> Tpetra_Import;


  Teuchos::RCP<Teuchos::MpiComm<int> > comm = Teuchos::rcp(new Teuchos::MpiComm<int>(MPI_COMM_WORLD));

  // This is required
  TEST_ASSERT(comm->getSize()==2);

  std::vector<Ordinal64> ghosted(5);
  std::vector<Ordinal64> owned(3);

  if(comm->getRank()==0) {
    owned[0] = 0;
    owned[1] = 1;
    owned[2] = 2;

    ghosted[0] = 0;
    ghosted[1] = 1;
    ghosted[2] = 2;
    ghosted[3] = 3;
    ghosted[4] = 4;
  }
  else {
    owned[0] = 3;
    owned[1] = 4;
    owned[2] = 5;

    ghosted[0] = 1;
    ghosted[1] = 2;
    ghosted[2] = 3;
    ghosted[3] = 4;
    ghosted[4] = 5;
  }

  RCP<const Tpetra_Map> ownedMap = rcp(new Tpetra_Map(-1,owned,0,comm));
  RCP<const Tpetra_Map> ghostedMap = rcp(new Tpetra_Map(-1,ghosted,0,comm));
  RCP<const Tpetra_Import> importer = rcp(new Tpetra_Import(ownedMap,ghostedMap));

  RCP<TpetraVector_ReadOnly_GlobalEvaluationData<double,int,Ordinal64> > ged_a, ged_b;
  ged_a = rcp(new TpetraVector_ReadOnly_GlobalEvaluationData<double,int,Ordinal64>(importer,ghostedMap,ownedMap));
  ged_b = rcp(new TpetraVector_ReadOnly_GlobalEvaluationData<double,int,Ordinal64>(importer,ghostedMap,ownedMap));
  std::vector<RCP<ReadOnlyVector_GlobalEvaluationData> > gedBlocks;
  gedBlocks.push_back(ged_a);
  gedBlocks.push_back(ged_b);

  RCP<const Thyra::VectorSpaceBase<double> > ownedSpace_ab = Thyra::tpetraVectorSpace<double,int,Ordinal64>(ownedMap);
  RCP<const Thyra::VectorSpaceBase<double> > ghostedSpace_ab = ged_a->getGhostedVector()->space();

  RCP<Thyra::DefaultProductVectorSpace<double> > ownedSpace = Thyra::productVectorSpace<double>(ownedSpace_ab,2);
  RCP<Thyra::DefaultProductVectorSpace<double> > ghostedSpace = Thyra::productVectorSpace<double>(ghostedSpace_ab,2);

  BlockedVector_ReadOnly_GlobalEvaluationData ged;
  ged.initialize(ghostedSpace,ownedSpace,gedBlocks);

  RCP<Thyra::VectorBase<double> > ownedVec = Thyra::createMember(*ownedSpace);

  {
    RCP<Thyra::ProductVectorBase<double> > vec = Thyra::castOrCreateNonconstProductVectorBase(ownedVec);

    TEST_ASSERT(vec->productSpace()->numBlocks()==2);

    if(comm->getRank()==0) {
      Teuchos::ArrayRCP<double> thyraVec;

      rcp_dynamic_cast<Thyra_SpmdVec>(vec->getNonconstVectorBlock(0))->getNonconstLocalData(Teuchos::ptrFromRef(thyraVec));
      thyraVec[0] = 3.14;
      thyraVec[1] = 1.82;
      thyraVec[2] = -.91;

      rcp_dynamic_cast<Thyra_SpmdVec>(vec->getNonconstVectorBlock(1))->getNonconstLocalData(Teuchos::ptrFromRef(thyraVec));
      thyraVec[0] = 3.14+9.0;
      thyraVec[1] = 1.82+9.0;
      thyraVec[2] = -.91+9.0;
    }
    else {
      Teuchos::ArrayRCP<double> thyraVec;

      rcp_dynamic_cast<Thyra_SpmdVec>(vec->getNonconstVectorBlock(0))->getNonconstLocalData(Teuchos::ptrFromRef(thyraVec));
      thyraVec[0] = 2.72;
      thyraVec[1] = 6.23;
      thyraVec[2] = -.17;

      rcp_dynamic_cast<Thyra_SpmdVec>(vec->getNonconstVectorBlock(1))->getNonconstLocalData(Teuchos::ptrFromRef(thyraVec));
      thyraVec[0] = 2.72+7.0;
      thyraVec[1] = 6.23+7.0;
      thyraVec[2] = -.17+7.0;
    }
  }

  ged.setOwnedVector(ownedVec);

  ged.initializeData();
  ged.globalToGhost(0);

  {
    RCP<Thyra::ProductVectorBase<double> > ghostedVec = Thyra::castOrCreateNonconstProductVectorBase(ged.getGhostedVector());

    if(comm->getRank()==0) {
      Teuchos::ArrayRCP<const double> thyraVec;
      rcp_dynamic_cast<const Thyra_SpmdVec>(ghostedVec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(thyraVec));

      TEST_EQUALITY(thyraVec[0],3.14);
      TEST_EQUALITY(thyraVec[1],1.82);
      TEST_EQUALITY(thyraVec[2],-.91);
      TEST_EQUALITY(thyraVec[3],2.72);
      TEST_EQUALITY(thyraVec[4],6.23);

      rcp_dynamic_cast<const Thyra_SpmdVec>(ghostedVec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(thyraVec));

      TEST_EQUALITY(thyraVec[0],3.14+9.0);
      TEST_EQUALITY(thyraVec[1],1.82+9.0);
      TEST_EQUALITY(thyraVec[2],-.91+9.0);
      TEST_EQUALITY(thyraVec[3],2.72+7.0);
      TEST_EQUALITY(thyraVec[4],6.23+7.0);
    }
    else {
      Teuchos::ArrayRCP<const double> thyraVec;
      rcp_dynamic_cast<const Thyra_SpmdVec>(ghostedVec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(thyraVec));

      TEST_EQUALITY(thyraVec[0],1.82);
      TEST_EQUALITY(thyraVec[1],-.91);
      TEST_EQUALITY(thyraVec[2],2.72);
      TEST_EQUALITY(thyraVec[3],6.23);
      TEST_EQUALITY(thyraVec[4],-.17);

      rcp_dynamic_cast<const Thyra_SpmdVec>(ghostedVec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(thyraVec));

      TEST_EQUALITY(thyraVec[0],1.82+9.0);
      TEST_EQUALITY(thyraVec[1],-.91+9.0);
      TEST_EQUALITY(thyraVec[2],2.72+7.0);
      TEST_EQUALITY(thyraVec[3],6.23+7.0);
      TEST_EQUALITY(thyraVec[4],-.17+7.0);
    }
  }
}