void EpetraLinearOp::computeAbsRowSum(Epetra_Vector & x) const { TEUCHOS_ASSERT(!is_null(rowMatrix_)); RCP<Epetra_CrsMatrix> crsMatrix = Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(rowMatrix_); TEUCHOS_TEST_FOR_EXCEPTION(is_null(crsMatrix), Exceptions::OpNotSupported, "EpetraLinearOp::computeAbsRowSum(...): wrapped matrix must be of type " "Epetra_CrsMatrix for this method. Other operator types are not supported." ); // // Put inverse of the sum of absolute values of the ith row of A in x[i]. // (this is a modified copy of Epetra_CrsMatrix::InvRowSums) // if (crsMatrix->Filled()) { TEUCHOS_TEST_FOR_EXCEPTION(is_null(crsMatrix), std::invalid_argument, "EpetraLinearOp::computeAbsRowSum(...): Epetra_CrsMatrix must be filled" ); } int i, j; x.PutScalar(0.0); // Make sure we sum into a vector of zeros. double * xp = (double*)x.Values(); if (crsMatrix->Graph().RangeMap().SameAs(x.Map()) && crsMatrix->Exporter() != 0) { Epetra_Vector x_tmp(crsMatrix->RowMap()); x_tmp.PutScalar(0.0); double * x_tmp_p = (double*)x_tmp.Values(); for (i=0; i < crsMatrix->NumMyRows(); i++) { int NumEntries = 0; double * RowValues = 0; crsMatrix->ExtractMyRowView(i,NumEntries,RowValues); for (j=0; j < NumEntries; j++) x_tmp_p[i] += std::abs(RowValues[j]); } TEUCHOS_TEST_FOR_EXCEPT(0!=x.Export(x_tmp, *crsMatrix->Exporter(), Add)); //Export partial row sums to x. } else if (crsMatrix->Graph().RowMap().SameAs(x.Map())) { for (i=0; i < crsMatrix->NumMyRows(); i++) { int NumEntries = 0; double * RowValues = 0; crsMatrix->ExtractMyRowView(i,NumEntries,RowValues); double scale = 0.0; for (j=0; j < NumEntries; j++) scale += std::abs(RowValues[j]); xp[i] = scale; } } else { // x.Map different than both crsMatrix->Graph().RowMap() and crsMatrix->Graph().RangeMap() TEUCHOS_TEST_FOR_EXCEPT(true); // The map of x must be the RowMap or RangeMap of A. } }
TEUCHOS_UNIT_TEST(bcstrategy, constant_bc_strategy) { PHX::KokkosDeviceSession session; using std::cout; using std::endl; using Teuchos::RCP; // pause_to_attach(); RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList); pl->set("X Blocks",1); pl->set("Y Blocks",1); pl->set("X Elements",1); pl->set("Y Elements",1); panzer_stk_classic::SquareQuadMeshFactory factory; factory.setParameterList(pl); RCP<panzer_stk_classic::STK_Interface> mesh = factory.buildMesh(MPI_COMM_WORLD); RCP<Epetra_Comm> Comm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD)); 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 = 1; 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; { std::map<std::string,std::string> block_ids_to_physics_ids; block_ids_to_physics_ids["eblock-0_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"); Teuchos::RCP<panzer::GlobalData> gd = panzer::createGlobalData(); const 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, physicsBlocks); } // build worksets ////////////////////////////////////////////////////////////// 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,physicsBlocks,workset_size)); // build DOF Manager ///////////////////////////////////////////////////////////// // build the connection manager const Teuchos::RCP<panzer::ConnManager<int,int> > conn_manager = Teuchos::rcp(new panzer_stk_classic::STKConnManager<int>(mesh)); panzer::DOFManagerFactory<int,int> globalIndexerFactory; RCP<panzer::UniqueGlobalIndexer<int,int> > dofManager = globalIndexerFactory.buildUniqueGlobalIndexer(Teuchos::opaqueWrapper(MPI_COMM_WORLD),physicsBlocks,conn_manager); Teuchos::RCP<panzer::EpetraLinearObjFactory<panzer::Traits,int> > eLinObjFactory = Teuchos::rcp(new panzer::EpetraLinearObjFactory<panzer::Traits,int>(Comm.getConst(),dofManager)); Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > linObjFactory = eLinObjFactory; // setup field manager build ///////////////////////////////////////////////////////////// // Add in the application specific closure model factory panzer::ClosureModelFactory_TemplateManager<panzer::Traits> cm_factory; user_app::MyModelFactory_TemplateBuilder cm_builder; 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); RCP<panzer::EpetraLinearObjContainer> eGhosted = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(linObjFactory->buildGhostedLinearObjContainer()); RCP<panzer::EpetraLinearObjContainer> eGlobal = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(linObjFactory->buildLinearObjContainer()); eLinObjFactory->initializeGhostedContainer(panzer::EpetraLinearObjContainer::X | panzer::EpetraLinearObjContainer::DxDt | panzer::EpetraLinearObjContainer::F | panzer::EpetraLinearObjContainer::Mat,*eGhosted); eLinObjFactory->initializeContainer(panzer::EpetraLinearObjContainer::X | panzer::EpetraLinearObjContainer::DxDt | panzer::EpetraLinearObjContainer::F | panzer::EpetraLinearObjContainer::Mat,*eGlobal); panzer::AssemblyEngineInArgs input(eGhosted,eGlobal); RCP<Epetra_Vector> x = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(input.container_)->get_x(); x->PutScalar(1.0); input.beta = 1.0; ae_tm.getAsObject<panzer::Traits::Residual>()->evaluate(input); ae_tm.getAsObject<panzer::Traits::Jacobian>()->evaluate(input); // Check residual values. Evaluation should have put (x - 5.0) // into each residual. With initial guess of 1.0, check to make // sure each entry in residual has -4.0. Note that we are using // one element with same dirichlet bc on each side, so all nodes // have same dirichlet bc applied to it. RCP<Epetra_Vector> f = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(input.container_)->get_f(); double tol = 10.0*std::numeric_limits<double>::epsilon(); for (int i=0; i < f->MyLength(); ++i) { TEST_FLOATING_EQUALITY((*f)[i], -4.0, tol ); } // Check Jacobian values. Should have one on diagonal and zero // elsewhere. RCP<Epetra_CrsMatrix> jac = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(input.container_)->get_A(); for (int i=0; i < jac->NumMyRows(); ++i) { int num_indices = -1; double* values = NULL; int* local_column_indices = NULL; jac->ExtractMyRowView(i, num_indices, values, local_column_indices); for (int j=0; j < num_indices; j++) { std::cout << "J(" <<jac->GRID(i) << "," << jac->GCID(local_column_indices[j]) << ") = " << values[j] << std::endl; if (jac->GRID(i) == jac->GCID(local_column_indices[j])) { TEST_FLOATING_EQUALITY(values[j], 1.0, tol); } else { TEST_FLOATING_EQUALITY(values[j], 0.0, tol); } } } jac->Print(std::cout); }