コード例 #1
0
Teuchos::RCP< std::vector<panzer::Workset> > 
panzer::buildWorksets(const panzer::PhysicsBlock& pb,
		      const std::vector<std::size_t>& local_cell_ids,
		      const ArrayT& vertex_coordinates)
{
  using std::vector;
  using std::string;
  using Teuchos::RCP;
  using Teuchos::rcp;

  panzer::IntrepidFieldContainerFactory arrayFactory;

  std::size_t total_num_cells = local_cell_ids.size();

  std::size_t workset_size = pb.cellData().numCells();

  Teuchos::RCP< std::vector<panzer::Workset> > worksets_ptr = 
    Teuchos::rcp(new std::vector<panzer::Workset>);
  std::vector<panzer::Workset>& worksets = *worksets_ptr;
   
  // special case for 0 elements!
  if(total_num_cells==0) {

     // Setup integration rules and basis
     RCP<vector<int> > ir_degrees = rcp(new vector<int>(0));
     RCP<vector<string> > basis_names = rcp(new vector<string>(0));
      
     worksets.resize(1);
     std::vector<panzer::Workset>::iterator i = worksets.begin();
     i->num_cells = 0;
     i->block_id = pb.elementBlockID();
     i->ir_degrees = ir_degrees;
     i->basis_names = basis_names;

     const std::map<int,RCP<panzer::IntegrationRule> >& int_rules = pb.getIntegrationRules();
     
     for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
	  ir_itr != int_rules.end(); ++ir_itr) {
         
       RCP<panzer::IntegrationValues<double,Intrepid::FieldContainer<double> > > iv = 
	 rcp(new panzer::IntegrationValues<double,Intrepid::FieldContainer<double> >);
	 
       iv->setupArrays(ir_itr->second);

       ir_degrees->push_back(ir_itr->first);
       i->int_rules.push_back(iv);
     }

     const std::map<std::string,Teuchos::RCP<panzer::PureBasis> >& bases= pb.getBases();

     // Need to create all combinations of basis/ir pairings 
     for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
	  ir_itr != int_rules.end(); ++ir_itr) {

       for (std::map<std::string,Teuchos::RCP<panzer::PureBasis> >::const_iterator b_itr = bases.begin();
	    b_itr != bases.end(); ++b_itr) {

	 RCP<panzer::BasisIRLayout> b_layout = rcp(new panzer::BasisIRLayout(b_itr->second,*ir_itr->second));
	 
	 RCP<panzer::BasisValues<double,Intrepid::FieldContainer<double> > > bv = 
	   rcp(new panzer::BasisValues<double,Intrepid::FieldContainer<double> >);
	 
	 bv->setupArrays(b_layout,arrayFactory);

	 basis_names->push_back(b_layout->name());
	 i->bases.push_back(bv);
       }

     }

     i->details.push_back(Teuchos::rcpFromRef(*i));

     return worksets_ptr;
  } // end special case

  {
    std::size_t num_worksets = total_num_cells / workset_size;
    bool last_set_is_full = true;
    std::size_t last_workset_size = total_num_cells % workset_size;
    if (last_workset_size != 0) {
      num_worksets += 1;
      last_set_is_full = false;
    }    

    worksets.resize(num_worksets);
    std::vector<panzer::Workset>::iterator i;
    for (i = worksets.begin(); i != worksets.end(); ++i)
      i->num_cells = workset_size;
	 
    if (!last_set_is_full) {
      worksets.back().num_cells = last_workset_size;
    }
  }

  // assign workset cell local ids
  std::vector<std::size_t>::const_iterator local_begin = local_cell_ids.begin();
  for (std::vector<panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) {
    std::vector<std::size_t>::const_iterator begin_iter = local_begin;
    std::vector<std::size_t>::const_iterator end_iter = begin_iter + wkst->num_cells;
    local_begin = end_iter;
    wkst->cell_local_ids.assign(begin_iter,end_iter);
    wkst->cell_vertex_coordinates.resize(workset_size,
					 vertex_coordinates.dimension(1),
					 vertex_coordinates.dimension(2));
    wkst->block_id = pb.elementBlockID();
    wkst->subcell_dim = pb.cellData().baseCellDimension();
    wkst->subcell_index = 0;
    wkst->details.push_back(Teuchos::rcpFromRef(*wkst));
  }
  
  TEUCHOS_ASSERT(local_begin == local_cell_ids.end());

  // Copy cell vertex coordinates into local workset arrays
  std::size_t offset = 0;
  for (std::vector<panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) {
    for (std::size_t cell = 0; cell < wkst->num_cells; ++cell)
      for (std::size_t vertex = 0; vertex < Teuchos::as<std::size_t>(vertex_coordinates.dimension(1)); ++ vertex)
	for (std::size_t dim = 0; dim < Teuchos::as<std::size_t>(vertex_coordinates.dimension(2)); ++ dim)
	  wkst->cell_vertex_coordinates(cell,vertex,dim) = vertex_coordinates(cell + offset,vertex,dim);

    offset += wkst->num_cells;
  }

  TEUCHOS_ASSERT(offset == Teuchos::as<std::size_t>(vertex_coordinates.dimension(0)));
  
  // Set ir and basis arrayskset
  RCP<vector<int> > ir_degrees = rcp(new vector<int>(0));
  RCP<vector<string> > basis_names = rcp(new vector<string>(0));
  for (std::vector<panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) {
    wkst->ir_degrees = ir_degrees;
    wkst->basis_names = basis_names;
  }

  const std::map<int,RCP<panzer::IntegrationRule> >& int_rules = pb.getIntegrationRules();

  for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
       ir_itr != int_rules.end(); ++ir_itr) {
    
    ir_degrees->push_back(ir_itr->first);

    for (std::vector<panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) {
      
      RCP<panzer::IntegrationValues<double,Intrepid::FieldContainer<double> > > iv = 
	rcp(new panzer::IntegrationValues<double,Intrepid::FieldContainer<double> >);
    
      iv->setupArrays(ir_itr->second);
      iv->evaluateValues(wkst->cell_vertex_coordinates);
      
      wkst->int_rules.push_back(iv);

    }
  }

  const std::map<std::string,Teuchos::RCP<panzer::PureBasis> >& bases= pb.getBases();
     

  // Need to create all combinations of basis/ir pairings 

  // Loop over ir
  for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
       ir_itr != int_rules.end(); ++ir_itr) {
    
    // Loop over basis
    for (std::map<std::string,Teuchos::RCP<panzer::PureBasis> >::const_iterator b_itr = bases.begin();
	 b_itr != bases.end(); ++b_itr) {
      
      RCP<panzer::BasisIRLayout> b_layout = rcp(new panzer::BasisIRLayout(b_itr->second,*ir_itr->second));
      basis_names->push_back(b_layout->name());
      
      // Loop over worksets
      for (std::vector<panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) {
	
	RCP<panzer::BasisValues<double,Intrepid::FieldContainer<double> > > bv = 
	  rcp(new panzer::BasisValues<double,Intrepid::FieldContainer<double> >);
	
	bv->setupArrays(b_layout,arrayFactory);
	
	std::size_t int_degree_index = 
	  std::distance(ir_degrees->begin(), 
			std::find(ir_degrees->begin(), 
				  ir_degrees->end(), 
				  ir_itr->second->order()));
	
	bv->evaluateValues(wkst->int_rules[int_degree_index]->cub_points,
			   wkst->int_rules[int_degree_index]->jac,
			   wkst->int_rules[int_degree_index]->jac_det,
			   wkst->int_rules[int_degree_index]->jac_inv,
			   wkst->int_rules[int_degree_index]->weighted_measure,
			   wkst->cell_vertex_coordinates);

	wkst->bases.push_back(bv);

      }
      
    }
    
  }

  return worksets_ptr;
}
コード例 #2
0
Teuchos::RCP< std::vector<panzer::Workset> > 
panzer::buildEdgeWorksets(const panzer::PhysicsBlock & pb_a,
	  	          const std::vector<std::size_t>& local_cell_ids_a,
		          const std::vector<std::size_t>& local_side_ids_a,
		          const ArrayT& vertex_coordinates_a,
                          const panzer::PhysicsBlock & pb_b,
		          const std::vector<std::size_t>& local_cell_ids_b,
		          const std::vector<std::size_t>& local_side_ids_b,
		          const ArrayT& vertex_coordinates_b)
{
  using std::vector;
  using std::string;
  using Teuchos::RCP;
  using Teuchos::rcp;

  panzer::IntrepidFieldContainerFactory arrayFactory;

  std::size_t total_num_cells_a = local_cell_ids_a.size();
  std::size_t total_num_cells_b = local_cell_ids_b.size();

  TEUCHOS_ASSERT(total_num_cells_a==total_num_cells_b);
  TEUCHOS_ASSERT(local_side_ids_a.size() == local_cell_ids_a.size());
  TEUCHOS_ASSERT(local_side_ids_a.size() == static_cast<std::size_t>(vertex_coordinates_a.dimension(0)));
  TEUCHOS_ASSERT(local_side_ids_b.size() == local_cell_ids_b.size());
  TEUCHOS_ASSERT(local_side_ids_b.size() == static_cast<std::size_t>(vertex_coordinates_b.dimension(0)));

  std::size_t total_num_cells = total_num_cells_a;

  std::size_t workset_size = pb_a.cellData().numCells();

  Teuchos::RCP< std::vector<panzer::Workset> > worksets_ptr = 
    Teuchos::rcp(new std::vector<panzer::Workset>);
  std::vector<panzer::Workset>& worksets = *worksets_ptr;
   
  // special case for 0 elements!
  if(total_num_cells==0) {

     // Setup integration rules and basis
     RCP<vector<int> > ir_degrees = rcp(new vector<int>(0));
     RCP<vector<string> > basis_names = rcp(new vector<string>(0));
      
     worksets.resize(1);
     std::vector<panzer::Workset>::iterator i = worksets.begin();

     i->details.resize(2);
     i->details[0] = Teuchos::rcpFromRef(*i);
     i->details[0]->block_id = pb_a.elementBlockID();
     i->details[1] = Teuchos::rcp(new panzer::WorksetDetails);
     i->details[1]->block_id = pb_b.elementBlockID();

     i->num_cells = 0;
     i->ir_degrees = ir_degrees;
     i->basis_names = basis_names;

     const std::map<int,RCP<panzer::IntegrationRule> >& int_rules = pb_a.getIntegrationRules();
     
     for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
	  ir_itr != int_rules.end(); ++ir_itr) {
         
       RCP<panzer::IntegrationValues<double,Intrepid::FieldContainer<double> > > iv = 
	 rcp(new panzer::IntegrationValues<double,Intrepid::FieldContainer<double> >);
	 
       iv->setupArrays(ir_itr->second);

       ir_degrees->push_back(ir_itr->first);
       i->int_rules.push_back(iv);
     }

     const std::map<std::string,Teuchos::RCP<panzer::PureBasis> >& bases = pb_a.getBases();

     // Need to create all combinations of basis/ir pairings 
     for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin();
	  ir_itr != int_rules.end(); ++ir_itr) {

       for (std::map<std::string,Teuchos::RCP<panzer::PureBasis> >::const_iterator b_itr = bases.begin();
	    b_itr != bases.end(); ++b_itr) {

	 RCP<panzer::BasisIRLayout> b_layout = rcp(new panzer::BasisIRLayout(b_itr->second,*ir_itr->second));
	 
	 RCP<panzer::BasisValues<double,Intrepid::FieldContainer<double> > > bv = 
	   rcp(new panzer::BasisValues<double,Intrepid::FieldContainer<double> >);
	 
	 bv->setupArrays(b_layout,arrayFactory);

	 basis_names->push_back(b_layout->name());
	 i->bases.push_back(bv);
       }

     }

     return worksets_ptr;
  } // end special case

  // This collects all the elements that share the same sub cell pairs, this makes it easier to
  // build the required worksets
  // key is the pair of local face indices, value is a vector of cell indices that satisfy this pair
  std::map<std::pair<unsigned,unsigned>,std::vector<std::size_t> > element_list;
  for (std::size_t cell=0; cell < local_cell_ids_a.size(); ++cell)
    element_list[std::make_pair<unsigned,unsigned>(local_side_ids_a[cell],local_side_ids_b[cell])].push_back(cell);

  // this is the lone iterator that will be used to loop over the element edge list
  std::map<std::pair<unsigned,unsigned>,std::vector<std::size_t> >::const_iterator edge;

  // figure out how many worksets will be needed, resize workset vector accordingly
  std::size_t num_worksets = 0;
  for(edge=element_list.begin(); edge!=element_list.end();++edge) {
    std::size_t num_worksets_for_edge = edge->second.size() / workset_size;
    std::size_t last_workset_size = edge->second.size() % workset_size;
    if(last_workset_size!=0)
      num_worksets_for_edge += 1;

    num_worksets += num_worksets_for_edge;
  }
  worksets.resize(num_worksets);

  // fill the worksets
  std::vector<Workset>::iterator current_workset = worksets.begin();
  for(edge=element_list.begin(); edge!=element_list.end();++edge) {
    // loop over each workset
    const std::vector<std::size_t> & cell_indices = edge->second;
    
    current_workset = buildEdgeWorksets(cell_indices,
                                       pb_a,local_cell_ids_a,local_side_ids_a,vertex_coordinates_a,
                                       pb_b,local_cell_ids_b,local_side_ids_b,vertex_coordinates_b,
                                       current_workset);
  }

  // sanity check
  TEUCHOS_ASSERT(current_workset==worksets.end());

  return worksets_ptr;
}