Exemplo n.º 1
0
int main(int narg, char **arg)
{
  Teuchos::GlobalMPISession session(&narg, &arg);
  Teuchos::RCP<const Teuchos::Comm<int> > tcomm = 
               Teuchos::DefaultComm<int>::getComm();
  Teuchos::RCP<const Epetra_Comm> ecomm = Xpetra::toEpetra(tcomm);

  const int nGlobRows = 50;
  const Epetra_Map emap(nGlobRows, 0, *ecomm);
  Teuchos::RCP<const Epetra_BlockMap> ebmap = Teuchos::rcpFromRef(emap);

  typedef Xpetra::EpetraMapT<int, Tpetra::Map<>::node_type> xemap_t;
  Teuchos::RCP<const xemap_t> xmap(new xemap_t(ebmap));
  
  const Teuchos::RCP<const Teuchos::Comm<int> > &xcomm = xmap->getComm();

  std::cout << "Teuchos:  Hello from " 
            << tcomm->getRank() << " of " 
            << tcomm->getSize() << std::endl;
  std::cout << "Epetra:   Hello from " 
            << ecomm->MyPID() << " of " 
            << ecomm->NumProc() << std::endl;
  std::cout << "Xpetra:   Hello from " 
            << xcomm->getRank() << " of " 
            << xcomm->getSize() << std::endl;
}
Exemplo n.º 2
0
void Iterative_Inverse_Operator::operator () (const Epetra_MultiVector &b, Epetra_MultiVector &x)
{
  // Initialize the solution to zero
  x.PutScalar( 0.0 );

  // Reset the solver, problem, and status test for next solve (HKT)
  pProb->setProblem( Teuchos::rcp(&x, false), Teuchos::rcp(&b, false) );

  timer.start();
  Belos::ReturnType ret = pBelos->solve();
  timer.stop();

  int pid = pComm->MyPID();

  if (pid == 0 && print) {
    if (ret == Belos::Converged)
    {
      std::cout << std::endl << "pid[" << pid << "] Block GMRES converged" << std::endl;
      std::cout << "Solution time: " << timer.totalElapsedTime() << std::endl;

    }
    else
      std::cout << std::endl << "pid[" << pid << "] Block GMRES did not converge" << std::endl;
  }
}
Exemplo n.º 3
0
Real random(const Teuchos::RCP<Epetra_Comm> &comm) {
  Real val = 0.0;
  if ( comm->MyPID()==0 ) {
    val = (Real)rand()/(Real)RAND_MAX;
  }
  comm->Broadcast(&val,1,0);
  return val;
}
Exemplo n.º 4
0
TEUCHOS_UNIT_TEST(tSGEpetraLinearObjFactory, basic)
{
   // 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;

   int myRank = eComm->MyPID();
   int numProc = eComm->NumProc();

   // panzer::pauseToAttach();

   RCP<Stokhos::OrthogPolyExpansion<int,double> > sgExpansion = buildExpansion(3,5);
   RCP<panzer::UniqueGlobalIndexer<int,int> > indexer 
         = rcp(new unit_test::UniqueGlobalIndexer<int>(myRank,numProc));
 
   // setup factory
   RCP<panzer::EpetraLinearObjFactory<panzer::Traits,int> > epetraFactory
         = rcp(new panzer::EpetraLinearObjFactory<panzer::Traits,int>(eComm.getConst(),indexer));
   RCP<panzer::SGEpetraLinearObjFactory<panzer::Traits,int> > la_factory
         = rcp(new panzer::SGEpetraLinearObjFactory<panzer::Traits,int>(epetraFactory,sgExpansion,Teuchos::null));
   
   RCP<panzer::LinearObjContainer> ghostedContainer = la_factory->buildGhostedLinearObjContainer(); 
   RCP<panzer::LinearObjContainer> container = la_factory->buildLinearObjContainer(); 

   TEST_NOTHROW(rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(ghostedContainer,true));
   TEST_NOTHROW(rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(container,true));

   RCP<panzer::SGEpetraLinearObjContainer> sgGhostedContainer 
         = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(ghostedContainer,true);
   RCP<panzer::SGEpetraLinearObjContainer> sgContainer 
         = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(container,true);

   // make sure we have correct number of sub containers
   TEST_EQUALITY(sgExpansion->size(),sgGhostedContainer->end()-sgGhostedContainer->begin());
   TEST_EQUALITY(sgExpansion->size(),sgContainer->end()-sgContainer->begin());

   // make sure all "sub-containers" are epetra containers
   panzer::SGEpetraLinearObjContainer::const_iterator itr;
   for(itr=sgGhostedContainer->begin();itr!=sgGhostedContainer->end();++itr)
      TEST_NOTHROW(rcp_dynamic_cast<EpetraLinearObjContainer>(*itr));
   for(itr=sgContainer->begin();itr!=sgContainer->end();++itr)
      TEST_NOTHROW(rcp_dynamic_cast<EpetraLinearObjContainer>(*itr));

   la_factory->ghostToGlobalContainer(*ghostedContainer,*container,0);
   la_factory->globalToGhostContainer(*container,*ghostedContainer,0);
}
Exemplo n.º 5
0
TEUCHOS_UNIT_TEST(tCloneLOF, blocked_epetra)
{

   // 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

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


   int myRank = eComm->MyPID();
   int numProc = eComm->NumProc();

   RCP<ConnManager<int,int> > connManager = rcp(new unit_test::ConnManager(myRank,numProc));

   RCP<const FieldPattern> patternC1
         = buildFieldPattern<Intrepid2::Basis_HGRAD_HEX_C1_FEM<double,FieldContainer> >();

   RCP<panzer::BlockedDOFManager<int,int> > indexer = rcp(new panzer::BlockedDOFManager<int,int>());
   indexer->setConnManager(connManager,MPI_COMM_WORLD);
   indexer->addField("U",patternC1);
   indexer->addField("V",patternC1);

   std::vector<std::vector<std::string> > fieldOrder(2);
   fieldOrder[0].push_back("U");
   fieldOrder[1].push_back("V");
   indexer->setFieldOrder(fieldOrder);
   indexer->buildGlobalUnknowns();

   RCP<panzer::BlockedDOFManager<int,int> > control_indexer = rcp(new panzer::BlockedDOFManager<int,int>());
   control_indexer->setConnManager(connManager,MPI_COMM_WORLD);
   control_indexer->addField("Z",patternC1);
   fieldOrder[0][0] = "Z";
   control_indexer->buildGlobalUnknowns();
 
   // setup factory
   RCP<BlockedEpetraLinearObjFactory<Traits,int> > ep_lof
         = Teuchos::rcp(new BlockedEpetraLinearObjFactory<Traits,int>(tComm,indexer));
   
   // this is the member we are testing!
   RCP<const LinearObjFactory<Traits> > control_lof = cloneWithNewDomain(*ep_lof,control_indexer);
   RCP<const BlockedEpetraLinearObjFactory<Traits,int> > ep_control_lof 
       = rcp_dynamic_cast<const BlockedEpetraLinearObjFactory<Traits,int> >(control_lof);

/*
   TEST_ASSERT(ep_control_lof->getMap()->SameAs(*ep_lof->getMap()));
   TEST_EQUALITY(ep_control_lof->getColMap()->NumMyElements(),Teuchos::as<int>(control_owned.size()));
*/
}
Exemplo n.º 6
0
void
Albany::IossSTKMeshStruct::readSerialMesh(const Teuchos::RCP<const Epetra_Comm>& comm,
                                          std::vector<std::string>& entity_rank_names){

#ifdef ALBANY_ZOLTAN // rebalance needs Zoltan

  MPI_Group group_world;
  MPI_Group peZero;
  MPI_Comm peZeroComm;

  // Read a single exodus mesh on Proc 0 then rebalance it across the machine

  MPI_Comm theComm = Albany::getMpiCommFromEpetraComm(*comm);

  int process_rank[1]; // the reader process

  process_rank[0] = 0;
  int my_rank = comm->MyPID();

  //get the group under theComm
  MPI_Comm_group(theComm, &group_world);
  // create the new group. This group includes only processor zero - that is the only processor that reads the file
  MPI_Group_incl(group_world, 1, process_rank, &peZero);
  // create the new communicator - it just contains processor zero
  MPI_Comm_create(theComm, peZero, &peZeroComm);

  // Note that peZeroComm == MPI_COMM_NULL on all processors but processor 0

  if(my_rank == 0){

    *out << "Albany_IOSS: Loading serial STKMesh from Exodus file  " 
         << params->get<std::string>("Exodus Input File Name") << std::endl;

  }

  /* 
   * This checks the existence of the file, checks to see if we can open it, builds a handle to the region
   * and puts it in mesh_data (in_region), and reads the metaData into metaData.
   */

  stk::io::create_input_mesh("exodusii",
//  create_input_mesh("exodusii",
                             params->get<std::string>("Exodus Input File Name"), 
                             peZeroComm, 
                             *metaData, *mesh_data,
                             entity_rank_names); 

  // Here, all PEs have read the metaData from the input file, and have a pointer to in_region in mesh_data

#endif

}
Exemplo n.º 7
0
Albany::AsciiSTKMesh2D::AsciiSTKMesh2D(
		const Teuchos::RCP<Teuchos::ParameterList>& params,
		const Teuchos::RCP<const Epetra_Comm>& comm) :
		GenericSTKMeshStruct(params, Teuchos::null, 2), out(
				Teuchos::VerboseObjectBase::getDefaultOStream()), periodic(false), sh(0) {
	std::string fname = params->get("Ascii Input Mesh File Name",
			"greenland.msh");

	std::string shape;
	if (comm->MyPID() == 0) {
		std::ifstream ifile;

		NumElemNodes = 0;
		ifile.open(fname.c_str());
		if (ifile.is_open()) {
		  ifile >> shape >> NumElemNodes;
		  if(shape == "Triangle") {
		    TEUCHOS_TEST_FOR_EXCEPTION(NumElemNodes != 3, Teuchos::Exceptions::InvalidParameter,
		              std::endl << "Error in AsciiSTKMesh2D: Triangles must be linear. Number of nodes per element in file " << fname << " is: " << NumElemNodes << ". Should be 3!" << std::endl);
		  }
		  else if(shape == "Quadrilateral") {
        TEUCHOS_TEST_FOR_EXCEPTION(NumElemNodes != 4, Teuchos::Exceptions::InvalidParameter,
                  std::endl << "Error in AsciiSTKMesh2D: Quadrilaterals must be bilinear. Number of nodes per element in file " << fname << " is: "  << " is: " << NumElemNodes << ". Should be 4!" << std::endl);
      }
		  else
		    TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
		                      std::endl << "Error in AsciiSTKMesh2D: Only Triangle or Quadrilateral grids can be imported. Shape in in file " << fname << " is: " << shape << ". Should be Triangle or Quadrialteral" << std::endl);


			ifile >> NumNodes >> NumEles >> NumBdEdges;
			//read in nodes coordinates
			xyz = new double[NumNodes][3];
			for (int i = 0; i < NumNodes; i++) {
				ifile >> xyz[i][0] >> xyz[i][1] >> xyz[i][2];
			}

			//read in element connectivity
			eles = new int[NumEles][4];
			int temp;

			if(shape == "Triangle")
        for (int i = 0; i < NumEles; i++) {
          ifile >> eles[i][0] >> eles[i][1] >> eles[i][2] >> temp;
			  }
			else
			  for (int i = 0; i < NumEles; i++) {
Exemplo n.º 8
0
Albany::AsciiSTKMesh2D::AsciiSTKMesh2D(
		const Teuchos::RCP<Teuchos::ParameterList>& params,
		const Teuchos::RCP<const Epetra_Comm>& comm) :
		GenericSTKMeshStruct(params, Teuchos::null, 2), out(
				Teuchos::VerboseObjectBase::getDefaultOStream()), periodic(false), sh(0) {
	std::string fname = params->get("Ascii Input Mesh File Name",
			"greenland.msh");

	if (comm->MyPID() == 0) {
		std::ifstream ifile;
		ifile.open(fname.c_str());
		if (ifile.is_open()) {
			ifile >> NumNodes >> NumEles >> NumBdEdges;
			//read in nodes coordinates
			xyz = new double[NumNodes][3];
			for (int i = 0; i < NumNodes; i++) {
				ifile >> xyz[i][0] >> xyz[i][1] >> xyz[i][2];
				*out << "i: " << i << ", x: " << xyz[i][0] << ", y: " << xyz[i][1]
						<< ", z: " << xyz[i][2] << std::endl;
			}
			//read in element connectivity
			eles = new int[NumEles][4];
			int temp;
			for (int i = 0; i < NumEles; i++) {
				ifile >> eles[i][0] >> eles[i][1] >> eles[i][2] >> temp;
				*out << "elm" << i << ": " << eles[i][0] << " " << eles[i][1] << " "
						<< eles[i][2] << std::endl;
			}
			//read in boundary edges connectivity
			be = new int[NumBdEdges][2];
			for (int i = 0; i < NumBdEdges; i++) {
				ifile >> be[i][0] >> be[i][1] >> temp;
				*out << "edge #:" << i << " " << be[i][0] << " " << be[i][1]
						<< std::endl;
			}
			ifile.close();
		} else {
Exemplo n.º 9
0
void
Albany::IossSTKMeshStruct::setFieldAndBulkData(
                                               const Teuchos::RCP<const Epetra_Comm>& comm,
                                               const Teuchos::RCP<Teuchos::ParameterList>& params,
                                               const unsigned int neq_,
                                               const AbstractFieldContainer::FieldContainerRequirements& req,
                                               const Teuchos::RCP<Albany::StateInfoStruct>& sis,
                                               const unsigned int worksetSize)
{
  this->SetupFieldData(comm, neq_, req, sis, worksetSize);

  *out << "IOSS-STK: number of node sets = " << nsPartVec.size() << std::endl;
  *out << "IOSS-STK: number of side sets = " << ssPartVec.size() << std::endl;

  metaData->commit();

  // Restart index to read solution from exodus file.
  int index = params->get("Restart Index",-1); // Default to no restart
  double res_time = params->get<double>("Restart Time",-1.0); // Default to no restart
  Ioss::Region *region = mesh_data->m_input_region;

  /*
   * The following code block reads a single mesh on PE 0, then distributes the mesh across
   * the other processors. stk_rebalance is used, which requires Zoltan
   *
   * This code is only compiled if ALBANY_MPI and ALBANY_ZOLTAN are true
   */

#ifdef ALBANY_ZOLTAN // rebalance needs Zoltan

  if(useSerialMesh){

    bulkData->modification_begin();

    if(comm->MyPID() == 0){ // read in the mesh on PE 0

      stk::io::process_mesh_bulk_data(region, *bulkData);

      // Read solution from exodus file.
      if (index >= 0) { // User has specified a time step to restart at
        *out << "Restart Index set, reading solution index : " << index << std::endl;
        stk::io::input_mesh_fields(region, *bulkData, index);
        m_restartDataTime = region->get_state_time(index);
        m_hasRestartSolution = true;
      }
      else if (res_time >= 0) { // User has specified a time to restart at
        *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
        stk::io::input_mesh_fields(region, *bulkData, res_time);
        m_restartDataTime = res_time;
        m_hasRestartSolution = true;
      }
      else {

        *out << "Neither restart index or time are set. Not reading solution data from exodus file"<< std::endl;

      }
    }

    bulkData->modification_end();

  } // End UseSerialMesh - reading mesh on PE 0

  else 
#endif

    /*
     * The following code block reads a single mesh when Albany is compiled serially, or a
     * Nemspread fileset if ALBANY_MPI is true.
     *
     */

  { // running in Serial or Parallel read from Nemspread files

    stk::io::populate_bulk_data(*bulkData, *mesh_data);

    if (!usePamgen)  {

      // Read solution from exodus file.
      if (index >= 0) { // User has specified a time step to restart at
        *out << "Restart Index set, reading solution index : " << index << std::endl;
        stk::io::process_input_request(*mesh_data, *bulkData, index);
        m_restartDataTime = region->get_state_time(index);
        m_hasRestartSolution = true;
      }
      else if (res_time >= 0) { // User has specified a time to restart at
        *out << "Restart solution time set, reading solution time : " << res_time << std::endl;
        stk::io::process_input_request(*mesh_data, *bulkData, res_time);
        m_restartDataTime = res_time;
        m_hasRestartSolution = true;
      }
      else {
        *out << "Restart Index not set. Not reading solution from exodus (" 
             << index << ")"<< std::endl;

      }
    }

    bulkData->modification_end();

  } // End Parallel Read - or running in serial

  if(m_hasRestartSolution){

    Teuchos::Array<std::string> default_field;
    default_field.push_back("solution");
    Teuchos::Array<std::string> restart_fields =
      params->get<Teuchos::Array<std::string> >("Restart Fields", default_field);

    // Get the fields to be used for restart

    // See what state data was initialized from the stk::io request
    // This should be propagated into stk::io
    const Ioss::ElementBlockContainer& elem_blocks = region->get_element_blocks();

    /*
    // Uncomment to print what fields are in the exodus file
    Ioss::NameList exo_fld_names;
    elem_blocks[0]->field_describe(&exo_fld_names);
    for(std::size_t i = 0; i < exo_fld_names.size(); i++){
    *out << "Found field \"" << exo_fld_names[i] << "\" in exodus file" << std::endl;
    }
    */

    for (std::size_t i=0; i<sis->size(); i++) {
      Albany::StateStruct& st = *((*sis)[i]);

      if(elem_blocks[0]->field_exists(st.name))

        for(std::size_t j = 0; j < restart_fields.size(); j++)

          if(boost::iequals(st.name, restart_fields[j])){

            *out << "Restarting from field \"" << st.name << "\" found in exodus file." << std::endl;
            st.restartDataAvailable = true;
            break;

          }
    }
  }

//  coordinates_field = metaData->get_field<VectorFieldType>(std::string("coordinates"));
//#ifdef ALBANY_FELIX
//  surfaceHeight_field = metaData->get_field<ScalarFieldType>(std::string("surface height"));
//#endif

  // Refine the mesh before starting the simulation if indicated
  uniformRefineMesh(comm);

  // Rebalance the mesh before starting the simulation if indicated
  rebalanceInitialMesh(comm);

  // Build additional mesh connectivity needed for mesh fracture (if indicated)
  computeAddlConnectivity();

}
Exemplo n.º 10
0
Albany::AsciiSTKMeshStruct::AsciiSTKMeshStruct(
                                             const Teuchos::RCP<Teuchos::ParameterList>& params, 
                                             const Teuchos::RCP<const Epetra_Comm>& comm) :
  GenericSTKMeshStruct(params,Teuchos::null,3),
  out(Teuchos::VerboseObjectBase::getDefaultOStream()),
  periodic(false)
{
   int numProc = comm->NumProc(); //total number of processors
   contigIDs = params->get("Contiguous IDs", true); 
   std::cout << "Number of processors: " << numProc << std::endl; 
   //names of files giving the mesh
   char meshfilename[100]; 
   char shfilename[100];
   char confilename[100];
   char bffilename[100];
   char geIDsfilename[100];
   char gnIDsfilename[100];
   char bfIDsfilename[100];
   char flwafilename[100]; //flow factor file
   char tempfilename[100]; //temperature file
   char betafilename[100]; //basal friction coefficient file
   if ((numProc == 1) & (contigIDs == true)) { //serial run with contiguous global IDs
     std::cout << "Ascii mesh has contiguous IDs; no bfIDs, geIDs, gnIDs files required." << std::endl;
     sprintf(meshfilename, "%s", "xyz");
     sprintf(shfilename, "%s", "sh");
     sprintf(confilename, "%s", "eles");
     sprintf(bffilename, "%s", "bf");
     sprintf(flwafilename, "%s", "flwa");
     sprintf(tempfilename, "%s", "temp");
     sprintf(betafilename, "%s", "beta");
   }
   else { //parallel run or serial run with non-contiguous global IDs - proc # is appended to file name to indicate what processor the mesh piece is on 
     if ((numProc == 1) & (contigIDs == false))
        std::cout << "1 processor run with non-contiguous IDs; bfIDs0, geIDs0, gnIDs0 files required." << std::endl;
     int suffix = comm->MyPID(); //current processor number 
     sprintf(meshfilename, "%s%i", "xyz", suffix);
     sprintf(shfilename, "%s%i", "sh", suffix);
     sprintf(confilename, "%s%i", "eles", suffix);
     sprintf(bffilename, "%s%i", "bf", suffix);
     sprintf(geIDsfilename, "%s%i", "geIDs", suffix);
     sprintf(gnIDsfilename, "%s%i", "gnIDs", suffix);
     sprintf(bfIDsfilename, "%s%i", "bfIDs", suffix);
     sprintf(flwafilename, "%s%i", "flwa", suffix);
     sprintf(tempfilename, "%s%i", "temp", suffix);
     sprintf(betafilename, "%s%i", "beta", suffix);
   }

    //read in coordinates of mesh -- right now hard coded for 3D
    //assumes mesh file is called "xyz" and its first row is the number of nodes  
    FILE *meshfile = fopen(meshfilename,"r");
    if (meshfile == NULL) { //check if coordinates file exists
      *out << "Error in AsciiSTKMeshStruct: coordinates file " << meshfilename <<" not found!"<< std::endl;
      TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
          std::endl << "Error in AsciiSTKMeshStruct: coordinates file " << meshfilename << " not found!"<< std::endl);
    }
    double temp; 
    fseek(meshfile, 0, SEEK_SET); 
    fscanf(meshfile, "%lf", &temp); 
    NumNodes = int(temp); 
    std::cout << "numNodes: " << NumNodes << std::endl;  
    xyz = new double[NumNodes][3]; 
    char buffer[100];
    fgets(buffer, 100, meshfile); 
    for (int i=0; i<NumNodes; i++){
      fgets(buffer, 100, meshfile); 
      sscanf(buffer, "%lf %lf %lf", &xyz[i][0], &xyz[i][1], &xyz[i][2]); 
      //*out << "i: " << i << ", x: " << xyz[i][0] << ", y: " << xyz[i][1] << ", z: " << xyz[i][2] << std::endl; 
     }
    //read in surface height data from mesh 
    //assumes surface height file is called "sh" and its first row is the number of nodes  
    FILE *shfile = fopen(shfilename,"r");
    have_sh = false;
    if (shfile != NULL) have_sh = true;
    if (have_sh) {
      fseek(shfile, 0, SEEK_SET); 
      fscanf(shfile, "%lf", &temp); 
      int NumNodesSh = int(temp);
      std::cout << "NumNodesSh: " << NumNodesSh<< std::endl; 
      if (NumNodesSh != NumNodes) { 
           *out << "Error in AsciiSTKMeshStruct: sh file must have same number nodes as xyz file!  numNodes in xyz = " << NumNodes <<", numNodes in sh = "<< NumNodesSh  << std::endl;
          TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
            std::endl << "Error in AsciiSTKMeshStruct: sh file must have same number nodes as xyz file!  numNodes in xyz = " << NumNodes << ", numNodes in sh = "<< NumNodesSh << std::endl);
      }
      sh = new double[NumNodes]; 
      fgets(buffer, 100, shfile); 
      for (int i=0; i<NumNodes; i++){
        fgets(buffer, 100, shfile); 
        sscanf(buffer, "%lf", &sh[i]); 
        //*out << "i: " << i << ", sh: " << sh[i] << std::endl; 
       }
     }
     //read in connectivity file -- right now hard coded for 3D hexes
     //assumes mesh file is called "eles" and its first row is the number of elements  
     FILE *confile = fopen(confilename,"r"); 
     if (confile == NULL) { //check if element connectivity file exists
      *out << "Error in AsciiSTKMeshStruct: element connectivity file " << confilename <<" not found!"<< std::endl;
      TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
          std::endl << "Error in AsciiSTKMeshStruct: element connectivity file " << confilename << " not found!"<< std::endl);
     }
     fseek(confile, 0, SEEK_SET); 
     fscanf(confile, "%lf", &temp); 
     NumEles = int(temp); 
     std::cout << "numEles: " << NumEles << std::endl; 
     eles = new int[NumEles][8]; 
     fgets(buffer, 100, confile); 
     for (int i=0; i<NumEles; i++){
        fgets(buffer, 100, confile); 
        sscanf(buffer, "%i %i %i %i %i %i %i %i", &eles[i][0], &eles[i][1], &eles[i][2], &eles[i][3], &eles[i][4], &eles[i][5], &eles[i][6], &eles[i][7]);
        //*out << "elt # " << i << ": " << eles[i][0] << " " << eles[i][1] << " " << eles[i][2] << " " << eles[i][3] << " " << eles[i][4] << " "
        //                  << eles[i][5] << " " << eles[i][6] << " " << eles[i][7] << std::endl; 
     }
    //read in basal face connectivity file from ascii file
    //assumes basal face connectivity file is called "bf" and its first row is the number of faces on basal boundary
    FILE *bffile = fopen(bffilename,"r");
    have_bf = false;
    if (bffile != NULL) have_bf = true;
    if (have_bf) {
      fseek(bffile, 0, SEEK_SET); 
      fscanf(bffile, "%lf", &temp); 
      NumBasalFaces = int(temp); 
      std::cout << "numBasalFaces: " << NumBasalFaces << std::endl;  
      bf = new int[NumBasalFaces][5]; //1st column of bf: element # that face belongs to, 2rd-5th columns of bf: connectivity (hard-coded for quad faces) 
      fgets(buffer, 100, bffile); 
      for (int i=0; i<NumBasalFaces; i++){
        fgets(buffer, 100, bffile); 
        sscanf(buffer, "%i %i %i %i %i", &bf[i][0], &bf[i][1], &bf[i][2], &bf[i][3], &bf[i][4]); 
        //*out << "face #:" << bf[i][0] << ", face conn:" << bf[i][1] << " " << bf[i][2] << " " << bf[i][3] << " " << bf[i][4] << std::endl; 
       }
     }
     //Create array w/ global element IDs 
     globalElesID = new int[NumEles];
     if ((numProc == 1) & (contigIDs == true)) { //serial run with contiguous global IDs: element IDs are just 0->NumEles-1
       for (int i=0; i<NumEles; i++) {
          globalElesID[i] = i; 
          //*out << "local element ID #:" << i << ", global element ID #:" << globalElesID[i] << std::endl;
       }
     }
     else {//parallel run: read global element IDs from file.  
           //This file should have a header like the other files, and length NumEles.
       FILE *geIDsfile = fopen(geIDsfilename,"r");
       if (geIDsfile == NULL) { //check if global element IDs file exists
         *out << "Error in AsciiSTKMeshStruct: global element IDs file " << geIDsfilename <<" not found!"<< std::endl;
         TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
            std::endl << "Error in AsciiSTKMeshStruct: global element IDs file " << geIDsfilename << " not found!"<< std::endl);
       }
       fseek(geIDsfile, 0, SEEK_SET);
       fgets(buffer, 100, geIDsfile);
       for (int i=0; i<NumEles; i++){
         fgets(buffer, 100, geIDsfile);
         sscanf(buffer, "%i ", &globalElesID[i]);
         globalElesID[i] = globalElesID[i]-1; //subtract 1 b/c global element IDs file assumed to be 1-based not 0-based
         //*out << "local element ID #:" << i << ", global element ID #:" << globalElesID[i] << std::endl;
       }
     }
     //Create array w/ global node IDs 
     globalNodesID = new int[NumNodes];
     if ((numProc == 1) & (contigIDs == true)) { //serial run with contiguous global IDs: element IDs are just 0->NumEles-1
       for (int i=0; i<NumNodes; i++) { 
          globalNodesID[i] = i; 
          //*out << "local node ID #:" << i << ", global node ID #:" << globalNodesID[i] << std::endl;
       }
     }
     else {//parallel run: read global node IDs from file.  
           //This file should have a header like the other files, and length NumNodes
       FILE *gnIDsfile = fopen(gnIDsfilename,"r");
       if (gnIDsfile == NULL) { //check if global node IDs file exists
         *out << "Error in AsciiSTKMeshStruct: global node IDs file " << gnIDsfilename <<" not found!"<< std::endl;
         TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
            std::endl << "Error in AsciiSTKMeshStruct: global node IDs file " << gnIDsfilename << " not found!"<< std::endl);
       }
       fseek(gnIDsfile, 0, SEEK_SET);
       fgets(buffer, 100, gnIDsfile);
       for (int i=0; i<NumNodes; i++){
         fgets(buffer, 100, gnIDsfile);
         sscanf(buffer, "%i ", &globalNodesID[i]);
         globalNodesID[i] = globalNodesID[i]-1; //subtract 1 b/c global node IDs file assumed to be 1-based not 0-based 
         //*out << "local node ID #:" << i << ", global node ID #:" << globalNodesID[i] << std::endl;
       }
     }
     basalFacesID = new int[NumBasalFaces];
     if ((numProc == 1) & (contigIDs == true)) { //serial run with contiguous global IDs: element IDs are just 0->NumEles-1
       for (int i=0; i<NumBasalFaces; i++) { 
          basalFacesID[i] = i; 
          //*out << "local face ID #:" << i << ", global face ID #:" << basalFacesID[i] << std::endl;
       }
     }
     else {//parallel run: read basal face IDs from file.  
           //This file should have a header like the other files, and length NumBasalFaces
       FILE *bfIDsfile = fopen(bfIDsfilename,"r");
       fseek(bfIDsfile, 0, SEEK_SET);
       fgets(buffer, 100, bfIDsfile);
       for (int i=0; i<NumBasalFaces; i++){
         fgets(buffer, 100, bfIDsfile);
         sscanf(buffer, "%i ", &basalFacesID[i]);
         basalFacesID[i] = basalFacesID[i]-1; //subtract 1 b/c basal face IDs file assumed to be 1-based not 0-based
         //*out << "local face ID #:" << i << ", global face ID #:" << basalFacesID[i] << std::endl;
       }
     }
    //read in flow factor (flwa) data from mesh 
    //assumes flow factor file is called "flwa" and its first row is the number of elements in the mesh
    FILE *flwafile = fopen(flwafilename,"r");
    have_flwa = false;
    if (flwafile != NULL) have_flwa = true;
    if (have_flwa) {
      fseek(flwafile, 0, SEEK_SET); 
      fscanf(flwafile, "%lf", &temp); 
      flwa = new double[NumEles]; 
      fgets(buffer, 100, flwafile); 
      for (int i=0; i<NumEles; i++){
        fgets(buffer, 100, flwafile); 
        sscanf(buffer, "%lf", &flwa[i]); 
        //*out << "i: " << i << ", flwa: " << flwa[i] << std::endl; 
       }
     }
    //read in temperature data from mesh 
    //assumes temperature file is called "temp" and its first row is the number of elements in the mesh
    FILE *tempfile = fopen(tempfilename,"r");
    have_temp = false;
    if (tempfile != NULL) have_temp = true;
    if (have_temp) {
      fseek(tempfile, 0, SEEK_SET); 
      fscanf(tempfile, "%lf", &temp); 
      temper = new double[NumEles]; 
      fgets(buffer, 100, tempfile); 
      for (int i=0; i<NumEles; i++){
        fgets(buffer, 100, tempfile); 
        sscanf(buffer, "%lf", &temper[i]); 
        //*out << "i: " << i << ", temp: " << temper[i] << std::endl; 
       }
     }
    //read in basal friction (beta) data from mesh 
    //assumes basal friction file is called "beta" and its first row is the number of nodes  
    FILE *betafile = fopen(betafilename,"r");
    have_beta = false;
    if (betafile != NULL) have_beta = true;
    if (have_beta) {
      fseek(betafile, 0, SEEK_SET); 
      fscanf(betafile, "%lf", &temp); 
      beta = new double[NumNodes]; 
      fgets(buffer, 100, betafile); 
      for (int i=0; i<NumNodes; i++){
        fgets(buffer, 100, betafile); 
        sscanf(buffer, "%lf", &beta[i]); 
        //*out << "i: " << i << ", beta: " << beta[i] << std::endl; 
       }
     }
 
  elem_map = Teuchos::rcp(new Epetra_Map(-1, NumEles, globalElesID, 0, *comm)); //Distribute the elements according to the global element IDs
  node_map = Teuchos::rcp(new Epetra_Map(-1, NumNodes, globalNodesID, 0, *comm)); //Distribute the nodes according to the global node IDs 
  basal_face_map = Teuchos::rcp(new Epetra_Map(-1, NumBasalFaces, basalFacesID, 0, *comm)); //Distribute the elements according to the basal face IDs

  
  params->validateParameters(*getValidDiscretizationParameters(),0);


  std::string ebn="Element Block 0";
  partVec[0] = & metaData->declare_part(ebn, metaData->element_rank() );
  ebNameToIndex[ebn] = 0;

#ifdef ALBANY_SEACAS
  stk::io::put_io_part_attribute(*partVec[0]);
#endif


  std::vector<std::string> nsNames;
  std::string nsn="Bottom";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet0";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet1";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet2";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet3";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet4";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif
  nsn="NodeSet5";
  nsNames.push_back(nsn);
  nsPartVec[nsn] = & metaData->declare_part(nsn, metaData->node_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*nsPartVec[nsn]);
#endif


  std::vector<std::string> ssNames;
  std::string ssn="Basal";
  ssNames.push_back(ssn);
    ssPartVec[ssn] = & metaData->declare_part(ssn, metaData->side_rank() );
#ifdef ALBANY_SEACAS
    stk::io::put_io_part_attribute(*ssPartVec[ssn]);
#endif

  stk::mesh::fem::set_cell_topology<shards::Hexahedron<8> >(*partVec[0]);
  stk::mesh::fem::set_cell_topology<shards::Quadrilateral<4> >(*ssPartVec[ssn]);

  numDim = 3;
  int cub = params->get("Cubature Degree",3);
  int worksetSizeMax = params->get("Workset Size",50);
  int worksetSize = this->computeWorksetSize(worksetSizeMax, elem_map->NumMyElements());

  const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData();

  this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub,
                             nsNames, ssNames, worksetSize, partVec[0]->name(),
                             ebNameToIndex, this->interleavedOrdering));


}
Exemplo n.º 11
0
void
createEpetraProblem (const Teuchos::RCP<const Epetra_Comm>& epetraComm,
		     const std::string& filename,
		     Teuchos::RCP<Epetra_Map>& rowMap,
		     Teuchos::RCP<Epetra_CrsMatrix>& A,
		     Teuchos::RCP<Epetra_MultiVector>& B,
		     Teuchos::RCP<Epetra_MultiVector>& X,
		     int& numRHS)
{
  using Teuchos::inOutArg;
  using Teuchos::ptr;
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::set_extra_data;

  const int MyPID = epetraComm->MyPID();

  int n_nonzeros, N_update;
  int *bindx = NULL, *update = NULL, *col_inds = NULL;
  double *val = NULL, *row_vals = NULL;
  double *xguess = NULL, *b = NULL, *xexact = NULL;

  //
  // Set up the problem to be solved
  //
  int NumGlobalElements;  // total # of rows in matrix

  try {
    // Read in matrix from HB file
    Trilinos_Util_read_hb (const_cast<char *> (filename.c_str()), MyPID, 
			   &NumGlobalElements, &n_nonzeros, &val, &bindx, 
			   &xguess, &b, &xexact);

    // Distribute data among processors
    Trilinos_Util_distrib_msr_matrix (*epetraComm, &NumGlobalElements, 
				      &n_nonzeros, &N_update, &update, &val, 
				      &bindx, &xguess, &b, &xexact);
    //
    // Construct the matrix
    //
    int NumMyElements = N_update; // # local rows of matrix on processor
    //
    // Create an int array NumNz that is used to build the Petra Matrix.
    // NumNz[i] is the number of OFF-DIAGONAL terms for the i-th global
    // equation on this processor.
    //
    std::vector<int> NumNz (NumMyElements);
    for (int i = 0; i < NumMyElements; ++i) {
      NumNz[i] = bindx[i+1] - bindx[i] + 1;
    }
    rowMap = rcp (new Epetra_Map (NumGlobalElements, NumMyElements, 
				  update, 0, *epetraComm));
    //set_extra_data (epetraComm, "Map::Comm", inOutArg (rowMap));

    // Create an Epetra sparse matrix.
    if (NumMyElements == 0) {
      A = rcp (new Epetra_CrsMatrix (Copy, *rowMap, static_cast<int*>(NULL)));
    } else {
      A = rcp (new Epetra_CrsMatrix (Copy, *rowMap, &NumNz[0]));
    }
    //set_extra_data (rowMap, "Operator::Map", ptr (A));

    // Add rows to the sparse matrix one at a time.
    int NumEntries;
    for (int i = 0; i < NumMyElements; ++i) {
      row_vals = val + bindx[i];
      col_inds = bindx + bindx[i];
      NumEntries = bindx[i+1] - bindx[i];
      int info = A->InsertGlobalValues (update[i], NumEntries, row_vals, col_inds);
      TEUCHOS_TEST_FOR_EXCEPTION( info != 0, std::logic_error,
				  "Failed to insert global value into A." );
      info = A->InsertGlobalValues (update[i], 1, val+i, update+i);
      TEUCHOS_TEST_FOR_EXCEPTION( info != 0, std::logic_error,
				  "Failed to insert global value into A." );
    }
    // Finish initializing the sparse matrix.
    int info = A->FillComplete();
    TEUCHOS_TEST_FOR_EXCEPTION( info != 0, std::logic_error,
				"FillComplete() failed on the sparse matrix A.");
    info = A->OptimizeStorage();
    TEUCHOS_TEST_FOR_EXCEPTION( info != 0, std::logic_error,
				"OptimizeStorage() failed on the sparse matrix A.");
    A->SetTracebackMode (1); // Shut down Epetra warning tracebacks
    //
    // Construct the right-hand side and solution multivectors.
    //
    if (false && b != NULL) {
      B = rcp (new Epetra_MultiVector (::Copy, *rowMap, b, NumMyElements, 1));
      numRHS = 1;
    } else {
      B = rcp (new Epetra_MultiVector (*rowMap, numRHS));
      B->Random ();
    }
    X = rcp (new Epetra_MultiVector (*rowMap, numRHS));
    X->PutScalar (0.0);

    //set_extra_data (rowMap, "X::Map", Teuchos::ptr (X));
    //set_extra_data (rowMap, "B::Map", Teuchos::ptr (B));
  } 
  catch (std::exception& e) {
    // Free up memory before rethrowing the exception.
    if (update) free(update);
    if (val) free(val);
    if (bindx) free(bindx);
    if (xexact) free(xexact);
    if (xguess) free(xguess);
    if (b) free(b);
    throw e; // Rethrow the exception.
  } 
  catch (...) { // Epetra sometimes throws an int "object."
    // Free up memory before rethrowing the exception.
    if (update) free(update);
    if (val) free(val);
    if (bindx) free(bindx);
    if (xexact) free(xexact);
    if (xguess) free(xguess);
    if (b) free(b);
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, 
			       "Generating the Epetra problem to solve failed "
			       "with an unknown error.");
  }

  //if (false) {
    //
    // Create workspace
    //
    //Teuchos::set_default_workspace_store (rcp (new Teuchos::WorkspaceStoreInitializeable(static_cast<size_t>(2e+6))));
  //}

  //
  // Free up memory.
  //
  if (update) free(update);
  if (val) free(val);
  if (bindx) free(bindx);
  if (xexact) free(xexact);
  if (xguess) free(xguess);
  if (b) free(b);
}
Exemplo n.º 12
0
int main(int argc, char *argv[]) {

  int status=0; // 0 = pass, failures are incremented
  bool success = true;
  Teuchos::GlobalMPISession mpiSession(&argc,&argv);

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

  RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream());
  
  //***********************************************************
  // Command-line argument for input file
  //***********************************************************

  Albany::CmdLineArgs cmd;
  cmd.parse_cmdline(argc, argv, *out);
  std::string xmlfilename_coupled = cmd.xml_filename;


  try {

    RCP<Teuchos::Time> totalTime = 
      Teuchos::TimeMonitor::getNewTimer("AlbanySG: ***Total Time***");
    RCP<Teuchos::Time> setupTime = 
      Teuchos::TimeMonitor::getNewTimer("AlbanySG: Setup Time");
    Teuchos::TimeMonitor totalTimer(*totalTime); //start timer

    //***********************************************************
    // Set up coupled solver first to setup comm's
    //***********************************************************
    Teuchos::RCP<Epetra_Comm> globalComm = 
      Albany::createEpetraCommFromMpiComm(Albany_MPI_COMM_WORLD);
    // Connect vtune for performance profiling
    if (cmd.vtune) {
      Albany::connect_vtune(globalComm->MyPID());
    }
    Albany::SolverFactory coupled_slvrfctry(xmlfilename_coupled, 
					    Albany::createTeuchosCommFromEpetraComm(globalComm));
    Teuchos::ParameterList& coupledParams = coupled_slvrfctry.getParameters();
    Teuchos::ParameterList& coupledSystemParams = 
      coupledParams.sublist("Coupled System");
    Teuchos::Array<std::string> model_filenames =
      coupledSystemParams.get<Teuchos::Array<std::string> >("Model XML Files");
    int num_models = model_filenames.size();
    Teuchos::Array< RCP<Albany::Application> > apps(num_models);
    Teuchos::Array< RCP<EpetraExt::ModelEvaluator> > models(num_models);
    Teuchos::Array< RCP<Teuchos::ParameterList> > piroParams(num_models);
    Teuchos::RCP< Teuchos::ParameterList> coupledPiroParams = 
      Teuchos::rcp(&(coupledParams.sublist("Piro")),false);
    Teuchos::RCP<Piro::Epetra::StokhosSolver> coupledSolver =
      Teuchos::rcp(new Piro::Epetra::StokhosSolver(coupledPiroParams, 
						   globalComm));
    Teuchos::RCP<const Epetra_Comm> app_comm = coupledSolver->getSpatialComm();

    // Set up each model
    Teuchos::Array< Teuchos::RCP<NOX::Epetra::Observer> > observers(num_models);
    for (int m=0; m<num_models; m++) {
      Albany::SolverFactory slvrfctry(
	model_filenames[m], 
	Albany::createTeuchosCommFromEpetraComm(app_comm));
      models[m] = slvrfctry.createAlbanyAppAndModel(apps[m], app_comm);
      Teuchos::ParameterList& appParams = slvrfctry.getParameters();
      piroParams[m] = Teuchos::rcp(&(appParams.sublist("Piro")),false);
      observers[m] = Teuchos::rcp(new Albany_NOXObserver(apps[m]));
    }

    // Setup network model
    std::string network_name = 
      coupledSystemParams.get("Network Model", "Param To Response");
    RCP<Piro::Epetra::AbstractNetworkModel> network_model;
    if (network_name == "Param To Response")
      network_model = rcp(new Piro::Epetra::ParamToResponseNetworkModel);
    else if (network_name == "Reactor Network")
      network_model = rcp(new Albany::ReactorNetworkModel(1));
    else
      TEUCHOS_TEST_FOR_EXCEPTION(
	true, std::logic_error, "Invalid network model name " << network_name);
    RCP<EpetraExt::ModelEvaluator> coupledModel =
      rcp(new Piro::Epetra::NECoupledModelEvaluator(models, piroParams,
						    network_model,
						    coupledPiroParams, 
						    globalComm,
						    observers));
    coupledSolver->setup(coupledModel);

    // Solve coupled system
    EpetraExt::ModelEvaluator::InArgs inArgs = coupledSolver->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs outArgs = coupledSolver->createOutArgs();
    for (int i=0; i<inArgs.Np(); i++)
      if (inArgs.supports(EpetraExt::ModelEvaluator::IN_ARG_p_sg, i))
	inArgs.set_p_sg(i, coupledSolver->get_p_sg_init(i));
    for (int i=0; i<outArgs.Ng(); i++) 
      if (outArgs.supports(EpetraExt::ModelEvaluator::OUT_ARG_g_sg, i)) {
	RCP<Stokhos::EpetraVectorOrthogPoly> g_sg = 
	  coupledSolver->create_g_sg(i);
	outArgs.set_g_sg(i, g_sg);
      }
    coupledSolver->evalModel(inArgs, outArgs);

    // Print results
    bool printResponse = 
      coupledSystemParams.get("Print Response Expansion", true);
    int idx = outArgs.Ng()-1;
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> g_sg = 
      outArgs.get_g_sg(idx);
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      coupledSolver->get_sg_model();
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> g_sg_local = 
      //sg_model->import_solution_poly(*(g_sg->getBlockVector()));
      g_sg;
    Epetra_Vector g_mean(*(g_sg->coefficientMap()));
    Epetra_Vector g_std_dev(*(g_sg->coefficientMap()));
    g_sg->computeMean(g_mean);
    g_sg->computeStandardDeviation(g_std_dev);
    RCP<Epetra_Vector> g_mean_local = rcp(&g_mean,false);
    RCP<Epetra_Vector> g_std_dev_local = rcp(&g_std_dev,false);
    if (g_mean.Map().DistributedGlobal()) {
      Epetra_LocalMap local_map(g_mean.GlobalLength(), 0, 
				g_mean.Map().Comm());
      g_mean_local = rcp(new Epetra_Vector(local_map));
      g_std_dev_local = rcp(new Epetra_Vector(local_map));
      Epetra_Import importer(local_map, g_mean.Map());
      g_mean_local->Import(g_mean, importer, Insert);
      g_std_dev_local->Import(g_std_dev, importer, Insert);
    }
    out->precision(16);
    *out << std::endl
	 << "Final value of coupling variables:" << std::endl
	 << "Mean:" << std::endl << *g_mean_local << std::endl
	 << "Std. Dev.:" << std::endl << *g_std_dev_local << std::endl;
    if (printResponse)
      *out << "PCE:" << std::endl << *g_sg_local << std::endl;

    status += coupled_slvrfctry.checkSGTestResults(
        0,
        g_sg_local,
        g_mean_local.get(),
        g_std_dev_local.get());
    *out << "\nNumber of Failed Comparisons: " << status << std::endl;
  }

  TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success);
  if (!success) status+=10000;

  Teuchos::TimeMonitor::summarize(*out,false,true,false/*zero timers*/);
  return status;
}
Exemplo n.º 13
0
void
Albany::MpasSTKMeshStruct::constructMesh(
                                               const Teuchos::RCP<const Epetra_Comm>& comm,
                                               const Teuchos::RCP<Teuchos::ParameterList>& params,
                                               const unsigned int neq_,
                                               const Albany::AbstractFieldContainer::FieldContainerRequirements& req,
                                               const Teuchos::RCP<Albany::StateInfoStruct>& sis,
                                               const std::vector<int>& indexToVertexID, const std::vector<double>& verticesCoords, const std::vector<bool>& isVertexBoundary, int nGlobalVertices,
                                               const std::vector<int>& verticesOnTria,
                                               const std::vector<bool>& isBoundaryEdge, const std::vector<int>& trianglesOnEdge, const std::vector<int>& trianglesPositionsOnEdge,
                                               const std::vector<int>& verticesOnEdge,
                                               const std::vector<int>& indexToEdgeID, int nGlobalEdges,
                                               const unsigned int worksetSize)
{
  this->SetupFieldData(comm, neq_, req, sis, worksetSize);

  metaData->commit();

  bulkData->modification_begin(); // Begin modifying the mesh

  stk::mesh::PartVector nodePartVec;
  stk::mesh::PartVector singlePartVec(1);
  stk::mesh::PartVector emptyPartVec;
  std::cout << "elem_map # elments: " << elem_map->NumMyElements() << std::endl;
  unsigned int ebNo = 0; //element block #??? 
  int sideID = 0;

  AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field = fieldContainer->getProcRankField();
  AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();

  for (int i=0; i<indexToVertexID.size(); i++)
  {
	  stk::mesh::Entity node = bulkData->declare_entity(stk::topology::NODE_RANK, indexToVertexID[i]+1, nodePartVec);

	  double* coord;
	  coord = stk::mesh::field_data(*coordinates_field, node);
	  coord[0] = verticesCoords[3*i];   coord[1] = verticesCoords[3*i+1]; coord[2] = verticesCoords[3*i+2];
  }

  for (int i=0; i<elem_map->NumMyElements(); i++)
  {

     singlePartVec[0] = partVec[ebNo];
     stk::mesh::Entity elem  = bulkData->declare_entity(stk::topology::ELEMENT_RANK, elem_map->GID(i)+1, singlePartVec);

     for(int j=0; j<3; j++)
     {
    	 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, indexToVertexID[verticesOnTria[3*i+j]]+1);
    	 bulkData->declare_relation(elem, node, j);
     }
    
     int* p_rank = (int*)stk::mesh::field_data(*proc_rank_field, elem);
     p_rank[0] = comm->MyPID();
  }

  for (int i=0; i<indexToEdgeID.size(); i++) {

	 if(isBoundaryEdge[i])
	 {

		 singlePartVec[0] = ssPartVec["lateralside"];
		 stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), indexToEdgeID[i]+1, singlePartVec);
		 stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  elem_map->GID(trianglesOnEdge[2*i])+1);
		 bulkData->declare_relation(elem, side,  trianglesPositionsOnEdge[2*i] /*local side id*/);
		 for(int j=0; j<2; j++)
		 {
			 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, indexToVertexID[verticesOnEdge[2*i+j]]+1);
			 bulkData->declare_relation(side, node, j);
		 }
	 }
  }

  bulkData->modification_end();
}
Exemplo n.º 14
0
TEUCHOS_UNIT_TEST(tSGEpetraLinearObjFactory, initializeContainer)
{
   typedef EpetraLinearObjContainer ELOC;

   // 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;

   int myRank = eComm->MyPID();
   int numProc = eComm->NumProc();

   // panzer::pauseToAttach();

   RCP<Stokhos::OrthogPolyExpansion<int,double> > sgExpansion = buildExpansion(3,5);
   RCP<panzer::UniqueGlobalIndexer<int,int> > indexer 
         = rcp(new unit_test::UniqueGlobalIndexer<int>(myRank,numProc));

   std::vector<int> ownedIndices, ownedAndSharedIndices;
   indexer->getOwnedIndices(ownedIndices);
   indexer->getOwnedAndSharedIndices(ownedAndSharedIndices);
 
   // setup factory
   RCP<panzer::EpetraLinearObjFactory<panzer::Traits,int> > epetraFactory
         = rcp(new panzer::EpetraLinearObjFactory<panzer::Traits,int>(eComm.getConst(),indexer));
   RCP<panzer::SGEpetraLinearObjFactory<panzer::Traits,int> > la_factory
         = rcp(new panzer::SGEpetraLinearObjFactory<panzer::Traits,int>(epetraFactory,sgExpansion,Teuchos::null));
   
   RCP<panzer::LinearObjContainer> ghostedContainer = la_factory->buildGhostedLinearObjContainer(); 
   RCP<panzer::LinearObjContainer> container = la_factory->buildLinearObjContainer(); 

   RCP<panzer::SGEpetraLinearObjContainer> sgGhostedContainer 
         = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(ghostedContainer,true);
   RCP<panzer::SGEpetraLinearObjContainer> sgContainer 
         = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(container,true);

   la_factory->initializeContainer(ELOC::X | ELOC::DxDt,*container);
   la_factory->initializeGhostedContainer(ELOC::X | ELOC::DxDt,*ghostedContainer);

   // make sure all "sub-containers" are epetra containers
   panzer::SGEpetraLinearObjContainer::const_iterator itr;
   for(itr=sgContainer->begin();itr!=sgContainer->end();++itr) {
      TEST_ASSERT((*itr)->get_x()!=Teuchos::null);
      TEST_ASSERT((*itr)->get_dxdt()!=Teuchos::null);
      TEST_EQUALITY((*itr)->get_f(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_A(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_x()->MyLength(),(int) ownedIndices.size());
      TEST_EQUALITY((*itr)->get_dxdt()->MyLength(),(int) ownedIndices.size());
   }
   for(itr=sgGhostedContainer->begin();itr!=sgGhostedContainer->end();++itr) {
      TEST_ASSERT((*itr)->get_x()!=Teuchos::null);
      TEST_ASSERT((*itr)->get_dxdt()!=Teuchos::null);
      TEST_EQUALITY((*itr)->get_f(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_A(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_x()->MyLength(),(int) ownedAndSharedIndices.size());
      TEST_EQUALITY((*itr)->get_dxdt()->MyLength(),(int) ownedAndSharedIndices.size());
   }

   la_factory->initializeContainer(ELOC::Mat | ELOC::F,*container);
   la_factory->initializeGhostedContainer(ELOC::Mat | ELOC::F,*ghostedContainer);

   // make sure all "sub-containers" are epetra containers
   for(itr=sgContainer->begin();itr!=sgContainer->end();++itr) {
      TEST_ASSERT((*itr)->get_f()!=Teuchos::null);
      TEST_ASSERT((*itr)->get_A()!=Teuchos::null);
      TEST_EQUALITY((*itr)->get_x(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_dxdt(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_f()->MyLength(),(int) ownedIndices.size());
      TEST_EQUALITY((*itr)->get_A()->NumMyRows(),(int) ownedIndices.size());
   }
   for(itr=sgGhostedContainer->begin();itr!=sgGhostedContainer->end();++itr) {
      TEST_ASSERT((*itr)->get_f()!=Teuchos::null);
      TEST_ASSERT((*itr)->get_A()!=Teuchos::null);
      TEST_EQUALITY((*itr)->get_x(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_dxdt(),Teuchos::null);
      TEST_EQUALITY((*itr)->get_f()->MyLength(),(int) ownedAndSharedIndices.size());
      TEST_EQUALITY((*itr)->get_A()->NumMyRows(),(int) ownedAndSharedIndices.size());
   }

}
Exemplo n.º 15
0
int main(int argc, char *argv[]) {

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

  int MyPID;

  try {

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();
    
    // Create Stochastic Galerkin basis and expansion
    int p = 5;
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(1); 
    bases[0] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    Cijk = basis->computeTripleProductTensor();
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();
    
    // Create application model evaluator
    Teuchos::RCP<EpetraExt::ModelEvaluator> model = 
      Teuchos::rcp(new SimpleME(app_comm));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    sgParams->set("Jacobian Method", "Matrix Free");
    sgParams->set("Mean Preconditioner Type", "Ifpack");

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
    						 expansion, sg_parallel_data, 
						 sgParams));

    // Stochastic Galerkin initial guess
    // Set the mean to the deterministic initial guess, higher-order terms
    // to zero
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> x_init_sg = 
      sg_model->create_x_sg();
    x_init_sg->init(0.0);
    (*x_init_sg)[0] = *(model->get_x_init());
    sg_model->set_x_sg_init(*x_init_sg);

    // Stochastic Galerkin parameters
    // Linear expansion with the mean given by the deterministic initial
    // parameter values, linear terms equal to 1, and higher order terms
    // equal to zero.
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> p_init_sg =
      sg_model->create_p_sg(0);
    p_init_sg->init(0.0);
    (*p_init_sg)[0] = *(model->get_p_init(0));
    for (int i=0; i<model->get_p_map(0)->NumMyElements(); i++)
      (*p_init_sg)[i+1][i] = 1.0;
    sg_model->set_p_sg_init(0, *p_init_sg);
    std::cout << "Stochatic Galerkin parameter expansion = " << std::endl
	      << *p_init_sg << std::endl;

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams =
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

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

    // Create printing utilities
    NOX::Utils utils(printParams);

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

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->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", 100);
    lsParams.set("Size of Krylov Subspace", 100);
    lsParams.set("Tolerance", 1e-4); 
    lsParams.set("Output Frequency", 10);
    lsParams.set("Preconditioner", "Ifpack");

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", 1e-10);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 10);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
    Teuchos::RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
    Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
    lsParams.set("Preconditioner", "User Defined");
    linsys = 
      Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
    							iJac, A, iPrec, M,
    							*u));
    // linsys = 
    //   Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
    // 							iReq, iJac, A, *u));

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));

    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

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

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

    // Get final solution
    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();

    // Convert block Epetra_Vector to orthogonal polynomial of Epetra_Vector's
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> x_sg =
      sg_model->create_x_sg(View, &finalSolution);

    utils.out() << "Final Solution (block vector) = " << std::endl;
    std::cout << finalSolution << std::endl;
    utils.out() << "Final Solution (polynomial) = " << std::endl;
    std::cout << *x_sg << std::endl;

    if (status == NOX::StatusTest::Converged && MyPID == 0) 
      utils.out() << "Example Passed!" << std::endl;

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
  TEUCHOS_UNIT_TEST(block_assembly, scatter_dirichlet_residual)
  {
    PHX::KokkosDeviceSession session;

#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

    int myRank = eComm->MyPID();

    const std::size_t workset_size = 4;
    const std::string fieldName1_q1 = "U";
    const std::string fieldName2_q1 = "V";
    const std::string fieldName_qedge1 = "B";

    Teuchos::RCP<panzer_stk_classic::STK_Interface> mesh = buildMesh(2,2);

    // build input physics block
    Teuchos::RCP<panzer::PureBasis> basis_q1 = buildBasis(workset_size,"Q1");
    Teuchos::RCP<panzer::PureBasis> basis_qedge1 = buildBasis(workset_size,"QEdge1");

    Teuchos::RCP<Teuchos::ParameterList> ipb = Teuchos::parameterList();
    testInitialization(ipb);

    const int default_int_order = 1;
    std::string eBlockID = "eblock-0_0";    
    Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
    panzer::CellData cellData(workset_size,mesh->getCellTopology("eblock-0_0"));
    Teuchos::RCP<panzer::GlobalData> gd = panzer::createGlobalData();
    Teuchos::RCP<panzer::PhysicsBlock> physicsBlock = 
      Teuchos::rcp(new PhysicsBlock(ipb,eBlockID,default_int_order,cellData,eqset_factory,gd,false));

    Teuchos::RCP<std::vector<panzer::Workset> > work_sets = panzer_stk_classic::buildWorksets(*mesh,*physicsBlock); 
    TEST_EQUALITY(work_sets->size(),1);

    // build connection manager and field manager
    const Teuchos::RCP<panzer::ConnManager<int,int> > conn_manager = Teuchos::rcp(new panzer_stk_classic::STKConnManager<int>(mesh));
    RCP<panzer::BlockedDOFManager<int,int> > dofManager = Teuchos::rcp(new panzer::BlockedDOFManager<int,int>(conn_manager,MPI_COMM_WORLD));

    dofManager->addField(fieldName1_q1,Teuchos::rcp(new panzer::IntrepidFieldPattern(basis_q1->getIntrepidBasis())));
    dofManager->addField(fieldName2_q1,Teuchos::rcp(new panzer::IntrepidFieldPattern(basis_q1->getIntrepidBasis())));
    dofManager->addField(fieldName_qedge1,Teuchos::rcp(new panzer::IntrepidFieldPattern(basis_qedge1->getIntrepidBasis())));

    std::vector<std::vector<std::string> > fieldOrder(3);
    fieldOrder[0].push_back(fieldName1_q1);
    fieldOrder[1].push_back(fieldName_qedge1);
    fieldOrder[2].push_back(fieldName2_q1);
    dofManager->setFieldOrder(fieldOrder);

    // dofManager->setOrientationsRequired(true);
    dofManager->buildGlobalUnknowns();

    // setup linear object factory
    /////////////////////////////////////////////////////////////

    Teuchos::RCP<BlockedEpetraLinearObjFactory<panzer::Traits,int> > be_lof 
       = Teuchos::rcp(new BlockedEpetraLinearObjFactory<panzer::Traits,int>(eComm.getConst(),dofManager));
    Teuchos::RCP<LinearObjFactory<panzer::Traits> > lof = be_lof;
    Teuchos::RCP<LinearObjContainer> dd_loc = be_lof->buildGhostedLinearObjContainer();
    Teuchos::RCP<LinearObjContainer> loc = be_lof->buildGhostedLinearObjContainer();
    be_lof->initializeGhostedContainer(LinearObjContainer::F,*dd_loc);
    dd_loc->initialize();

    be_lof->initializeGhostedContainer(LinearObjContainer::X | LinearObjContainer::F,*loc);
    loc->initialize();

    Teuchos::RCP<BlockedEpetraLinearObjContainer> b_dd_loc = Teuchos::rcp_dynamic_cast<BlockedEpetraLinearObjContainer>(dd_loc);
    Teuchos::RCP<BlockedEpetraLinearObjContainer> b_loc = Teuchos::rcp_dynamic_cast<BlockedEpetraLinearObjContainer>(loc);
    Teuchos::RCP<Thyra::ProductVectorBase<double> > p_vec = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<double> >(b_loc->get_x());
    Thyra::assign(p_vec->getNonconstVectorBlock(0).ptr(),123.0+myRank);
    Thyra::assign(p_vec->getNonconstVectorBlock(1).ptr(),456.0+myRank);
    Thyra::assign(p_vec->getNonconstVectorBlock(2).ptr(),789.0+myRank);

    // setup field manager, add evaluator under test
    /////////////////////////////////////////////////////////////
 
    PHX::FieldManager<panzer::Traits> fm;

    std::string resName = "";
    Teuchos::RCP<std::map<std::string,std::string> > names_map =
       Teuchos::rcp(new std::map<std::string,std::string>);
    names_map->insert(std::make_pair(fieldName1_q1,resName+fieldName1_q1));
    names_map->insert(std::make_pair(fieldName2_q1,resName+fieldName2_q1));
    names_map->insert(std::make_pair(fieldName_qedge1,resName+fieldName_qedge1));

    // evaluators under test
    {
       using Teuchos::RCP;
       using Teuchos::rcp;
       RCP<std::vector<std::string> > names = rcp(new std::vector<std::string>);
       names->push_back(resName+fieldName1_q1);
       names->push_back(resName+fieldName2_q1);

       Teuchos::ParameterList pl; 
       pl.set("Scatter Name", "ScatterQ1");
       pl.set("Basis", basis_q1);
       pl.set("Dependent Names", names);
       pl.set("Dependent Map", names_map);
       pl.set("Side Subcell Dimension", 1);
       pl.set("Local Side ID", 2);
       pl.set("Check Apply BC", false);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = lof->buildScatterDirichlet<panzer::Traits::Residual>(pl);

       TEST_EQUALITY(evaluator->evaluatedFields().size(),1);

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
       fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]);
    }
    {
       using Teuchos::RCP;
       using Teuchos::rcp;
       RCP<std::vector<std::string> > names = rcp(new std::vector<std::string>);
       names->push_back(resName+fieldName_qedge1);

       Teuchos::ParameterList pl; 
       pl.set("Scatter Name", "ScatterQEdge1");
       pl.set("Basis", basis_qedge1);
       pl.set("Dependent Names", names);
       pl.set("Dependent Map", names_map);
       pl.set("Side Subcell Dimension", 1);
       pl.set("Local Side ID", 2);
       pl.set("Check Apply BC", false);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = lof->buildScatterDirichlet<panzer::Traits::Residual>(pl);

       TEST_EQUALITY(evaluator->evaluatedFields().size(),1);

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
       fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]);
    }

    // support evaluators
    {
       using Teuchos::RCP;
       using Teuchos::rcp;
       RCP<std::vector<std::string> > names = rcp(new std::vector<std::string>);
       names->push_back(fieldName1_q1);
       names->push_back(fieldName2_q1);

       Teuchos::ParameterList pl; 
       pl.set("Basis", basis_q1);
       pl.set("DOF Names",names);
       pl.set("Indexer Names",names);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = lof->buildGather<panzer::Traits::Residual>(pl);

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
    }
    {
       using Teuchos::RCP;
       using Teuchos::rcp;
       RCP<std::vector<std::string> > names = rcp(new std::vector<std::string>);
       names->push_back(fieldName_qedge1);

       Teuchos::ParameterList pl; 
       pl.set("Basis", basis_qedge1);
       pl.set("DOF Names",names);
       pl.set("Indexer Names",names);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = lof->buildGather<panzer::Traits::Residual>(pl);

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
    }

    std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(12);
    fm.setKokkosExtendedDataTypeDimensions<panzer::Traits::Jacobian>(derivative_dimensions);

    panzer::Traits::SetupData sd;
    fm.postRegistrationSetup(sd);

    // panzer::Traits::PED ped;
    // ped.dirichletData.ghostedCounter = dd_loc;
    // fm.preEvaluate<panzer::Traits::Residual>(ped);
    panzer::Traits::PreEvalData ped;
    ped.gedc.addDataObject("Dirichlet Counter",dd_loc);
    ped.gedc.addDataObject("Solution Gather Container",loc);
    ped.gedc.addDataObject("Residual Scatter Container",loc);
    fm.preEvaluate<panzer::Traits::Residual>(ped);


    // run tests
    /////////////////////////////////////////////////////////////

    panzer::Workset & workset = (*work_sets)[0];
    workset.alpha = 0.0;
    workset.beta = 2.0; // derivatives multiplied by 2
    workset.time = 0.0;
    workset.evaluate_transient_terms = false;

    fm.evaluateFields<panzer::Traits::Residual>(workset);

    // test Residual fields
    std::size_t dd_count = 0;
    Teuchos::ArrayRCP<const double> data, dd_data;
    Teuchos::RCP<const Thyra::ProductVectorBase<double> > f_vec = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<double> >(b_loc->get_f());
    Teuchos::RCP<const Thyra::ProductVectorBase<double> > dd_vec = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<double> >(b_dd_loc->get_f());

    // check all the residual values. This is kind of crappy test since it simply checks twice the target
    // value and the target. Its this way because you add two entries across elements.

    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(f_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(data));
    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(dd_vec->getVectorBlock(0))->getLocalData(Teuchos::ptrFromRef(dd_data));
    TEST_EQUALITY(data.size(),b_loc->getMapForBlock(0)->NumMyElements());
    TEST_EQUALITY(data.size(),dd_data.size());
    dd_count = 0;
    for(int i=0;i<data.size();i++) {
 
       double target = 123.0+myRank;
       if(dd_data[i]==0.0)
       {  TEST_EQUALITY(data[i],0.0); }
       else
       {  TEST_EQUALITY(data[i],target); dd_count++; }
    }
    TEST_EQUALITY(dd_count,2*workset.num_cells); // there are 2 nodes on the side and the sides are not shared

    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(f_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(data));
    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(dd_vec->getVectorBlock(1))->getLocalData(Teuchos::ptrFromRef(dd_data));
    TEST_EQUALITY(data.size(),b_loc->getMapForBlock(1)->NumMyElements());
    TEST_EQUALITY(data.size(),dd_data.size());
    dd_count = 0;
    for(int i=0;i<data.size();i++) {
 
       double target = 456.0+myRank;
       if(dd_data[i]==0.0)
       {  TEST_EQUALITY(data[i],0.0); }
       else
       {  TEST_EQUALITY(data[i],target); dd_count++; }
    }
    TEST_EQUALITY(dd_count,workset.num_cells); // there are 2 nodes on the side and the sides are not shared

    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(f_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(data));
    Teuchos::rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(dd_vec->getVectorBlock(2))->getLocalData(Teuchos::ptrFromRef(dd_data));
    TEST_EQUALITY(data.size(),b_loc->getMapForBlock(2)->NumMyElements());
    TEST_EQUALITY(data.size(),dd_data.size());
    dd_count = 0;
    for(int i=0;i<data.size();i++) {
 
       double target = 789.0+myRank;
       if(dd_data[i]==0.0)
       {  TEST_EQUALITY(data[i],0.0); }
       else
       {  TEST_EQUALITY(data[i],target); dd_count++; }
    }
    TEST_EQUALITY(dd_count,2*workset.num_cells); // there are 2 nodes on the side and the sides are not shared

  }
Exemplo n.º 17
0
int main(int argc, char *argv[]) {   

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

  // Create a communicator for Epetra objects
  Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
  globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
  globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
  int MyPID = globalComm->MyPID();

  try {

    // Setup command line options
    Teuchos::CommandLineProcessor CLP;
    CLP.setDocString(
      "This example runs a variety of stochastic Galerkin solvers.\n");

    int n = 32;
    CLP.setOption("num_mesh", &n, "Number of mesh points in each direction");

    bool symmetric = false;
    CLP.setOption("symmetric", "unsymmetric", &symmetric, 
		  "Symmetric discretization");

    int num_spatial_procs = -1;
    CLP.setOption("num_spatial_procs", &num_spatial_procs, "Number of spatial processors (set -1 for all available procs)");

    bool rebalance_stochastic_graph = false;
    CLP.setOption("rebalance", "no-rebalance", &rebalance_stochastic_graph, 
		  "Rebalance parallel stochastic graph (requires Isorropia)");

    SG_RF randField = UNIFORM;
    CLP.setOption("rand_field", &randField, 
		   num_sg_rf, sg_rf_values, sg_rf_names,
		  "Random field type");

    double mean = 0.2;
    CLP.setOption("mean", &mean, "Mean");

    double sigma = 0.1;
    CLP.setOption("std_dev", &sigma, "Standard deviation");

    double weightCut = 1.0;
    CLP.setOption("weight_cut", &weightCut, "Weight cut");

    int num_KL = 2;
    CLP.setOption("num_kl", &num_KL, "Number of KL terms");

    int p = 3;
    CLP.setOption("order", &p, "Polynomial order");

    bool normalize_basis = true;
    CLP.setOption("normalize", "unnormalize", &normalize_basis, 
		  "Normalize PC basis");
    
    SG_Solver solve_method = SG_KRYLOV;
    CLP.setOption("sg_solver", &solve_method, 
		  num_sg_solver, sg_solver_values, sg_solver_names, 
		  "SG solver method");

    Krylov_Method outer_krylov_method = GMRES;
    CLP.setOption("outer_krylov_method", &outer_krylov_method, 
		  num_krylov_method, krylov_method_values, krylov_method_names, 
		  "Outer Krylov method (for Krylov-based SG solver)");

    Krylov_Solver outer_krylov_solver = AZTECOO;
    CLP.setOption("outer_krylov_solver", &outer_krylov_solver, 
		  num_krylov_solver, krylov_solver_values, krylov_solver_names, 
		  "Outer linear solver");

    double outer_tol = 1e-12;
    CLP.setOption("outer_tol", &outer_tol, "Outer solver tolerance");

    int outer_its = 1000;
    CLP.setOption("outer_its", &outer_its, "Maximum outer iterations");

    Krylov_Method inner_krylov_method = GMRES;
    CLP.setOption("inner_krylov_method", &inner_krylov_method, 
		  num_krylov_method, krylov_method_values, krylov_method_names, 
		  "Inner Krylov method (for G-S, Jacobi, etc...)");

    Krylov_Solver inner_krylov_solver = AZTECOO;
    CLP.setOption("inner_krylov_solver", &inner_krylov_solver, 
		  num_krylov_solver, krylov_solver_values, krylov_solver_names, 
		  "Inner linear solver");

    double inner_tol = 3e-13;
    CLP.setOption("inner_tol", &inner_tol, "Inner solver tolerance");

    int inner_its = 1000;
    CLP.setOption("inner_its", &inner_its, "Maximum inner iterations");

    SG_Op opMethod = MATRIX_FREE;
    CLP.setOption("sg_operator_method", &opMethod, 
		  num_sg_op, sg_op_values, sg_op_names,
		  "Operator method");

    SG_Prec precMethod = AGS;
    CLP.setOption("sg_prec_method", &precMethod, 
		  num_sg_prec, sg_prec_values, sg_prec_names,
		  "Preconditioner method");

    double gs_prec_tol = 1e-1;
    CLP.setOption("gs_prec_tol", &gs_prec_tol, "Gauss-Seidel preconditioner tolerance");

    int gs_prec_its = 1;
    CLP.setOption("gs_prec_its", &gs_prec_its, "Maximum Gauss-Seidel preconditioner iterations");

    CLP.parse( argc, argv );

    if (MyPID == 0) {
      std::cout << "Summary of command line options:" << std::endl
		<< "\tnum_mesh            = " << n << std::endl
		<< "\tsymmetric           = " << symmetric << std::endl
		<< "\tnum_spatial_procs   = " << num_spatial_procs << std::endl
		<< "\trebalance           = " << rebalance_stochastic_graph
		<< std::endl
		<< "\trand_field          = " << sg_rf_names[randField] 
		<< std::endl
		<< "\tmean                = " << mean << std::endl
		<< "\tstd_dev             = " << sigma << std::endl
		<< "\tweight_cut          = " << weightCut << std::endl
		<< "\tnum_kl              = " << num_KL << std::endl
		<< "\torder               = " << p << std::endl
		<< "\tnormalize_basis     = " << normalize_basis << std::endl
		<< "\tsg_solver           = " << sg_solver_names[solve_method] 
		<< std::endl
		<< "\touter_krylov_method = " 
		<< krylov_method_names[outer_krylov_method] << std::endl
		<< "\touter_krylov_solver = " 
		<< krylov_solver_names[outer_krylov_solver] << std::endl
		<< "\touter_tol           = " << outer_tol << std::endl
		<< "\touter_its           = " << outer_its << std::endl
		<< "\tinner_krylov_method = " 
		<< krylov_method_names[inner_krylov_method] << std::endl
		<< "\tinner_krylov_solver = " 
		<< krylov_solver_names[inner_krylov_solver] << std::endl
		<< "\tinner_tol           = " << inner_tol << std::endl
		<< "\tinner_its           = " << inner_its << std::endl
		<< "\tsg_operator_method  = " << sg_op_names[opMethod] 
		<< std::endl
		<< "\tsg_prec_method      = " << sg_prec_names[precMethod] 
		<< std::endl
		<< "\tgs_prec_tol         = " << gs_prec_tol << std::endl
		<< "\tgs_prec_its         = " << gs_prec_its << std::endl;
    }

    bool nonlinear_expansion = false;
    if (randField == UNIFORM || randField == RYS)
      nonlinear_expansion = false;
    else if (randField == LOGNORMAL)
      nonlinear_expansion = true;
    bool scaleOP = true; 

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      if (randField == UNIFORM)
        bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,normalize_basis));
      else if (randField == RYS)
        bases[i] = Teuchos::rcp(new Stokhos::RysBasis<int,double>(p,weightCut,normalize_basis));
      else if (randField == LOGNORMAL)      
        bases[i] = Teuchos::rcp(new Stokhos::HermiteBasis<int,double>(p,normalize_basis));

    //  bases[i] = Teuchos::rcp(new Stokhos::DiscretizedStieltjesBasis<int,double>("beta",p,&uniform_weight,-weightCut,weightCut,true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor(sz);
    else
      Cijk = basis->computeTripleProductTensor(num_KL+1);
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    parallelParams.set("Rebalance Stochastic Graph", 
		       rebalance_stochastic_graph);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();
    
    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model =
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, sigma, 
					 mean, basis, nonlinear_expansion,
					 symmetric));

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams = 
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

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

    // Create printing utilities
    NOX::Utils utils(printParams);

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

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->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");

    // Alternative linear solver list for Stratimikos
    Teuchos::ParameterList& stratLinSolParams = 
      newtonParams.sublist("Stratimikos Linear Solver");
    // Teuchos::ParameterList& noxStratParams = 
    //   stratLinSolParams.sublist("NOX Stratimikos Options");
    Teuchos::ParameterList& stratParams = 
      stratLinSolParams.sublist("Stratimikos");

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", outer_tol);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 1);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> det_nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(model));

     // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> det_u = model->get_x_init();
    Teuchos::RCP<Epetra_Operator> det_A = model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> det_iReq = det_nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> det_iJac = det_nox_interface;
    Teuchos::ParameterList det_printParams;
    det_printParams.set("MyPID", MyPID); 
    det_printParams.set("Output Precision", 3);
    det_printParams.set("Output Processor", 0);
    det_printParams.set("Output Information", NOX::Utils::Error);
    
    Teuchos::ParameterList det_lsParams;
    Teuchos::ParameterList& det_stratParams = 
      det_lsParams.sublist("Stratimikos");
    if (inner_krylov_solver == AZTECOO) {
      det_stratParams.set("Linear Solver Type", "AztecOO");
      Teuchos::ParameterList& aztecOOParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
      Teuchos::ParameterList& aztecOOSettings =
	aztecOOParams.sublist("AztecOO Settings");
      if (inner_krylov_method == GMRES) {
	aztecOOSettings.set("Aztec Solver","GMRES");
      }
      else if (inner_krylov_method == CG) {
	aztecOOSettings.set("Aztec Solver","CG");
      }
      aztecOOSettings.set("Output Frequency", 0);
      aztecOOSettings.set("Size of Krylov Subspace", 100);
      aztecOOParams.set("Max Iterations", inner_its);
      aztecOOParams.set("Tolerance", inner_tol);
      Teuchos::ParameterList& verbParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("VerboseObject");
      verbParams.set("Verbosity Level", "none");
    }
    else if (inner_krylov_solver == BELOS) {
      det_stratParams.set("Linear Solver Type", "Belos");
      Teuchos::ParameterList& belosParams = 
	det_stratParams.sublist("Linear Solver Types").sublist("Belos");
      Teuchos::ParameterList* belosSolverParams = NULL;
      if (inner_krylov_method == GMRES || inner_krylov_method == FGMRES) {
	belosParams.set("Solver Type","Block GMRES");
	belosSolverParams = 
	  &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
	if (inner_krylov_method == FGMRES)
	  belosSolverParams->set("Flexible Gmres", true);
      }
      else if (inner_krylov_method == CG) {
	belosParams.set("Solver Type","Block CG");
	belosSolverParams = 
	  &(belosParams.sublist("Solver Types").sublist("Block CG"));
      }
      else if (inner_krylov_method == RGMRES) {
      	belosParams.set("Solver Type","GCRODR");
      	belosSolverParams = 
      	  &(belosParams.sublist("Solver Types").sublist("GCRODR"));
      }
      belosSolverParams->set("Convergence Tolerance", inner_tol);
      belosSolverParams->set("Maximum Iterations", inner_its);
      belosSolverParams->set("Output Frequency",0);
      belosSolverParams->set("Output Style",1);
      belosSolverParams->set("Verbosity",0);
      Teuchos::ParameterList& verbParams = belosParams.sublist("VerboseObject");
      verbParams.set("Verbosity Level", "none");
    }
    det_stratParams.set("Preconditioner Type", "ML");
    Teuchos::ParameterList& det_ML = 
      det_stratParams.sublist("Preconditioner Types").sublist("ML").sublist("ML Settings");
    ML_Epetra::SetDefaults("SA", det_ML);
    det_ML.set("ML output", 0);
    det_ML.set("max levels",5);
    det_ML.set("increasing or decreasing","increasing");
    det_ML.set("aggregation: type", "Uncoupled");
    det_ML.set("smoother: type","ML symmetric Gauss-Seidel");
    det_ML.set("smoother: sweeps",2);
    det_ML.set("smoother: pre or post", "both");
    det_ML.set("coarse: max size", 200);
#ifdef HAVE_ML_AMESOS
    det_ML.set("coarse: type","Amesos-KLU");
#else
    det_ML.set("coarse: type","Jacobi");
#endif
    Teuchos::RCP<NOX::Epetra::LinearSystem> det_linsys = 
      Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
		     det_printParams, det_lsParams, det_iJac, 
		     det_A, *det_u));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& sgOpParams = 
      sgParams->sublist("SG Operator");
    Teuchos::ParameterList& sgPrecParams = 
      sgParams->sublist("SG Preconditioner");

    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    if (opMethod == MATRIX_FREE)
      sgOpParams.set("Operator Method", "Matrix Free");
    else if (opMethod == KL_MATRIX_FREE)
      sgOpParams.set("Operator Method", "KL Matrix Free");
    else if (opMethod == KL_REDUCED_MATRIX_FREE) {
      sgOpParams.set("Operator Method", "KL Reduced Matrix Free");
      if (randField == UNIFORM || randField == RYS)
	sgOpParams.set("Number of KL Terms", num_KL);
      else
	sgOpParams.set("Number of KL Terms", basis->size());
      sgOpParams.set("KL Tolerance", outer_tol);
      sgOpParams.set("Sparse 3 Tensor Drop Tolerance", outer_tol);
      sgOpParams.set("Do Error Tests", true);
    }
    else if (opMethod == FULLY_ASSEMBLED)
      sgOpParams.set("Operator Method", "Fully Assembled");
    else
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
		       "Error!  Unknown operator method " << opMethod
			 << "." << std::endl);
    if (precMethod == MEAN)  {
      sgPrecParams.set("Preconditioner Method", "Mean-based");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if(precMethod == GS) {
      sgPrecParams.set("Preconditioner Method", "Gauss-Seidel");
      sgPrecParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      sgPrecParams.set("Deterministic Solver", det_linsys);
      sgPrecParams.set("Max Iterations", gs_prec_its);
      sgPrecParams.set("Tolerance", gs_prec_tol);
    }
    else if (precMethod == AGS)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
      if (outer_krylov_method == CG)
	sgPrecParams.set("Symmetric Gauss-Seidel", true);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if (precMethod == AJ)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Jacobi");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
        sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
      Teuchos::ParameterList& jacobiOpParams =
	sgPrecParams.sublist("Jacobi SG Operator");
      jacobiOpParams.set("Only Use Linear Terms", true);
    }
    else if (precMethod == ASC)  {
      sgPrecParams.set("Preconditioner Method", "Approximate Schur Complement");
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams =
	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams = det_ML;
    }
    else if (precMethod == KP)  {
      sgPrecParams.set("Preconditioner Method", "Kronecker Product");
      sgPrecParams.set("Only Use Linear Terms", true);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& meanPrecParams =
        sgPrecParams.sublist("Mean Preconditioner Parameters");
      meanPrecParams = det_ML;
      sgPrecParams.set("G Preconditioner Type", "Ifpack");
      Teuchos::ParameterList& GPrecParams =
        sgPrecParams.sublist("G Preconditioner Parameters");
      if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES)
	GPrecParams.set("Ifpack Preconditioner", "ILUT");
      if (outer_krylov_method == CG)
	GPrecParams.set("Ifpack Preconditioner", "ICT");
      GPrecParams.set("Overlap", 1);
      GPrecParams.set("fact: drop tolerance", 1e-4);
      GPrecParams.set("fact: ilut level-of-fill", 1.0);
      GPrecParams.set("schwarz: combine mode", "Add");
    }
    else if (precMethod == NONE)  {
      sgPrecParams.set("Preconditioner Method", "None");
    }
    else
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
		       "Error!  Unknown preconditioner method " << precMethod
			 << "." << std::endl);

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
                                                 expansion, sg_parallel_data, 
						 sgParams, scaleOP));
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = 
      sg_model->createOutArgs();

    // Set up stochastic parameters
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_init =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_init->term(i,0)[i] = 0.0;
      sg_p_init->term(i,1)[i] = 1.0;
    }
    sg_model->set_p_sg_init(0, *sg_p_init);

    // Setup stochastic initial guess
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_init = 
      sg_model->create_x_sg();
    sg_x_init->init(0.0);
    sg_model->set_x_sg_init(*sg_x_init);

     // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface =
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX stochastic linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<const Epetra_Map> base_map = model->get_x_map();
    Teuchos::RCP<const Epetra_Map> sg_map = sg_model->get_x_map();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;

    // Build linear solver
    Teuchos::RCP<NOX::Epetra::LinearSystem> linsys;
    if (solve_method==SG_KRYLOV) {
      bool has_M = 
	sg_outArgs.supports(EpetraExt::ModelEvaluator::OUT_ARG_WPrec);
      Teuchos::RCP<Epetra_Operator> M;
      Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec;
      if (has_M) {
	M = sg_model->create_WPrec()->PrecOp;
	iPrec = nox_interface;
      }
      stratParams.set("Preconditioner Type", "None");
      if (outer_krylov_solver == AZTECOO) {
	stratParams.set("Linear Solver Type", "AztecOO");
	Teuchos::ParameterList& aztecOOParams = 
	  stratParams.sublist("Linear Solver Types").sublist("AztecOO").sublist("Forward Solve");
	Teuchos::ParameterList& aztecOOSettings =
	  aztecOOParams.sublist("AztecOO Settings");
	if (outer_krylov_method == GMRES) {
	  aztecOOSettings.set("Aztec Solver","GMRES");
	}
	else if (outer_krylov_method == CG) {
	  aztecOOSettings.set("Aztec Solver","CG");
	}
	aztecOOSettings.set("Output Frequency", 1);
	aztecOOSettings.set("Size of Krylov Subspace", 100);
	aztecOOParams.set("Max Iterations", outer_its);
	aztecOOParams.set("Tolerance", outer_tol);
	stratLinSolParams.set("Preconditioner", "User Defined");
	if (has_M)
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, iPrec, M, 
			   *u, true));
	else
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, *u));
      }
      else if (outer_krylov_solver == BELOS){
	stratParams.set("Linear Solver Type", "Belos");
	Teuchos::ParameterList& belosParams = 
	  stratParams.sublist("Linear Solver Types").sublist("Belos");
	Teuchos::ParameterList* belosSolverParams = NULL;
	if (outer_krylov_method == GMRES || outer_krylov_method == FGMRES) {
	  belosParams.set("Solver Type","Block GMRES");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("Block GMRES"));
	  if (outer_krylov_method == FGMRES)
	    belosSolverParams->set("Flexible Gmres", true);
	}
	else if (outer_krylov_method == CG) {
	  belosParams.set("Solver Type","Block CG");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("Block CG"));
	}
	else if (inner_krylov_method == RGMRES) {
	  belosParams.set("Solver Type","GCRODR");
	  belosSolverParams = 
	    &(belosParams.sublist("Solver Types").sublist("GCRODR"));
	}
	belosSolverParams->set("Convergence Tolerance", outer_tol);
	belosSolverParams->set("Maximum Iterations", outer_its);
	belosSolverParams->set("Output Frequency",1);
	belosSolverParams->set("Output Style",1);
	belosSolverParams->set("Verbosity",33);
	stratLinSolParams.set("Preconditioner", "User Defined");
	if (has_M)
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, iPrec, M, 
			   *u, true));
	else
	  linsys = 
	    Teuchos::rcp(new NOX::Epetra::LinearSystemStratimikos(
			   printParams, stratLinSolParams, iJac, A, *u));
	  
      }
    }
    else if (solve_method==SG_GS) {
      lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      lsParams.set("Max Iterations", outer_its);
      lsParams.set("Tolerance", outer_tol);
      linsys =
	Teuchos::rcp(new NOX::Epetra::LinearSystemSGGS(
		       printParams, lsParams, det_linsys, iReq, iJac, 
		       basis, sg_parallel_data, A, base_map, sg_map));
    }
    else {
      lsParams.sublist("Deterministic Solver Parameters") = det_lsParams;
      lsParams.set("Max Iterations", outer_its);
      lsParams.set("Tolerance", outer_tol);
      Teuchos::ParameterList& jacobiOpParams =
	lsParams.sublist("Jacobi SG Operator");
      jacobiOpParams.set("Only Use Linear Terms", true);
      linsys =
	Teuchos::rcp(new NOX::Epetra::LinearSystemSGJacobi(
		       printParams, lsParams, det_linsys, iReq, iJac, 
		       basis, sg_parallel_data, A, base_map, sg_map));
    }

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));
    
    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

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

    // Solve the system
    NOX::StatusTest::StatusType status;
    {
      TEUCHOS_FUNC_TIME_MONITOR("Total Solve Time");
      status = solver->solve();
    }

    // Get final solution
    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();

    // Save final solution to file
    EpetraExt::VectorToMatrixMarketFile("nox_solver_stochastic_solution.mm", 
					finalSolution);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, &finalSolution);
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
      
    // Evaluate SG responses at SG parameters
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
    sg_outArgs.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs);

    // Print mean and standard deviation of response
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << "\nResponse Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    if (status == NOX::StatusTest::Converged && MyPID == 0) 
      utils.out() << "Example Passed!" << std::endl;

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
Exemplo n.º 18
0
int main(int argc, char* argv[]) {
  Teuchos::RCP<Epetra_Comm> comm;
#ifdef HAVE_MPI
  Teuchos::GlobalMPISession mpiSession(&argc, &argv,0);
  comm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
  comm = Teuchos::rcp(new Epetra_SerialComm());
#endif

  // 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 && comm->MyPID()==0)
    outStream = Teuchos::rcp(&std::cout, false);
  else
    outStream = Teuchos::rcp(&bhs, false);

  int errorFlag  = 0;

  try {
    /**********************************************************************************************/
    /************************* CONSTRUCT ROL ALGORITHM ********************************************/
    /**********************************************************************************************/
    // Get ROL parameterlist
    std::string filename = "input.xml";
    Teuchos::RCP<Teuchos::ParameterList> parlist = Teuchos::rcp( new Teuchos::ParameterList() );
    Teuchos::updateParametersFromXmlFile( filename, Teuchos::Ptr<Teuchos::ParameterList>(&*parlist) );
    // Build ROL algorithm
    double gtol = parlist->get("Gradient Tolerance",1.e-6);
    double stol = parlist->get("Step Tolerance",1.e-12);
    int maxit   = parlist->get("Maximum Number of Iterations",100);
    ROL::StatusTest<double> status(gtol,stol,maxit);
    //ROL::LineSearchStep<double> step(*parlist);
    Teuchos::RCP<ROL::Step<double> > step;
    Teuchos::RCP<ROL::DefaultAlgorithm<double> > algo;
    /**********************************************************************************************/
    /************************* CONSTRUCT SOL COMPONENTS *******************************************/
    /**********************************************************************************************/
    // Build vectors
    unsigned dim = 4;
    Teuchos::RCP<std::vector<double> > x_rcp  = Teuchos::rcp( new std::vector<double>(dim,0.0) );
    ROL::StdVector<double> x(x_rcp);
    Teuchos::RCP<std::vector<double> > x0_rcp = Teuchos::rcp( new std::vector<double>(dim,0.0) );
    ROL::StdVector<double> x0(x0_rcp);
    Teuchos::RCP<std::vector<double> > xr_rcp = Teuchos::rcp( new std::vector<double>(dim,0.0) );
    ROL::StdVector<double> xr(xr_rcp);
    Teuchos::RCP<std::vector<double> > d_rcp  = Teuchos::rcp( new std::vector<double>(dim,0.0) );
    ROL::StdVector<double> d(d_rcp);
    for ( unsigned i = 0; i < dim; i++ ) {
      (*x0_rcp)[i] = 1.0/(double)dim;
      (*xr_rcp)[i] = random<double>(comm);
      (*d_rcp)[i]  = random<double>(comm);
    }
    // Build samplers
    int nSamp = 1000;
    std::vector<std::vector<double> > bounds(dim);
    std::vector<double> tmp(2,0.0);
    double inc = 0.125;
    double val = -0.5;
    for (unsigned i = 0; i < dim; i++) {
      tmp[0] = val-inc; tmp[1] = val+inc;
      bounds[i] = tmp;
      inc *= 2.0;
    }
    Teuchos::RCP<ROL::BatchManager<double> > bman =
      Teuchos::rcp(new ROL::StdEpetraBatchManager<double>(comm));
    Teuchos::RCP<ROL::SampleGenerator<double> > sampler =
      Teuchos::rcp(new ROL::MonteCarloGenerator<double>(nSamp,bounds,bman,false,false,100));
    // Build risk-averse objective function
    bool storage = true;
    Teuchos::RCP<ROL::ParametrizedObjective<double> > pObj =
      Teuchos::rcp(new ParametrizedObjectiveEx1<double>(1.e1));
    Teuchos::RCP<ROL::RiskMeasure<double> > rm;
    Teuchos::RCP<ROL::Objective<double> > obj;
    // Build bound constraints
    std::vector<double> l(dim,0.0);
    std::vector<double> u(dim,1.0);
    Teuchos::RCP<ROL::BoundConstraint<double> > con = 
      Teuchos::rcp( new ROL::StdBoundConstraint<double>(l,u) );
    // Test parametrized objective functions
    *outStream << "Check Derivatives of Parametrized Objective Function\n";
    x.set(xr);
    pObj->setParameter(sampler->getMyPoint(0));
    pObj->checkGradient(x,d,true,*outStream);
    pObj->checkHessVec(x,d,true,*outStream);
    /**********************************************************************************************/
    /************************* RISK NEUTRAL *******************************************************/
    /**********************************************************************************************/
    *outStream << "\nRISK NEUTRAL\n";
    rm  = Teuchos::rcp( new ROL::RiskMeasure<double>() );
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    clock_t start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* RISK NEUTRAL *******************************************************/
    /**********************************************************************************************/
    *outStream << "\nRISK NEUTRAL\n";
    obj = Teuchos::rcp( new ROL::RiskNeutralObjective<double>(pObj,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS DEVIATION ************************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS DEVIATION\n";
    // Absolute value approximation
    double gamma = 0.0;
    ROL::EAbsoluteValue eav = ROL::ABSOLUTEVALUE_C2;
    Teuchos::RCP<ROL::PositiveFunction<double> > pf = Teuchos::rcp( new ROL::AbsoluteValue<double>(gamma,eav) );
    // Moment vector
    std::vector<double> order(2,0.0); order[0] = 2.0; order[1] = 4.0;
    // Moment coefficients
    std::vector<double> coeff(2,0.1);
    rm  = Teuchos::rcp( new ROL::MeanDeviation<double>(order,coeff,pf) );
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS VARIANCE *************************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS VARIANCE\n";
    rm  = Teuchos::rcp( new ROL::MeanVariance<double>(order,coeff,pf) );
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS DEVIATION FROM TARGET ************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS DEVIATION FROM TARGET\n";
    // Moment targets
    std::vector<double> target(2,-0.1);
    // Risk measure
    rm  = Teuchos::rcp( new ROL::MeanDeviationFromTarget<double>(target,order,coeff,pf) );
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS VARIANCE FROM TARGET *************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS VARIANCE FROM TARGET\n";
    // Risk measure
    coeff[1] = 0.0;
    rm  = Teuchos::rcp( new ROL::MeanVarianceFromTarget<double>(target,order,coeff,pf) );
    coeff[1] = 0.1;
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS SEMIDEVIATION ********************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS SEMIDEVIATION\n";
    // Plus function approximation
    gamma = 1.e2;
    std::vector<double> data2(2,0.0);
    data2[0] = 0.0; data2[1] = 1.0;
    Teuchos::RCP<ROL::Distribution<double> > dist2 =
      Teuchos::rcp(new ROL::Distribution<double>(ROL::DISTRIBUTION_PARABOLIC,data2));
    Teuchos::RCP<ROL::PlusFunction<double> > plusf =
      Teuchos::rcp(new ROL::PlusFunction<double>(dist2,1.0/gamma));
    pf = Teuchos::rcp(new ROL::PlusFunction<double>(dist2,1.0/gamma));
    // Risk measure
    rm  = Teuchos::rcp( new ROL::MeanDeviation<double>(order,coeff,pf) );
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS SEMIVARIANCE *********************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS SEMIVARIANCE\n";
    // Risk measure
    rm  = Teuchos::rcp( new ROL::MeanVariance<double>(order,coeff,pf) );
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS SEMIDEVIATION FROM TARGET ********************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS SEMIDEVIATION FROM TARGET\n";
    // Risk measure
    rm  = Teuchos::rcp( new ROL::MeanDeviationFromTarget<double>(target,order,coeff,pf) );
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS SEMIVARIANCE FROM TARGET *********************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS SEMIVARIANCE FROM TARGET\n";
    // Risk measure
    rm  = Teuchos::rcp( new ROL::MeanVarianceFromTarget<double>(target,order,coeff,pf) );
    // Risk averse objective
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* MEAN PLUS CVAR *****************************************************/
    /**********************************************************************************************/
    *outStream << "\nMEAN PLUS CONDITIONAL VALUE AT RISK\n";
    double prob = 0.8;
    double c = 0.8;
    rm  = Teuchos::rcp( new ROL::CVaR<double>(prob,c,plusf) );
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    Teuchos::RCP<ROL::BoundConstraint<double> > CVaRcon = 
      Teuchos::rcp( new ROL::CVaRBoundConstraint<double>(con) );
    // Test objective functions
    double xv = 10.0*random<double>(comm)-5.0;
    double dv = 10.0*random<double>(comm)-5.0;
    Teuchos::RCP<ROL::Vector<double> > xp = Teuchos::rcp(&x,false);
    Teuchos::RCP<ROL::Vector<double> > dp = Teuchos::rcp(&d,false);
    ROL::CVaRVector<double> xc(xv,xp);
    ROL::CVaRVector<double> dc(dv,dp);
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(xc,dc,true,*outStream);
    obj->checkHessVec(xc,dc,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(xc,*obj,*CVaRcon,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "t = " << xc.getVaR() << "\n";
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* SMOOTHED CVAR QUADRANGLE *******************************************/
    /**********************************************************************************************/
    *outStream << "\nSMOOTHED CONDITIONAL VALUE AT RISK \n";
    prob = 0.9;
    ROL::CVaRQuadrangle<double> scq(prob,1.0/gamma,plusf);
    //scq.checkRegret();
    rm  = Teuchos::rcp(&scq,false);
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    xv = 10.0*random<double>(comm)-5.0;
    dv = 10.0*random<double>(comm)-5.0;
    xp = Teuchos::rcp(&x,false);
    dp = Teuchos::rcp(&d,false);
    ROL::CVaRVector<double> xq(xv,xp);
    ROL::CVaRVector<double> dq(dv,dp);
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(xr);
    obj->checkGradient(xq,dq,true,*outStream);
    obj->checkHessVec(xq,dq,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(xq,*obj,*CVaRcon,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "t = " << xq.getVaR() << "\n";
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
    /**********************************************************************************************/
    /************************* EXPONENTIAL UTILITY FUNCTION ***************************************/
    /**********************************************************************************************/
    *outStream << "\nEXPONENTIAL UTILITY FUNCTION\n";
    rm  = Teuchos::rcp( new ROL::ExpUtility<double> );
    obj = Teuchos::rcp( new ROL::RiskAverseObjective<double>(pObj,rm,sampler,storage) );
    // Test objective functions
    *outStream << "\nCheck Derivatives of Risk-Averse Objective Function\n";
    x.set(x0);
    obj->checkGradient(x,d,true,*outStream);
    obj->checkHessVec(x,d,true,*outStream);
    // Run ROL algorithm
    step = Teuchos::rcp( new ROL::TrustRegionStep<double>(*parlist) );
    algo = Teuchos::rcp( new ROL::DefaultAlgorithm<double>(*step,status,false) );
    x.set(x0);
    start = clock();
    algo->run(x,*obj,*con,true,*outStream);
    *outStream << "Optimization time: " << (double)(clock()-start)/(double)CLOCKS_PER_SEC << " seconds.\n";
    // Print Solution
    *outStream << "x = (";
    for ( unsigned i = 0; i < dim-1; i++ ) {
      *outStream << (*x_rcp)[i] << ", ";
    }
    *outStream << (*x_rcp)[dim-1] << ")\n";
  }
  catch (std::logic_error err) {
    *outStream << err.what() << "\n";
    errorFlag = -1000;
  }; // end try

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

  return 0;
}
TEUCHOS_UNIT_TEST(PdQuickGridDiscretization_MPI_np2, SimpleTensorProductMeshTest) {

  Teuchos::RCP<Epetra_Comm> comm;
  comm = rcp(new Epetra_MpiComm(MPI_COMM_WORLD));

  int numProcs = comm->NumProc();
  int rank     = comm->MyPID();

  TEST_COMPARE(numProcs, ==, 2);

  if(numProcs != 2){
     std::cerr << "Unit test runtime ERROR: utPeridigm_PdQuickGridDiscretization_MPI_np2 only makes sense on 2 processors" << std::endl;
     return;
  }

  RCP<ParameterList> discParams = rcp(new ParameterList);

  // create a 2x2x2 discretization
  // specify a spherical neighbor search with the horizon a tad longer than the mesh spacing
  discParams->set("Type", "PdQuickGrid");
  discParams->set("NeighborhoodType", "Spherical");
  ParameterList& quickGridParams = discParams->sublist("TensorProduct3DMeshGenerator");
  quickGridParams.set("Type", "PdQuickGrid");
  quickGridParams.set("X Origin", 0.0);
  quickGridParams.set("Y Origin", 0.0);
  quickGridParams.set("Z Origin", 0.0);
  quickGridParams.set("X Length", 1.0);
  quickGridParams.set("Y Length", 1.0);
  quickGridParams.set("Z Length", 1.0);
  quickGridParams.set("Number Points X", 2);
  quickGridParams.set("Number Points Y", 2);
  quickGridParams.set("Number Points Z", 2);

  // initialize the horizon manager and set the horizon to 0.501
  ParameterList blockParameterList;
  ParameterList& blockParams = blockParameterList.sublist("My Block");
  blockParams.set("Block Names", "block_1");
  blockParams.set("Horizon", 0.501);
  PeridigmNS::HorizonManager::self().loadHorizonInformationFromBlockParameters(blockParameterList);

  // create the discretization
  RCP<PdQuickGridDiscretization> discretization =
    rcp(new PdQuickGridDiscretization(comm, discParams));

  // sanity check, calling with a dimension other than 1 or 3 should throw an exception
  TEST_THROW(discretization->getGlobalOwnedMap(0), Teuchos::Exceptions::InvalidParameter);
  TEST_THROW(discretization->getGlobalOwnedMap(2), Teuchos::Exceptions::InvalidParameter);
  TEST_THROW(discretization->getGlobalOwnedMap(4), Teuchos::Exceptions::InvalidParameter);

  // basic checks on the 1d map
  Teuchos::RCP<const Epetra_BlockMap> map = discretization->getGlobalOwnedMap(1);
  TEST_ASSERT(map->NumGlobalElements() == 8);
  TEST_ASSERT(map->NumMyElements() == 4);
  TEST_ASSERT(map->ElementSize() == 1);
  TEST_ASSERT(map->IndexBase() == 0);
  TEST_ASSERT(map->UniqueGIDs() == true);
  int* myGlobalElements = map->MyGlobalElements();
  if(rank == 0){
    TEST_ASSERT(myGlobalElements[0] == 0);
    TEST_ASSERT(myGlobalElements[1] == 2);
    TEST_ASSERT(myGlobalElements[2] == 4);
    TEST_ASSERT(myGlobalElements[3] == 6);
  }
  if(rank == 1){
    TEST_ASSERT(myGlobalElements[0] == 5);
    TEST_ASSERT(myGlobalElements[1] == 7);
    TEST_ASSERT(myGlobalElements[2] == 1);
    TEST_ASSERT(myGlobalElements[3] == 3);
  }

  // check the 1d overlap map
  // for this simple discretization, everything should be ghosted on both processors
  Teuchos::RCP<const Epetra_BlockMap> overlapMap = discretization->getGlobalOverlapMap(1);
  TEST_ASSERT(overlapMap->NumGlobalElements() == 16);
  TEST_ASSERT(overlapMap->NumMyElements() == 8);
  TEST_ASSERT(overlapMap->ElementSize() == 1);
  TEST_ASSERT(overlapMap->IndexBase() == 0);
  TEST_ASSERT(overlapMap->UniqueGIDs() == false);
  myGlobalElements = overlapMap->MyGlobalElements();
  if(rank == 0){
    TEST_ASSERT(myGlobalElements[0] == 0);
    TEST_ASSERT(myGlobalElements[1] == 2);
    TEST_ASSERT(myGlobalElements[2] == 4);
    TEST_ASSERT(myGlobalElements[3] == 6);
    TEST_ASSERT(myGlobalElements[4] == 1);
    TEST_ASSERT(myGlobalElements[5] == 3);
    TEST_ASSERT(myGlobalElements[6] == 5);
    TEST_ASSERT(myGlobalElements[7] == 7);
  }
  if(rank == 1){
    TEST_ASSERT(myGlobalElements[0] == 5);
    TEST_ASSERT(myGlobalElements[1] == 7);
    TEST_ASSERT(myGlobalElements[2] == 1);
    TEST_ASSERT(myGlobalElements[3] == 3);
    TEST_ASSERT(myGlobalElements[4] == 0);
    TEST_ASSERT(myGlobalElements[5] == 2);
    TEST_ASSERT(myGlobalElements[6] == 4);
    TEST_ASSERT(myGlobalElements[7] == 6);
  }

  // same checks for 3d map
  map = discretization->getGlobalOwnedMap(3);
  TEST_ASSERT(map->NumGlobalElements() == 8);
  TEST_ASSERT(map->NumMyElements() == 4);
  TEST_ASSERT(map->ElementSize() == 3);
  TEST_ASSERT(map->IndexBase() == 0);
  TEST_ASSERT(map->UniqueGIDs() == true);
  myGlobalElements = map->MyGlobalElements();
  if(rank == 0){
    TEST_ASSERT(myGlobalElements[0] == 0);
    TEST_ASSERT(myGlobalElements[1] == 2);
    TEST_ASSERT(myGlobalElements[2] == 4);
    TEST_ASSERT(myGlobalElements[3] == 6);
  }
  if(rank == 1){
    TEST_ASSERT(myGlobalElements[0] == 5);
    TEST_ASSERT(myGlobalElements[1] == 7);
    TEST_ASSERT(myGlobalElements[2] == 1);
    TEST_ASSERT(myGlobalElements[3] == 3);
  }

  // check the 3d overlap map
  // for this simple discretization, everything should be ghosted on both processors
  overlapMap = discretization->getGlobalOverlapMap(3);
  TEST_ASSERT(overlapMap->NumGlobalElements() == 16);
  TEST_ASSERT(overlapMap->NumMyElements() == 8);
  TEST_ASSERT(overlapMap->ElementSize() == 3);
  TEST_ASSERT(overlapMap->IndexBase() == 0);
  TEST_ASSERT(overlapMap->UniqueGIDs() == false);
  myGlobalElements = overlapMap->MyGlobalElements();
  if(rank == 0){
    TEST_ASSERT(myGlobalElements[0] == 0);
    TEST_ASSERT(myGlobalElements[1] == 2);
    TEST_ASSERT(myGlobalElements[2] == 4);
    TEST_ASSERT(myGlobalElements[3] == 6);
    TEST_ASSERT(myGlobalElements[4] == 1);
    TEST_ASSERT(myGlobalElements[5] == 3);
    TEST_ASSERT(myGlobalElements[6] == 5);
    TEST_ASSERT(myGlobalElements[7] == 7);
  }
  if(rank == 1){
    TEST_ASSERT(myGlobalElements[0] == 5);
    TEST_ASSERT(myGlobalElements[1] == 7);
    TEST_ASSERT(myGlobalElements[2] == 1);
    TEST_ASSERT(myGlobalElements[3] == 3);
    TEST_ASSERT(myGlobalElements[4] == 0);
    TEST_ASSERT(myGlobalElements[5] == 2);
    TEST_ASSERT(myGlobalElements[6] == 4);
    TEST_ASSERT(myGlobalElements[7] == 6);
  }

  // check the bond map
  // the horizon was chosen such that each point should have three neighbors
  // note that if the NeighborhoodType parameter is not set to Spherical, this will fail
  Teuchos::RCP<const Epetra_BlockMap> bondMap = discretization->getGlobalBondMap();
  TEST_ASSERT(bondMap->NumGlobalElements() == 8);
  TEST_ASSERT(bondMap->NumMyElements() == 4);
  TEST_ASSERT(bondMap->IndexBase() == 0);
  TEST_ASSERT(bondMap->UniqueGIDs() == true);
  myGlobalElements = bondMap->MyGlobalElements();
  if(rank == 0){
    TEST_ASSERT(myGlobalElements[0] == 0);
    TEST_ASSERT(myGlobalElements[1] == 2);
    TEST_ASSERT(myGlobalElements[2] == 4);
    TEST_ASSERT(myGlobalElements[3] == 6);
  }
  if(rank == 1){
    TEST_ASSERT(myGlobalElements[0] == 5);
    TEST_ASSERT(myGlobalElements[1] == 7);
    TEST_ASSERT(myGlobalElements[2] == 1);
    TEST_ASSERT(myGlobalElements[3] == 3);
  }
  TEST_ASSERT(discretization->getNumBonds() == 4*3);

  // check the initial positions
  // all three coordinates are contained in a single vector
  Teuchos::RCP<Epetra_Vector> initialX = discretization->getInitialX();
  TEST_ASSERT(initialX->MyLength() == 4*3);
  TEST_ASSERT(initialX->GlobalLength() == 8*3);
  if(rank == 0){
    TEST_FLOATING_EQUALITY((*initialX)[0],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[1],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[2],  0.25, 1.0e-16);
 
    TEST_FLOATING_EQUALITY((*initialX)[3],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[4],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[5],  0.25, 1.0e-16);

    TEST_FLOATING_EQUALITY((*initialX)[6],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[7],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[8],  0.75, 1.0e-16);

    TEST_FLOATING_EQUALITY((*initialX)[9],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[10], 0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[11], 0.75, 1.0e-16);
  }
  if(rank == 1){
    TEST_FLOATING_EQUALITY((*initialX)[0],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[1],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[2],  0.75, 1.0e-16);

    TEST_FLOATING_EQUALITY((*initialX)[3],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[4],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[5],  0.75, 1.0e-16);

    TEST_FLOATING_EQUALITY((*initialX)[6],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[7],  0.25, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[8],  0.25, 1.0e-16);

    TEST_FLOATING_EQUALITY((*initialX)[9],  0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[10], 0.75, 1.0e-16);
    TEST_FLOATING_EQUALITY((*initialX)[11], 0.25, 1.0e-16);
  }

  // check cell volumes
  Teuchos::RCP<Epetra_Vector> volume = discretization->getCellVolume();
  TEST_ASSERT(volume->MyLength() == 4);
  TEST_ASSERT(volume->GlobalLength() == 8);
  for(int i=0 ; i<volume->MyLength() ; ++i)
    TEST_FLOATING_EQUALITY((*volume)[i], 0.125, 1.0e-16);

  // check the neighbor lists
  Teuchos::RCP<PeridigmNS::NeighborhoodData> neighborhoodData = discretization->getNeighborhoodData();
  TEST_ASSERT(neighborhoodData->NumOwnedPoints() == 4);
  int* ownedIds = neighborhoodData->OwnedIDs();
  TEST_ASSERT(ownedIds[0] == 0);
  TEST_ASSERT(ownedIds[1] == 1);
  TEST_ASSERT(ownedIds[2] == 2);
  TEST_ASSERT(ownedIds[3] == 3);
  TEST_ASSERT(neighborhoodData->NeighborhoodListSize() == 16);
  int* neighborhood = neighborhoodData->NeighborhoodList();
  int* neighborhoodPtr = neighborhoodData->NeighborhoodPtr();
  // remember, these are local IDs on each processor, 
  // which includes both owned and ghost nodes (confusing!)
  if(rank == 0){
    TEST_ASSERT(neighborhoodPtr[0] == 0);
    TEST_ASSERT(neighborhood[0]    == 3);
    TEST_ASSERT(neighborhood[1]    == 4);
    TEST_ASSERT(neighborhood[2]    == 1);
    TEST_ASSERT(neighborhood[3]    == 2);

    TEST_ASSERT(neighborhoodPtr[1] == 4);
    TEST_ASSERT(neighborhood[4]    == 3);
    TEST_ASSERT(neighborhood[5]    == 0);
    TEST_ASSERT(neighborhood[6]    == 5);
    TEST_ASSERT(neighborhood[7]    == 3);

    TEST_ASSERT(neighborhoodPtr[2] == 8);
    TEST_ASSERT(neighborhood[8]    == 3);
    TEST_ASSERT(neighborhood[9]    == 0);
    TEST_ASSERT(neighborhood[10]   == 6);
    TEST_ASSERT(neighborhood[11]   == 3);

    TEST_ASSERT(neighborhoodPtr[3] == 12);
    TEST_ASSERT(neighborhood[12]   == 3);
    TEST_ASSERT(neighborhood[13]   == 1);
    TEST_ASSERT(neighborhood[14]   == 2);
    TEST_ASSERT(neighborhood[15]   == 7);
  }
  if(rank == 1){
    TEST_ASSERT(neighborhoodPtr[0] == 0);
    TEST_ASSERT(neighborhood[0]    == 3);
    TEST_ASSERT(neighborhood[1]    == 2);
    TEST_ASSERT(neighborhood[2]    == 6);
    TEST_ASSERT(neighborhood[3]    == 1);

    TEST_ASSERT(neighborhoodPtr[1] == 4);
    TEST_ASSERT(neighborhood[4]    == 3);
    TEST_ASSERT(neighborhood[5]    == 3);
    TEST_ASSERT(neighborhood[6]    == 0);
    TEST_ASSERT(neighborhood[7]    == 7);

    TEST_ASSERT(neighborhoodPtr[2] == 8);
    TEST_ASSERT(neighborhood[8]    == 3);
    TEST_ASSERT(neighborhood[9]    == 4);
    TEST_ASSERT(neighborhood[10]   == 3);
    TEST_ASSERT(neighborhood[11]   == 0);

    TEST_ASSERT(neighborhoodPtr[3] == 12);
    TEST_ASSERT(neighborhood[12]   == 3);
    TEST_ASSERT(neighborhood[13]   == 2);
    TEST_ASSERT(neighborhood[14]   == 5);
    TEST_ASSERT(neighborhood[15]   == 1);
  }
}
Exemplo n.º 20
0
void
Albany::MpasSTKMeshStruct::constructMesh(
                                               const Teuchos::RCP<const Epetra_Comm>& comm,
                                               const Teuchos::RCP<Teuchos::ParameterList>& params,
                                               const unsigned int neq_,
                                               const Albany::AbstractFieldContainer::FieldContainerRequirements& req,
                                               const Teuchos::RCP<Albany::StateInfoStruct>& sis,
                                               const std::vector<int>& indexToVertexID, const std::vector<double>& verticesCoords, const std::vector<bool>& isVertexBoundary, int nGlobalVertices,
                                               const std::vector<int>& verticesOnTria,
                                               const std::vector<bool>& isBoundaryEdge, const std::vector<int>& trianglesOnEdge, const std::vector<int>& trianglesPositionsOnEdge,
                                               const std::vector<int>& verticesOnEdge,
                                               const std::vector<int>& indexToEdgeID, int nGlobalEdges,
                                               const std::vector<int>& indexToTriangleID,
                                               const unsigned int worksetSize,
                                               int numLayers, int Ordering)
{
	this->SetupFieldData(comm, neq_, req, sis, worksetSize);

    int elemColumnShift = (Ordering == 1) ? 1 : elem_map->NumGlobalElements()/numLayers;
    int lElemColumnShift = (Ordering == 1) ? 1 : indexToTriangleID.size();
    int elemLayerShift = (Ordering == 0) ? 1 : numLayers;

    int vertexColumnShift = (Ordering == 1) ? 1 : nGlobalVertices;
    int lVertexColumnShift = (Ordering == 1) ? 1 : indexToVertexID.size();
    int vertexLayerShift = (Ordering == 0) ? 1 : numLayers+1;

    int edgeColumnShift = (Ordering == 1) ? 1 : nGlobalEdges;
    int lEdgeColumnShift = (Ordering == 1) ? 1 : indexToEdgeID.size();
    int edgeLayerShift = (Ordering == 0) ? 1 : numLayers;


  metaData->commit();

  bulkData->modification_begin(); // Begin modifying the mesh

  stk::mesh::PartVector nodePartVec;
  stk::mesh::PartVector singlePartVec(1);
  stk::mesh::PartVector emptyPartVec;
  std::cout << "elem_map # elments: " << elem_map->NumMyElements() << std::endl;
  unsigned int ebNo = 0; //element block #???

  singlePartVec[0] = nsPartVec["Bottom"];


  AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field = fieldContainer->getProcRankField();
  AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();
  stk::mesh::Field<double>* surfaceHeight_field = metaData->get_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "surface_height");

  for(int i=0; i< (numLayers+1)*indexToVertexID.size(); i++)
  {
	  int ib = (Ordering == 0)*(i%lVertexColumnShift) + (Ordering == 1)*(i/vertexLayerShift);
	  int il = (Ordering == 0)*(i/lVertexColumnShift) + (Ordering == 1)*(i%vertexLayerShift);

	  stk::mesh::Entity node;
	  if(il == 0)
		  node = bulkData->declare_entity(stk::topology::NODE_RANK, il*vertexColumnShift+vertexLayerShift * indexToVertexID[ib]+1, singlePartVec);
	  else
		  node = bulkData->declare_entity(stk::topology::NODE_RANK, il*vertexColumnShift+vertexLayerShift * indexToVertexID[ib]+1, nodePartVec);
	  int numBdEdges(0);
	  for (int i=0; i<indexToEdgeID.size(); i++)
		  numBdEdges += isBoundaryEdge[i];


          double* coord = stk::mesh::field_data(*coordinates_field, node);
	  coord[0] = verticesCoords[3*ib];   coord[1] = verticesCoords[3*ib+1]; coord[2] = double(il)/numLayers;

	  double* sHeight;
	   sHeight = stk::mesh::field_data(*surfaceHeight_field, node);
	   sHeight[0] = 1.;
  }

  for (int i=0; i<elem_map->NumMyElements(); i++) {

	 int ib = (Ordering == 0)*(i%lElemColumnShift) + (Ordering == 1)*(i/elemLayerShift);
	 int il = (Ordering == 0)*(i/lElemColumnShift) + (Ordering == 1)*(i%elemLayerShift);

	 int shift = il*vertexColumnShift;

	 singlePartVec[0] = partVec[ebNo];
     stk::mesh::Entity elem  = bulkData->declare_entity(stk::topology::ELEMENT_RANK, elem_map->GID(i)+1, singlePartVec);

     for(int j=0; j<3; j++)
     {
    	 int lowerId = shift+vertexLayerShift * indexToVertexID[verticesOnTria[3*ib+j]]+1;
    	 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, lowerId);
    	 bulkData->declare_relation(elem, node, j);

    	 stk::mesh::Entity node_top = bulkData->get_entity(stk::topology::NODE_RANK, lowerId+vertexColumnShift);
    	 bulkData->declare_relation(elem, node_top, j+3);
     }

     int* p_rank = (int*)stk::mesh::field_data(*proc_rank_field, elem);
     p_rank[0] = comm->MyPID();
  }


  singlePartVec[0] = ssPartVec["lateralside"];

  //first we store the lateral faces of prisms, which corresponds to edges of the basal mesh

  for (int i=0; i<indexToEdgeID.size()*numLayers; i++) {
	 int ib = (Ordering == 0)*(i%lEdgeColumnShift) + (Ordering == 1)*(i/edgeLayerShift);
	 if(isBoundaryEdge[ib])
	 {
		 int il = (Ordering == 0)*(i/lEdgeColumnShift) + (Ordering == 1)*(i%edgeLayerShift);
		 int basalEdgeId = indexToEdgeID[ib]*edgeLayerShift;
		 int basalElemId = indexToTriangleID[trianglesOnEdge[2*ib]]*elemLayerShift;
		 int basalVertexId[2] = {indexToVertexID[verticesOnEdge[2*ib]]*vertexLayerShift, indexToVertexID[verticesOnEdge[2*ib+1]]*vertexLayerShift};
		 stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), edgeColumnShift*il+basalEdgeId+1, singlePartVec);
		 stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  basalElemId+elemColumnShift*il+1);
		 bulkData->declare_relation(elem, side,  trianglesPositionsOnEdge[2*ib] );
		 for(int j=0; j<2; j++)
		 {
			 stk::mesh::Entity nodeBottom = bulkData->get_entity(stk::topology::NODE_RANK, basalVertexId[j]+vertexColumnShift*il+1);
			 bulkData->declare_relation(side, nodeBottom, j);
			 stk::mesh::Entity nodeTop = bulkData->get_entity(stk::topology::NODE_RANK, basalVertexId[j]+vertexColumnShift*(il+1)+1);
			 bulkData->declare_relation(side, nodeTop, j+2);
		 }
	 }
  }

  //then we store the lower and upper faces of prisms, which corresponds to triangles of the basal mesh

  edgeLayerShift = (Ordering == 0) ? 1 : numLayers+1;
  edgeColumnShift = elemColumnShift;

  singlePartVec[0] = ssPartVec["basalside"];

  int edgeOffset = nGlobalEdges*numLayers;
  for (int i=0; i<indexToTriangleID.size(); i++)
  {
	  stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), indexToTriangleID[i]*edgeLayerShift+edgeOffset+1, singlePartVec);
	  stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  indexToTriangleID[i]*elemLayerShift+1);
	  bulkData->declare_relation(elem, side,  3);
	  for(int j=0; j<3; j++)
	  {
		 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, vertexLayerShift*indexToVertexID[verticesOnTria[3*i+j]]+1);
		 bulkData->declare_relation(side, node, j);
	  }
  }

  singlePartVec[0] = ssPartVec["upperside"];

  for (int i=0; i<indexToTriangleID.size(); i++)
  {
  	  stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), indexToTriangleID[i]*edgeLayerShift+numLayers*edgeColumnShift+edgeOffset+1, singlePartVec);
  	  stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  indexToTriangleID[i]*elemLayerShift+(numLayers-1)*elemColumnShift+1);
  	  bulkData->declare_relation(elem, side,  4);
  	  for(int j=0; j<3; j++)
  	  {
  		 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, vertexLayerShift*indexToVertexID[verticesOnTria[3*i+j]]+numLayers*vertexColumnShift+1);
  		 bulkData->declare_relation(side, node, j);
  	  }
  }

  bulkData->modification_end();
}
Exemplo n.º 21
0
int main(int argc, char *argv[])
{
  
  // Initialize MPI
  Teuchos::GlobalMPISession mpiSession(&argc,&argv);

  int ierr = 0;
  int MyPID = 0;
  double alpha = 1.00; // stable steady state
  double beta = BETA_INIT;
  double D1 = 1.0/40.0;
  double D2 = 1.0/40.0;
  int NumGlobalNodes = 10;  // default
  int spatialProcs   = 1;   // default
  int numTimeSteps   = 100;  // default
  
  try {

    // Check for verbose output
    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
    if ((argc > 2) && (verbose))
      NumGlobalNodes = atoi(argv[2]) + 1;
    else if ((argc > 1) && (!verbose))
      NumGlobalNodes = atoi(argv[1]) + 1;

    // Get the number of processors to use for the spatial problem
    if ((argc > 3) && (verbose))
      spatialProcs = atoi(argv[3]);
    else if ((argc > 2) && (!verbose))
      spatialProcs = atoi(argv[2]);

    // Get the number of processors to use for the spatial problem
    if ((argc > 4) && (verbose))
      numTimeSteps = atoi(argv[4]);
    else if ((argc > 3) && (!verbose))
      numTimeSteps = atoi(argv[3]);

    // MPI MANIPULATION FOR XYZT PROBLEMS
#ifdef HAVE_MPI
    Teuchos::RCP<EpetraExt::MultiMpiComm> globalComm = 
      Teuchos::rcp(new EpetraExt::MultiMpiComm(MPI_COMM_WORLD, 
					       spatialProcs, numTimeSteps));
#else
    Teuchos::RCP<EpetraExt::MultiSerialComm> globalComm = 
      Teuchos::rcp(new EpetraExt::MultiSerialComm(numTimeSteps));
#endif
    Epetra_Comm& Comm = globalComm->SubDomainComm();
    MyPID = globalComm->MyPID();

    // Get the total number of processors
    int NumProc = Comm.NumProc();

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

    // Create the Brusselator problem class.  This creates all required
    // Epetra objects for the problem and allows calls to the 
    // function (F) and Jacobian evaluation routines.
    Brusselator::OverlapType OType = Brusselator::ELEMENTS;
    Brusselator Problem(NumGlobalNodes, Comm, OType);
    
    // Get the vector from the Problem
    Epetra_Vector& soln = Problem.getSolution();
    
    // Begin Nonlinear Solver ************************************
    
    // Create the top level parameter list
    Teuchos::RCP<Teuchos::ParameterList> paramList =
      Teuchos::rcp(new Teuchos::ParameterList);
    getParamList(&(*paramList), MyPID);
    
    // Sublist for "Linear Solver"
    Teuchos::ParameterList& lsParams = 
      paramList->sublist("NOX").sublist("Direction").sublist("Newton").sublist("Linear Solver");
    
    // Sublist for "Printing"
    Teuchos::ParameterList& printParams = 
      paramList->sublist("NOX").sublist("Printing");
    
    // Change NOX priting settings if "-verbose" not requested
    if (!verbose)
      printParams.set("Output Information", NOX::Utils::Error);
      
    // Create the interface between the test problem and the nonlinear solver
    Teuchos::RCP<Problem_Interface> interface = 
      Teuchos::rcp(new Problem_Interface(Problem));
      
    // Create the Epetra_RowMatrixfor the Jacobian/Preconditioner
    Teuchos::RCP<Epetra_RowMatrix> A = 
      Teuchos::rcp(&Problem.getJacobian(),false);
      
    // Create initial guess
    Epetra_MultiVector initGuess(soln.Map(), 
				 globalComm->NumTimeStepsOnDomain());
    for (int i=0; i<globalComm->NumTimeStepsOnDomain(); i++) 
      *(initGuess(i)) = soln;
      
    // Get XYZT preconditioner linear solver parameters
    Teuchos::RCP<Teuchos::ParameterList> precLSParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    getPrecLSParams(&(*precLSParams), MyPID);

    // Get XYZT preconditioner print parameters
    Teuchos::RCP<Teuchos::ParameterList> precPrintParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    getPrecPrintParams(&(*precPrintParams), MyPID);
      
    // Change xyztPrec priting settings if "-verbose" not requested
    if (!verbose)
      precPrintParams->set("Output Information", NOX::Utils::Error);
	
    // Create the XYZT object
    Teuchos::RCP<LOCA::Epetra::Interface::xyzt> ixyzt = 
      Teuchos::rcp(new LOCA::Epetra::Interface::xyzt(interface,
                                                     initGuess, A,
                                                     globalComm,
                                                     soln, 0.5,
                                                     precPrintParams.get(),
                                                     precLSParams.get()));

    // Create the XYZT operator, solution, and preconditioner
    Teuchos::RCP<Epetra_RowMatrix> Axyzt =
      Teuchos::rcp(&(ixyzt->getJacobian()),false);
    Epetra_Vector& solnxyzt = ixyzt->getSolution();
    Teuchos::RCP<Epetra_Operator> Mxyzt = 
      Teuchos::rcp(&(ixyzt->getPreconditioner()),false);
    
    // Create the Linear System
    Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = ixyzt;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = ixyzt;
    Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = 
      Teuchos::rcp(&(ixyzt->getPreconditioner()),false);
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys =
      Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							iJac, Axyzt, 
							iPrec, Mxyzt, 
							solnxyzt));

    // Create full xyzt initial guess
    NOX::Epetra::Vector initialGuess(solnxyzt);
      
    // Create and initialize the parameter vector
    LOCA::ParameterVector pVector;
    pVector.addParameter("alpha",alpha);
    pVector.addParameter("beta",beta);
    pVector.addParameter("D1",D1);
    pVector.addParameter("D2",D2);
      
    // Create Epetra factory
    Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory =
      Teuchos::rcp(new LOCA::Epetra::Factory);
      
    // Create global data object
    Teuchos::RCP<LOCA::GlobalData> globalData = 
      LOCA::createGlobalData(paramList, epetraFactory);
      
    Teuchos::RCP<LOCA::Epetra::Group> grp =
      Teuchos::rcp(new LOCA::Epetra::Group(globalData, printParams,
					   iReq, initialGuess, linSys, 
					   pVector));
      
    grp->computeF();
      
    // Create the convergence tests
    Teuchos::RCP<NOX::StatusTest::NormF> absresid = 
      Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-8, 
					      NOX::StatusTest::NormF::Unscaled));
    Teuchos::RCP<NOX::StatusTest::MaxIters> maxiters = 
      Teuchos::rcp(new NOX::StatusTest::MaxIters(MAX_NEWTON_ITERS));
    Teuchos::RCP<NOX::StatusTest::Combo> combo =
      Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR));
    combo->addStatusTest(absresid);
    combo->addStatusTest(maxiters);
      
    // Create stepper
    LOCA::Stepper stepper(globalData, grp, combo, paramList);
      
    LOCA::Abstract::Iterator::IteratorStatus status = stepper.run();
      
    if (status != LOCA::Abstract::Iterator::Finished) {
      ierr =1;
      if (globalData->locaUtils->isPrintType(NOX::Utils::Error))
	globalData->locaUtils->out() 
	  << "Stepper failed to converge!" << std::endl;
    }
      
    // Get the final solution from the stepper
    Teuchos::RCP<const LOCA::Epetra::Group> finalGroup = 
      Teuchos::rcp_dynamic_cast<const LOCA::Epetra::Group>(stepper.getSolutionGroup());
    const NOX::Epetra::Vector& finalSolution = 
      dynamic_cast<const NOX::Epetra::Vector&>(finalGroup->getX());
      
    // Output the parameter list
    if (globalData->locaUtils->isPrintType(NOX::Utils::StepperParameters)) {
      globalData->locaUtils->out() 
	<< std::endl << "Final Parameters" << std::endl
	<< "****************" << std::endl;
      stepper.getList()->print(globalData->locaUtils->out());
      globalData->locaUtils->out() << std::endl;
    }
      
    // Check some statistics on the solution
    NOX::TestCompare testCompare(globalData->locaUtils->out(), 
				 *(globalData->locaUtils));
      
    if (globalData->locaUtils->isPrintType(NOX::Utils::TestDetails))
      globalData->locaUtils->out() 
	<< std::endl 
	<< "***** Checking solution statistics *****" 
	<< std::endl;
      
    // Check number of continuation steps
    int numSteps = stepper.getStepNumber();
    int numSteps_expected = 3;
    ierr += testCompare.testValue(numSteps, numSteps_expected, 0.0,
				  "number of continuation steps",
				  NOX::TestCompare::Absolute);
      
    // Check number of failed steps
    int numFailedSteps = stepper.getNumFailedSteps();
    int numFailedSteps_expected = 0;
    ierr += testCompare.testValue(numFailedSteps, numFailedSteps_expected, 0.0,
				  "number of failed continuation steps",
				  NOX::TestCompare::Absolute);
      
    // Check final value of continuation parameter
    double beta_final = finalGroup->getParam("beta");
    double beta_expected = 2.0;
    ierr += testCompare.testValue(beta_final, beta_expected, 1.0e-14,
				  "final value of continuation parameter", 
				  NOX::TestCompare::Relative);
      
    // Check final value of ||F||
    double Fnorm_final = (const_cast<Teuchos::ParameterList&>(*stepper.getList()).sublist("NOX").sublist("Output").get("2-Norm of Residual",1.0e+10));
    double Fnorm_expected = 0.0;
    ierr += testCompare.testValue(Fnorm_final, Fnorm_expected, 1.0e-8,
				  "final value of ||F||", 
				  NOX::TestCompare::Absolute);
      
    // Check number of nonlinear iterations on last continuation step
    int nonlin_final = (const_cast<Teuchos::ParameterList&>(*stepper.getList()).sublist("NOX").
			sublist("Output").get("Nonlinear Iterations",MAX_NEWTON_ITERS));
    int nonlin_expected = 4;
    ierr += testCompare.testValue(nonlin_final, nonlin_expected, 0.0,
				  "number of nonlinear iterations on last continuation step", 
				  NOX::TestCompare::Absolute);
      
      
    // initialize solution comparison norm on all procs
    double solution_diff_norm = 0.0;
      
    // Compute norm of difference of computed solution - expected solution
    if (globalComm->MyPID() == (globalComm->NumProc()-1)) {
      // Get solution at last time step
      ixyzt->getSolution().ExtractBlockValues(soln, 
					      (globalComm->NumTimeStepsOnDomain() + 
					       globalComm->FirstTimeStepOnDomain() - 1));
	
      // Check final solution at final time step
      NOX::Epetra::Vector final_solution(soln);
      NOX::Epetra::Vector final_x_expected(final_solution);
      for (int i=0; i<NumGlobalNodes; i++) {
	final_x_expected.getEpetraVector()[2*i] = alpha;
	final_x_expected.getEpetraVector()[2*i+1] = beta_final/alpha;
      }
      solution_diff_norm = testCompare.computeVectorNorm(final_solution, 
							 final_x_expected, 
							 1.0e-4, 
							 1.0e-4);
	
    }
      
    // Check final solution at final time step on all procs
    globalComm->Broadcast(&solution_diff_norm, 1, globalComm->NumProc()-1);
    double solution_diff_norm_expected = 0.0;
    ierr += testCompare.testValue(solution_diff_norm, solution_diff_norm_expected, 1.0e-4,
				  "inf norm of (solution_final - solution_expected) at last time step", 
				  NOX::TestCompare::Absolute);
            
    LOCA::destroyGlobalData(globalData);
        
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
    ierr = 1;
  }
  catch (const char *s) {
    std::cout << s << std::endl;
    ierr = 1;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" << std::endl;
    ierr = 1;
  }

  if (MyPID == 0) {
    if (ierr == 0)
      std::cout << "All tests passed!" << std::endl;
    else
      std::cout << ierr << " test(s) failed!" << std::endl;
  }

  return ierr;
}
  TEUCHOS_UNIT_TEST(response_library_stk2, test)
  {
    typedef Traits::Residual EvalT;

    using Teuchos::RCP;

    PHX::KokkosDeviceSession session;

  #ifdef HAVE_MPI
     Teuchos::RCP<Teuchos::Comm<int> > tcomm = Teuchos::rcp(new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(MPI_COMM_WORLD)));
  #else
     Teuchos::RCP<Teuchos::Comm<int> > tcomm = Teuchos::rcp(new Teuchos::SerialComm<int>);
  #endif

    panzer_stk_classic::SquareQuadMeshFactory mesh_factory;
    Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
    user_app::BCFactory bc_factory;
    const std::size_t workset_size = 1;

    panzer::FieldManagerBuilder fmb;

    // setup mesh
    /////////////////////////////////////////////
    RCP<panzer_stk_classic::STK_Interface> mesh;
    {
       RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList);
       pl->set("X Blocks",2);
       pl->set("Y Blocks",1);
       pl->set("X Elements",2);
       pl->set("Y Elements",2);
       pl->set("X0",0.0);
       pl->set("Y0",0.0);
       pl->set("Xf",8.0);
       pl->set("Yf",4.0);
       mesh_factory.setParameterList(pl);
       mesh = mesh_factory.buildMesh(MPI_COMM_WORLD);
    }

    // setup physic blocks
    /////////////////////////////////////////////
    Teuchos::RCP<Teuchos::ParameterList> ipb = Teuchos::parameterList("Physics Blocks");
    std::vector<panzer::BC> bcs;
    std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physics_blocks;
    {
       testInitialzation(ipb, bcs);

       std::map<std::string,std::string> block_ids_to_physics_ids;
       block_ids_to_physics_ids["eblock-0_0"] = "test physics";
       block_ids_to_physics_ids["eblock-1_0"] = "test physics";

       std::map<std::string,Teuchos::RCP<const shards::CellTopology> > block_ids_to_cell_topo;
       block_ids_to_cell_topo["eblock-0_0"] = mesh->getCellTopology("eblock-0_0");
       block_ids_to_cell_topo["eblock-1_0"] = mesh->getCellTopology("eblock-1_0");
    
       Teuchos::RCP<panzer::GlobalData> gd = panzer::createGlobalData();

      int default_integration_order = 1;
      
       panzer::buildPhysicsBlocks(block_ids_to_physics_ids,
                                  block_ids_to_cell_topo,
				  ipb,
				  default_integration_order,
				  workset_size,
                                  eqset_factory,
				  gd,
		    	          false,
                                  physics_blocks);
    }

    // setup worksets
    /////////////////////////////////////////////
 
     std::vector<std::string> validEBlocks;
     mesh->getElementBlockNames(validEBlocks);

    // build WorksetContainer
    Teuchos::RCP<panzer_stk_classic::WorksetFactory> wkstFactory 
       = Teuchos::rcp(new panzer_stk_classic::WorksetFactory(mesh)); // build STK workset factory
    Teuchos::RCP<panzer::WorksetContainer> wkstContainer     // attach it to a workset container (uses lazy evaluation)
       = Teuchos::rcp(new panzer::WorksetContainer(wkstFactory,physics_blocks,workset_size));
 
    // setup DOF manager
    /////////////////////////////////////////////
    const Teuchos::RCP<panzer::ConnManager<int,int> > conn_manager 
           = Teuchos::rcp(new panzer_stk_classic::STKConnManager<int>(mesh));

    Teuchos::RCP<const panzer::UniqueGlobalIndexerFactory<int,int,int,int> > indexerFactory
          = Teuchos::rcp(new panzer::DOFManagerFactory<int,int>);
    const Teuchos::RCP<panzer::UniqueGlobalIndexer<int,int> > dofManager 
          = indexerFactory->buildUniqueGlobalIndexer(Teuchos::opaqueWrapper(MPI_COMM_WORLD),physics_blocks,conn_manager);

    // and linear object factory
    Teuchos::RCP<const Epetra_Comm> comm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
    Teuchos::RCP<panzer::EpetraLinearObjFactory<panzer::Traits,int> > elof 
          = Teuchos::rcp(new panzer::EpetraLinearObjFactory<panzer::Traits,int>(comm.getConst(),dofManager));

    Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > lof = elof;

    // setup field manager builder
    /////////////////////////////////////////////
      
    // Add in the application specific closure model factory
    user_app::MyModelFactory_TemplateBuilder cm_builder;
    panzer::ClosureModelFactory_TemplateManager<panzer::Traits> cm_factory; 
    cm_factory.buildObjects(cm_builder);

    Teuchos::ParameterList closure_models("Closure Models");
    closure_models.sublist("solid").sublist("SOURCE_TEMPERATURE").set<double>("Value",1.0);
    closure_models.sublist("ion solid").sublist("SOURCE_ION_TEMPERATURE").set<double>("Value",1.0);
    closure_models.sublist("Response Model");

    Teuchos::ParameterList user_data("User Data");
    user_data.sublist("Panzer Data").set("Mesh", mesh);
    user_data.sublist("Panzer Data").set("DOF Manager", dofManager);
    user_data.sublist("Panzer Data").set("Linear Object Factory", lof);
    user_data.set<int>("Workset Size",workset_size);

    // IP is in center of element
    user_data.sublist("IP Coordinates").set<int>("Integration Order",1);

    // setup and evaluate ResponseLibrary
    ///////////////////////////////////////////////////
 
    out << "Adding responses" << std::endl;

    RCP<ResponseLibrary<Traits> > rLibrary 
          = Teuchos::rcp(new ResponseLibrary<Traits>(wkstContainer,dofManager,lof));

    
    ResponseEvaluatorFactory_IPCoordinates_Builder builder;
    builder.cubatureDegree = 1;

    std::vector<std::string> blocks(1);
    blocks[0] = "eblock-0_0";
    rLibrary->addResponse("IPCoordinates-0_0",blocks,builder);
    blocks[0] = "eblock-1_0";
    rLibrary->addResponse("IPCoordinates-1_0",blocks,builder);

    Teuchos::RCP<ResponseBase> resp00 = rLibrary->getResponse<panzer::Traits::Residual>("IPCoordinates-0_0");
    Teuchos::RCP<ResponseBase> resp10 = rLibrary->getResponse<panzer::Traits::Residual>("IPCoordinates-1_0");

    TEST_NOTHROW(Teuchos::rcp_dynamic_cast<Response_IPCoordinates<panzer::Traits::Residual> >(resp00,true));
    TEST_NOTHROW(Teuchos::rcp_dynamic_cast<Response_IPCoordinates<panzer::Traits::Residual> >(resp10,true));

    rLibrary->buildResponseEvaluators(physics_blocks,
  				      cm_factory,
                                      closure_models,
  				      user_data,true);

    Teuchos::RCP<panzer::LinearObjContainer> loc = lof->buildLinearObjContainer();
    lof->initializeContainer(panzer::LinearObjContainer::X,*loc);
    Teuchos::RCP<panzer::LinearObjContainer> gloc = lof->buildGhostedLinearObjContainer();
    lof->initializeGhostedContainer(panzer::LinearObjContainer::X,*gloc);

    out << "evaluating VFM" << std::endl;
    panzer::AssemblyEngineInArgs ae_inargs(gloc,loc);
    rLibrary->addResponsesToInArgs<panzer::Traits::Residual>(ae_inargs);
    rLibrary->evaluate<panzer::Traits::Residual>(ae_inargs);
 
    std::map<std::string,Teuchos::RCP<const std::vector<panzer::Traits::Residual::ScalarT> > > coords;
    coords["eblock-0_0"] = Teuchos::rcp_dynamic_cast<Response_IPCoordinates<panzer::Traits::Residual> >(resp00,true)->getCoords();;
    coords["eblock-1_0"] = Teuchos::rcp_dynamic_cast<Response_IPCoordinates<panzer::Traits::Residual> >(resp10,true)->getCoords();;
    
    // Debugging
    if (true) {
      Teuchos::RCP<Teuchos::FancyOStream> out2 = Teuchos::getFancyOStream(Teuchos::rcp(&out,false));
      out2->setOutputToRootOnly(-1);
      *out2 << "\nPrinting IP coordinates for block: eblock-0_0" << std::endl;
      for (std::vector<panzer::Traits::Residual::ScalarT>::const_iterator i = (coords["eblock-0_0"])->begin(); i != (coords["eblock-0_0"])->end(); ++i)
	*out2 << "pid = " << comm->MyPID() << ", val = " << *i << std::endl;
      *out2 << "\nPrinting IP coordinates for block: eblock-1_0" << std::endl;
      for (std::vector<panzer::Traits::Residual::ScalarT>::const_iterator i = (coords["eblock-1_0"])->begin(); i != (coords["eblock-1_0"])->end(); ++i)
	*out2 << "pid = " << comm->MyPID() << ", val = " << *i << std::endl;
    }
   
    
    const double double_tol = 10.0*std::numeric_limits<double>::epsilon();

    // NOTE: if the ordering of elements in STK changes or the
    // ordering of integration points in Intrepid2 changes, this test
    // will break!  It assumes a fixed deterministic ordering.
    if (tcomm->getSize() == 1) {
      // eblock 1
      {
	const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-0_0"]); 
	TEST_FLOATING_EQUALITY(values[0], 1.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[1], 3.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[2], 1.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[3], 3.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[4], 1.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[5], 1.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[6], 3.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[7], 3.0, double_tol);  // y 
      }
      // eblock 2
      {
	const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-1_0"]);
	TEST_FLOATING_EQUALITY(values[0], 5.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[1], 7.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[2], 5.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[3], 7.0, double_tol);  // x 
	TEST_FLOATING_EQUALITY(values[4], 1.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[5], 1.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[6], 3.0, double_tol);  // y 
	TEST_FLOATING_EQUALITY(values[7], 3.0, double_tol);  // y 
      }
    }
    else if (tcomm->getSize() == 2) {

      if (comm->MyPID() == 0) {
	// eblock 1
	{
	  const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-0_0"]); 
	  TEST_FLOATING_EQUALITY(values[0], 1.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[1], 1.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[2], 1.0, double_tol);  // y 
	  TEST_FLOATING_EQUALITY(values[3], 3.0, double_tol);  // y 
	}
	// eblock 2
	{
	  const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-1_0"]);
	  TEST_FLOATING_EQUALITY(values[0], 5.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[1], 5.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[2], 1.0, double_tol);  // y 
	  TEST_FLOATING_EQUALITY(values[3], 3.0, double_tol);  // y 
	}
      }
      else if (comm->MyPID() == 1) {
	// eblock 1
	{
	  const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-0_0"]); 
	  TEST_FLOATING_EQUALITY(values[0], 3.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[1], 3.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[2], 1.0, double_tol);  // y 
	  TEST_FLOATING_EQUALITY(values[3], 3.0, double_tol);  // y 
	}
	// eblock 2
	{
	  const std::vector<panzer::Traits::Residual::ScalarT>& values = *(coords["eblock-1_0"]);
	  TEST_FLOATING_EQUALITY(values[0], 7.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[1], 7.0, double_tol);  // x 
	  TEST_FLOATING_EQUALITY(values[2], 1.0, double_tol);  // y 
	  TEST_FLOATING_EQUALITY(values[3], 3.0, double_tol);  // y 
	}
      }
    }
    else {
      TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error,"Error - this test can only be run with 1 or 2 processes!");
    }

  }
Exemplo n.º 23
0
TEUCHOS_UNIT_TEST(tCloneLOF, blocked_epetra_nonblocked_domain)
{
   typedef Thyra::ProductVectorBase<double> PVector;
   typedef Thyra::BlockedLinearOpBase<double> BLinearOp;
   typedef Thyra::VectorBase<double> Vector;

   // 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

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


   int myRank = eComm->MyPID();
   int numProc = eComm->NumProc();

   RCP<ConnManager<int,int> > connManager = rcp(new unit_test::ConnManager<int>(myRank,numProc));

   RCP<const FieldPattern> patternC1
         = buildFieldPattern<Intrepid2::Basis_HGRAD_QUAD_C1_FEM<double,FieldContainer> >();
   RCP<const FieldPattern> patternC2
         = buildFieldPattern<Intrepid2::Basis_HGRAD_QUAD_C2_FEM<double,FieldContainer> >();

   RCP<panzer::BlockedDOFManager<int,int> > indexer = rcp(new panzer::BlockedDOFManager<int,int>());
   {
     std::vector<std::vector<std::string> > fieldOrder(2);

     indexer->setConnManager(connManager,MPI_COMM_WORLD);
     indexer->addField("U",patternC1);
     indexer->addField("V",patternC1);

     fieldOrder[0].push_back("U");
     fieldOrder[1].push_back("V");
     indexer->setFieldOrder(fieldOrder);
     indexer->buildGlobalUnknowns();
   }

   RCP<panzer::DOFManager<int,int> > control_indexer = rcp(new panzer::DOFManager<int,int>());
   {
     control_indexer->setConnManager(connManager,MPI_COMM_WORLD);
     control_indexer->addField("Z",patternC1);
     control_indexer->buildGlobalUnknowns();

     patternC2->print(out);
   }

   // setup factory
   out << "build lof" << std::endl;
   RCP<BlockedEpetraLinearObjFactory<Traits,int> > ep_lof
         = Teuchos::rcp(new BlockedEpetraLinearObjFactory<Traits,int>(tComm,indexer));
   
   // this is the member we are testing!
   out << "cloning lof" << std::endl;
   RCP<const LinearObjFactory<Traits> > control_lof = cloneWithNewDomain(*ep_lof,control_indexer);

   out << "casting lof" << std::endl;
   RCP<const BlockedEpetraLinearObjFactory<Traits,int> > ep_control_lof 
       = rcp_dynamic_cast<const BlockedEpetraLinearObjFactory<Traits,int> >(control_lof,true);

   out << "using casted lof" << std::endl;
   RCP<BLinearOp> mat  = rcp_dynamic_cast<BLinearOp>(ep_control_lof->getThyraMatrix(),true); 
   RCP<BLinearOp> gmat = rcp_dynamic_cast<BLinearOp>(ep_control_lof->getGhostedThyraMatrix(),true); 
   RCP<Vector>    x    = ep_control_lof->getThyraDomainVector();
   RCP<Vector>    gx   = ep_control_lof->getGhostedThyraDomainVector();
   RCP<PVector>   f    = rcp_dynamic_cast<PVector>(ep_control_lof->getThyraRangeVector(),true); 
   RCP<PVector>   gf   = rcp_dynamic_cast<PVector>(ep_control_lof->getGhostedThyraRangeVector(),true); 

   TEST_EQUALITY(x->space()->dim(),18);
   TEST_EQUALITY(gx->space()->dim(),10+15);

   TEST_EQUALITY(f->productSpace()->numBlocks(),2);
   TEST_EQUALITY(f->productSpace()->dim(),36);
   TEST_EQUALITY(gf->productSpace()->numBlocks(),2);
   TEST_EQUALITY(gf->productSpace()->dim(),50);


   TEST_EQUALITY(mat->productRange()->numBlocks(),2);
   TEST_EQUALITY(mat->productRange()->dim(),36);
   TEST_EQUALITY(mat->productDomain()->numBlocks(),1);
   TEST_EQUALITY(mat->productDomain()->dim(),18);

   TEST_EQUALITY(gmat->productRange()->numBlocks(),2);
   TEST_EQUALITY(gmat->productRange()->dim(),50);
   TEST_EQUALITY(gmat->productDomain()->numBlocks(),1);
   TEST_EQUALITY(gmat->productDomain()->dim(),10+15);
}
Exemplo n.º 24
0
int main(int argc, char *argv[]) {
  int n = 32;                        // spatial discretization (per dimension)
  int num_KL = 2;                    // number of KL terms
  int p = 3;                         // polynomial order
  double mu = 0.1;                   // mean of exponential random field
  double s = 0.2;                    // std. dev. of exponential r.f.
  bool nonlinear_expansion = false;  // nonlinear expansion of diffusion coeff
                                     // (e.g., log-normal)
  bool matrix_free = true;           // use matrix-free stochastic operator
  bool symmetric = false;            // use symmetric formulation

  double g_mean_exp = 0.172988;      // expected response mean
  double g_std_dev_exp = 0.0380007;  // expected response std. dev.
  double g_tol = 1e-6;               // tolerance on determining success

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

  int MyPID;

  try {

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();
    
    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p, true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor();
    else
      Cijk = basis->computeLinearTripleProductTensor();
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    if (argc > 1)
      num_spatial_procs = std::atoi(argv[1]);
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();

    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model =
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, mu, s, basis, 
					 nonlinear_expansion, symmetric));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& sgOpParams = 
      sgParams->sublist("SG Operator");
    Teuchos::ParameterList& sgPrecParams = 
      sgParams->sublist("SG Preconditioner");
    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    if (matrix_free) {
      sgOpParams.set("Operator Method", "Matrix Free");
      sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
      sgPrecParams.set("Symmetric Gauss-Seidel", symmetric);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams = 
      	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams.set("default values", "SA");
      precParams.set("ML output", 0);
      precParams.set("max levels",5);
      precParams.set("increasing or decreasing","increasing");
      precParams.set("aggregation: type", "Uncoupled");
      precParams.set("smoother: type","ML symmetric Gauss-Seidel");
      precParams.set("smoother: sweeps",2);
      precParams.set("smoother: pre or post", "both");
      precParams.set("coarse: max size", 200);
#ifdef HAVE_ML_AMESOS
      precParams.set("coarse: type","Amesos-KLU");
#else
      precParams.set("coarse: type","Jacobi");
#endif
    }
    else {
      sgOpParams.set("Operator Method", "Fully Assembled");
      sgPrecParams.set("Preconditioner Method", "None");
    }

   // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
                                                 expansion, sg_parallel_data, 
						 sgParams));

    // Set up stochastic parameters
    // The current implementation of the model doesn't actually use these 
    // values, but is hard-coded to certain uncertainty models
    Teuchos::Array<double> point(num_KL, 1.0);
    Teuchos::Array<double> basis_vals(sz);
    basis->evaluateBases(point, basis_vals);
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_init =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_init->term(i,0)[i] = 0.0;
      sg_p_init->term(i,1)[i] = 1.0 / basis_vals[i+1];
    }
    sg_model->set_p_sg_init(0, *sg_p_init);

    // Setup stochastic initial guess
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_init = 
      sg_model->create_x_sg();
    sg_x_init->init(0.0);
    sg_model->set_x_sg_init(*sg_x_init);

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams = 
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

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

    // Create printing utilities
    NOX::Utils utils(printParams);

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

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->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");
    if (symmetric)
      lsParams.set("Aztec Solver", "CG");
    else
      lsParams.set("Aztec Solver", "GMRES");
    lsParams.set("Max Iterations", 1000);
    lsParams.set("Size of Krylov Subspace", 100);
    lsParams.set("Tolerance", 1e-12); 
    lsParams.set("Output Frequency", 1);
    if (matrix_free)
      lsParams.set("Preconditioner", "User Defined");
    else {
      lsParams.set("Preconditioner", "ML");
      Teuchos::ParameterList& precParams = 
	lsParams.sublist("ML");
      ML_Epetra::SetDefaults("DD", precParams);
      lsParams.set("Write Linear System", false);
    }

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", 1e-10);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 1);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
    if (matrix_free) {
      Teuchos::RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
      Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iJac, A, iPrec, M,
							  *u));
    }
    else {
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iReq, iJac, A, 
							  *u));
    }

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));

    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

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

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

    // Get final solution
    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();

    // Save final solution to file
    EpetraExt::VectorToMatrixMarketFile("nox_stochastic_solution.mm", 
					finalSolution);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, &finalSolution);
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
      
    // Evaluate SG responses at SG parameters
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = 
      sg_model->createOutArgs();
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
    sg_outArgs.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs);

    // Print mean and standard deviation of response
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << std::endl;
    std::cout << "Response Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    // Determine if example passed
    bool passed = false;
    if (status == NOX::StatusTest::Converged &&
	std::abs(g_mean[0]-g_mean_exp) < g_tol &&
	std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
      passed = true;
    if (MyPID == 0) {
      if (passed)
	std::cout << "Example Passed!" << std::endl;
      else
	std::cout << "Example Failed!" << std::endl;
    }

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
Exemplo n.º 25
0
int main(int argc, char *argv[])
{
  
  using Teuchos::rcp_implicit_cast;

  int i, ierr, gerr;
  gerr = 0;

#ifdef HAVE_MPI
  // Initialize MPI and setup an Epetra communicator
  MPI_Init(&argc,&argv);
  Teuchos::RCP<Epetra_MpiComm> Comm = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_WORLD) );
#else
  // If we aren't using MPI, then setup a serial communicator.
  Teuchos::RCP<Epetra_SerialComm> Comm = Teuchos::rcp( new Epetra_SerialComm() );
#endif


   // number of global elements
  int dim = 100;
  int blockSize = 3;

  // PID info
  int MyPID = Comm->MyPID();
  bool verbose = 0;

  if (argc>1) {
    if (argv[1][0]=='-' && argv[1][1]=='v') {
      verbose = true;
    }
  }

  // Construct a Map that puts approximately the same number of 
  // equations on each processor.
  Teuchos::RCP<Epetra_Map> Map = Teuchos::rcp( new Epetra_Map(dim, 0, *Comm) );
  
  // Get update list and number of local equations from newly created Map.
  int NumMyElements = Map->NumMyElements();
  std::vector<int> MyGlobalElements(NumMyElements);
  Map->MyGlobalElements(&MyGlobalElements[0]);

  // Create an integer std::vector NumNz that is used to build the Petra Matrix.
  // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation 
  // on this processor
  std::vector<int> NumNz(NumMyElements);

  // We are building a tridiagonal matrix where each row has (-1 2 -1)
  // So we need 2 off-diagonal terms (except for the first and last equation)
  for (i=0; i<NumMyElements; i++) {
    if (MyGlobalElements[i]==0 || MyGlobalElements[i] == dim-1) {
      NumNz[i] = 2;
    }
    else {
      NumNz[i] = 3;
    }
  }

  // Create an Epetra_Matrix
  Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( new Epetra_CrsMatrix(Copy, *Map, &NumNz[0]) );
   
  // Add  rows one-at-a-time
  // Need some vectors to help
  // Off diagonal Values will always be -1
  std::vector<double> Values(2);
  Values[0] = -1.0; Values[1] = -1.0;
  std::vector<int> Indices(2);
  double two = 2.0;
  int NumEntries;
  for (i=0; i<NumMyElements; i++) {
    if (MyGlobalElements[i]==0) {
      Indices[0] = 1;
      NumEntries = 1;
    }
    else if (MyGlobalElements[i] == dim-1) {
      Indices[0] = dim-2;
      NumEntries = 1;
    }
    else {
      Indices[0] = MyGlobalElements[i]-1;
      Indices[1] = MyGlobalElements[i]+1;
      NumEntries = 2;
    }
    ierr = A->InsertGlobalValues(MyGlobalElements[i],NumEntries,&Values[0],&Indices[0]);
    assert(ierr==0);
    // Put in the diagonal entry
    ierr = A->InsertGlobalValues(MyGlobalElements[i],1,&two,&MyGlobalElements[i]);
    assert(ierr==0);
  }
   
  // Finish building the epetra matrix A
  ierr = A->FillComplete();
  assert(ierr==0);

  // Create an Belos::EpetraOp from this Epetra_CrsMatrix
  Teuchos::RCP<Belos::EpetraOp> op = Teuchos::rcp(new Belos::EpetraOp(A));

  // Issue several useful typedefs;
  typedef Belos::MultiVec<double> EMV;
  typedef Belos::Operator<double> EOP;

  // Create an Epetra_MultiVector for an initial std::vector to start the solver.
  // Note that this needs to have the same number of columns as the blocksize.
  Teuchos::RCP<Belos::EpetraMultiVec> ivec = Teuchos::rcp( new Belos::EpetraMultiVec(*Map, blockSize) );
  ivec->Random();

  // Create an output manager to handle the I/O from the solver
  Teuchos::RCP<Belos::OutputManager<double> > MyOM = Teuchos::rcp( new Belos::OutputManager<double>( MyPID ) );
  if (verbose) {
    MyOM->setVerbosity( Belos::Errors + Belos::Warnings );
  }

#ifdef HAVE_EPETRA_THYRA
  typedef Thyra::MultiVectorBase<double> TMVB;
  typedef Thyra::LinearOpBase<double>    TLOB;
  // create thyra objects from the epetra objects

  // first, a Thyra::VectorSpaceBase
  Teuchos::RCP<const Thyra::VectorSpaceBase<double> > epetra_vs = 
    Thyra::create_VectorSpace(Map);

  // then, a MultiVectorBase (from the Epetra_MultiVector)
  Teuchos::RCP<Thyra::MultiVectorBase<double> > thyra_ivec = 
    Thyra::create_MultiVector(rcp_implicit_cast<Epetra_MultiVector>(ivec),epetra_vs);

  // then, a LinearOpBase (from the Epetra_CrsMatrix)
  Teuchos::RCP<Thyra::LinearOpBase<double> > thyra_op = 
    Teuchos::rcp( new Thyra::EpetraLinearOp(A) );


  // test the Thyra adapter multivector
  ierr = Belos::TestMultiVecTraits<double,TMVB>(MyOM,thyra_ivec);
  gerr |= ierr;
  switch (ierr) {
  case Belos::Ok:
    if ( verbose && MyPID==0 ) {
      std::cout << "*** ThyraAdapter PASSED TestMultiVecTraits()" << std::endl;
    }
    break;
  case Belos::Error:
    if ( verbose && MyPID==0 ) {
      std::cout << "*** ThyraAdapter FAILED TestMultiVecTraits() ***" 
           << std::endl << std::endl;
    }
    break;
  }

  // test the Thyra adapter operator 
  ierr = Belos::TestOperatorTraits<double,TMVB,TLOB>(MyOM,thyra_ivec,thyra_op);
  gerr |= ierr;
  switch (ierr) {
  case Belos::Ok:
    if ( verbose && MyPID==0 ) {
      std::cout << "*** ThyraAdapter PASSED TestOperatorTraits()" << std::endl;
    }
    break;
  case Belos::Error:
    if ( verbose && MyPID==0 ) {
      std::cout << "*** ThyraAdapter FAILED TestOperatorTraits() ***" 
           << std::endl << std::endl;
    }
    break;
  }
#endif

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  if (gerr) {
    if (verbose && MyPID==0)
      std::cout << "End Result: TEST FAILED" << std::endl;	
    return -1;
  }
  //
  // Default return value
  //
  if (verbose && MyPID==0)
    std::cout << "End Result: TEST PASSED" << std::endl;
  return 0;

}
Exemplo n.º 26
0
int main(int argc, char *argv[]) {
  int n = 32;                        // spatial discretization (per dimension)
  int num_KL = 2;                    // number of KL terms
  int p = 3;                         // polynomial order
  double mu = 0.1;                   // mean of exponential random field
  double s = 0.2;                    // std. dev. of exponential r.f.
  bool nonlinear_expansion = false;  // nonlinear expansion of diffusion coeff
                                     // (e.g., log-normal)
  bool symmetric = false;            // use symmetric formulation

  double g_mean_exp = 0.172988;      // expected response mean
  double g_std_dev_exp = 0.0380007;  // expected response std. dev.
  double g_tol = 1e-6;               // tolerance on determining success

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

  int MyPID;

  try {

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();

    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p,true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases,
		     1e-12));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor(sz);
    else
      Cijk = basis->computeTripleProductTensor(num_KL+1);
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    // parallelParams.set("Rebalance Stochastic Graph", true);
    // Teuchos::ParameterList& isorropia_params = 
    //   parallelParams.sublist("Isorropia");
    // isorropia_params.set("Balance objective", "nonzeros");
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();

    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model = 
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, mu, s, basis, 
					 nonlinear_expansion, symmetric));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    
    Teuchos::ParameterList precParams;
    precParams.set("default values", "SA");
    precParams.set("ML output", 0);
    precParams.set("max levels",5);
    precParams.set("increasing or decreasing","increasing");
    precParams.set("aggregation: type", "Uncoupled");
    precParams.set("smoother: type","ML symmetric Gauss-Seidel");
    precParams.set("smoother: sweeps",2);
    precParams.set("smoother: pre or post", "both");
    precParams.set("coarse: max size", 200);
    //precParams.set("PDE equations",sz);
#ifdef HAVE_ML_AMESOS
    precParams.set("coarse: type","Amesos-KLU");
#else
    precParams.set("coarse: type","Jacobi");
#endif

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator_Interlaced> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator_Interlaced(
		     model, basis, Teuchos::null,
		     expansion, sg_parallel_data, 
		     sgParams));

    // Set up stochastic parameters
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_poly =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_poly->term(i,0)[i] = 0.0;
      sg_p_poly->term(i,1)[i] = 1.0;
    }

    // Create vectors and operators
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_p_poly->getBlockVector();
    Teuchos::RCP<Epetra_Vector> sg_x =
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
    sg_x->PutScalar(0.0);
    Teuchos::RCP<Epetra_Vector> sg_f = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_f_map())));
    Teuchos::RCP<Epetra_Vector> sg_dx = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_x_map())));
    Teuchos::RCP<Epetra_CrsMatrix> sg_J = 
      Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(sg_model->create_W());
    Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> sg_M =
      Teuchos::rcp(new ML_Epetra::MultiLevelPreconditioner(*sg_J, precParams,
							   false));
    
    // Setup InArgs and OutArgs
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = sg_model->createOutArgs();
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(sg_x);
    sg_outArgs.set_f(sg_f);
    sg_outArgs.set_W(sg_J);

    // Evaluate model
    sg_model->evalModel(sg_inArgs, sg_outArgs);
    sg_M->ComputePreconditioner();

    // Print initial residual norm
    double norm_f;
    sg_f->Norm2(&norm_f);
    if (MyPID == 0)
      std::cout << "\nInitial residual norm = " << norm_f << std::endl;

    // Setup AztecOO solver
    AztecOO aztec;
    if (symmetric)
      aztec.SetAztecOption(AZ_solver, AZ_cg);
    else
      aztec.SetAztecOption(AZ_solver, AZ_gmres);
    aztec.SetAztecOption(AZ_precond, AZ_none);
    aztec.SetAztecOption(AZ_kspace, 20);
    aztec.SetAztecOption(AZ_conv, AZ_r0);
    aztec.SetAztecOption(AZ_output, 1);
    aztec.SetUserOperator(sg_J.get());
    aztec.SetPrecOperator(sg_M.get());
    aztec.SetLHS(sg_dx.get());
    aztec.SetRHS(sg_f.get());

    // Solve linear system
    aztec.Iterate(1000, 1e-12);

    // Update x
    sg_x->Update(-1.0, *sg_dx, 1.0);

    // Save solution to file
    EpetraExt::VectorToMatrixMarketFile("stochastic_solution_interlaced.mm", 
					*sg_x);

    // Save RHS to file
    EpetraExt::VectorToMatrixMarketFile("stochastic_RHS_interlaced.mm", 
					*sg_f);

    // Save operator to file
    EpetraExt::RowMatrixToMatrixMarketFile("stochastic_operator_interlaced.mm", 
					   *sg_J);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, sg_x.get());
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal_interlaced.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal_interlaced.mm", std_dev);

    // Compute new residual & response function
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs2 = sg_model->createOutArgs();
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_f->PutScalar(0.0);
    sg_outArgs2.set_f(sg_f);
    sg_outArgs2.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs2);

    // Print initial residual norm
    sg_f->Norm2(&norm_f);
    if (MyPID == 0)
      std::cout << "\nFinal residual norm = " << norm_f << std::endl;

    // Print mean and standard deviation of responses
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << "\nResponse Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    // Determine if example passed
    bool passed = false;
    if (norm_f < 1.0e-10 &&
	std::abs(g_mean[0]-g_mean_exp) < g_tol &&
	std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
      passed = true;
    if (MyPID == 0) {
      if (passed)
	std::cout << "Example Passed!" << std::endl;
      else
	std::cout << "Example Failed!" << std::endl;
    }

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
Exemplo n.º 27
0
void
Albany::MpasSTKMeshStruct::constructMesh(
                                               const Teuchos::RCP<const Epetra_Comm>& comm,
                                               const Teuchos::RCP<Teuchos::ParameterList>& params,
                                               const unsigned int neq_,
                                               const Albany::AbstractFieldContainer::FieldContainerRequirements& req,
                                               const Teuchos::RCP<Albany::StateInfoStruct>& sis,
                                               const std::vector<int>& indexToVertexID, const std::vector<int>& indexToMpasVertexID, const std::vector<double>& verticesCoords, const std::vector<bool>& isVertexBoundary, int nGlobalVertices,
                                               const std::vector<int>& verticesOnTria,
                                               const std::vector<bool>& isBoundaryEdge, const std::vector<int>& trianglesOnEdge, const std::vector<int>& trianglesPositionsOnEdge,
                                               const std::vector<int>& verticesOnEdge,
                                               const std::vector<int>& indexToEdgeID, int nGlobalEdges,
                                               const std::vector<int>& indexToTriangleID,
                                               const unsigned int worksetSize,
                                               int numLayers, int Ordering)
{
	this->SetupFieldData(comm, neq_, req, sis, worksetSize);

    int elemColumnShift = (Ordering == 1) ? 3 : elem_map->NumGlobalElements()/numLayers;
    int lElemColumnShift = (Ordering == 1) ? 3 : 3*indexToTriangleID.size();
    int elemLayerShift = (Ordering == 0) ? 3 : 3*numLayers;

    int vertexColumnShift = (Ordering == 1) ? 1 : nGlobalVertices;
    int lVertexColumnShift = (Ordering == 1) ? 1 : indexToVertexID.size();
    int vertexLayerShift = (Ordering == 0) ? 1 : numLayers+1;

    int edgeColumnShift = (Ordering == 1) ? 2 : 2*nGlobalEdges;
    int lEdgeColumnShift = (Ordering == 1) ? 1 : indexToEdgeID.size();
    int edgeLayerShift = (Ordering == 0) ? 1 : numLayers;


  metaData->commit();

  bulkData->modification_begin(); // Begin modifying the mesh

  stk::mesh::PartVector nodePartVec;
  stk::mesh::PartVector singlePartVec(1);
  stk::mesh::PartVector emptyPartVec;
  std::cout << "elem_map # elments: " << elem_map->NumMyElements() << std::endl;
  unsigned int ebNo = 0; //element block #???

  singlePartVec[0] = nsPartVec["Bottom"];

  AbstractSTKFieldContainer::IntScalarFieldType* proc_rank_field = fieldContainer->getProcRankField();
  AbstractSTKFieldContainer::VectorFieldType* coordinates_field = fieldContainer->getCoordinatesField();

  for(int i=0; i< (numLayers+1)*indexToVertexID.size(); i++)
  {
	  int ib = (Ordering == 0)*(i%lVertexColumnShift) + (Ordering == 1)*(i/vertexLayerShift);
	  int il = (Ordering == 0)*(i/lVertexColumnShift) + (Ordering == 1)*(i%vertexLayerShift);

	  stk::mesh::Entity node;
	  if(il == 0)
		  node = bulkData->declare_entity(stk::topology::NODE_RANK, il*vertexColumnShift+vertexLayerShift * indexToVertexID[ib]+1, singlePartVec);
	  else
		  node = bulkData->declare_entity(stk::topology::NODE_RANK, il*vertexColumnShift+vertexLayerShift * indexToVertexID[ib]+1, nodePartVec);

      double* coord = stk::mesh::field_data(*coordinates_field, node);
	  coord[0] = verticesCoords[3*ib];   coord[1] = verticesCoords[3*ib+1]; coord[2] = double(il)/numLayers;
  }

  int tetrasLocalIdsOnPrism[3][4];

  for (int i=0; i<elem_map->NumMyElements()/3; i++) {

	 int ib = (Ordering == 0)*(i%(lElemColumnShift/3)) + (Ordering == 1)*(i/(elemLayerShift/3));
	 int il = (Ordering == 0)*(i/(lElemColumnShift/3)) + (Ordering == 1)*(i%(elemLayerShift/3));

	 int shift = il*vertexColumnShift;

	 singlePartVec[0] = partVec[ebNo];


     //TODO: this could be done only in the first layer and then copied into the other layers
     int prismMpasIds[3], prismGlobalIds[6];
     for (int j = 0; j < 3; j++)
	 {
    	 int mpasLowerId = vertexLayerShift * indexToMpasVertexID[verticesOnTria[3*ib+j]];
    	 int lowerId = shift+vertexLayerShift * indexToVertexID[verticesOnTria[3*ib+j]];
    	 prismMpasIds[j] = mpasLowerId;
		 prismGlobalIds[j] = lowerId;
		 prismGlobalIds[j + 3] = lowerId+vertexColumnShift;
	 }

     tetrasFromPrismStructured (prismMpasIds, prismGlobalIds, tetrasLocalIdsOnPrism);


     for(int iTetra = 0; iTetra<3; iTetra++)
     {
    	 stk::mesh::Entity elem  = bulkData->declare_entity(stk::topology::ELEMENT_RANK, elem_map->GID(3*i+iTetra)+1, singlePartVec);
		 for(int j=0; j<4; j++)
		 {
			 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, tetrasLocalIdsOnPrism[iTetra][j]+1);
			 bulkData->declare_relation(elem, node, j);
		 }
		 int* p_rank = (int*)stk::mesh::field_data(*proc_rank_field, elem);
		 p_rank[0] = comm->MyPID();
     }


  }


  singlePartVec[0] = ssPartVec["lateralside"];

  //first we store the lateral faces of prisms, which corresponds to edges of the basal mesh
  int tetraSidePoints[4][3] = {{0, 1, 3}, {1, 2, 3}, {0, 3, 2}, {0, 2, 1}};
  std::vector<int> tetraPos(2), facePos(2);

  std::vector<std::vector<std::vector<int> > > prismStruct(3, std::vector<std::vector<int> >(4, std::vector<int>(3)));
  for (int i=0; i<indexToEdgeID.size()*numLayers; i++) {
	 int ib = (Ordering == 0)*(i%lEdgeColumnShift) + (Ordering == 1)*(i/edgeLayerShift);
	 if(isBoundaryEdge[ib])
	 {
		 int il = (Ordering == 0)*(i/lEdgeColumnShift) + (Ordering == 1)*(i%edgeLayerShift);
		 int lBasalElemId = trianglesOnEdge[2*ib];
		 int basalElemId = indexToTriangleID[lBasalElemId];

		 //TODO: this could be done only in the first layer and then copied into the other layers
		 int prismMpasIds[3], prismGlobalIds[6];
		 int shift = il*vertexColumnShift;
		 for (int j = 0; j < 3; j++)
		 {
			 int mpasLowerId = vertexLayerShift * indexToMpasVertexID[verticesOnTria[3*lBasalElemId+j]];
			 int lowerId = shift+vertexLayerShift * indexToVertexID[verticesOnTria[3*lBasalElemId+j]];
			 prismMpasIds[j] = mpasLowerId;
			 prismGlobalIds[j] = lowerId;
			 prismGlobalIds[j + 3] = lowerId+vertexColumnShift;
		 }

		  tetrasFromPrismStructured (prismMpasIds, prismGlobalIds, tetrasLocalIdsOnPrism);


		for(int iTetra = 0; iTetra<3; iTetra++)
		  {
			 std::vector<std::vector<int> >& tetraStruct =prismStruct[iTetra];
			 stk::mesh::EntityId tetraPoints[4];
			 for(int j=0; j<4; j++)
			 {
                           tetraPoints[j] = tetrasLocalIdsOnPrism[iTetra][j]+1;
				// std::cout<< tetraPoints[j] << ", ";
			 }
			 for(int iFace=0; iFace<4; iFace++)
			 {
				 std::vector<int>&  face = tetraStruct[iFace];
				 for(int j=0; j<3; j++)
				 	 face[j] = tetraPoints[tetraSidePoints[iFace][j]];
			 }
		  }



		 int basalVertexId[2] = {indexToVertexID[verticesOnEdge[2*ib]]*vertexLayerShift, indexToVertexID[verticesOnEdge[2*ib+1]]*vertexLayerShift};
		 std::vector<int> bdPrismFaceIds(4);

		 bdPrismFaceIds[0] = indexToVertexID[verticesOnEdge[2*ib]]*vertexLayerShift+vertexColumnShift*il+1;
		 bdPrismFaceIds[1] = indexToVertexID[verticesOnEdge[2*ib+1]]*vertexLayerShift+vertexColumnShift*il+1;
		 bdPrismFaceIds[2] = bdPrismFaceIds[0]+vertexColumnShift;
		 bdPrismFaceIds[3] = bdPrismFaceIds[1]+vertexColumnShift;

		 //std::cout<< "bdPrismFaceIds: (" << bdPrismFaceIds[0] << ", " << bdPrismFaceIds[1] << ", " << bdPrismFaceIds[2] << ", " << bdPrismFaceIds[3] << ")"<<std::endl;



		 setBdFacesOnPrism (prismStruct, bdPrismFaceIds, tetraPos, facePos);

		 int basalEdgeId = indexToEdgeID[ib]*2*edgeLayerShift;
		 for(int k=0; k< tetraPos.size(); k++)
		 {
			 int iTetra = tetraPos[k];
			 int iFace = facePos[k];
			 stk::mesh::Entity elem = bulkData->get_entity(stk::topology::ELEMENT_RANK, il*elemColumnShift+elemLayerShift * basalElemId +iTetra+1);
			 std::vector<int>& faceIds = prismStruct[iTetra][iFace];
			 stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), edgeColumnShift*il+basalEdgeId+k+1, singlePartVec);
			 bulkData->declare_relation(elem, side,  iFace );
			 for(int j=0; j<3; j++)
			 {
				 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, faceIds[j]);
				 bulkData->declare_relation(side, node, j);
			 }
		 }
	 }
  }

  //then we store the lower and upper faces of prisms, which corresponds to triangles of the basal mesh

  edgeLayerShift = (Ordering == 0) ? 1 : numLayers+1;
  edgeColumnShift = 2*(elemColumnShift/3);

  singlePartVec[0] = ssPartVec["basalside"];

  int edgeOffset = 2*nGlobalEdges*numLayers;
  for (int i=0; i<indexToTriangleID.size(); i++)
  {
	  stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), indexToTriangleID[i]*edgeLayerShift+edgeOffset+1, singlePartVec);
	  stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  indexToTriangleID[i]*elemLayerShift+1);
	  bulkData->declare_relation(elem, side,  3);
	  for(int j=0; j<3; j++)
	  {
		 stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, vertexLayerShift*indexToVertexID[verticesOnTria[3*i+j]]+1);
		 bulkData->declare_relation(side, node, j);
	  }
  }

  singlePartVec[0] = ssPartVec["upperside"];

  for (int i=0; i<indexToTriangleID.size(); i++)
  {
	stk::mesh::Entity side = bulkData->declare_entity(metaData->side_rank(), indexToTriangleID[i]*edgeLayerShift+numLayers*edgeColumnShift+edgeOffset+1, singlePartVec);
	stk::mesh::Entity elem  = bulkData->get_entity(stk::topology::ELEMENT_RANK,  indexToTriangleID[i]*elemLayerShift+(numLayers-1)*elemColumnShift+1+2);
	bulkData->declare_relation(elem, side,  1);
	for(int j=0; j<3; j++)
	{
	  stk::mesh::Entity node = bulkData->get_entity(stk::topology::NODE_RANK, vertexLayerShift*indexToVertexID[verticesOnTria[3*i+j]]+numLayers*vertexColumnShift+1);
	  bulkData->declare_relation(side, node, j);
	}
  }

  bulkData->modification_end();
}
PeridigmNS::TextFileDiscretization::TextFileDiscretization(const Teuchos::RCP<const Epetra_Comm>& epetra_comm,
                                                           const Teuchos::RCP<Teuchos::ParameterList>& params) :
  minElementRadius(1.0e50),
  maxElementRadius(0.0),
  maxElementDimension(0.0),
  numBonds(0),
  maxNumBondsPerElem(0),
  myPID(epetra_comm->MyPID()),
  numPID(epetra_comm->NumProc()),
  bondFilterCommand("None"),
  comm(epetra_comm)
{
  TEUCHOS_TEST_FOR_EXCEPT_MSG(params->get<string>("Type") != "Text File", "Invalid Type in TextFileDiscretization");

  string meshFileName = params->get<string>("Input Mesh File");
  if(params->isParameter("Omit Bonds Between Blocks"))
    bondFilterCommand = params->get<string>("Omit Bonds Between Blocks");

  // Set up bond filters
  createBondFilters(params);

  QUICKGRID::Data decomp = getDecomp(meshFileName, params);

  // \todo Refactor; the createMaps() call is currently inside getDecomp() due to order-of-operations issues with tracking element blocks.
  //createMaps(decomp);
  createNeighborhoodData(decomp);

  // \todo Move this functionality to base class, it's currently duplicated in PdQuickGridDiscretization.
  // Create the bondMap, a local map used for constitutive data stored on bonds.
  // Due to Epetra_BlockMap restrictions, there can not be any entries with length zero.
  // This means that points with no neighbors can not appear in the bondMap.
  int numMyElementsUpperBound = oneDimensionalMap->NumMyElements();
  int numGlobalElements = -1; 
  int numMyElements = 0;
  int maxNumBonds = 0;
  int* oneDimensionalMapGlobalElements = oneDimensionalMap->MyGlobalElements();
  int* myGlobalElements = new int[numMyElementsUpperBound];
  int* elementSizeList = new int[numMyElementsUpperBound];
  int* const neighborhood = neighborhoodData->NeighborhoodList();
  int neighborhoodIndex = 0;
  int numPointsWithZeroNeighbors = 0;
  for(int i=0 ; i<neighborhoodData->NumOwnedPoints() ; ++i){
    int numNeighbors = neighborhood[neighborhoodIndex];
    if(numNeighbors > 0){
      numMyElements++;
      myGlobalElements[i-numPointsWithZeroNeighbors] = oneDimensionalMapGlobalElements[i];
      elementSizeList[i-numPointsWithZeroNeighbors] = numNeighbors;
    }
    else{
      numPointsWithZeroNeighbors++;
    }
    numBonds += numNeighbors;
    if(numNeighbors>maxNumBonds) maxNumBonds = numNeighbors;
    neighborhoodIndex += 1 + numNeighbors;
  }
  maxNumBondsPerElem = maxNumBonds;
  int indexBase = 0;
  bondMap = Teuchos::rcp(new Epetra_BlockMap(numGlobalElements, numMyElements, myGlobalElements, elementSizeList, indexBase, *comm));
  delete[] myGlobalElements;
  delete[] elementSizeList;

  // 3D only
  TEUCHOS_TEST_FOR_EXCEPT_MSG(decomp.dimension != 3, "Invalid dimension in decomposition (only 3D is supported)");

  // fill the x vector with the current positions (owned positions only)
  initialX = Teuchos::rcp(new Epetra_Vector(Copy, *threeDimensionalMap, decomp.myX.get()));

  // fill cell volumes
  cellVolume = Teuchos::rcp(new Epetra_Vector(Copy,*oneDimensionalMap,decomp.cellVolume.get()) );

  // find the minimum element radius
  for(int i=0 ; i<cellVolume->MyLength() ; ++i){
    double radius = pow(0.238732414637843*(*cellVolume)[i], 0.33333333333333333);
    if(radius < minElementRadius)
      minElementRadius = radius;
    if(radius > maxElementRadius)
      maxElementRadius = radius;
  }
  vector<double> localMin(1);
  vector<double> globalMin(1);
  localMin[0] = minElementRadius;
  epetra_comm->MinAll(&localMin[0], &globalMin[0], 1);
  minElementRadius = globalMin[0];
  localMin[0] = maxElementRadius;
  epetra_comm->MaxAll(&localMin[0], &globalMin[0], 1);
  maxElementRadius = globalMin[0];
}
Exemplo n.º 29
0
twoD_diffusion_ME::
twoD_diffusion_ME(
  const Teuchos::RCP<const Epetra_Comm>& comm, int n, int d,
  double s, double mu,
  const Teuchos::RCP<const Stokhos::OrthogPolyBasis<int,double> >& basis_,
  bool log_normal_,
  bool eliminate_bcs_,
  const Teuchos::RCP<Teuchos::ParameterList>& precParams_) :
  mesh(n*n),
  basis(basis_),
  log_normal(log_normal_),
  eliminate_bcs(eliminate_bcs_),
  precParams(precParams_)
{
  //////////////////////////////////////////////////////////////////////////////
  // Construct the mesh.
  // The mesh is uniform and the nodes are numbered
  // LEFT to RIGHT, DOWN to UP.
  //
  // 5-6-7-8-9
  // | | | | |
  // 0-1-2-3-4
  /////////////////////////////////////////////////////////////////////////////
  double xyLeft = -.5;
  double xyRight = .5;
  h = (xyRight - xyLeft)/((double)(n-1));
  Teuchos::Array<int> global_dof_indices;
  for (int j=0; j<n; j++) {
    double y = xyLeft + j*h;
    for (int i=0; i<n; i++) {
      double x = xyLeft + i*h;
      int idx = j*n+i;
      mesh[idx].x = x;
      mesh[idx].y = y;
      if (i == 0 || i == n-1 || j == 0 || j == n-1)
        mesh[idx].boundary = true;
      if (i != 0)
        mesh[idx].left = idx-1;
      if (i != n-1)
        mesh[idx].right = idx+1;
      if (j != 0)
        mesh[idx].down = idx-n;
      if (j != n-1)
        mesh[idx].up = idx+n;
      if (!(eliminate_bcs && mesh[idx].boundary))
        global_dof_indices.push_back(idx);
    }
  }

  // Solution vector map
  int n_global_dof = global_dof_indices.size();
  int n_proc = comm->NumProc();
  int proc_id = comm->MyPID();
  int n_my_dof = n_global_dof / n_proc;
  if (proc_id == n_proc-1)
    n_my_dof += n_global_dof % n_proc;
  int *my_dof = global_dof_indices.getRawPtr() + proc_id*(n_global_dof / n_proc);
  x_map =
    Teuchos::rcp(new Epetra_Map(n_global_dof, n_my_dof, my_dof, 0, *comm));

  // Initial guess, initialized to 0.0
  x_init = Teuchos::rcp(new Epetra_Vector(*x_map));
  x_init->PutScalar(0.0);

  // Parameter vector map
  p_map = Teuchos::rcp(new Epetra_LocalMap(d, 0, *comm));

  // Response vector map
  g_map = Teuchos::rcp(new Epetra_LocalMap(1, 0, *comm));

  // Initial parameters
  p_init = Teuchos::rcp(new Epetra_Vector(*p_map));
  p_init->PutScalar(0.0);

  // Parameter names
  p_names = Teuchos::rcp(new Teuchos::Array<std::string>(d));
  for (int i=0;i<d;i++) {
    std::stringstream ss;
    ss << "KL Random Variable " << i+1;
    (*p_names)[i] = ss.str();
  }

  // Build Jacobian graph
  int NumMyElements = x_map->NumMyElements();
  int *MyGlobalElements = x_map->MyGlobalElements();
  graph = Teuchos::rcp(new Epetra_CrsGraph(Copy, *x_map, 5));
  for (int i=0; i<NumMyElements; ++i ) {

    // Center
    int global_idx = MyGlobalElements[i];
    graph->InsertGlobalIndices(global_idx, 1, &global_idx);

    if (!mesh[global_idx].boundary) {
      // Down
      if (!(eliminate_bcs && mesh[mesh[global_idx].down].boundary))
        graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].down);

      // Left
      if (!(eliminate_bcs && mesh[mesh[global_idx].left].boundary))
        graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].left);

      // Right
      if (!(eliminate_bcs && mesh[mesh[global_idx].right].boundary))
        graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].right);

      // Up
      if (!(eliminate_bcs && mesh[mesh[global_idx].up].boundary))
        graph->InsertGlobalIndices(global_idx, 1, &mesh[global_idx].up);
    }
  }
  graph->FillComplete();
  graph->OptimizeStorage();

  KL_Diffusion_Func klFunc(xyLeft, xyRight, mu, s, 1.0, d);
  if (!log_normal) {
    // Fill coefficients of KL expansion of operator
    if (basis == Teuchos::null) {
      fillMatrices(klFunc, d+1);
    }
    else {
      Normalized_KL_Diffusion_Func<KL_Diffusion_Func> nklFunc(klFunc, *basis);
      fillMatrices(nklFunc, d+1);
    }
  }
  else {
    // Fill coefficients of PC expansion of operator
    int sz = basis->size();
    Teuchos::RCP<const Stokhos::ProductBasis<int, double> > prodbasis =
      Teuchos::rcp_dynamic_cast<const Stokhos::ProductBasis<int, double> >(
        basis, true);
    LogNormal_Diffusion_Func<KL_Diffusion_Func> lnFunc(mu, klFunc, prodbasis);
    fillMatrices(lnFunc, sz);
  }

  // Construct deterministic operator
  A = Teuchos::rcp(new Epetra_CrsMatrix(Copy, *graph));

  // Construct the RHS vector.
  b = Teuchos::rcp(new Epetra_Vector(*x_map));
  for( int i=0 ; i<NumMyElements; ++i ) {
    int global_idx = MyGlobalElements[i];
    if (mesh[global_idx].boundary)
      (*b)[i] = 0;
    else
      (*b)[i] = 1;
  }

  if (basis != Teuchos::null) {
    point.resize(d);
    basis_vals.resize(basis->size());
  }

  if (precParams != Teuchos::null) {
    std::string name = precParams->get("Preconditioner Type", "Ifpack");
    Teuchos::RCP<Teuchos::ParameterList> p =
      Teuchos::rcp(&(precParams->sublist("Preconditioner Parameters")), false);
    precFactory =
      Teuchos::rcp(new Stokhos::PreconditionerFactory(name, p));
  }
}
Exemplo n.º 30
0
TEUCHOS_UNIT_TEST(field_manager_builder, basic)
{
  // 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;

  int myRank = eComm->MyPID();
  int numProc = eComm->NumProc();

  Teuchos::RCP<panzer::GlobalData> global_data = panzer::createGlobalData();

  RCP<Stokhos::OrthogPolyExpansion<int,double> > sgExpansion = buildExpansion(3,5);
  RCP<unit_test::UniqueGlobalIndexer> indexer
        = rcp(new unit_test::UniqueGlobalIndexer(myRank,numProc));
  indexer->buildGlobalUnknowns();

  Teuchos::RCP<Teuchos::ParameterList> ipb = Teuchos::parameterList("Physics Blocks");
  std::vector<panzer::BC> bcs;
  testInitialzation(ipb, bcs);

  Teuchos::RCP<panzer::FieldManagerBuilder> fmb = 
    Teuchos::rcp(new panzer::FieldManagerBuilder);

  // build physics blocks
  //////////////////////////////////////////////////////////////
  const std::size_t workset_size = 20;
  Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
  user_app::BCFactory bc_factory;
  std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks;

  Teuchos::RCP<const shards::CellTopology> topo = 
      Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >()));
  {
    std::map<std::string,std::string> block_ids_to_physics_ids;
    block_ids_to_physics_ids["block_0"] = "test physics";

    std::map<std::string,Teuchos::RCP<const shards::CellTopology> > block_ids_to_cell_topo;
    block_ids_to_cell_topo["block_0"] = topo;
    
    int default_integration_order = 1;
      
    panzer::buildPhysicsBlocks(block_ids_to_physics_ids,
                               block_ids_to_cell_topo,
			       ipb,
			       default_integration_order,
			       workset_size,
                               eqset_factory,
                               global_data,
			       false,
                               physicsBlocks);
  }

  // build worksets
  //////////////////////////////////////////////////////////////
  Intrepid::FieldContainer<double> coords;
  std::vector<std::size_t> cellIds(1,0);
  std::vector<std::size_t> sideIds(1,0);
  sideIds[0] = (myRank==0) ? 0 : 1;
  indexer->getCoordinates(cellIds[0],coords);

   Teuchos::RCP<panzer::WorksetFactoryBase> wkstFactory
     = Teuchos::rcp(new TestWorksetFactory(topo,cellIds,sideIds,coords,*physicsBlocks[0],bcs,myRank));
   Teuchos::RCP<panzer::WorksetContainer> wkstContainer
     = Teuchos::rcp(new panzer::WorksetContainer(wkstFactory,physicsBlocks,workset_size));

  // build DOF Manager
  /////////////////////////////////////////////////////////////

  Teuchos::RCP<panzer::EpetraLinearObjFactory<panzer::Traits,int> > eLinObjFactory
        = Teuchos::rcp(new panzer::EpetraLinearObjFactory<panzer::Traits,int>(eComm.getConst(),indexer));
  Teuchos::RCP<panzer::SGEpetraLinearObjFactory<panzer::Traits,int> > sgeLinObjFactory
        = Teuchos::rcp(new panzer::SGEpetraLinearObjFactory<panzer::Traits,int>(eLinObjFactory,sgExpansion,Teuchos::null));
  Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > linObjFactory = sgeLinObjFactory;

  // setup field manager build
  /////////////////////////////////////////////////////////////
 
  // Add in the application specific closure model factory
  user_app::MyModelFactory_TemplateBuilder cm_builder;
  panzer::ClosureModelFactory_TemplateManager<panzer::Traits> cm_factory;
  cm_factory.buildObjects(cm_builder);

  Teuchos::ParameterList closure_models("Closure Models");
  closure_models.sublist("solid").sublist("SOURCE_TEMPERATURE").set<double>("Value",1.0);
  closure_models.sublist("ion solid").sublist("SOURCE_ION_TEMPERATURE").set<double>("Value",1.0);

  Teuchos::ParameterList user_data("User Data");

  fmb->setWorksetContainer(wkstContainer);
  fmb->setupVolumeFieldManagers(physicsBlocks,cm_factory,closure_models,*linObjFactory,user_data);
  fmb->setupBCFieldManagers(bcs,physicsBlocks,*eqset_factory,cm_factory,bc_factory,closure_models,*linObjFactory,user_data);

  panzer::AssemblyEngine_TemplateManager<panzer::Traits> ae_tm;
  panzer::AssemblyEngine_TemplateBuilder builder(fmb,linObjFactory);
  ae_tm.buildObjects(builder);

  // setup deterministic linear object containers
  RCP<panzer::LinearObjContainer> ghosted = eLinObjFactory->buildGhostedLinearObjContainer();
  RCP<panzer::LinearObjContainer> global = eLinObjFactory->buildLinearObjContainer();
  RCP<panzer::EpetraLinearObjContainer> e_ghosted = rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(ghosted);
  RCP<panzer::EpetraLinearObjContainer> e_global = rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(global);

  eLinObjFactory->initializeGhostedContainer(panzer::EpetraLinearObjContainer::X |
                                             panzer::EpetraLinearObjContainer::DxDt |
                                             panzer::EpetraLinearObjContainer::F |
                                             panzer::EpetraLinearObjContainer::Mat,*ghosted);
  eLinObjFactory->initializeContainer(panzer::EpetraLinearObjContainer::X |
                                      panzer::EpetraLinearObjContainer::DxDt |
                                      panzer::EpetraLinearObjContainer::F |
                                      panzer::EpetraLinearObjContainer::Mat,*global);

  panzer::AssemblyEngineInArgs input(ghosted,global);
  input.alpha = 0;
  input.beta = 1;

  // setup stochastic linear object containers
  RCP<panzer::LinearObjContainer> sg_ghosted = linObjFactory->buildGhostedLinearObjContainer();
  RCP<panzer::LinearObjContainer> sg_global = linObjFactory->buildLinearObjContainer();
  RCP<panzer::SGEpetraLinearObjContainer> sgeGhosted = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(sg_ghosted);
  RCP<panzer::SGEpetraLinearObjContainer> sgeGlobal = rcp_dynamic_cast<panzer::SGEpetraLinearObjContainer>(sg_global);

  sgeLinObjFactory->initializeGhostedContainer(panzer::EpetraLinearObjContainer::X |
                                             panzer::EpetraLinearObjContainer::DxDt |
                                             panzer::EpetraLinearObjContainer::F |
                                             panzer::EpetraLinearObjContainer::Mat,*sg_ghosted);
  sgeLinObjFactory->initializeContainer(panzer::EpetraLinearObjContainer::X |
                                      panzer::EpetraLinearObjContainer::DxDt |
                                      panzer::EpetraLinearObjContainer::F |
                                      panzer::EpetraLinearObjContainer::Mat,*sg_global);

  panzer::AssemblyEngineInArgs sg_input(sg_ghosted,sg_global);
  sg_input.alpha = 0;
  sg_input.beta = 1;

  // evaluate both deterministic and stochastic problem
  ae_tm.getAsObject<panzer::Traits::Jacobian>()->evaluate(input);
  ae_tm.getAsObject<panzer::Traits::SGJacobian>()->evaluate(sg_input);

  out << "Determ Solution" << std::endl;
  e_global->get_A()->Print(out);
  e_global->get_f()->Print(out);

  out << "SG Solution" << std::endl;
  (*sgeGlobal->begin())->get_A()->Print(out);
  (*sgeGlobal->begin())->get_f()->Print(out);

  double diff,exact;

  // test residuals
  {
     (*sgeGlobal->begin())->get_f()->Update(-1.0,*e_global->get_f(),1.0);
     e_global->get_f()->Norm2(&exact);
     (*sgeGlobal->begin())->get_f()->Norm2(&diff);
     TEST_ASSERT(diff/exact < 1e-15);
  }

  // test jacobian
  {
     Epetra_Vector x(e_global->get_A()->RowMap());
     Epetra_Vector y1(e_global->get_A()->RowMap());
     Epetra_Vector y2(e_global->get_A()->RowMap());

     // test a bunch of vectors
     for(int i=0;i<10;i++) {
        x.Random();
        y1.PutScalar(0);
        y2.PutScalar(0);

        e_global->get_A()->Apply(x,y1);
        (*sgeGlobal->begin())->get_A()->Apply(x,y2);

        y2.Update(-1.0,y1,1.0);
        y1.Norm2(&exact);
        y2.Norm2(&diff);

        TEST_ASSERT(diff/exact < 1e-15);
     }
  }
}