int main(int ac, char* av[]) { KokkosGuard kokkos(ac, av); typedef PHX::MDField<PHAL::AlbanyTraits::Residual::ScalarT>::size_type size_type; typedef PHAL::AlbanyTraits::Residual Residual; typedef PHAL::AlbanyTraits::Residual::ScalarT ScalarT; typedef PHAL::AlbanyTraits Traits; std::cout.precision(15); // // Create a command line processor and parse command line options // Teuchos::CommandLineProcessor command_line_processor; command_line_processor.setDocString( "Material Point Simulator.\n" "For testing material models in LCM.\n"); std::string input_file = "materials.xml"; command_line_processor.setOption("input", &input_file, "Input File Name"); std::string timing_file = "timing.csv"; command_line_processor.setOption("timing", &timing_file, "Timing File Name"); int workset_size = 1; command_line_processor.setOption("wsize", &workset_size, "Workset Size"); int num_pts = 1; command_line_processor.setOption( "npoints", &num_pts, "Number of Gaussian Points"); size_t memlimit = 1024; // 1GB heap limit by default command_line_processor.setOption( "memlimit", &memlimit, "Heap memory limit in MB for CUDA kernels"); // Throw a warning and not error for unrecognized options command_line_processor.recogniseAllOptions(true); // Don't throw exceptions for errors command_line_processor.throwExceptions(false); // Parse command line Teuchos::CommandLineProcessor::EParseCommandLineReturn parse_return = command_line_processor.parse(ac, av); std::ofstream tout(timing_file.c_str()); if (parse_return == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED) { return 0; } if (parse_return != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { return 1; } util::TimeMonitor& tmonitor = util::PerformanceContext::instance().timeMonitor(); Teuchos::RCP<Teuchos::Time> total_time = tmonitor["MPS: Total Time"]; Teuchos::RCP<Teuchos::Time> compute_time = tmonitor["MPS: Compute Time"]; // // Process material.xml file // Read into materialDB and get material model name // // A mpi object must be instantiated before using the comm to read // material file Teuchos::GlobalMPISession mpi_session(&ac, &av); Teuchos::RCP<const Teuchos_Comm> commT = Albany::createTeuchosCommFromMpiComm(Albany_MPI_COMM_WORLD); Teuchos::RCP<Albany::MaterialDatabase> material_db; material_db = Teuchos::rcp(new Albany::MaterialDatabase(input_file, commT)); // Get the name of the material model to be used (and make sure there is one) std::string element_block_name = "Block0"; std::string material_model_name; material_model_name = material_db->getElementBlockSublist(element_block_name, "Material Model") .get<std::string>("Model Name"); TEUCHOS_TEST_FOR_EXCEPTION( material_model_name.length() == 0, std::logic_error, "A material model must be defined for block: " + element_block_name); // // Preloading stage setup // set up evaluators, create field and state managers // // Set up the data layout // const int workset_size = 1; const int num_dims = 3; const int num_vertices = 8; const int num_nodes = 8; const Teuchos::RCP<Albany::Layouts> dl = Teuchos::rcp(new Albany::Layouts( workset_size, num_vertices, num_nodes, num_pts, num_dims)); // create field name strings LCM::FieldNameMap field_name_map(false); Teuchos::RCP<std::map<std::string, std::string>> fnm = field_name_map.getMap(); //--------------------------------------------------------------------------- // Deformation gradient // initially set the deformation gradient to the identity Teuchos::ArrayRCP<ScalarT> def_grad(workset_size * num_pts * 9); for (int i = 0; i < workset_size; ++i) { for (int j = 0; j < num_pts; ++j) { int base = i * num_pts * 9 + j * 9; for (int k = 0; k < 9; ++k) def_grad[base + k] = 0.0; def_grad[base + 0] = 1.0; def_grad[base + 4] = 1.0; def_grad[base + 8] = 1.0; } } // SetField evaluator, which will be used to manually assign a value // to the def_grad field Teuchos::ParameterList setDefGradP("SetFieldDefGrad"); setDefGradP.set<std::string>("Evaluated Field Name", "F"); setDefGradP.set<Teuchos::RCP<PHX::DataLayout>>( "Evaluated Field Data Layout", dl->qp_tensor); setDefGradP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", def_grad); auto setFieldDefGrad = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDefGradP)); //--------------------------------------------------------------------------- // Det(deformation gradient) Teuchos::ArrayRCP<ScalarT> detdefgrad(workset_size * num_pts); for (int i = 0; i < workset_size * num_pts; ++i) detdefgrad[i] = 1.0; // SetField evaluator, which will be used to manually assign a value // to the detdefgrad field Teuchos::ParameterList setDetDefGradP("SetFieldDetDefGrad"); setDetDefGradP.set<std::string>("Evaluated Field Name", "J"); setDetDefGradP.set<Teuchos::RCP<PHX::DataLayout>>( "Evaluated Field Data Layout", dl->qp_scalar); setDetDefGradP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", detdefgrad); auto setFieldDetDefGrad = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDetDefGradP)); //--------------------------------------------------------------------------- // Small strain tensor // initially set the strain tensor to zeros Teuchos::ArrayRCP<ScalarT> strain(workset_size * num_pts * 9); for (int i = 0; i < workset_size; ++i) { for (int j = 0; j < num_pts; ++j) { int base = i * num_pts * 9 + j * 9; for (int k = 0; k < 9; ++k) strain[base + k] = 0.0; } } // SetField evaluator, which will be used to manually assign a value // to the strain field Teuchos::ParameterList setStrainP("SetFieldStrain"); setStrainP.set<std::string>("Evaluated Field Name", "Strain"); setStrainP.set<Teuchos::RCP<PHX::DataLayout>>( "Evaluated Field Data Layout", dl->qp_tensor); setStrainP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", strain); auto setFieldStrain = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setStrainP)); //--------------------------------------------------------------------------- // Instantiate a field manager PHX::FieldManager<Traits> fieldManager; // Instantiate a field manager for States PHX::FieldManager<Traits> stateFieldManager; // Register the evaluators with the field manager fieldManager.registerEvaluator<Residual>(setFieldDefGrad); fieldManager.registerEvaluator<Residual>(setFieldDetDefGrad); fieldManager.registerEvaluator<Residual>(setFieldStrain); // Register the evaluators with the state field manager stateFieldManager.registerEvaluator<Residual>(setFieldDefGrad); stateFieldManager.registerEvaluator<Residual>(setFieldDetDefGrad); stateFieldManager.registerEvaluator<Residual>(setFieldStrain); // Instantiate a state manager Albany::StateManager stateMgr; // extract the Material ParameterList for use below std::string matName = material_db->getElementBlockParam<std::string>( element_block_name, "material"); Teuchos::ParameterList& paramList = material_db->getElementBlockSublist(element_block_name, matName); Teuchos::ParameterList& mpsParams = paramList.sublist("Material Point Simulator"); // Get loading parameters from .xml file std::string load_case = mpsParams.get<std::string>("Loading Case Name", "uniaxial"); int number_steps = mpsParams.get<int>("Number of Steps", 10); double step_size = mpsParams.get<double>("Step Size", 1.0e-2); std::cout << "Loading parameters:" << "\n number of steps: " << number_steps << "\n step_size : " << step_size << std::endl; // determine if temperature is being used bool have_temperature = mpsParams.get<bool>("Use Temperature", false); std::cout << "have_temp: " << have_temperature << std::endl; //--------------------------------------------------------------------------- // Temperature (optional) if (have_temperature) { Teuchos::ArrayRCP<ScalarT> temperature(workset_size); ScalarT temp = mpsParams.get<double>("Temperature", 1.0); for (int i = 0; i < workset_size * num_pts; ++i) temperature[0] = temp; // SetField evaluator, which will be used to manually assign a value // to the detdefgrad field Teuchos::ParameterList setTempP("SetFieldTemperature"); setTempP.set<std::string>("Evaluated Field Name", "Temperature"); setTempP.set<Teuchos::RCP<PHX::DataLayout>>( "Evaluated Field Data Layout", dl->qp_scalar); setTempP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", temperature); auto setFieldTemperature = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setTempP)); fieldManager.registerEvaluator<Residual>(setFieldTemperature); stateFieldManager.registerEvaluator<Residual>(setFieldTemperature); } //--------------------------------------------------------------------------- // Time step Teuchos::ArrayRCP<ScalarT> delta_time(1); delta_time[0] = step_size; Teuchos::ParameterList setDTP("SetFieldTimeStep"); setDTP.set<std::string>("Evaluated Field Name", "Delta Time"); setDTP.set<Teuchos::RCP<PHX::DataLayout>>( "Evaluated Field Data Layout", dl->workset_scalar); setDTP.set<Teuchos::ArrayRCP<ScalarT>>("Field Values", delta_time); auto setFieldDT = Teuchos::rcp(new LCM::SetField<Residual, Traits>(setDTP)); fieldManager.registerEvaluator<Residual>(setFieldDT); stateFieldManager.registerEvaluator<Residual>(setFieldDT); // check if the material wants the tangent to be computed bool check_stability; check_stability = mpsParams.get<bool>("Check Stability", false); paramList.set<bool>("Compute Tangent", check_stability); std::cout << "Check stability = " << check_stability << std::endl; //--------------------------------------------------------------------------- // std::cout << "// Constitutive Model Parameters" //<< std::endl; Teuchos::ParameterList cmpPL; paramList.set<Teuchos::RCP<std::map<std::string, std::string>>>( "Name Map", fnm); cmpPL.set<Teuchos::ParameterList*>("Material Parameters", ¶mList); if (have_temperature) { cmpPL.set<std::string>("Temperature Name", "Temperature"); paramList.set<bool>("Have Temperature", true); } auto CMP = Teuchos::rcp( new LCM::ConstitutiveModelParameters<Residual, Traits>(cmpPL, dl)); fieldManager.registerEvaluator<Residual>(CMP); stateFieldManager.registerEvaluator<Residual>(CMP); //--------------------------------------------------------------------------- // std::cout << "// Constitutive Model Interface Evaluator" // << std::endl; Teuchos::ParameterList cmiPL; cmiPL.set<Teuchos::ParameterList*>("Material Parameters", ¶mList); if (have_temperature) { cmiPL.set<std::string>("Temperature Name", "Temperature"); } Teuchos::RCP<LCM::ConstitutiveModelInterface<Residual, Traits>> CMI = Teuchos::rcp( new LCM::ConstitutiveModelInterface<Residual, Traits>(cmiPL, dl)); fieldManager.registerEvaluator<Residual>(CMI); stateFieldManager.registerEvaluator<Residual>(CMI); // Set the evaluated fields as required for (std::vector<Teuchos::RCP<PHX::FieldTag>>::const_iterator it = CMI->evaluatedFields().begin(); it != CMI->evaluatedFields().end(); ++it) { fieldManager.requireField<Residual>(**it); } // register state variables Teuchos::RCP<Teuchos::ParameterList> p; Teuchos::RCP<PHX::Evaluator<Traits>> ev; for (int sv(0); sv < CMI->getNumStateVars(); ++sv) { CMI->fillStateVariableStruct(sv); p = stateMgr.registerStateVariable( CMI->getName(), CMI->getLayout(), dl->dummy, element_block_name, CMI->getInitType(), CMI->getInitValue(), CMI->getStateFlag(), CMI->getOutputFlag()); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); } //--------------------------------------------------------------------------- if (check_stability) { std::string parametrization_type = mpsParams.get<std::string>("Parametrization Type", "Spherical"); double parametrization_interval = mpsParams.get<double>("Parametrization Interval", 0.05); std::cout << "Bifurcation Check in Material Point Simulator:" << std::endl; std::cout << "Parametrization Type: " << parametrization_type << std::endl; Teuchos::ParameterList bcPL; bcPL.set<Teuchos::ParameterList*>("Material Parameters", ¶mList); bcPL.set<std::string>("Parametrization Type Name", parametrization_type); bcPL.set<double>("Parametrization Interval Name", parametrization_interval); bcPL.set<std::string>("Material Tangent Name", "Material Tangent"); bcPL.set<std::string>("Ellipticity Flag Name", "Ellipticity_Flag"); bcPL.set<std::string>("Bifurcation Direction Name", "Direction"); bcPL.set<std::string>("Min detA Name", "Min detA"); Teuchos::RCP<LCM::BifurcationCheck<Residual, Traits>> BC = Teuchos::rcp(new LCM::BifurcationCheck<Residual, Traits>(bcPL, dl)); fieldManager.registerEvaluator<Residual>(BC); stateFieldManager.registerEvaluator<Residual>(BC); // register the ellipticity flag p = stateMgr.registerStateVariable( "Ellipticity_Flag", dl->qp_scalar, dl->dummy, element_block_name, "scalar", 0.0, false, true); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); // register the direction p = stateMgr.registerStateVariable( "Direction", dl->qp_vector, dl->dummy, element_block_name, "scalar", 0.0, false, true); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); // register min(det(A)) p = stateMgr.registerStateVariable( "Min detA", dl->qp_scalar, dl->dummy, element_block_name, "scalar", 0.0, false, true); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); } //--------------------------------------------------------------------------- // std::cout << "// register deformation gradient" // << std::endl; p = stateMgr.registerStateVariable( "F", dl->qp_tensor, dl->dummy, element_block_name, "identity", 1.0, true, true); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); //--------------------------------------------------------------------------- // std::cout << "// register small strain tensor" // << std::endl; p = stateMgr.registerStateVariable( "Strain", dl->qp_tensor, dl->dummy, element_block_name, "scalar", 0.0, false, true); ev = Teuchos::rcp(new PHAL::SaveStateField<Residual, Traits>(*p)); fieldManager.registerEvaluator<Residual>(ev); stateFieldManager.registerEvaluator<Residual>(ev); //--------------------------------------------------------------------------- // Traits::SetupData setupData = "Test String"; // std::cout << "Calling postRegistrationSetup" << std::endl; fieldManager.postRegistrationSetup(setupData); // std::cout << "// set the required fields for the state manager" //<< std::endl; Teuchos::RCP<PHX::DataLayout> dummy = Teuchos::rcp(new PHX::MDALayout<Dummy>(0)); std::vector<std::string> responseIDs = stateMgr.getResidResponseIDsToRequire(element_block_name); std::vector<std::string>::const_iterator it; for (it = responseIDs.begin(); it != responseIDs.end(); it++) { const std::string& responseID = *it; PHX::Tag<PHAL::AlbanyTraits::Residual::ScalarT> res_response_tag( responseID, dummy); stateFieldManager.requireField<PHAL::AlbanyTraits::Residual>( res_response_tag); } stateFieldManager.postRegistrationSetup(""); // std::cout << "Process using 'dot -Tpng -O <name>'\n"; fieldManager.writeGraphvizFile<Residual>("FM", true, true); stateFieldManager.writeGraphvizFile<Residual>("SFM", true, true); //--------------------------------------------------------------------------- // grab the output file name // std::string output_file = mpsParams.get<std::string>("Output File Name", "output.exo"); //--------------------------------------------------------------------------- // Create discretization, as required by the StateManager // Teuchos::RCP<Teuchos::ParameterList> discretizationParameterList = Teuchos::rcp(new Teuchos::ParameterList("Discretization")); discretizationParameterList->set<int>("1D Elements", workset_size); discretizationParameterList->set<int>("2D Elements", 1); discretizationParameterList->set<int>("3D Elements", 1); discretizationParameterList->set<std::string>("Method", "STK3D"); discretizationParameterList->set<int>("Number Of Time Derivatives", 0); discretizationParameterList->set<std::string>( "Exodus Output File Name", output_file); discretizationParameterList->set<int>("Workset Size", workset_size); Teuchos::RCP<Tpetra_Map> mapT = Teuchos::rcp(new Tpetra_Map( workset_size * num_dims * num_nodes, 0, commT, Tpetra::LocallyReplicated)); Teuchos::RCP<Tpetra_Vector> solution_vectorT = Teuchos::rcp(new Tpetra_Vector(mapT)); int numberOfEquations = 3; Albany::AbstractFieldContainer::FieldContainerRequirements req; Teuchos::RCP<Albany::AbstractSTKMeshStruct> stkMeshStruct = Teuchos::rcp(new Albany::TmplSTKMeshStruct<3>( discretizationParameterList, Teuchos::null, commT)); stkMeshStruct->setFieldAndBulkData( commT, discretizationParameterList, numberOfEquations, req, stateMgr.getStateInfoStruct(), stkMeshStruct->getMeshSpecs()[0]->worksetSize); Teuchos::RCP<Albany::AbstractDiscretization> discretization = Teuchos::rcp(new Albany::STKDiscretization( discretizationParameterList, stkMeshStruct, commT)); //--------------------------------------------------------------------------- // Associate the discretization with the StateManager // stateMgr.setupStateArrays(discretization); //--------------------------------------------------------------------------- // Create a workset // PHAL::Workset workset; workset.numCells = workset_size; workset.stateArrayPtr = &stateMgr.getStateArray(Albany::StateManager::ELEM, 0); // create MDFields PHX::MDField<ScalarT, Cell, QuadPoint, Dim, Dim> stressField( "Cauchy_Stress", dl->qp_tensor); // construct the final deformation gradient based on the loading case std::vector<ScalarT> F_vector(9, 0.0); if (load_case == "uniaxial") { F_vector[0] = 1.0 + number_steps * step_size; F_vector[4] = 1.0; F_vector[8] = 1.0; } else if (load_case == "simple-shear") { F_vector[0] = 1.0; F_vector[1] = number_steps * step_size; F_vector[4] = 1.0; F_vector[8] = 1.0; } else if (load_case == "hydrostatic") { F_vector[0] = 1.0 + number_steps * step_size; F_vector[4] = 1.0 + number_steps * step_size; F_vector[8] = 1.0 + number_steps * step_size; } else if (load_case == "general") { F_vector = mpsParams.get<Teuchos::Array<double>>("Deformation Gradient Components") .toVector(); } else { TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "Improper Loading Case in Material Point Simulator block"); } minitensor::Tensor<ScalarT> F_tensor(3, &F_vector[0]); minitensor::Tensor<ScalarT> log_F_tensor = minitensor::log(F_tensor); std::cout << "F\n" << F_tensor << std::endl; // std::cout << "log F\n" << log_F_tensor << std::endl; // // Setup loading scenario and instantiate evaluatFields // PHX::MDField<ScalarT, Cell, QuadPoint> minDetA("Min detA", dl->qp_scalar); PHX::MDField<ScalarT, Cell, QuadPoint, Dim> direction( "Direction", dl->qp_vector); // Bifurcation check parameters double mu_0 = 0; double mu_k = 0; int bifurcationTime_rough = number_steps; bool bifurcation_flag = false; for (int istep(0); istep <= number_steps; ++istep) { util::TimeGuard total_time_guard(total_time); // std::cout << "****** in MPS step " << istep << " ****** " << std::endl; // alpha \in [0,1] double alpha = double(istep) / number_steps; // std::cout << "alpha: " << alpha << std::endl; minitensor::Tensor<ScalarT> scaled_log_F_tensor = alpha * log_F_tensor; minitensor::Tensor<ScalarT> current_F = minitensor::exp(scaled_log_F_tensor); // std::cout << "scaled log F\n" << scaled_log_F_tensor << std::endl; // std::cout << "current F\n" << current_F << std::endl; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { def_grad[3 * i + j] = current_F(i, j); } } // jacobian detdefgrad[0] = minitensor::det(current_F); // small strain tensor minitensor::Tensor<ScalarT> current_strain; current_strain = 0.5 * (current_F + minitensor::transpose(current_F)) - minitensor::eye<ScalarT>(3); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { strain[3 * i + j] = current_strain(i, j); } } // std::cout << "current strain\n" << current_strain << std::endl; // Call the evaluators, evaluateFields() is the function that // computes stress based on deformation gradient compute_time->start(); fieldManager.preEvaluate<Residual>(workset); fieldManager.evaluateFields<Residual>(workset); fieldManager.postEvaluate<Residual>(workset); compute_time->stop(); stateFieldManager.getFieldData<Residual>(stressField); // Call the state field manager // std::cout << "+++ calling the stateFieldManager\n"; compute_time->start(); stateFieldManager.preEvaluate<Residual>(workset); stateFieldManager.evaluateFields<Residual>(workset); stateFieldManager.postEvaluate<Residual>(workset); compute_time->stop(); stateMgr.updateStates(); // output to the exodus file // Don't include this in timing data... total_time->stop(); discretization->writeSolutionT( *solution_vectorT, Teuchos::as<double>(istep)); // if check for bifurcation, adaptive step total_time->start(); if (check_stability) { // get current minDet(A) stateFieldManager.getFieldData<Residual>(minDetA); if (istep == 0) { mu_0 = minDetA(0, 0); } if (minDetA(0, 0) <= 0 && !bifurcation_flag) { mu_k = minDetA(0, 0); bifurcationTime_rough = istep; bifurcation_flag = true; // adaptive step begin std::cout << "\nAdaptive step begin - step " << istep << std::endl; // initialization for adaptive step double tol = 1E-8; double alpha_local = 1.0; double alpha_local_step = 0.5; int k = 1; int maxIteration = 50; // small strain tensor minitensor::Tensor<ScalarT> current_strain; // iteration begin while (((mu_k <= 0) || (std::abs(mu_k / mu_0) > tol))) { alpha = double(bifurcationTime_rough - 1 + alpha_local) / number_steps; minitensor::Tensor<ScalarT> scaled_log_F_tensor = alpha * log_F_tensor; minitensor::Tensor<ScalarT> current_F = minitensor::exp(scaled_log_F_tensor); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { def_grad[3 * i + j] = current_F(i, j); } } // jacobian detdefgrad[0] = minitensor::det(current_F); current_strain = 0.5 * (current_F + minitensor::transpose(current_F)) - minitensor::eye<ScalarT>(3); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { strain[3 * i + j] = current_strain(i, j); } } // Call the evaluators, evaluateFields() is the function that // computes stress based on deformation gradient fieldManager.preEvaluate<Residual>(workset); fieldManager.evaluateFields<Residual>(workset); fieldManager.postEvaluate<Residual>(workset); // Call the state field manager // std::cout << "+++ calling the stateFieldManager\n"; stateFieldManager.preEvaluate<Residual>(workset); stateFieldManager.evaluateFields<Residual>(workset); stateFieldManager.postEvaluate<Residual>(workset); stateFieldManager.getFieldData<Residual>(minDetA); stateFieldManager.getFieldData<Residual>(direction); mu_k = minDetA(0, 0); if (mu_k > 0) { alpha_local += alpha_local_step; } else { alpha_local -= alpha_local_step; } alpha_local_step /= 2; k = k + 1; if (k >= maxIteration) { std::cout << "Adaptive step for bifurcation check not converging after " << k << " iterations" << std::endl; break; } } // adaptive step iteration end } // end adaptive step } // end check bifurcation stateMgr.updateStates(); // if (bifurcation_flag) { // break the loading step after adaptive time step loop break; } // } // end loading steps // Summarize with AlbanyUtil performance monitors if (tout) { util::PerformanceContext::instance().timeMonitor().summarize(tout); tout.close(); } }
TEUCHOS_UNIT_TEST(response_assembly, test) { typedef Traits::Residual EvalT; // build global (or serial communicator) #ifdef HAVE_MPI Teuchos::RCP<Teuchos::Comm<int> > comm = Teuchos::rcp(new Teuchos::MpiComm<int>(Teuchos::opaqueWrapper(MPI_COMM_WORLD))); #else Teuchos::RCP<Teuchos::Comm<int> > comm = Teuchos::rcp(new Teuchos::SerialComm<int>); #endif using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_dynamic_cast; // panzer::pauseToAttach(); int worksetSize = 10; Teuchos::ParameterList mainParam; mainParam.set<int>("Workset Size", worksetSize); // build basic field manager PHX::FieldManager<Traits> fm; { RCP<PHX::Evaluator<Traits> > testEval = rcp(new TestEvaluator<EvalT,Traits>(mainParam)); fm.registerEvaluator<EvalT>(testEval); } std::vector<std::string> fields, testFields; fields.push_back("Dog"); fields.push_back("Horse"); RCP<WorksetContainer> wkstContainer = Teuchos::rcp(new WorksetContainer); RCP<ResponseLibrary<Traits> > rLibrary = Teuchos::rcp(new ResponseLibrary<Traits>(wkstContainer,Teuchos::null,Teuchos::null)); rLibrary->defineDefaultAggregators(); RCP<ResponseContainerBase<Traits> > container = Teuchos::rcp(new ResponseContainer<EvalT,Traits>(rLibrary)); ResponseId dResp = buildResponse("Dog","Functional"); ResponseId hResp = buildResponse("Horse","Functional"); ResponseId hResp2 = buildResponse("Horse","Max"); // should be able to add ResponseId cResp = buildResponse("Cat","Functional"); // not added container->reserve(dResp); container->reserve(hResp); // container->reserve(hResp2); container->reserve(hResp); // You can reserve things multiple times, should // not increased number of reserved items // TEST_EQUALITY(container->getReserved().size(),3); TEST_EQUALITY(container->getReserved().size(),2); TEST_ASSERT(container->contains(dResp)); TEST_ASSERT(container->contains(hResp)); // TEST_ASSERT(container->contains(hResp2)); TEST_ASSERT(!container->contains(cResp)); PhysicsBlock pb; // need for testing purposes (default constructor does nothing!) container->buildResponseDataObjs(); container->registerResponses(fm,pb,mainParam); // evaluate on block 0 { Teuchos::RCP<panzer::Workset> workset = Teuchos::rcp(new panzer::Workset); workset->num_cells = worksetSize; workset->block_id = "block_0"; panzer::Traits::SetupData setupData; setupData.worksets_ = rcp(new std::vector<panzer::Workset>); setupData.worksets_->push_back(*workset); panzer::GlobalEvaluationDataContainer preEvalData; fm.postRegistrationSetup(setupData); fm.writeGraphvizFile(); fm.preEvaluate<EvalT>(preEvalData); fm.evaluateFields<EvalT>(*workset); fm.postEvaluate<EvalT>(0); } double sum_dog = 0.0; double sum_horse = 0.0; for(int i=0;i<worksetSize;i++) { sum_dog += double(i)+1.0; sum_horse += -double(i)-5.5; } { Teuchos::RCP<ResponseData<Traits> > data = container->getResponseData("Functional"); panzer::Response<panzer::Traits> dResp_o(dResp), hResp_o(hResp); data->fillResponse("Dog",dResp_o); data->fillResponse("Horse",hResp_o); TEST_EQUALITY(dResp_o.getValue(),sum_dog); TEST_EQUALITY(hResp_o.getValue(),sum_horse); } { Teuchos::RCP<ResponseData<Traits> > data = container->getResponseData("Functional"); container->globalReduction(*comm); panzer::Response<panzer::Traits> dResp_o(dResp), hResp_o(hResp); data->fillResponse("Dog",dResp_o); data->fillResponse("Horse",hResp_o); TEST_EQUALITY(dResp_o.getValue(),comm->getSize()*sum_dog); TEST_EQUALITY(hResp_o.getValue(),comm->getSize()*sum_horse); } }
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 }
TEUCHOS_UNIT_TEST(gather_orientation, gather_constr) { const std::size_t workset_size = 4; const std::string fieldName_q1 = "U"; const std::string fieldName_qedge1 = "V"; 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::DOFManager<int,int> > dofManager = Teuchos::rcp(new panzer::DOFManager<int,int>(conn_manager,MPI_COMM_WORLD)); dofManager->addField(fieldName_q1,Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis()))); dofManager->addField(fieldName_qedge1,Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis()))); dofManager->setOrientationsRequired(true); dofManager->buildGlobalUnknowns(); // setup field manager, add evaluator under test ///////////////////////////////////////////////////////////// PHX::FieldManager<panzer::Traits> fm; Teuchos::RCP<PHX::FieldTag> evalField_q1, evalField_qedge1; { Teuchos::RCP<std::vector<std::string> > dofNames = Teuchos::rcp(new std::vector<std::string>); dofNames->push_back(fieldName_q1); Teuchos::ParameterList pl; pl.set("Indexer Names",dofNames); pl.set("DOF Names",dofNames); pl.set("Basis",basis_q1); Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = Teuchos::rcp(new panzer::GatherOrientation<panzer::Traits::Residual,panzer::Traits,int,int>(dofManager,pl)); TEST_EQUALITY(evaluator->evaluatedFields().size(),1); evalField_q1 = evaluator->evaluatedFields()[0]; TEST_EQUALITY(evalField_q1->name(),basis_q1->name()+" Orientation"); TEST_EQUALITY(evalField_q1->dataLayout().dimension(0),basis_q1->functional->dimension(0)); TEST_EQUALITY(evalField_q1->dataLayout().dimension(1),basis_q1->functional->dimension(1)); fm.registerEvaluator<panzer::Traits::Residual>(evaluator); fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]); } { Teuchos::RCP<std::vector<std::string> > dofNames = Teuchos::rcp(new std::vector<std::string>); dofNames->push_back(fieldName_qedge1); Teuchos::ParameterList pl; pl.set("Indexer Names",dofNames); pl.set("DOF Names",dofNames); pl.set("Basis",basis_qedge1); Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator = Teuchos::rcp(new panzer::GatherOrientation<panzer::Traits::Residual,panzer::Traits,int,int>(dofManager,pl)); TEST_EQUALITY(evaluator->evaluatedFields().size(),1); evalField_qedge1 = evaluator->evaluatedFields()[0]; TEST_EQUALITY(evalField_qedge1->name(),basis_qedge1->name()+" Orientation"); TEST_EQUALITY(evalField_qedge1->dataLayout().dimension(0),basis_qedge1->functional->dimension(0)); TEST_EQUALITY(evalField_qedge1->dataLayout().dimension(1),basis_qedge1->functional->dimension(1)); fm.registerEvaluator<panzer::Traits::Residual>(evaluator); fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]); } panzer::Traits::SetupData sd; 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); // <cell,basis> PHX::MDField<panzer::Traits::Residual::ScalarT> fieldData_q1(evalField_q1->name(),basis_q1->functional); // <cell,basis> PHX::MDField<panzer::Traits::Residual::ScalarT> fieldData_qedge1(evalField_qedge1->name(),basis_qedge1->functional); fm.getFieldData<panzer::Traits::Residual::ScalarT,panzer::Traits::Residual>(fieldData_q1); fm.getFieldData<panzer::Traits::Residual::ScalarT,panzer::Traits::Residual>(fieldData_qedge1); for(int i=0;i<fieldData_q1.size();i++) { TEST_EQUALITY(fieldData_q1[i],1); } for(int i=0;i<fieldData_qedge1.dimension(0);i++) { TEST_EQUALITY(fieldData_qedge1(i,0), 1); TEST_EQUALITY(fieldData_qedge1(i,1), 1); TEST_EQUALITY(fieldData_qedge1(i,2),-1); TEST_EQUALITY(fieldData_qedge1(i,3),-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] }