//---------------------------------------------------------------------------// // Tests. //---------------------------------------------------------------------------// TEUCHOS_UNIT_TEST( LAPACK, block_inversion ) { // Build a 4x4 block. int m = 4; int n = 4; Teuchos::SerialDenseMatrix<int,double> block( m, n ); block(0,0) = 3.2; block(0,1) = -1.43; block(0,2) = 2.98; block(0,3) = 0.32; block(1,0) = -4.12; block(1,1) = -7.53; block(1,2) = 1.44; block(1,3) = -3.72; block(2,0) = 4.24; block(2,1) = -6.42; block(2,2) = 1.82; block(2,3) = 2.67; block(3,0) = -0.23; block(3,1) = 5.8; block(3,2) = 1.13; block(3,3) = -3.73; // Make a LAPACK object. Teuchos::LAPACK<int,double> lapack; // Compute the LU-factorization of the block. Teuchos::ArrayRCP<int> ipiv( block.numRows() ); int info = 0; int lda = m; lapack.GETRF( m, n, block.values(), lda, ipiv.getRawPtr(), &info ); TEST_EQUALITY( info, 0 ); // Compute the inverse of the block from the LU-factorization. Teuchos::ArrayRCP<double> work( m ); lapack.GETRI( n, block.values(), lda, ipiv.getRawPtr(), work.getRawPtr(), work.size(), &info ); TEST_EQUALITY( info, 0 ); TEST_EQUALITY( work[0], m ); // Check the inversion against matlab. TEST_FLOATING_EQUALITY( block(0,0), -0.461356423424245, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(0,1), -0.060920073472551, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(0,2), 0.547244760641934, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(0,3), 0.412904055961420, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(1,0), 0.154767451798665, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(1,1), -0.056225122550555, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(1,2), -0.174451348828054, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(1,3), -0.055523340725809, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(2,0), 0.848746201780808, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(2,1), 0.045927762119214, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(2,2), -0.618485718805259, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(2,3), -0.415712965073367, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(3,0), 0.526232280383953, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(3,1), -0.069757566407458, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(3,2), -0.492378815120724, 1.0e-14 ); TEST_FLOATING_EQUALITY( block(3,3), -0.505833501236923, 1.0e-14 ); }
TEUCHOS_UNIT_TEST(point_values, md_field_evaluate) { typedef panzer::Traits::FadType ScalarType; typedef PHX::MDField<ScalarType> ArrayType; typedef PHX::KokkosViewFactory<ScalarType,PHX::Device> ViewFactory; typedef PHX::MDField<double>::size_type size_type; Teuchos::RCP<shards::CellTopology> topo = Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >())); const int num_cells = 4; const int base_cell_dimension = 2; const panzer::CellData cell_data(num_cells,topo); int num_points = 3; RCP<PointRule> point_rule = rcp(new PointRule("RandomPoints",num_points, cell_data)); TEST_EQUALITY(point_rule->num_points,num_points); panzer::PointValues<ScalarType,PHX::MDField<ScalarType> > point_values; panzer::MDFieldArrayFactory af("prefix_"); point_values.setupArrays(point_rule,af); // Set up node coordinates. Here we assume the following // ordering. This needs to be consistent with shards topology, // otherwise we will get negative determinates // 3(0,1)---2(1,1) // | 0 | // | | // 0(0,0)---1(1,0) const size_type derivative_dim = 4; const std::vector<PHX::index_size_type> ddims(1,derivative_dim); const int num_vertices = point_rule->topology->getNodeCount(); ArrayType node_coordinates = af.buildArray<ScalarType,Cell,NODE,Dim>("node_coordinates",num_cells, num_vertices, base_cell_dimension); node_coordinates.setFieldData(ViewFactory::buildView(node_coordinates.fieldTag(),ddims)); const size_type x = 0; const size_type y = 1; for (size_type cell = 0; cell < node_coordinates.dimension(0); ++cell) { int xleft = cell % 2; int yleft = int(cell/2); node_coordinates(cell,0,x) = xleft*0.5; node_coordinates(cell,0,y) = yleft*0.5; node_coordinates(cell,1,x) = (xleft+1)*0.5; node_coordinates(cell,1,y) = yleft*0.5; node_coordinates(cell,2,x) = (xleft+1)*0.5; node_coordinates(cell,2,y) = (yleft+1)*0.5; node_coordinates(cell,3,x) = xleft*0.5; node_coordinates(cell,3,y) = (yleft+1)*0.5; out << "Cell " << cell << " = "; for(int i=0;i<4;i++) out << "(" << node_coordinates(cell,i,x) << ", " << node_coordinates(cell,i,y) << ") "; out << std::endl; } // Build the evaluation points ArrayType point_coordinates = af.buildArray<ScalarType,IP,Dim>("points",num_points, base_cell_dimension); point_coordinates.setFieldData(ViewFactory::buildView(point_coordinates.fieldTag(),ddims)); point_coordinates(0,0) = 0.0; point_coordinates(0,1) = 0.0; // mid point point_coordinates(1,0) = 0.5; point_coordinates(1,1) = 0.5; // mid point of upper left quadrant point_coordinates(2,0) = -0.5; point_coordinates(2,1) = 0.0; // mid point of line from center to left side point_values.coords_ref.setFieldData(ViewFactory::buildView(point_values.coords_ref.fieldTag(),ddims)); point_values.node_coordinates.setFieldData(ViewFactory::buildView(point_values.node_coordinates.fieldTag(),ddims)); point_values.point_coords.setFieldData(ViewFactory::buildView(point_values.point_coords.fieldTag(),ddims)); point_values.jac.setFieldData(ViewFactory::buildView(point_values.jac.fieldTag(),ddims)); point_values.jac_inv.setFieldData(ViewFactory::buildView(point_values.jac_inv.fieldTag(),ddims)); point_values.jac_det.setFieldData(ViewFactory::buildView(point_values.jac_det.fieldTag(),ddims)); point_values.evaluateValues(node_coordinates,point_coordinates); // check the reference values (ensure copying) for(int p=0;p<num_points;p++) for(size_type d=0;d<base_cell_dimension;d++) TEST_EQUALITY(point_values.coords_ref(p,d).val(),point_coordinates(p,d).val()); // check the shifted values (ensure physical mapping) for(int c=0;c<num_cells;c++) { double dx = 0.5; double dy = 0.5; for(int p=0;p<num_points;p++) { double x = dx*(point_coordinates(p,0).val()+1.0)/2.0 + node_coordinates(c,0,0).val(); double y = dy*(point_coordinates(p,1).val()+1.0)/2.0 + node_coordinates(c,0,1).val(); TEST_FLOATING_EQUALITY(point_values.point_coords(c,p,0).val(),x,1e-10); TEST_FLOATING_EQUALITY(point_values.point_coords(c,p,1).val(),y,1e-10); } } // check the jacobian for(int c=0;c<num_cells;c++) { double dx = 0.5; double dy = 0.5; for(int p=0;p<num_points;p++) { TEST_FLOATING_EQUALITY(point_values.jac(c,p,0,0).val(),dx/2.0,1e-10); TEST_FLOATING_EQUALITY(point_values.jac(c,p,0,1).val(),0.0,1e-10); TEST_FLOATING_EQUALITY(point_values.jac(c,p,1,0).val(),0.0,1e-10); TEST_FLOATING_EQUALITY(point_values.jac(c,p,1,1).val(),dy/2.0,1e-10); } } for(int c=0;c<num_cells;c++) { double dx = 0.5; double dy = 0.5; for(int p=0;p<num_points;p++) { TEST_FLOATING_EQUALITY(point_values.jac_det(c,p).val(),dy*dx/4.0,1e-10); } } out << "TESTING" << std::endl; for(size_type c=0;c<point_values.jac_det.size();c++) { point_values.jac_det[c] = c+1.0; out << " " << point_values.jac_det[c] << ", " << c+1.0 << std::endl; } out << "TESTING B" << std::endl; for(size_type c=0;c<point_values.jac_det.size();c++) out << " " << point_values.jac_det[c] << ", " << c << std::endl; // check the inverse jacobian for(int c=0;c<num_cells;c++) { double dx = 0.5; double dy = 0.5; for(int p=0;p<num_points;p++) { TEST_FLOATING_EQUALITY(point_values.jac_inv(c,p,0,0).val(),2.0/dx,1e-10); TEST_FLOATING_EQUALITY(point_values.jac_inv(c,p,0,1).val(),0.0,1e-10); TEST_FLOATING_EQUALITY(point_values.jac_inv(c,p,1,0).val(),0.0,1e-10); TEST_FLOATING_EQUALITY(point_values.jac_inv(c,p,1,1).val(),2.0/dy,1e-10); } } }
TEUCHOS_UNIT_TEST(point_values, intrepid_container) { Teuchos::RCP<shards::CellTopology> topo = Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >())); const int num_cells = 4; const int base_cell_dimension = 2; const panzer::CellData cell_data(num_cells,topo); int num_points = 3; RCP<PointRule> point_rule = rcp(new PointRule("RandomPoints",num_points, cell_data)); TEST_EQUALITY(point_rule->num_points,num_points); panzer::PointValues<double,Kokkos::DynRankView<double,PHX::Device> > point_values; panzer::Intrepid2FieldContainerFactory af; point_values.setupArrays(point_rule,af); // Set up node coordinates. Here we assume the following // ordering. This needs to be consistent with shards topology, // otherwise we will get negative determinates // 3(0,1)---2(1,1) // | 0 | // | | // 0(0,0)---1(1,0) const int num_vertices = point_rule->topology->getNodeCount(); Kokkos::DynRankView<double,PHX::Device> node_coordinates(num_cells, num_vertices, base_cell_dimension); typedef panzer::ArrayTraits<double,Kokkos::DynRankView<double,PHX::Device> >::size_type size_type; const size_type x = 0; const size_type y = 1; for (size_type cell = 0; cell < node_coordinates.dimension(0); ++cell) { int xleft = cell % 2; int yleft = int(cell/2); node_coordinates(cell,0,x) = xleft*0.5; node_coordinates(cell,0,y) = yleft*0.5; node_coordinates(cell,1,x) = (xleft+1)*0.5; node_coordinates(cell,1,y) = yleft*0.5; node_coordinates(cell,2,x) = (xleft+1)*0.5; node_coordinates(cell,2,y) = (yleft+1)*0.5; node_coordinates(cell,3,x) = xleft*0.5; node_coordinates(cell,3,y) = (yleft+1)*0.5; out << "Cell " << cell << " = "; for(int i=0;i<4;i++) out << "(" << node_coordinates(cell,i,x) << ", " << node_coordinates(cell,i,y) << ") "; out << std::endl; } // Build the evaluation points Kokkos::DynRankView<double,PHX::Device> point_coordinates("a",num_points, base_cell_dimension); point_coordinates(0,0) = 0.0; point_coordinates(0,1) = 0.0; // mid point point_coordinates(1,0) = 0.5; point_coordinates(1,1) = 0.5; // mid point of upper left quadrant point_coordinates(2,0) = -0.5; point_coordinates(2,1) = 0.0; // mid point of line from center to left side point_values.evaluateValues(node_coordinates,point_coordinates); for(size_type p=0;p<num_points;p++) for(size_type d=0;d<base_cell_dimension;d++) TEST_EQUALITY(point_values.coords_ref(p,d),point_coordinates(p,d)); for(int c=0;c<num_cells;c++) { double dx = 0.5; double dy = 0.5; for(size_type p=0;p<num_points;p++) { double x = dx*(point_coordinates(p,0)+1.0)/2.0 + node_coordinates(c,0,0); double y = dy*(point_coordinates(p,1)+1.0)/2.0 + node_coordinates(c,0,1); TEST_FLOATING_EQUALITY(point_values.point_coords(c,p,0),x,1e-10); TEST_FLOATING_EQUALITY(point_values.point_coords(c,p,1),y,1e-10); } } }
TEUCHOS_UNIT_TEST( Rythmos_GlobalErrorEstimator, SinCos ) { typedef Teuchos::ScalarTraits<double> ST; // Forward Solve, storing data in linear interpolation buffer int storageLimit = 100; double finalTime = 0.1; double dt = 0.1; RCP<IntegratorBuilder<double> > ib = integratorBuilder<double>(); { RCP<ParameterList> ibPL = Teuchos::parameterList(); ibPL->sublist("Integrator Settings").sublist("Integrator Selection").set("Integrator Type","Default Integrator"); ibPL->sublist("Integrator Settings").set("Final Time",finalTime); ibPL->sublist("Integration Control Strategy Selection").set("Integration Control Strategy Type","Simple Integration Control Strategy"); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Take Variable Steps",false); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Fixed dt",dt); ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Backward Euler"); //ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Implicit RK"); //ibPL->sublist("Stepper Settings").sublist("Runge Kutta Butcher Tableau Selection").set("Runge Kutta Butcher Tableau Type","Backward Euler"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").set("Interpolation Buffer Type","Interpolation Buffer"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").sublist("Interpolation Buffer").set("StorageLimit",storageLimit); ibPL->sublist("Interpolation Buffer Settings").sublist("Interpolator Selection").set("Interpolator Type","Linear Interpolator"); ib->setParameterList(ibPL); } RCP<SinCosModel> fwdModel = sinCosModel(true); // implicit formulation Thyra::ModelEvaluatorBase::InArgs<double> fwdIC = fwdModel->getNominalValues(); RCP<Thyra::NonlinearSolverBase<double> > fwdNLSolver = timeStepNonlinearSolver<double>(); RCP<IntegratorBase<double> > fwdIntegrator = ib->create(fwdModel,fwdIC,fwdNLSolver); RCP<const VectorBase<double> > x_final; { Array<double> time_vec; time_vec.push_back(finalTime); Array<RCP<const Thyra::VectorBase<double> > > x_final_array; fwdIntegrator->getFwdPoints(time_vec,&x_final_array,NULL,NULL); x_final = x_final_array[0]; } // Verify x_final is correct { // Defaults from SinCos Model: double f = 1.0; double L = 1.0; double a = 0.0; double x_ic_0 = 0.0; double x_ic_1 = 1.0; double x_0 = dt/(1.0+std::pow(dt*f/L,2))*(x_ic_0/dt+x_ic_1+dt*std::pow(f/L,2)*a); double x_1 = dt/(1.0+std::pow(dt*f/L,2))*(-std::pow(f/L,2)*x_ic_0+x_ic_1/dt+std::pow(f/L,2)*a); double tol = 1.0e-10; Thyra::ConstDetachedVectorView<double> x_final_view( *x_final ); TEST_FLOATING_EQUALITY( x_final_view[0], x_0, tol ); TEST_FLOATING_EQUALITY( x_final_view[1], x_1, tol ); } // Copy InterpolationBuffer data into Cubic Spline interpolation buffer for use in Adjoint Solve TimeRange<double> fwdTimeRange; RCP<InterpolationBufferBase<double> > fwdCubicSplineInterpBuffer; { RCP<PointwiseInterpolationBufferAppender<double> > piba = pointwiseInterpolationBufferAppender<double>(); RCP<InterpolationBuffer<double> > sinkInterpBuffer = interpolationBuffer<double>(); sinkInterpBuffer->setStorage(storageLimit); RCP<CubicSplineInterpolator<double> > csi = cubicSplineInterpolator<double>(); sinkInterpBuffer->setInterpolator(csi); RCP<const InterpolationBufferBase<double> > sourceInterpBuffer; { RCP<TrailingInterpolationBufferAcceptingIntegratorBase<double> > tibaib = Teuchos::rcp_dynamic_cast<TrailingInterpolationBufferAcceptingIntegratorBase<double> >(fwdIntegrator,true); sourceInterpBuffer = tibaib->getTrailingInterpolationBuffer(); } fwdTimeRange = sourceInterpBuffer->getTimeRange(); piba->append(*sourceInterpBuffer, fwdTimeRange, Teuchos::outArg(*sinkInterpBuffer)); fwdCubicSplineInterpBuffer = sinkInterpBuffer; TimeRange<double> sourceRange = sourceInterpBuffer->getTimeRange(); TimeRange<double> sinkRange = sinkInterpBuffer->getTimeRange(); TEST_EQUALITY( sourceRange.lower(), sinkRange.lower() ); TEST_EQUALITY( sourceRange.upper(), sinkRange.upper() ); } // Adjoint Solve, reading forward solve data from Cubic Spline interpolation buffer { RCP<ParameterList> ibPL = Teuchos::parameterList(); ibPL->sublist("Integrator Settings").sublist("Integrator Selection").set("Integrator Type","Default Integrator"); ibPL->sublist("Integrator Settings").set("Final Time",finalTime); ibPL->sublist("Integration Control Strategy Selection").set("Integration Control Strategy Type","Simple Integration Control Strategy"); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Take Variable Steps",false); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Fixed dt",dt); ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Backward Euler"); //ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Implicit RK"); //ibPL->sublist("Stepper Settings").sublist("Runge Kutta Butcher Tableau Selection").set("Runge Kutta Butcher Tableau Type","Implicit 1 Stage 2nd order Gauss"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").set("Interpolation Buffer Type","Interpolation Buffer"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").sublist("Interpolation Buffer").set("StorageLimit",storageLimit); ibPL->sublist("Interpolation Buffer Settings").sublist("Interpolator Selection").set("Interpolator Type","Linear Interpolator"); ib->setParameterList(ibPL); } RCP<Thyra::ModelEvaluator<double> > adjModel; { RCP<Rythmos::AdjointModelEvaluator<double> > model = Rythmos::adjointModelEvaluator<double>( fwdModel, fwdTimeRange ); //model->setFwdStateSolutionBuffer(fwdCubicSplineInterpBuffer); adjModel = model; } Thyra::ModelEvaluatorBase::InArgs<double> adjIC = adjModel->getNominalValues(); double phi_ic_0 = 2.0; double phi_ic_1 = 3.0; { // Initial conditions for adjoint: const RCP<const Thyra::VectorSpaceBase<double> > f_space = fwdModel->get_f_space(); const RCP<Thyra::VectorBase<double> > x_ic = createMember(f_space); { Thyra::DetachedVectorView<double> x_ic_view( *x_ic ); x_ic_view[0] = phi_ic_0; x_ic_view[1] = phi_ic_1; } const RCP<Thyra::VectorBase<double> > xdot_ic = createMember(f_space); V_S( Teuchos::outArg(*xdot_ic), ST::zero() ); adjIC.set_x(x_ic); adjIC.set_x_dot(xdot_ic); } RCP<Thyra::LinearNonlinearSolver<double> > adjNLSolver = Thyra::linearNonlinearSolver<double>(); RCP<IntegratorBase<double> > adjIntegrator = ib->create(adjModel,adjIC,adjNLSolver); RCP<const VectorBase<double> > phi_final; { Array<double> time_vec; time_vec.push_back(finalTime); Array<RCP<const Thyra::VectorBase<double> > > phi_final_array; adjIntegrator->getFwdPoints(time_vec,&phi_final_array,NULL,NULL); phi_final = phi_final_array[0]; } // Verify phi_final is correct { // Defaults from SinCos Model: double f = 1.0; double L = 1.0; double h = -dt; double phi_0 = 1.0/(1.0+std::pow(f*h/L,2.0))*(phi_ic_0+std::pow(f/L,2.0)*h*phi_ic_1); double phi_1 = 1.0/(1.0+std::pow(f*h/L,2.0))*(-h*phi_ic_0+phi_ic_1); double tol = 1.0e-10; Thyra::ConstDetachedVectorView<double> phi_final_view( *phi_final ); TEST_FLOATING_EQUALITY( phi_final_view[0], phi_0, tol ); TEST_FLOATING_EQUALITY( phi_final_view[1], phi_1, tol ); } // Compute error estimate //TEST_ASSERT( false ); }
TEUCHOS_UNIT_TEST(RAPFactory, Correctness) { out << "version: " << MueLu::Version() << std::endl; RCP<const Teuchos::Comm<int> > comm = Parameters::getDefaultComm(); Level fineLevel, coarseLevel; TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::createTwoLevelHierarchy(fineLevel, coarseLevel); RCP<Matrix> Op = TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::Build1DPoisson(27*comm->getSize()); fineLevel.Set("A",Op); TentativePFactory tentpFactory; SaPFactory sapFactory; sapFactory.SetFactory("P",rcpFromRef(tentpFactory)); TransPFactory transPFactory; transPFactory.SetFactory("P", rcpFromRef(sapFactory)); //todo:rcpFromRef coarseLevel.Request("P",&sapFactory); coarseLevel.Request("R",&transPFactory); coarseLevel.Request(sapFactory); coarseLevel.Request(transPFactory); sapFactory.Build(fineLevel,coarseLevel); transPFactory.Build(fineLevel,coarseLevel); RAPFactory rap; rap.SetFactory("P", rcpFromRef(sapFactory)); rap.SetFactory("R", rcpFromRef(transPFactory)); coarseLevel.Request(rap); coarseLevel.Request("A",&rap); rap.Build(fineLevel,coarseLevel); RCP<Matrix> A = fineLevel.Get< RCP<Matrix> >("A"); RCP<Matrix> P = coarseLevel.Get< RCP<Matrix> >("P", &sapFactory); RCP<Matrix> R = coarseLevel.Get< RCP<Matrix> >("R", &transPFactory); RCP<MultiVector> workVec1 = MultiVectorFactory::Build(P->getRangeMap(),1); RCP<MultiVector> workVec2 = MultiVectorFactory::Build(Op->getRangeMap(),1); RCP<MultiVector> result1 = MultiVectorFactory::Build(R->getRangeMap(),1); RCP<MultiVector> X = MultiVectorFactory::Build(P->getDomainMap(),1); X->randomize(); //Calculate result1 = R*(A*(P*X)) P->apply(*X,*workVec1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Op->apply(*workVec1,*workVec2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); R->apply(*workVec2,*result1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); RCP<Matrix> coarseOp = coarseLevel.Get< RCP<Matrix> >("A", &rap); //Calculate result2 = (R*A*P)*X RCP<MultiVector> result2 = MultiVectorFactory::Build(R->getRangeMap(),1); coarseOp->apply(*X,*result2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Teuchos::Array<ST::magnitudeType> normX(1), normResult1(1),normResult2(1); X->norm2(normX); out << "This test checks the correctness of the Galerkin triple " << "matrix product by comparing (RAP)*X to R(A(P*X))." << std::endl; out << "||X||_2 = " << normX << std::endl; result1->norm2(normResult1); result2->norm2(normResult2); TEST_FLOATING_EQUALITY(normResult1[0], normResult2[0], 1e-12); } // Correctness test
TEUCHOS_UNIT_TEST(RAPFactory, ImplicitTranspose) { out << "version: " << MueLu::Version() << std::endl; RCP<const Teuchos::Comm<int> > comm = Parameters::getDefaultComm(); if (comm->getSize() > 1 && TestHelpers::Parameters::getLib() == Xpetra::UseEpetra ) { out << "Skipping ImplicitTranspose test for Epetra and #proc>1" << std::endl; return; } // build test-specific default factory manager RCP<FactoryManager> defManager = rcp(new FactoryManager()); defManager->SetFactory("A", rcp(MueLu::NoFactory::get(),false)); // dummy factory for A defManager->SetFactory("Nullspace", rcp(new NullspaceFactory())); // real null space factory for Ptent defManager->SetFactory("Graph", rcp(new CoalesceDropFactory())); // real graph factory for Ptent defManager->SetFactory("Aggregates", rcp(new CoupledAggregationFactory())); // real aggregation factory for Ptent Level fineLevel, coarseLevel; TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::createTwoLevelHierarchy(fineLevel, coarseLevel); // overwrite default factory manager fineLevel.SetFactoryManager(defManager); coarseLevel.SetFactoryManager(defManager); RCP<Matrix> Op = TestHelpers::TestFactory<SC, LO, GO, NO, LMO>::Build1DPoisson(19*comm->getSize()); fineLevel.Set("A",Op); TentativePFactory tentpFactory; SaPFactory sapFactory; sapFactory.SetFactory("P",rcpFromRef(tentpFactory)); TransPFactory transPFactory; transPFactory.SetFactory("P", rcpFromRef(sapFactory)); coarseLevel.Request("P", &sapFactory); coarseLevel.Request("R", &transPFactory); coarseLevel.Request(sapFactory); coarseLevel.Request(transPFactory); sapFactory.Build(fineLevel, coarseLevel); transPFactory.Build(fineLevel,coarseLevel); RAPFactory rap; rap.SetFactory("P", rcpFromRef(sapFactory)); rap.SetFactory("R", rcpFromRef(transPFactory)); coarseLevel.Request("A", &rap); rap.SetImplicitTranspose(true); coarseLevel.Request(rap); rap.Build(fineLevel,coarseLevel); RCP<Matrix> A = fineLevel.Get< RCP<Matrix> >("A"); RCP<Matrix> P = coarseLevel.Get< RCP<Matrix> >("P", &sapFactory); RCP<Matrix> R = coarseLevel.Get< RCP<Matrix> >("R", &transPFactory); //std::string filename = "A.dat"; //Utils::Write(filename,Op); //filename = "P.dat"; //Utils::Write(filename,P); RCP<MultiVector> workVec1 = MultiVectorFactory::Build(P->getRangeMap(),1); RCP<MultiVector> workVec2 = MultiVectorFactory::Build(Op->getRangeMap(),1); RCP<MultiVector> result1 = MultiVectorFactory::Build(P->getDomainMap(),1); RCP<MultiVector> X = MultiVectorFactory::Build(P->getDomainMap(),1); X->randomize(); //out.precision(12); //out.setOutputToRootOnly(-1); //X->describe(out,Teuchos::VERB_EXTREME); //Calculate result1 = P^T*(A*(P*X)) P->apply(*X,*workVec1,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Op->apply(*workVec1,*workVec2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); P->apply(*workVec2,*result1,Teuchos::TRANS,(SC)1.0,(SC)0.0); RCP<Matrix> coarseOp = coarseLevel.Get< RCP<Matrix> >("A", &rap); //Calculate result2 = (R*A*P)*X RCP<MultiVector> result2 = MultiVectorFactory::Build(P->getDomainMap(),1); coarseOp->apply(*X,*result2,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); Teuchos::Array<ST::magnitudeType> normX(1), normResult1(1),normResult2(1); X->norm2(normX); out << "This test checks the correctness of the Galerkin triple " << "matrix product by comparing (RAP)*X to R(A(P*X)), where R is the implicit tranpose of P." << std::endl; out << "||X||_2 = " << normX << std::endl; result1->norm2(normResult1); result2->norm2(normResult2); TEST_FLOATING_EQUALITY(normResult1[0], normResult2[0], 1e-12); } // Correctness test
TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( SpmdLocalDataAccess, getNonconstLocalSubVectorView_procRankLocalDim, Scalar ) { typedef typename ScalarTraits<Scalar>::magnitudeType ScalarMag; const RCP<const DefaultSpmdVectorSpace<Scalar> > vs = createProcRankLocalDimVS<Scalar>(); const RCP<const Teuchos::Comm<Ordinal> > comm = vs->getComm(); const int procRank = comm->getRank(); PRINT_VAR(procRank); const int numProcs = comm->getSize(); PRINT_VAR(numProcs); out << "*** A) Test that we get and change the nonconst view" << " directly through an SPMD Vector ...\n"; { const RCP<VectorBase<Scalar> > v = createMember<Scalar>(vs); const Scalar val = as<Scalar>(1.5); PRINT_VAR(val); assign<Scalar>(v.ptr(), val); const ScalarMag tol = 100.0*ScalarTraits<Scalar>::eps(); TEST_FLOATING_EQUALITY(sum<Scalar>(*v), as<Scalar>(vs->dim())*val, tol); { out << "*** A.1) Get the non-const view and set the local elements ...\n"; RTOpPack::SubVectorView<Scalar> lsv = getNonconstLocalSubVectorView<Scalar>(v); TEST_EQUALITY(lsv.globalOffset(), as<Ordinal>((procRank*(procRank+1))/2)); TEST_EQUALITY(lsv.subDim(), procRank+1); TEST_EQUALITY_CONST(lsv.stride(), 1); for (int k = 0; k < lsv.subDim(); ++k) { lsv[k] = lsv.globalOffset() + k + 1; } const Ordinal n = vs->dim(); TEST_FLOATING_EQUALITY(sum<Scalar>(*v), as<Scalar>((n*(n+1))/2.0), tol); } { out << "*** A.2) Get the const view and check the local elemetns ...\n"; RTOpPack::ConstSubVectorView<Scalar> lsv = getLocalSubVectorView<Scalar>(v); TEST_EQUALITY(lsv.subDim(), procRank+1); TEST_EQUALITY_CONST(lsv.stride(), 1); for (int k = 0; k < lsv.subDim(); ++k) { TEST_EQUALITY(lsv[k], as<Scalar>(lsv.globalOffset() + k + 1)); } } } out << "*** B) Test that we get and change the nonconst view" << " indirectly through a product vector with one block ...\n"; { const RCP<const VectorSpaceBase<Scalar> > pvs = productVectorSpace<Scalar>(tuple<RCP<const VectorSpaceBase<Scalar> > >(vs)()); const RCP<VectorBase<Scalar> > pv = createMember<Scalar>(pvs); const Scalar val = as<Scalar>(1.7); PRINT_VAR(val); assign<Scalar>(pv.ptr(), val); const ScalarMag tol = 100.0*ScalarTraits<Scalar>::eps(); { out << "*** B.1) Get the non-const view and set the local elements ...\n"; RTOpPack::SubVectorView<Scalar> lsv = getNonconstLocalSubVectorView<Scalar>(pv); TEST_EQUALITY(lsv.globalOffset(), as<Ordinal>((procRank*(procRank+1))/2)); TEST_EQUALITY(lsv.subDim(), procRank+1); TEST_EQUALITY_CONST(lsv.stride(), 1); for (int k = 0; k < lsv.subDim(); ++k) { lsv[k] = lsv.globalOffset() + k + 1; } const Ordinal n = vs->dim(); TEST_FLOATING_EQUALITY(sum<Scalar>(*pv), as<Scalar>((n*(n+1))/2.0), tol); } { out << "*** B.2) Get the const view and check the local elemetns ...\n"; RTOpPack::ConstSubVectorView<Scalar> lsv = getLocalSubVectorView<Scalar>(pv); TEST_EQUALITY(lsv.subDim(), procRank+1); TEST_EQUALITY_CONST(lsv.stride(), 1); for (int k = 0; k < lsv.subDim(); ++k) { TEST_EQUALITY(lsv[k], as<Scalar>(lsv.globalOffset() + k + 1)); } } } }
TEUCHOS_UNIT_TEST(basis_time_vector, residual) { PHX::KokkosDeviceSession session; const std::size_t workset_size = 1; const std::string fieldName_q1 = "TEMPERATURE"; const std::string fieldName_qedge1 = "ION_TEMPERATURE"; Teuchos::RCP<panzer_stk_classic::STK_Interface> mesh = buildMesh(1,1); // 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<panzer::IntegrationRule> ir = buildIR(workset_size,4); Teuchos::RCP<panzer::BasisIRLayout> layout_qedge1 = Teuchos::rcp(new panzer::BasisIRLayout(basis_qedge1,*ir)); // 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::DOFManager<int,int> > dofManager = Teuchos::rcp(new panzer::DOFManager<int,int>(conn_manager,MPI_COMM_WORLD)); dofManager->addField(fieldName_q1,Teuchos::rcp(new panzer::IntrepidFieldPattern(basis_q1->getIntrepidBasis()))); dofManager->addField(fieldName_qedge1,Teuchos::rcp(new panzer::IntrepidFieldPattern(basis_qedge1->getIntrepidBasis()))); dofManager->setOrientationsRequired(true); dofManager->buildGlobalUnknowns(); // build worksets std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks; physicsBlocks.push_back(physicsBlock); // pushing back singular panzer::WorksetContainer wkstContainer(Teuchos::rcp(new panzer_stk_classic::WorksetFactory(mesh)),physicsBlocks,workset_size); wkstContainer.setGlobalIndexer(dofManager); Teuchos::RCP<std::vector<panzer::Workset> > work_sets = wkstContainer.getVolumeWorksets(physicsBlock->elementBlockID()); TEST_EQUALITY(work_sets->size(),1); // setup field manager, add evaluator under test ///////////////////////////////////////////////////////////// PHX::FieldManager<panzer::Traits> fm; { Teuchos::ParameterList pl; pl.set("Name","Integrand"); pl.set("IR",ir); pl.set("Is Vector",true); pl.set<Teuchos::RCP<const PointEvaluation<panzer::Traits::Residual::ScalarT> > >("Point Evaluator", Teuchos::rcp(new BilinearPointEvaluator)); Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = Teuchos::rcp(new PointEvaluator<panzer::Traits::Residual,panzer::Traits>(pl)); fm.registerEvaluator<panzer::Traits::Residual>(evaluator); } { Teuchos::ParameterList pl; pl.set("Residual Name","Residual"); pl.set("Value Name","Integrand"); pl.set("Test Field Name",fieldName_qedge1); pl.set("Basis",layout_qedge1); pl.set("IR",ir); pl.set<double>("Multiplier", 1.0); Teuchos::RCP<const std::vector<std::string> > vec = Teuchos::rcp(new std::vector<std::string>); pl.set("Field Multipliers", vec); Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = Teuchos::rcp(new panzer::Integrator_BasisTimesVector<panzer::Traits::Residual,panzer::Traits>(pl)); fm.registerEvaluator<panzer::Traits::Residual>(evaluator); fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]); } std::vector<PHX::index_size_type> derivative_dimensions; derivative_dimensions.push_back(8); fm.setKokkosExtendedDataTypeDimensions<panzer::Traits::Jacobian>(derivative_dimensions); panzer::Traits::SetupData sd; sd.worksets_ = work_sets; fm.postRegistrationSetup(sd); // run tests ///////////////////////////////////////////////////////////// panzer::Workset & workset = (*work_sets)[0]; workset.alpha = 0.0; workset.beta = 0.0; workset.time = 0.0; workset.evaluate_transient_terms = false; fm.evaluateFields<panzer::Traits::Residual>(workset); PHX::MDField<panzer::Traits::Residual::ScalarT,panzer::Cell,panzer::BASIS> fieldData_qedge1("Residual",basis_qedge1->functional); fm.getFieldData<panzer::Traits::Residual::ScalarT,panzer::Traits::Residual>(fieldData_qedge1); TEST_EQUALITY(fieldData_qedge1.dimension(0),1); TEST_EQUALITY(fieldData_qedge1.dimension(1),4); // Transformation is [x,y] = F[x_ref,y_ref] = 0.5*[1,1]+0.5*[1,0;0,1]*[x_ref,y_ref] // therefore transformation matrix is DF^{-T} = 2*[1,0;0,1] // so curl vector u_ref:Ref_coord=>Ref_Vec transforms with // // u(x,y)=DF^{-T}*u_ref(F^{-1}(x,y)) TEST_FLOATING_EQUALITY(fieldData_qedge1(0,0),5.0/12.0,1e-5); // 0 edge basis is [(1-y_ref)/4, 0] TEST_FLOATING_EQUALITY(fieldData_qedge1(0,2),3.0/4.0,1e-5); // 2 edge basis is [(1+y_ref)/4, 0] // these two have sign changes because of the mesh topology! TEST_FLOATING_EQUALITY(fieldData_qedge1(0,1),0.428925006266,1e-5); // 1 edge basis is [(1+x_ref)/4, 0] TEST_FLOATING_EQUALITY(fieldData_qedge1(0,3),0.344719536524,1e-5); // 3 edge basis is [(1-x_ref)/4, 0] }