virtual void buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& side_pb, const LinearObjFactory<panzer::Traits> & lof, const Teuchos::ParameterList& user_data) const { side_pb.buildAndRegisterGatherAndOrientationEvaluators(fm,lof,user_data); side_pb.buildAndRegisterDOFProjectionsToIPEvaluators(fm,user_data); }
virtual void buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& side_pb, const LinearObjFactory<panzer::Traits> & lof, const Teuchos::ParameterList& user_data) const { using Teuchos::RCP; using Teuchos::rcp; side_pb.buildAndRegisterGatherAndOrientationEvaluators(fm,lof,user_data); side_pb.buildAndRegisterDOFProjectionsToIPEvaluators(fm,Teuchos::ptrFromRef(lof),user_data); // add in side normals const std::map<int,Teuchos::RCP<panzer::IntegrationRule> > & int_rules = side_pb.getIntegrationRules(); for(std::map<int,Teuchos::RCP<panzer::IntegrationRule> >::const_iterator itr=int_rules.begin(); itr!=int_rules.end();++itr) { std::stringstream s; s << "Side Normal:" << side_pb.cellData().side(); Teuchos::ParameterList p(s.str()); p.set<std::string>("Name","Side Normal"); p.set<int>("Side ID",side_pb.cellData().side()); p.set< Teuchos::RCP<panzer::IntegrationRule> >("IR", Teuchos::rcp_const_cast<panzer::IntegrationRule>(itr->second)); p.set<bool>("Normalize",true); RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Normals<EvalT,panzer::Traits>(p)); fm.template registerEvaluator<EvalT>(op); } }
void Example::BCStrategy_Interface_WeakDirichletMatch<EvalT>:: setup(const panzer::PhysicsBlock& side_pb, const Teuchos::ParameterList& user_data) { using Teuchos::RCP; using std::vector; using std::string; using std::pair; const int di = this->getDetailsIndex(); // obtain the dof name const string dof_name = di == 0 ? this->m_bc.equationSetName() : this->m_bc.equationSetName2(); other_dof_name = di == 1 ? this->m_bc.equationSetName() : this->m_bc.equationSetName2(); // need the dof value to form the residual this->requireDOFGather(dof_name); // unique residual name const string residual_name = "Residual_" + this->m_bc.equationSetName(); const string diff_name = "Difference"; const std::map<int,RCP< panzer::IntegrationRule > >& ir = side_pb.getIntegrationRules(); TEUCHOS_ASSERT(ir.size() == 1); const int integration_order = ir.begin()->second->order(); this->addResidualContribution(residual_name,dof_name,diff_name,integration_order,side_pb); }
Teuchos::RCP<panzer::IntegrationRule> panzer::BCStrategy_Interface_DefaultImpl<EvalT>:: buildIntegrationRule(const int integration_order,const panzer::PhysicsBlock& side_pb) const { TEUCHOS_ASSERT(side_pb.cellData().isSide()); Teuchos::RCP<panzer::IntegrationRule> ir = Teuchos::rcp(new panzer::IntegrationRule(integration_order,side_pb.cellData())); return ir; }
void ResponseEvaluatorFactory_ExtremeValue<EvalT,LO,GO>:: buildAndRegisterEvaluators(const std::string & responseName, PHX::FieldManager<panzer::Traits> & fm, const panzer::PhysicsBlock & physicsBlock, const Teuchos::ParameterList & user_data) const { using Teuchos::RCP; using Teuchos::rcp; // build integration evaluator (integrate over element) if(requiresCellExtreme_) { std::string field = (quadPointField_=="" ? responseName : quadPointField_); // build integration rule to use in cell integral RCP<IntegrationRule> ir = rcp(new IntegrationRule(cubatureDegree_,physicsBlock.cellData())); Teuchos::ParameterList pl; pl.set("Extreme Name",field); pl.set("Field Name",field); pl.set("IR",ir); pl.set("Use Max",useMax_); Teuchos::RCP<PHX::Evaluator<panzer::Traits> > eval = Teuchos::rcp(new CellExtreme<EvalT,panzer::Traits>(pl)); this->template registerEvaluator<EvalT>(fm, eval); } // build scatter evaluator { Teuchos::RCP<ExtremeValueScatterBase> scatterObj = (globalIndexer_!=Teuchos::null) ? Teuchos::rcp(new ExtremeValueScatter<LO,GO>(globalIndexer_)) : Teuchos::null; std::string field = (quadPointField_=="" ? responseName : quadPointField_); // build useful evaluator Teuchos::RCP<PHX::Evaluator<panzer::Traits> > eval = Teuchos::rcp(new ResponseScatterEvaluator_ExtremeValue<EvalT,panzer::Traits>(field, responseName, physicsBlock.cellData(), useMax_, scatterObj)); this->template registerEvaluator<EvalT>(fm, eval); // require last field fm.template requireField<EvalT>(*eval->evaluatedFields()[0]); } }
void Example::BCStrategy_Interface_WeakDirichletMatch<EvalT>:: buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& pb, const panzer::LinearObjFactory<panzer::Traits> & lof, const Teuchos::ParameterList& user_data) const { using Teuchos::RCP; using Teuchos::rcp; using std::vector; using std::map; using std::string; using std::pair; // Gather pb.buildAndRegisterGatherAndOrientationEvaluators(fm,lof,user_data); }
void user_app::BCStrategy_Dirichlet_Constant<EvalT>:: setup(const panzer::PhysicsBlock& side_pb, const Teuchos::ParameterList& user_data) { using Teuchos::RCP; using std::vector; using std::string; using std::pair; /* // need the dof value to form the residual this->required_dof_names.push_back(this->m_bc.equationSetName()); // unique residual name this->residual_name = "Residual_" + this->m_bc.identifier(); // map residual to dof this->residual_to_dof_names_map[residual_name] = this->m_bc.equationSetName(); // map residual to target field this->residual_to_target_field_map[residual_name] = "Constant_" + this->m_bc.equationSetName(); */ // gather the DOF this->addDOF(this->m_bc.equationSetName()); // DOF Name // add in the targert this->addTarget("Constant_"+this->m_bc.equationSetName(), // Target Name this->m_bc.equationSetName(), // DOF Name "Residual_"+this->m_bc.identifier()); // Residual Name // find the basis for this dof const vector<pair<string,RCP<panzer::PureBasis> > >& dofs = side_pb.getProvidedDOFs(); for (vector<pair<string,RCP<panzer::PureBasis> > >::const_iterator dof_it = dofs.begin(); dof_it != dofs.end(); ++dof_it) { if (dof_it->first == this->m_bc.equationSetName()) this->basis = dof_it->second; } TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(this->basis), std::runtime_error, "Error the name \"" << this->m_bc.equationSetName() << "\" is not a valid DOF for the boundary condition:\n" << this->m_bc << "\n"); }
virtual void buildAndRegisterEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& side_pb, const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>& factory, const Teuchos::ParameterList& models, const Teuchos::ParameterList& user_data) const { side_pb.buildAndRegisterEquationSetEvaluators(fm, user_data); side_pb.buildAndRegisterClosureModelEvaluatorsForType<EvalT>(fm,factory,models,user_data); for(std::size_t i=0;i<refVec_.size();i++) { Teuchos::RCP<const ResponseEvaluatorFactoryBase> respEvalFact = refVec_[i].second->template getAsBase<EvalT>(); // only register evaluators if the type is supported if(respEvalFact->typeSupported()) respEvalFact->buildAndRegisterEvaluators(refVec_[i].first,fm,side_pb,user_data); } }
void populateValueArrays(std::size_t num_cells,bool isSide,const panzer::PhysicsBlock & in_pb,WorksetDetails & details) { using Teuchos::RCP; using Teuchos::rcp; panzer::IntrepidFieldContainerFactory arrayFactory; // setup the integration rules and bases RCP<const panzer::PhysicsBlock> pb = Teuchos::rcpFromRef(in_pb); if(isSide) { const panzer::CellData side_cell_data(num_cells, details.subcell_index, in_pb.cellData().getCellTopology()); pb = in_pb.copyWithCellData(side_cell_data); } const std::map<int,RCP<panzer::IntegrationRule> >& int_rules = pb->getIntegrationRules(); details.ir_degrees = rcp(new std::vector<int>(0)); details.basis_names = rcp(new std::vector<std::string>(0)); for (std::map<int,RCP<panzer::IntegrationRule> >::const_iterator ir_itr = int_rules.begin(); ir_itr != int_rules.end(); ++ir_itr) { details.ir_degrees->push_back(ir_itr->first); RCP<panzer::IntegrationValues<double,Intrepid::FieldContainer<double> > > iv = rcp(new panzer::IntegrationValues<double,Intrepid::FieldContainer<double> >); iv->setupArrays(ir_itr->second); iv->evaluateValues(details.cell_vertex_coordinates); details.int_rules.push_back(iv); // Need to create all combinations of basis/ir pairings const std::map<std::string,Teuchos::RCP<panzer::PureBasis> >& bases = pb->getBases(); 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)); details.basis_names->push_back(b_layout->name()); 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(details.ir_degrees->begin(), std::find(details.ir_degrees->begin(), details.ir_degrees->end(), ir_itr->second->order())); bv->evaluateValues(details.int_rules[int_degree_index]->cub_points, details.int_rules[int_degree_index]->jac, details.int_rules[int_degree_index]->jac_det, details.int_rules[int_degree_index]->jac_inv, details.int_rules[int_degree_index]->weighted_measure, details.cell_vertex_coordinates); details.bases.push_back(bv); } } }
void panzer::BCStrategy_Interface_DefaultImpl<EvalT>:: buildAndRegisterGatherAndOrientationEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& pb, const panzer::LinearObjFactory<panzer::Traits> & lof, const Teuchos::ParameterList& user_data) const { using Teuchos::ParameterList; using Teuchos::RCP; using Teuchos::rcp; using std::vector; using std::map; using std::string; using std::pair; // Gather pb.buildAndRegisterGatherAndOrientationEvaluators(fm,lof,user_data); // Iterate over each residual contribution for (vector<boost::tuples::tuple<std::string,std::string,std::string,int,Teuchos::RCP<panzer::PureBasis>,Teuchos::RCP<panzer::IntegrationRule> > >::const_iterator eq = m_residual_contributions.begin(); eq != m_residual_contributions.end(); ++eq) { const string& residual_name = eq->get<0>(); const string& dof_name = eq->get<1>(); const string& flux_name = eq->get<2>(); //const int& integration_order = eq->get<3>(); const RCP<const panzer::PureBasis> basis = eq->get<4>(); const RCP<const panzer::IntegrationRule> ir = eq->get<5>(); // Normals evaluator { std::stringstream s; s << "Side Normal:" << pb.cellData().side(); ParameterList p(s.str()); p.set<std::string>("Name","Side Normal"); p.set<int>("Side ID",pb.cellData().side()); p.set< Teuchos::RCP<panzer::IntegrationRule> >("IR", Teuchos::rcp_const_cast<panzer::IntegrationRule>(ir)); p.set<bool>("Normalize",true); RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Normals<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } // Interface Residual evaluator: residual += phi n dot flux { ParameterList p("Interface Residual: " + residual_name + " to DOF: " + dof_name); p.set("Residual Name", residual_name); p.set("DOF Name",dof_name); p.set("Flux Name", flux_name); p.set("Normal Name", "Side Normal"); p.set("Basis", basis); p.set("IR", ir); RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::InterfaceResidual<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } } }
Teuchos::RCP<panzer::PureBasis> panzer::BCStrategy_Interface_DefaultImpl<EvalT>:: getBasis(const std::string dof_name,const panzer::PhysicsBlock& side_pb) const { const std::vector<std::pair<std::string,Teuchos::RCP<panzer::PureBasis> > >& dofBasisPair = side_pb.getProvidedDOFs(); Teuchos::RCP<panzer::PureBasis> basis; for (std::vector<std::pair<std::string,Teuchos::RCP<panzer::PureBasis> > >::const_iterator it = dofBasisPair.begin(); it != dofBasisPair.end(); ++it) { if (it->first == dof_name) basis = it->second; } TEUCHOS_TEST_FOR_EXCEPTION(is_null(basis), std::runtime_error, "Error the name \"" << dof_name << "\" is not a valid DOF for the boundary condition:\n" << this->m_bc << "\n"); return basis; }
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; }
std::vector<panzer::Workset>::iterator panzer::buildEdgeWorksets(const std::vector<std::size_t> & cell_indices, 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, std::vector<Workset>::iterator beg) { std::vector<Workset>::iterator wkst = beg; std::size_t current_cell_index = 0; while (current_cell_index<cell_indices.size()) { std::size_t workset_size = pb_a.cellData().numCells(); // allocate workset details (associate one with the workset // object itself) wkst->details.resize(2); wkst->details[0] = Teuchos::rcpFromRef(*wkst); wkst->details[1] = Teuchos::rcp(new panzer::WorksetDetails); wkst->subcell_dim = pb_a.cellData().baseCellDimension()-1; wkst->details[0]->subcell_index = local_side_ids_a[cell_indices[current_cell_index]]; wkst->details[0]->block_id = pb_a.elementBlockID(); wkst->details[0]->cell_vertex_coordinates.resize(workset_size, vertex_coordinates_a.dimension(1), vertex_coordinates_a.dimension(2)); wkst->details[1]->subcell_index = local_side_ids_b[cell_indices[current_cell_index]]; wkst->details[1]->block_id = pb_b.elementBlockID(); wkst->details[1]->cell_vertex_coordinates.resize(workset_size, vertex_coordinates_a.dimension(1), vertex_coordinates_a.dimension(2)); std::size_t remaining_cells = cell_indices.size()-current_cell_index; if(remaining_cells<workset_size) workset_size = remaining_cells; // this is the true number of cells in this workset wkst->num_cells = workset_size; wkst->details[0]->cell_local_ids.resize(workset_size); wkst->details[1]->cell_local_ids.resize(workset_size); for(std::size_t cell=0;cell<workset_size; cell++,current_cell_index++) { wkst->details[0]->cell_local_ids[cell] = local_cell_ids_a[cell_indices[current_cell_index]]; wkst->details[1]->cell_local_ids[cell] = local_cell_ids_b[cell_indices[current_cell_index]]; for (std::size_t vertex = 0; vertex < Teuchos::as<std::size_t>(vertex_coordinates_a.dimension(1)); ++ vertex) { for (std::size_t dim = 0; dim < Teuchos::as<std::size_t>(vertex_coordinates_a.dimension(2)); ++ dim) { wkst->details[0]->cell_vertex_coordinates(cell,vertex,dim) = vertex_coordinates_a(cell_indices[current_cell_index],vertex,dim); wkst->details[1]->cell_vertex_coordinates(cell,vertex,dim) = vertex_coordinates_b(cell_indices[current_cell_index],vertex,dim); } } } // fill the BasisValues and IntegrationValues arrays std::size_t max_workset_size = pb_a.cellData().numCells(); populateValueArrays(max_workset_size,true,pb_a,*wkst->details[0]); // populate "side" values populateValueArrays(max_workset_size,true,pb_b,*wkst->details[1]); wkst++; } return wkst; }
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; }
Teuchos::RCP<std::map<unsigned,panzer::Workset> > panzer::buildBCWorkset(const panzer::PhysicsBlock & volume_pb, const std::vector<std::size_t>& local_cell_ids, const std::vector<std::size_t>& local_side_ids, const ArrayT& vertex_coordinates) { using std::vector; using std::map; using std::string; using Teuchos::RCP; using Teuchos::rcp; // key is local face index, value is workset with all elements // for that local face Teuchos::RCP<std::map<unsigned,panzer::Workset> > worksets_ptr = Teuchos::rcp(new std::map<unsigned,panzer::Workset>); // All elements of boundary condition should go into one workset. // However due to design of Intrepid (requires same basis for all // cells), we have to separate the workset based on the local side // index. Each workset for a boundary condition is associated with // a local side for the element // std::cout << "local_side_ids.size() = " << local_side_ids.size() // << std::endl; TEUCHOS_ASSERT(local_side_ids.size() == local_cell_ids.size()); TEUCHOS_ASSERT(local_side_ids.size() == static_cast<std::size_t>(vertex_coordinates.dimension(0))); // key is local face index, value is a pair of cell index and vector of element local ids std::map<unsigned,std::vector<std::pair<std::size_t,std::size_t> > > element_list; for (std::size_t cell=0; cell < local_cell_ids.size(); ++cell) element_list[local_side_ids[cell]].push_back(std::make_pair(cell,local_cell_ids[cell])); std::map<unsigned,panzer::Workset>& worksets = *worksets_ptr; // create worksets std::map<unsigned,std::vector<std::pair<std::size_t,std::size_t> > >::const_iterator side; for (side = element_list.begin(); side != element_list.end(); ++side) { std::vector<std::size_t>& cell_local_ids = worksets[side->first].cell_local_ids; Intrepid::FieldContainer<double> & coords = worksets[side->first].cell_vertex_coordinates; coords.resize(side->second.size(),vertex_coordinates.dimension(1),vertex_coordinates.dimension(2)); for (std::size_t cell = 0; cell < side->second.size(); ++cell) { cell_local_ids.push_back(side->second[cell].second); 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) coords(cell,vertex,dim) = vertex_coordinates(side->second[cell].first,vertex,dim); } worksets[side->first].num_cells = worksets[side->first].cell_local_ids.size(); worksets[side->first].block_id = volume_pb.elementBlockID(); worksets[side->first].subcell_dim = volume_pb.cellData().baseCellDimension() - 1; worksets[side->first].subcell_index = side->first; worksets[side->first].details.push_back(Teuchos::rcpFromRef(worksets[side->first])); } // setup the integration rules and bases for (std::map<unsigned,panzer::Workset>::iterator wkst = worksets.begin(); wkst != worksets.end(); ++wkst) { populateValueArrays(wkst->second.num_cells,true,volume_pb,wkst->second); // populate "side" values } return worksets_ptr; }
void Example::BCStrategy_Interface_WeakDirichletMatch<EvalT>:: buildAndRegisterEvaluators(PHX::FieldManager<panzer::Traits>& fm, const panzer::PhysicsBlock& pb, const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>& factory, const Teuchos::ParameterList& models, const Teuchos::ParameterList& user_data) const { using Teuchos::ParameterList; using Teuchos::RCP; using Teuchos::rcp; using std::string; const std::vector<boost::tuples::tuple<string,string,string,int,Teuchos::RCP<panzer::PureBasis>, Teuchos::RCP<panzer::IntegrationRule> > > data = this->getResidualContributionData(); string residual_name = data[0].get<0>(); string dof_name = data[0].get<1>(); string diff_name = data[0].get<2>(); RCP<panzer::IntegrationRule> ir = data[0].get<5>(); RCP<const panzer::FieldLayoutLibrary> fll = pb.getFieldLibrary()->buildFieldLayoutLibrary(*ir); RCP<panzer::BasisIRLayout> basis = fll->lookupLayout(dof_name); if (this->getDetailsIndex() == 0) { const std::string dof_grad_name = dof_name + "_gradient", cancel_natural_name = dof_name + "_cancel", my_normal_name = "My_Normal", sum_contributions_name = "Sum_Contributions"; // Weak Dirichlet match. { { // Get values on my side. ParameterList p("My DOF"); p.set("Name", dof_name); p.set("Basis", basis); p.set("IR", ir); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::DOF<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } { // Other DOF - my DOF. ParameterList p("other DOF - my DOF"); p.set("Sum Name", diff_name); setSumValues(p, other_dof_name, 1, dof_name, -1); p.set("Data Layout", ir->dl_scalar); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Sum<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } } // Cancel my natural (Neumann) BC. { { // Normal. ParameterList p("My Side Normal"); p.set("Name", my_normal_name); p.set("Side ID", pb.cellData().side()); p.set("IR", ir); p.set("Normalize", true); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Normals<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } { // Gradient. ParameterList p("My DOF gradient"); p.set("Name", dof_name); p.set("Gradient Name", dof_grad_name); p.set("Basis", basis); p.set("IR", ir); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::DOFGradient<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } { // dot(DOF gradient, normal). ParameterList p("dot(my DOF gradient, my normal)"); p.set("Result Name", cancel_natural_name); p.set("Vector A Name", dof_grad_name); p.set("Vector B Name", my_normal_name); p.set("Point Rule", Teuchos::rcp_dynamic_cast<const panzer::PointRule>(ir)); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::DotProduct<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } } // Add contributions to the residual. { { // Weak Dirichlet Match + Cancel Neumann ParameterList p("Weak Dirichlet Match + Cancel Neumann"); p.set("Sum Name", sum_contributions_name); setSumValues(p, diff_name, 1e5, cancel_natural_name, -1); p.set("Data Layout", ir->dl_scalar); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Sum<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } { ParameterList p("Weak Dirichlet Match And Cancel Neumann Residual"); p.set("Residual Name", residual_name); p.set("Value Name", sum_contributions_name); p.set("Basis", basis); p.set("IR", ir); p.set("Multiplier", 1.0); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::Integrator_BasisTimesScalar<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } } } else { { // Get values on other side. ParameterList p("Other DOF"); p.set("Name", dof_name); p.set("Basis", basis); p.set("IR", ir); const RCP< PHX::Evaluator<panzer::Traits> > op = rcp(new panzer::DOF<EvalT,panzer::Traits>(p)); this->template registerEvaluator<EvalT>(fm, op); } } }